# How I write Python

## Contents


## Library recommendations {#lib-recs}

### HTTP client {#http}

I previously recommended [HTTPX](https://www.python-httpx.org/).
However, the project has recently had troubled development, which has been documented in a [post announcing a fork](https://tildeweb.nl/~michiel/httpxyz.html).
I don&#39;t have a current recommendation for a third-party library.

HTTPX has a similar API to [Requests](https://docs.python-requests.org/) in both sync and async and with integrated type annotations.
(There are third-party type annotations for Requests.)
It makes it easy to use a SOCKS proxy.

My candidates for replacing HTTPX include:

- [aiohttp](https://docs.aiohttp.org/) with [aiohttp-socks](https://github.com/romis2012/aiohttp-socks) for async only
- [curl_cffi](https://github.com/lexiforest/curl_cffi), typed bindings for cURL
- [HTTPXYZ](https://httpxyz.org/), the fresh HTTPX fork
- [Niquests](https://github.com/jawah/niquests), a fork of Requests with added async, HTTP/2, and type annotations
- [pyreqwest](https://github.com/MarkusSintonen/pyreqwest) based on the Rust reqwest library
- [wreq-python](https://github.com/0x676e67/wreq-python) based on the Rust wreq library

[`urllib.request`](https://docs.python.org/3/library/urllib.request.html) in the standard library continues to work well as a fallback.

### DOM

[Selectolax](https://github.com/rushter/selectolax) is faster than [Beautiful Soup](https://beautiful-soup-4.readthedocs.io/) with either [html5-parser](https://html5-parser.readthedocs.io/) or [html5lib](https://github.com/html5lib/html5lib-python).
It is easier to install than html5-parser since it doesn&#39;t require disabling binary wheels for [lxml](https://lxml.de/).
The API design helps with type safety.

### Configuration {#config}

[tomllib](https://docs.python.org/3/library/tomllib.html) has been part of the standard library since Python 3.11.
While [`configparser`](https://docs.python.org/3/library/configparser.html) is also in the standard library, [TOML](https://toml.io) is standardized and allows more structure.
For writing TOML files, there is [tomli-w](https://github.com/hukkin/tomli-w).

### Date and time {#date-time}

[Whenever](https://whenever.readthedocs.io/) correctly handles daylight saving time and uses types to prevent common mistakes.
For more context, see [&#34;Ten Python datetime pitfalls, and what libraries are (not) doing about it&#34;](https://dev.arie.bovenberg.net/blog/python-datetime-pitfalls/) by Arie Bovenberg (2024).

### Markdown rendering {#markdown}

[markdown-it-py](https://github.com/executablebooks/markdown-it-py) follows the [CommonMark](https://commonmark.org/) standard, is typed, and is [faster](https://markdown-it-py.readthedocs.io/en/latest/performance.html) than other CommonMark libraries implemented in pure Python.

### Serialization {#serialization}

[msgspec](https://jcristharif.com/msgspec/) provides fast JSON, MessagePack, TOML, and YAML serialization of [dataclass](https://docs.python.org/3/library/dataclasses.html)-like classes with type support.

### Templating {#template}

[Jinja](https://jinja.palletsprojects.com/) offers expressive, flexible templates for HTML and other text formats.
Its [macros](https://jinja.palletsprojects.com/en/stable/templates/#macros) have proven particularly useful in practice.

### URLs {#url}

[yarl](https://yarl.aio-libs.org/en/latest/) percent-decodes paths and has a well-designed API with properly named fields and query parameters stored in a `MultiDict`.

As a fallback, [`urllib.parse`](https://docs.python.org/3/library/urllib.parse.html) in the standard library can handle both parsing and quoting.

### XML

[xmltodict](https://github.com/martinblech/xmltodict) is the most fun XML library I&#39;ve used.
Despite its name, xmltodict is bidirectional: it can both parse and generate XML.


## Development tooling {#dev-tool}

I have a [Copier template](https://github.com/dbohdan/python-template) that packages my preferred development tooling.
[Type checkers](#type-checkers) are covered in the static-typing section.

### Project management {#pm}

[uv](https://github.com/astral-sh/uv) is fast and manages Python versions as well as projects.
It can also run single-file [scripts with dependencies](/scripts-with-dependencies).

As a fallback, [Poetry](https://github.com/python-poetry/poetry) is capable and uses standard metadata since version 2.
Poetry works on platforms where uv doesn&#39;t, like NetBSD, though it has [problems with PyTorch](https://github.com/python-poetry/poetry/issues/6409).

### Linting and formatting {#lint-format}

[codespell](https://github.com/codespell-project/codespell) checks for common misspellings in code.
[Ruff](https://docs.astral.sh/ruff/) is a fast Python linter and code formatter written in Rust that can replace many other tools, like `black`, `isort`, `pylint`, and `flake8`.

### Distribution {#distrib}

[shiv](https://github.com/linkedin/shiv) is a command line utility for building self-contained Python [zipapps](https://docs.python.org/3/library/zipapp.html).
Its only serious downside is that it only packages binary dependencies [for the current platform](https://github.com/linkedin/shiv/issues/26).

### Testing {#test}

[pytest](https://docs.pytest.org/) produces more readable tests with `assert` compared to the specialized assertions in [`unittest`](https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertRaisesRegex).
It has a coverage plugin, [pytest-cov](https://pytest-cov.readthedocs.io/).

As a fallback, `unittest` in the standard library isn&#39;t bad.


## Static typing {#typing}

Python has robust optional static typing.
If you took a break from Python in the mid-2010s like I did,
it may come as a surprise.
This page links to resources for writing statically-typed Python,
plus a few that make use of type hints at runtime.

### Articles {#typing-articles}

- &lt;!-- 2021-04-26 --&gt;[&#34;Deploying a distributed system? A type system helps a lot&#34;](http://catern.com/progsys.html), Spencer Baugh (2021).
- &lt;!-- 2023-04-06 --&gt;[&#34;Algebraic Data Types in (typed) Python&#34;](https://threeofwands.com/algebraic-data-types-in-python/), Tin Tvrtković (2023)
- &lt;!-- 2023-05-20 --&gt;[&#34;Writing Python like it&#39;s Rust&#34;](https://kobzol.github.io/rust/python/2023/05/20/writing-python-like-its-rust.html), Jakub Beránek (2023). The author&#39;s style resembles the style I have arrived it.
- &lt;!-- 2024-04-12 --&gt;[&#34;Shape typing in Python&#34;](https://jameshfisher.com/2024/04/12/shape-typing-in-python/), Jim Fisher (2024)

### Exercises {#typing-exercises}

- [Python Type Challenges](https://github.com/laike9m/Python-Type-Challenges)

### Official documentation {#typing-official-docs}

- [&#34;Static Typing with Python&#34;](https://typing.readthedocs.io/en/latest/)
- [&#34;`typing` --- Support for type hints&#34;](https://docs.python.org/3/library/typing.html)

### Packages {#typing-packages}

#### CLI {#typing-cli}

- [jsonargparse](https://github.com/omni-us/jsonargparse)---&#34;Implement minimal boilerplate CLIs derived from type hints and parse from command line, config files and environment variables&#34;
- [Typed Argument Parser (Tap)](https://github.com/swansonk14/typed-argument-parser)---&#34;Typed argument parser for Python&#34;
- [Typer](https://github.com/tiangolo/typer)---&#34;Typer, build great CLIs. Easy to code. Based on Python type hints.&#34;
- [tyro](https://github.com/brentyi/tyro)---&#34;Zero-effort CLI interfaces &amp; config objects, from types&#34;

#### Error handling {#typing-errors}

- [poltergeist](https://github.com/alexandermalyga/poltergeist)---&#34;Rust-like error handling in Python, with type-safety in mind.&#34;

### Type checkers {#type-checkers}

My preferred type checker is [Pyright](https://github.com/microsoft/pyright).

- Fast
- Good error messages

&lt;!-- Break. --&gt;

- [Python type checkers](https://github.com/stars/dbohdan/lists/python-type-checkers)---my GitHub list

### See also {#typing-see-also}

- [&#34;Awesome Python Typing&#34;](https://github.com/typeddjango/awesome-python-typing)---a collection of links to software and articles

## Page metadata

URL: <https://dbohdan.com/python.md>

Published 2024-06-15, updated 2026-04-07.

Tags:

- bookmarks
- programming
- programming languages
- Python
