nanosdk¶
A tiny, fully typed HTTP client core built on httpx and pydantic. Declare routes with request and response models; nanosdk gives you sync and async clients whose methods are typed end to end: arguments come from the request model's constructor, return values from the response type.
import nanosdk
from pydantic import BaseModel
class User(BaseModel):
id: int
login: str
class GetUser(BaseModel):
username: str
class GitHub(nanosdk.Client):
get_user = nanosdk.get("/users/{username}", request=GetUser, response=User)
with GitHub("https://api.github.com") as gh:
user = gh.get_user(username="octocat") # -> User; username: str is type-checked
No code generation and no metaclasses: a Route is a generic descriptor,
and the request model's __init__ signature becomes the signature of the bound method.
pyright, mypy and ty all see it.
Install¶
pip install nanosdk # or: uv add nanosdk
pip install "nanosdk[polars]" # + DataFrame helpers (also: pandas)
Python 3.13+, httpx ≥ 0.27, pydantic ≥ 2.6.
What's included¶
| Routes | get, post, ... with request fields placed in the path, query, headers, JSON, form or files (field markers) |
| Clients | Client and AsyncClient sharing one set of route declarations |
| Pagination | Cursor, Offset, PageNumber, LinkHeader or your own strategy; .iter() across pages |
| Retries | Retry with backoff, jitter and Retry-After |
| Auth | Bearer, ApiKey, OAuth2ClientCredentials, or any httpx.Auth |
| Transforms | Route.map, and DataFrames via polars or pandas |
| Code generation | nanosdk generate writes a typed client package from an OpenAPI spec |
| Hooks | _prepare_request, _process_response, _raise_for_status, _retry_policy; a client instance exposes only your routes, with_options and close |
Read the guide for a tour, or go straight to the API reference.