Arrest
- Documentation: https://s-bose.github.io/arrest/
Arrest is a type-safe HTTP client for Python built on httpx and Pydantic. Define your REST APIs declaratively — routes, request/response models, retries, and error handling in one place — and get full static analysis, autocomplete, and runtime validation for every call.
Features
- Type-safe — Pydantic models, dataclasses, dicts, lists, and XML models for request and response validation
- Declarative — Services, resources, and handlers keep your API surface organized
- JSON, Form, Multipart, and XML —
application/json,application/x-www-form-urlencoded,multipart/form-data, andapplication/xmlcontent types - Retries — Built-in exponential backoff via tenacity, or transport-level retries via httpx
- Exception handling — Custom hooks per exception type, clean
RequestErrorfor transport failures - OpenAPI codegen — Generate Arrest services and Pydantic models from an OpenAPI spec
H()helper — IDE-friendly handler definitions with keyword-argument autocomplete- Unified
Response[T]— One response type for all HTTP status codes withis_success,is_client_error, etc. - pydantic-ai toolset — Expose a
Serviceas agent-callable tools viaArrestToolset
Installation
uv
uv add arrest
pip
pip install arrest
OpenAPI support (optional)
uv add 'arrest[openapi]'
pydantic-ai toolset (optional)
uv add arrest --extra ai
Quickstart
from arrest import H, Resource, Service, GET, POST
user = Resource(
route="/users",
handlers=[
H(GET, "/"),
H(GET, "/{user_id}"),
H(POST, "/", request=NewUserRequest, response=UserResponse),
],
)
svc = Service(
name="api",
url="https://api.example.com/v1",
resources=[user],
)
# GET /users
resp = await svc.users.get("/")
if resp.is_success:
print(resp.data)
# POST /users with type-safe request body
resp = await svc.users.post("/", request=NewUserRequest(name="Alice", email="a@b.com"))
XML, Form, and File uploads
from pydantic_xml import BaseXmlModel, element
from arrest.params import Form, File
from arrest.types import UploadFile
# XML request/response
class XmlPayload(BaseXmlModel, tag="payload"):
key: str = element()
value: str = element()
# Form-encoded
class Login(BaseModel):
username: str = Form(...)
password: str = Form(...)
# Multipart file upload
class Profile(BaseModel):
name: str = Form(...)
avatar: UploadFile = File(...)
OpenAPI codegen
arrest --url https://petstore3.swagger.io/api/v3/openapi.json -o ./generated
Generates models.py, resources.py, and services.py from any OpenAPI spec.
pydantic-ai toolset
Expose a Service as agent-callable tools by opting handlers in with tool_meta:
from arrest.ai.meta import ToolMeta
from arrest.ai.toolset import ArrestToolset
from pydantic_ai import Agent
users = Resource(
name="users",
route="/users",
handlers=[
H(GET, "/{user_id}", None, User, tool_meta=ToolMeta(name="get_user_by_id")),
],
)
service = Service(name="example", url="http://localhost:8080/api", resources=[users])
toolset = ArrestToolset(service)
agent = Agent(model="anthropic:claude-haiku-4-5", toolsets=[toolset])
result = await agent.run("Look up user abc123.") # pydantic-ai enters/exits the toolset for you
See the pydantic-ai toolset docs for include/exclude filtering, retry behavior, and result truncation.
Contributing
See CONTRIBUTING.md.
License
MIT
Metadata
Release files for arrest 0.2.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| arrest-0.2.2.tar.gz | 728.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| arrest-0.2.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 767.0 kB
Release files / arrest-0.2.2.tar.gz
| Download URL | arrest-0.2.2.tar.gz |
|---|---|
| Size | 728.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a0a441218caf30a013d36e9ca67705e3810788c335914c6ecc7e445a895773e6
|
|
BLAKE2b-256 checksum How to use checksums |
315a582d3cdb45f7d52c4fb7c31b0fcbfdedddfed42bfb5466f006f54db69c31
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / arrest-0.2.2-py3-none-any.whl
| Download URL | arrest-0.2.2-py3-none-any.whl |
|---|---|
| Size | 38.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
17acf8b8c485a3b1bb610255e7f581c026198170ad14d4e787e569f135da055b
|
|
BLAKE2b-256 checksum How to use checksums |
3540b84361539722329746299a3d069c7a164b94cb339d61dd300f6b8b5a18c0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|