Skip to content

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.