Claude Code for os and os.path: System Interface in Python — Claude Skills 360 Blog
Blog / AI / Claude Code for os and os.path: System Interface in Python
AI

Claude Code for os and os.path: System Interface in Python

Published: July 26, 2028
Read time: 5 min read
By: Claude Skills 360

Python’s os module provides a portable interface to the operating system. import os. environ: os.environ["HOME"]; os.environ.get("PORT", "8080"); os.environ["KEY"] = "val". getenv: os.getenv("KEY", default). path.join: os.path.join("/base", "sub", "file.txt"). path.split: os.path.split("/a/b/c.txt") → (“a/b”, “c.txt”). path.basename: os.path.basename("/a/b/c.txt") → “c.txt”. path.dirname: os.path.dirname("/a/b/c.txt") → “/a/b”. path.splitext: os.path.splitext("file.tar.gz") → (“file.tar”, “.gz”). path.abspath: os.path.abspath("."). path.realpath: follows symlinks. path.expanduser: os.path.expanduser("~/file"). path.exists / isfile / isdir / islink. getcwd: os.getcwd(). chdir: os.chdir(path). makedirs: os.makedirs(path, exist_ok=True). listdir: os.listdir(".") → list of names. scandir: with os.scandir(".") as it: for e in it: e.name, e.stat(). walk: for root, dirs, files in os.walk("/path"):. stat: st = os.stat(path); st.st_size, st.st_mtime, st.st_mode. rename: os.rename(src, dst). replace: os.replace(src, dst) — atomic. remove: os.remove(path). rmdir: os.rmdir(path). symlink: os.symlink(target, link). readlink: os.readlink(link). cpu_count: os.cpu_count(). getpid / getppid: os.getpid(). urandom: os.urandom(32) — crypto-secure bytes. Claude Code generates env loaders, file walkers, directory scanners, and deployment helpers.

CLAUDE.md for os

## os Stack
- Stdlib: import os; from pathlib import Path  (prefer Path for new code)
- Env:    os.getenv("KEY", "default")  |  os.environ["KEY"]
- Path:   os.path.join(base, sub)  — or Path(base) / sub
- Check:  os.path.exists/isfile/isdir(path)
- Dir:    os.makedirs(path, exist_ok=True)
- Walk:   for root, dirs, files in os.walk(top):
- Rand:   os.urandom(32)  — crypto-safe bytes

os System Interface Pipeline

# app/osutil.py — env, path, walk, scandir, stat, process, urandom
from __future__ import annotations

import os
import stat
from pathlib import Path
from typing import Any, Callable, Iterator


# ─────────────────────────────────────────────────────────────────────────────
# 1. Environment helpers
# ─────────────────────────────────────────────────────────────────────────────

def require_env(key: str) -> str:
    """
    Return env var value; raise EnvironmentError if missing.

    Example:
        secret = require_env("DATABASE_URL")
    """
    val = os.environ.get(key)
    if val is None:
        raise EnvironmentError(f"Required environment variable {key!r} is not set")
    return val


def load_env_subset(keys: list[str], defaults: dict[str, str] | None = None) -> dict[str, str]:
    """
    Return a dict of specific env vars, using defaults for missing ones.

    Example:
        cfg = load_env_subset(["HOST", "PORT", "DEBUG"], defaults={"PORT": "8080"})
    """
    defaults = defaults or {}
    return {k: os.environ.get(k, defaults.get(k, "")) for k in keys}


def with_env(extra: dict[str, str]) -> dict[str, str]:
    """
    Return os.environ merged with extra vars — suitable for subprocess env.

    Example:
        env = with_env({"NODE_ENV": "production", "PORT": "9000"})
        subprocess.run(cmd, env=env)
    """
    return {**os.environ, **extra}


# ─────────────────────────────────────────────────────────────────────────────
# 2. Path helpers (os.path style, for legacy/compatibility code)
# ─────────────────────────────────────────────────────────────────────────────

def join(*parts: str) -> str:
    """
    Join path parts using os.path.join.

    Example:
        p = join("/var/data", "uploads", "img.png")
    """
    return os.path.join(*parts)


def ensure_dir(path: str | Path, mode: int = 0o755) -> str:
    """
    Create path and all parents if they don't exist. Return path.

    Example:
        ensure_dir("output/reports")
        ensure_dir("/tmp/myapp/cache")
    """
    os.makedirs(str(path), mode=mode, exist_ok=True)
    return str(path)


def file_extension(path: str | Path) -> str:
    """
    Return the final file extension (e.g. ".py"), lowercase.

    Example:
        file_extension("app.tar.gz")     # ".gz"
        file_extension("Makefile")       # ""
    """
    return os.path.splitext(str(path))[1].lower()


def stem(path: str | Path) -> str:
    """
    Return filename without the last extension.

    Example:
        stem("report.2024.csv")  # "report.2024"
    """
    return os.path.splitext(os.path.basename(str(path)))[0]


def home_dir() -> str:
    """Return the current user's home directory."""
    return os.path.expanduser("~")


# ─────────────────────────────────────────────────────────────────────────────
# 3. Directory scanning and walking
# ─────────────────────────────────────────────────────────────────────────────

def list_files(
    directory: str | Path,
    pattern: str | None = None,
    recursive: bool = False,
) -> list[str]:
    """
    List files in directory (absolute paths). Optionally filter by extension prefix.

    Example:
        py_files  = list_files("src", pattern=".py", recursive=True)
        all_files = list_files("dist")
    """
    root = str(directory)
    results = []
    if recursive:
        for dirpath, _, filenames in os.walk(root):
            for f in filenames:
                full = os.path.join(dirpath, f)
                if pattern is None or f.endswith(pattern):
                    results.append(full)
    else:
        with os.scandir(root) as it:
            for entry in it:
                if entry.is_file(follow_symlinks=False):
                    if pattern is None or entry.name.endswith(pattern):
                        results.append(entry.path)
    return sorted(results)


def walk_files(
    root: str | Path,
    extensions: set[str] | None = None,
    skip_dirs: set[str] | None = None,
) -> Iterator[str]:
    """
    Recursively walk a directory, yielding file paths.

    Example:
        for path in walk_files("src", extensions={".py", ".pyi"}, skip_dirs={"__pycache__"}):
            process(path)
    """
    skip = skip_dirs or set()
    for dirpath, dirnames, filenames in os.walk(str(root)):
        dirnames[:] = [d for d in dirnames if d not in skip]
        for f in filenames:
            if extensions is None or os.path.splitext(f)[1].lower() in extensions:
                yield os.path.join(dirpath, f)


def dir_tree(root: str | Path, max_depth: int = 3, indent: int = 0) -> str:
    """
    Return a text representation of a directory tree.

    Example:
        print(dir_tree("src", max_depth=2))
    """
    root = str(root)
    name = os.path.basename(root) or root
    lines = ["  " * indent + name + "/"]
    if max_depth > 0 and os.path.isdir(root):
        try:
            entries = sorted(os.listdir(root))
        except PermissionError:
            return "\n".join(lines)
        for entry in entries[:20]:  # limit display
            full = os.path.join(root, entry)
            if os.path.isdir(full):
                lines.append(dir_tree(full, max_depth - 1, indent + 1))
            else:
                lines.append("  " * (indent + 1) + entry)
    return "\n".join(lines)


# ─────────────────────────────────────────────────────────────────────────────
# 4. File metadata and stat
# ─────────────────────────────────────────────────────────────────────────────

def file_info(path: str | Path) -> dict[str, Any]:
    """
    Return a dict of file metadata.

    Example:
        info = file_info("app.py")
        info["size_bytes"]
        info["mtime"]
    """
    p = str(path)
    st = os.stat(p)
    return {
        "path":       os.path.abspath(p),
        "name":       os.path.basename(p),
        "size_bytes": st.st_size,
        "mtime":      st.st_mtime,
        "is_file":    os.path.isfile(p),
        "is_dir":     os.path.isdir(p),
        "is_symlink": os.path.islink(p),
        "readable":   os.access(p, os.R_OK),
        "writable":   os.access(p, os.W_OK),
        "executable": os.access(p, os.X_OK),
    }


def newest_file(directory: str | Path, pattern: str | None = None) -> str | None:
    """
    Return the most recently modified file in directory or None.

    Example:
        latest = newest_file("logs", ".log")
    """
    files = list_files(directory, pattern=pattern)
    return max(files, key=os.path.getmtime, default=None)


def total_size(path: str | Path) -> int:
    """
    Return total bytes of all files under path (recursive).

    Example:
        mb = total_size("data") / 1_048_576
    """
    total = 0
    for _, _, filenames in os.walk(str(path)):
        for f in filenames:
            try:
                total += os.path.getsize(os.path.join(_, f))
            except OSError:
                pass
    return total


# ─────────────────────────────────────────────────────────────────────────────
# 5. Process and system info
# ─────────────────────────────────────────────────────────────────────────────

def process_info() -> dict[str, Any]:
    """
    Return current process metadata.

    Example:
        info = process_info()
        print(f"PID={info['pid']} on {info['cpu_count']} CPUs")
    """
    return {
        "pid":       os.getpid(),
        "ppid":      os.getppid(),
        "cwd":       os.getcwd(),
        "cpu_count": os.cpu_count(),
        "uid":       os.getuid() if hasattr(os, "getuid") else None,
        "gid":       os.getgid() if hasattr(os, "getgid") else None,
    }


def secure_random(n: int = 32) -> bytes:
    """
    Return n cryptographically secure random bytes from the OS.
    Equivalent to os.urandom but with a clearer name.

    Example:
        key  = secure_random(32)     # 256-bit key
        salt = secure_random(16)     # 128-bit salt
        nonce = secure_random(12)    # AES-GCM nonce
    """
    return os.urandom(n)


# ─────────────────────────────────────────────────────────────────────────────
# Demo
# ─────────────────────────────────────────────────────────────────────────────

if __name__ == "__main__":
    import tempfile

    print("=== os demo ===")

    print("\n--- require_env / load_env_subset ---")
    os.environ["DEMO_HOST"] = "localhost"
    os.environ["DEMO_PORT"] = "8080"
    cfg = load_env_subset(["DEMO_HOST", "DEMO_PORT", "DEMO_DEBUG"], defaults={"DEMO_DEBUG": "false"})
    print(f"  cfg: {cfg}")

    print("\n--- path helpers ---")
    p = join("/var", "data", "uploads", "img.png")
    print(f"  join:      {p!r}")
    print(f"  extension: {file_extension(p)!r}")
    print(f"  stem:      {stem(p)!r}")
    print(f"  home:      {home_dir()!r}")

    print("\n--- directory scanning ---")
    with tempfile.TemporaryDirectory() as td:
        # Create test tree
        ensure_dir(os.path.join(td, "src", "app"))
        ensure_dir(os.path.join(td, "src", "__pycache__"))
        for name in ["main.py", "utils.py", "README.md"]:
            open(os.path.join(td, "src", name), "w").close()
        for name in ["models.py", "cache.cpython-312.pyc"]:
            open(os.path.join(td, "src", "app", name), "w").close()

        py_files = list_files(os.path.join(td, "src"), pattern=".py", recursive=True)
        print(f"  .py files: {[os.path.basename(f) for f in py_files]}")

        walked = list(walk_files(td, extensions={".py"}, skip_dirs={"__pycache__"}))
        print(f"  walk (skip pycache): {[os.path.basename(f) for f in walked]}")

        print("\n--- dir_tree ---")
        print(dir_tree(os.path.join(td, "src"), max_depth=2))

        print("\n--- file_info ---")
        main = os.path.join(td, "src", "main.py")
        info = file_info(main)
        print(f"  name={info['name']!r}  size={info['size_bytes']}  readable={info['readable']}")

        print("\n--- total_size ---")
        sz = total_size(td)
        print(f"  total: {sz} bytes")

    print("\n--- process_info ---")
    info = process_info()
    print(f"  pid={info['pid']}  cpu_count={info['cpu_count']}  cwd={info['cwd']!r}")

    print("\n--- secure_random ---")
    key = secure_random(32)
    print(f"  32 random bytes: {key.hex()[:24]}...")

    print("\n=== done ===")

For the pathlib alternative — pathlib.Path (also stdlib) provides an object-oriented API for all the path operations in os.path with p / "sub" joining, p.read_text(), p.glob("*.py"), and .rglob() for recursive search — use pathlib.Path for new code dealing with files and directories (it’s now the recommended stdlib approach), os and os.path for code interoperating with legacy APIs, subprocess environments (env=), process attributes (os.getpid(), os.cpu_count()), and os.urandom() which have no pathlib equivalent. For the environs alternative — environs (PyPI) provides typed environment variable parsing: env.str("HOST"), env.int("PORT"), env.bool("DEBUG"), env.list("ALLOWED_HOSTS") with automatic casting and validation; os.environ.get() returns raw strings requiring manual casting — use environs or python-decouple in twelve-factor applications where strongly typed env var parsing with validation is critical, os.getenv in scripts, utilities, and library code where pulling a raw string value is sufficient. The Claude Skills 360 bundle includes os skill sets covering require_env()/load_env_subset()/with_env() environment helpers, join()/ensure_dir()/file_extension()/stem()/home_dir() path utilities, list_files()/walk_files()/dir_tree() directory scanning, file_info()/newest_file()/total_size() metadata helpers, and process_info()/secure_random() system utilities. Start with the free tier to try system interface automation and os pipeline code generation.

Keep Reading

AI

Claude Code for email.contentmanager: Python Email Content Accessors

Read and write EmailMessage body content with Python's email.contentmanager module and Claude Code — email contentmanager ContentManager for the class that maps content types to get and set handler functions allowing EmailMessage to support get_content and set_content with type-specific behaviour, email contentmanager raw_data_manager for the ContentManager instance that handles raw bytes and str payloads without any conversion, email contentmanager content_manager for the standard ContentManager instance used by email.policy.default that intelligently handles text plain text html multipart and binary content types, email contentmanager get_content_text for the handler that returns the decoded text payload of a text-star message part as a str, email contentmanager get_content_binary for the handler that returns the raw decoded bytes payload of a non-text message part, email contentmanager get_data_manager for the get-handler lookup used by EmailMessage get_content to find the right reader function for the content type, email contentmanager set_content text for the handler that creates and sets a text part correctly choosing charset and transfer encoding, email contentmanager set_content bytes for the handler that creates and sets a binary part with base64 encoding and optional filename Content-Disposition, email contentmanager EmailMessage get_content for the method that reads the message body using the registered content manager handlers, email contentmanager EmailMessage set_content for the method that sets the message body and MIME headers in one call, email contentmanager EmailMessage make_alternative make_mixed make_related for the methods that convert a simple message into a multipart container, email contentmanager EmailMessage add_attachment for the method that attaches a file or bytes to a multipart message, and email contentmanager integration with email.message and email.policy and email.mime and io for building high-level email readers attachment extractors text body accessors HTML readers and policy-aware MIME construction pipelines.

5 min read Feb 12, 2029
AI

Claude Code for email.charset: Python Email Charset Encoding

Control header and body encoding for international email with Python's email.charset module and Claude Code — email charset Charset for the class that wraps a character set name with the encoding rules for header encoding and body encoding describing how to encode text for that charset in email messages, email charset Charset header_encoding for the attribute specifying whether headers using this charset should use QP quoted-printable encoding BASE64 encoding or no encoding, email charset Charset body_encoding for the attribute specifying the Content-Transfer-Encoding to use for message bodies in this charset such as QP or BASE64, email charset Charset output_codec for the attribute giving the Python codec name used to encode the string to bytes for the wire format, email charset Charset input_codec for the attribute giving the Python codec name used to decode incoming bytes to str, email charset Charset get_output_charset for returning the output charset name, email charset Charset header_encode for encoding a header string using the charset's header_encoding method, email charset Charset body_encode for encoding body content using the charset's body_encoding, email charset Charset convert for converting a string from the input_codec to the output_codec, email charset add_charset for registering a new charset with custom encoding rules in the global charset registry, email charset add_alias for adding an alias name that maps to an existing registered charset, email charset add_codec for registering a codec name mapping for use by the charset machinery, and email charset integration with email.message and email.mime and email.policy and email.encoders for building international email senders non-ASCII header encoders Content-Transfer-Encoding selectors charset-aware message constructors and MIME encoding pipelines.

5 min read Feb 11, 2029
AI

Claude Code for email.utils: Python Email Address and Header Utilities

Parse and format RFC 2822 email addresses and dates with Python's email.utils module and Claude Code — email utils parseaddr for splitting a display-name plus angle-bracket address string into a realname and email address tuple, email utils formataddr for combining a realname and address string into a properly quoted RFC 2822 address with angle brackets, email utils getaddresses for parsing a list of raw address header strings each potentially containing multiple comma-separated addresses into a list of realname address tuples, email utils parsedate for parsing an RFC 2822 date string into a nine-tuple compatible with time.mktime, email utils parsedate_tz for parsing an RFC 2822 date string into a ten-tuple that includes the UTC offset timezone in seconds, email utils parsedate_to_datetime for parsing an RFC 2822 date string into an aware datetime object with timezone, email utils formatdate for formatting a POSIX timestamp or the current time as an RFC 2822 date string with optional usegmt and localtime flags, email utils format_datetime for formatting a datetime object as an RFC 2822 date string, email utils make_msgid for generating a globally unique Message-ID string with optional idstring and domain components, email utils decode_rfc2231 for decoding an RFC 2231 encoded parameter value into a tuple of charset language and value, email utils encode_rfc2231 for encoding a string as an RFC 2231 encoded parameter value, email utils collapse_rfc2231_value for collapsing a decoded RFC 2231 tuple to a Unicode string, and email utils integration with email.message and email.headerregistry and datetime and time for building address parsers date formatters message-id generators header extractors and RFC-compliant email construction utilities.

5 min read Feb 10, 2029

Put these ideas into practice

Claude Skills 360 gives you production-ready skills for everything in this article — and 2,350+ more. Start free or go all-in.

Back to Blog

Get 360 skills free