# Coding Python Use Modern Libraries

> Use when choosing a Python library for a task (HTTP, JSON, XML, TOML, YAML, data models, enums, dates, compression, database, testing, linting and formatting, type checking, CLI parsing, retry/backoff, text encoding, layered configuration, MCP servers), writing new Python code that needs a dependency, or reviewing imports for dated defaults. For building/editing JSON/XML/YAML files specifically, see bitranox:files-edit-json, bitranox:files-edit-xml, bitranox:files-edit-yml. Public, mainstream defaults; adjust per project.

- Skill: `bitranox/coding-python-use-modern-libraries` (Agent Skill, multi-file: 10 files)
- Install (CLI): `npx skillmds@latest add bitranox/coding-python-use-modern-libraries`
- Raw SKILL.md: https://api.skillmd.com/api/skills/bitranox/coding-python-use-modern-libraries/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: bitranox (https://skillmd.com/u/bitranox)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/bitranox/coding-python-use-modern-libraries

---


# Modern Python library choices

Default to current, well-maintained libraries over dated stdlib or legacy packages when the
better option is clear. Install third-party deps via `uv` (a tool with `uvx`, or a script with
PEP-723 inline metadata run by `uv run`). Libraries on this list are pre-approved: just use
them and let `uv` fetch them, no need to ask. These are general public defaults, not absolutes:
a project's own conventions win.

## Adding an entry

Before adding a library here, vet it: trustworthy (reputable maintainer or community, not a
typo-squat), common (widely adopted), and modern (actively maintained, current releases). Each
new row must carry: a short **description** of what it is for (in the `Use` cell), the older
library/libraries it **replaces** (in the `Avoid` cell), and - **whenever the pick is not
self-evident** - **why** it is better (the parenthetical note in the `Use` cell). A swap that
explains itself (`pathlib.Path` over `os.path`, `pytest` over `unittest`) needs no parenthetical;
a contested or trade-off pick (`isal` vs `deflate`, one MySQL driver over another) always does.
Keep rows one line; do not add anyone's private or in-house packages here.

If the new library overlaps in function with an existing entry, resolve it - never leave two
rows silently competing for the same job:
- **Both have a place:** keep both and make the distinction explicit - state when to use which
  and why (e.g. one streaming vs one one-shot, sync vs async, simple vs full-featured).
- **The new one supersedes the old:** only when you are sure, replace the old row with the new
  one, move the now-obsolete library into the new row's `Avoid` cell, and say why it was
  replaced.

## Quick reference

`Use` names the pick with a brief why; `Avoid` names what it replaces.

| Task                                                                                | Use                                                                                                                                                                                                                                                                                             | Avoid                                                                                                                                                                                |
|-------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| HTTP / REST                                                                         | `httpx2` (HTTP/2; the new Pydantic-org successor to httpx) or httpx                                                                                                                                                                                                                             | `requests`                                                                                                                                                                           |
| JSON                                                                                | `orjson` (fast, correct, bytes)                                                                                                                                                                                                                                                                 | `json` stdlib for hot paths                                                                                                                                                          |
| TOML                                                                                | `rtoml`                                                                                                                                                                                                                                                                                         | `tomllib`, `tomli`                                                                                                                                                                   |
| YAML                                                                                | `ruamel.yaml` (round-trips comments)                                                                                                                                                                                                                                                            | `PyYAML`                                                                                                                                                                             |
| XML                                                                                 | `lxml` (XPath, schema validation, fast C parser)                                                                                                                                                                                                                                                | `xml.etree`, `minidom`, `xmltodict`                                                                                                                                                  |
| Structured data (pure / internal layers)                                            | `dataclasses` (stdlib, lightweight; trusted internal data)                                                                                                                                                                                                                                      | bare `dict`, `attrs`, hand-rolled classes                                                                                                                                            |
| Structured data at boundaries (parse input)                                         | `pydantic` (validates + parses untrusted input at the edge)                                                                                                                                                                                                                                     | bare `dict`, `attrs`, hand-rolled parsing                                                                                                                                            |
| Enums                                                                               | `IntEnum` / `StrEnum` (`StrEnum` is 3.11+)                                                                                                                                                                                                                                                      | plain `Enum`, magic strings                                                                                                                                                          |
| Terminal output                                                                     | `rich`                                                                                                                                                                                                                                                                                          | `colorama` (fallback only)                                                                                                                                                           |
| TUI                                                                                 | `textual`                                                                                                                                                                                                                                                                                       | `curses`                                                                                                                                                                             |
| Paths                                                                               | `pathlib.Path`                                                                                                                                                                                                                                                                                  | `os.path`                                                                                                                                                                            |
| Date / time                                                                         | stdlib `datetime` + `zoneinfo` (tz-aware)                                                                                                                                                                                                                                                       | `pytz`, naive datetimes                                                                                                                                                              |
| Compression (streaming / web / high speed)                                          | `isal` (igzip) - speed tuned, bigger files                                                                                                                                                                                                                                                      | `gzip` stdlib for throughput                                                                                                                                                         |
| Compression (archival, high ratio)                                                  | `deflate` (libdeflate bindings, high ratio, smaller files, C-extension dependency)                                                                                                                                                                                                              | `gzip` stdlib                                                                                                                                                                        |
| .env files                                                                          | `python-dotenv`                                                                                                                                                                                                                                                                                 | manual parsing                                                                                                                                                                       |
| Database (ODBC)                                                                     | `pyodbc`                                                                                                                                                                                                                                                                                        | raw ODBC bindings                                                                                                                                                                    |
| Database (MySQL)                                                                    | `mysql-connector-python` or `SQLAlchemy`                                                                                                                                                                                                                                                        | `PyMySQL`, `mysqlclient`                                                                                                                                                             |
| ORM / complex queries                                                               | `SQLAlchemy`                                                                                                                                                                                                                                                                                    | custom ORM, raw SQL for complex apps                                                                                                                                                 |
| Testing                                                                             | `pytest`                                                                                                                                                                                                                                                                                        | `unittest`                                                                                                                                                                           |
| Lint / format                                                                       | `ruff` (`ruff check` + `ruff format`; one Rust-fast tool replacing the whole flake8/black/isort stack, single config in pyproject)                                                                                                                                                              | `flake8`, `black`, `isort`, `pylint`, `pyupgrade`, `autoflake`                                                                                                                       |
| Type checking                                                                       | `pyright` in strict mode (fast, no plugin setup, same engine as the editor's Pylance, narrows better on `TypedDict`/`Protocol`/generics)                                                                                                                                                        | `mypy`, untyped code, blanket `# type: ignore`                                                                                                                                       |
| CLI args / parsing                                                                  | `rich-click` (Click-based, rich-formatted --help; drop-in for click)                                                                                                                                                                                                                            | `argparse`, `optparse`, `getopt`, bare `click`                                                                                                                                       |
| Subprocess                                                                          | `subprocess.run([...])` (argv list)                                                                                                                                                                                                                                                             | `os.system`, `shell=True`                                                                                                                                                            |
| PowerShell / Windows + OS admin objects                                             | `pwshpy` (typed records + lazy pipeline over native OS bindings, real exceptions, memory-bounded; use over the Subprocess row when the job is querying/mutating OS objects - services, registry, event log, ACLs, tasks, accounts - not launching a program; see bitranox:coding-python-pwshpy) | shelling out to `pwsh.exe` / `powershell` / `wevtutil` / `sc`; raw `pywin32` / `wmi` + manual text parsing                                                                           |
| Retry / backoff                                                                     | `tenacity` (declarative retry, exponential backoff + jitter; see bitranox:coding-resilience)                                                                                                                                                                                                    | hand-rolled `while`/`sleep` retry loops                                                                                                                                              |
| .gitignore parse / file filtering                                                   | `igittigitt` (git-exact, include mode, memory-bounded; see bitranox:coding-python-gitignore)                                                                                                                                                                                                    | hand-rolled `fnmatch`/`glob`/`re`; `gitignore_parser`; `pathspec`                                                                                                                    |
| Text encoding / mojibake repair                                                     | `ftfy` (repairs mixed / double-encoded mojibake, e.g. `Ã¼`->`ü`; leaves already-correct text untouched)                                                                                                                                                                                         | blanket `.encode('latin-1').decode('utf-8')` round-trips; manual char swaps                                                                                                          |
| MCP server / client (Model Context Protocol)                                        | `fastmcp` (decorator API for tools/resources/prompts plus auth, server composition, proxying, OpenAPI generation, built-in testing)                                                                                                                                                             | hand-rolled JSON-RPC; the official `mcp` SDK's low-level server API and its bundled `mcp.server.fastmcp` (frozen 1.0 feature set)                                                    |
| ICMP ping / reachability / traceroute / port scan / MAC / ARP / routes / interfaces | `ipscout` (in-process, no subprocess; unprivileged ICMP via the ping socket on Linux/macOS and iphlpapi on Windows, so no root or Administrator; also port scanning, neighbour and route lookup, subnets, wake-on-LAN and path MTU; see bitranox:coding-python-network-probe)                   | `icmplib` (forces raw sockets on Windows, needs Administrator), `scapy`, `python-nmap`, `netifaces` (unmaintained, needs a C build), `subprocess` around `ping`/`tracert`/`arp`/`ip` |
| Layered / cross-platform app config                                                 | `lib_layered_config` (merges defaults/app/host/user/.env/env into one immutable object with per-key provenance and profiles; resolves Linux/macOS/Windows paths; library + CLI; see bitranox:coding-python-layered-config)                                                                      | ad-hoc `os.environ` reads plus scattered file loads with hand-rolled precedence                                                                                                      |

## Structured data: pydantic at the edges, dataclasses inside

For any structured data in a Python app, parse untrusted/external input into `pydantic` models at
every boundary, and use `dataclasses` for pure internal layers. Do NOT use `attrs`, hand-woven
classes, or raw `dict`s for structured data. For the full end-to-end discipline (parse once at the
boundary, typed models throughout, Enums for fixed values, minimal conversions), use the
`bitranox:coding-python-enforce-data-architecture-strict` skill.

## HTTP example (httpx2)

    import httpx2 as httpx          # API-compatible with httpx
    with httpx.Client(timeout=30.0, proxy="http://user:pass@host:port") as client:
        r = client.get("https://api.example.com/data")
        r.raise_for_status()
        data = r.json()

Use a `Client` for many requests (connection reuse), and `AsyncClient` under asyncio. Both
support `proxy=` (one proxy), `mounts=` (per-scheme proxy transports), `timeout=`, and HTTP/2.
There is no `proxies=` kwarg - httpx dropped it in 0.28 and httpx2 never had it, so passing it
raises `TypeError: Client.__init__() got an unexpected keyword argument 'proxies'`.

`httpx2` (`github.com/pydantic/httpx2`) is the legitimate Pydantic-org-stewarded successor to httpx
and a drop-in replacement. Some security scanners flag it as a typosquat - that is a FALSE POSITIVE
(verified: Pydantic org + Trusted Publisher + Sigstore). If a scanner re-flags it, re-verify the
publisher independently and surface it to the user rather than auto-dismissing; do not silently
swap it out.

## Notes

- Prefer a library over an external command-line tool: `httpx2` instead of shelling out to
  `curl`, stdlib/`orjson` instead of `jq`, `re`/stdlib instead of `grep`/`sed`. Libraries are
  the same on every OS; external commands may be missing or take different flags on Windows.
- Reach for stdlib when no third-party library is warranted (small glue, no hot path): the
  point is "best tool", not "most dependencies".
- Logging and CLI framework are deliberately left to each project's own conventions rather
  than prescribed here.
- **`subprocess` raises a DIFFERENT exception type per OS for the same condition, so never branch
  on which one you got.** A missing `cwd` raises `FileNotFoundError` on POSIX but
  `OSError [WinError 267] "The directory name is invalid"` on Windows, so a
  `FileNotFoundError -> 127 / OSError -> 126` mapping returns two different exit codes for one
  condition - and the POSIX run stays green because POSIX happens to raise the type the code
  expected. Pre-check the path yourself (`Path(cwd).exists()` / `.is_dir()`) and decide the result
  explicitly, then run the missing-path test on Windows before trusting its exit code.
- **On 3.14+, `except A, B:` without parentheses is VALID (PEP 758) and catches both.** On 3.13 and
  earlier the same line is a `SyntaxError` under the old Python-2 `except E, name:` grammar, so it
  reads like an obvious bug. Check `requires-python` or the interpreter and probe with `python -c`
  before "fixing" it; on 3.14+ adding parentheses is a style choice, not a correction.

