Skip to main content

Action0-Req

CI PyPI

Typed Python representations of HTTP requests and responses with convenient creation, duplication and manipulation. The companion of action0-url, which provides the URL representation.

Requires Python 3.11 or newer.

Full documentation including the API reference: https://laughinjar.github.io/action0-req/

Status: the core API is complete — the header name, status code and method constants, the Headers mapping, Request and Response, and sync/async body streaming via BodyProducer (BytesBody, FileBody, IterableBody, AsyncIterableBody).

Usage

Header, Status and Method are StrEnum/IntEnum constants for the IANA-registered header field names, status codes and request methods — every member is its string or integer value:

from action0.req import Header, Method, Status

print(Header.CONTENT_TYPE)  # Content-Type
print(Method.POST)  # POST
print(Status.NOT_FOUND)  # 404
print(Status.NOT_FOUND.phrase)  # Not Found
print(Status.NOT_FOUND.is_client_error)  # True

Headers is an ordered, case-insensitive, multi-value aware mapping of header fields that preserves the representation (order and casing) exactly:

from action0.req import Headers

headers = Headers({"Content-Type": "text/html"})
headers.add("Set-Cookie", "a=1")
headers.add("set-cookie", "b=2")
print(headers["CONTENT-TYPE"])  # text/html
print(headers.get_all("Set-Cookie"))  # ['a=1', 'b=2']
print(headers.as_str(separator="\n"))  # "\r\n" by default
# Content-Type: text/html
# Set-Cookie: a=1
# set-cookie: b=2

# repr()/str() redact secrets, only as_str() renders them
print(Headers({"Authorization": "Bearer tok"}))  # Headers(Authorization: ***)

Request combines a method, a Url (from action0-url), Headers, a meta dict for application metadata (never on the wire) and a body (bytes, str or a streaming BodyProducer — retrievable in any of the three forms):

from action0.req import Request

req = Request("https://api.example.com/items", query={"page": 2})
req.headers["Accept"] = "application/json"
print(req.as_str(separator="\n"))  # "\r\n" by default
# GET /items?page=2 HTTP/1.1
# Host: api.example.com
# Accept: application/json

post = req.copy(method="POST", body='{"a": 1}')
print(post.body_bytes())  # b'{"a": 1}'
print(post)  # Request(POST https://api.example.com/items?page=2)

Response mirrors it for the server side — status (with reason phrase fallback and category properties), headers, body:

from action0.req import Response, Status

resp = Response(Status.NOT_FOUND, headers={"Content-Type": "text/plain"}, body="not here")
print(resp.phrase, resp.is_client_error)  # Not Found True
print(resp.as_str(separator="\n"))  # "\r\n" by default
# HTTP/1.1 404 Not Found
# Content-Type: text/plain

Installation

Not published to PyPI yet; install straight from GitHub:

uv add "action0-req @ git+https://github.com/LaughInJar/action0-req"

Development

The project is managed with uv; uv run creates and syncs the virtual environment automatically:

uv run pytest        # run the tests (incl. the docstring examples as doctests)
uv run ruff check    # lint
uv run ruff format   # format
uv run mypy          # type-check (also: uv run pyright, uv run ty check)

# build the docs (Sphinx; deployed to GitHub Pages on push to main)
uv run --group docs sphinx-build -W docs docs/_build/html

Releasing

The version lives only in src/action0/req/__init__.py (__version__). To release: bump it, merge to main, then tag the release commit and push the tag — the release workflow re-runs all checks, verifies the tag matches __version__, builds sdist + wheel and publishes to PyPI via trusted publishing:

git tag v0.1.0
git push origin v0.1.0

AI-assisted development

In the spirit of transparency: most of this project's code, tests and documentation are written by Claude Code, Anthropic's coding agent — under human direction and review. The designs are specified, discussed and iterated by a human, and every change is reviewed before it lands in main or in a release. AI-authored commits carry a Co-Authored-By: Claude ... trailer.

About action0

This is just the namespace I like to use for my personal projects. I quite like namespaces.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

action0_req-0.1.0.tar.gz (98.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

action0_req-0.1.0-py3-none-any.whl (25.6 kB view details)

Uploaded Python 3

File details

Details for the file action0_req-0.1.0.tar.gz.

File metadata

  • Download URL: action0_req-0.1.0.tar.gz
  • Upload date:
  • Size: 98.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for action0_req-0.1.0.tar.gz
Algorithm Hash digest
SHA256 143debfd71c1ab8026d89e7b01c0dc5cb4ce278614f69cf35cf43eacb8728066
MD5 bf7cbb9e39916644a842082dc7e71b7f
BLAKE2b-256 e6a315efca2004782520b39cdf2fe51c6c506982ed29b52d47fcebc4f905cbb5

See more details on using hashes here.

Provenance

The following attestation bundles were made for action0_req-0.1.0.tar.gz:

Publisher: release.yml on LaughInJar/action0-req

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file action0_req-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: action0_req-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 25.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for action0_req-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d2d205566a3e2131c2dee0a9eb65de44ae071d5ee07e7a66f0ea889b55599d81
MD5 f9eef5e8bb8e3a45552b92a0056b98c1
BLAKE2b-256 a07cc0e01ac7cd97303d10faa088b37cf1acd5af0ee1a132c77f3e52dd0fc05c

See more details on using hashes here.

Provenance

The following attestation bundles were made for action0_req-0.1.0-py3-none-any.whl:

Publisher: release.yml on LaughInJar/action0-req

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page