Typed Client
Nestipy can build a typed HTTP client directly from your controllers. This mirrors the “router‑based client” flow you get in frameworks like Hono or tRPC, but stays fully HTTP.
Generate From App
from nestipy.core import NestipyFactory
from app_module import AppModule
app = NestipyFactory.create(AppModule)
# Generate a sync client
app.generate_typed_client("clients/api_client.py", class_name="ApiClient")
# Generate an async client
app.generate_typed_client(
"clients/api_client_async.py",
class_name="ApiClientAsync",
async_client=True,
)
The generator reads:
- Controller route metadata
- HTTP method + path
- Parameter sources (Param, Query, Body, Header)
- Return annotations (for type hints)
Generate From Router Spec
from nestipy.router import build_router_spec, write_client_file, write_typescript_client_file
from app_module import AppModule
spec = build_router_spec([AppModule], prefix="/api")
write_client_file(spec, "clients/api_client.py", class_name="ApiClient")
write_typescript_client_file(spec, "clients/api_client.ts", class_name="ApiClient")
Client Usage
from clients.api_client import ApiClient
client = ApiClient(base_url="http://localhost:8001")
cat = client.get_cat(1, query={"q": "tom"})
client.close()
Notes:
- Query/body/header values set to None are skipped.
- Body values support dicts, dataclasses, and Pydantic models.
- The generated client can use httpx, requests, or any client that exposes .request(...).
- Path params are positional arguments; query/headers/body/cookies are grouped into dicts.
Dynamic HTTP Clients
You can inject any HTTP implementation:
import requests
from clients.api_client import ApiClient
session = requests.Session()
client = ApiClient(base_url="http://localhost:8001", client=session)
Or pass a custom request function:
def request(method, url, **kwargs):
...
client = ApiClient(base_url="http://localhost:8001", request=request)
TypeScript Client
from nestipy.core import NestipyFactory
from app_module import AppModule
app = NestipyFactory.create(AppModule)
app.generate_typescript_client("clients/api_client.ts", class_name="ApiClient")
The generated client uses fetch by default and accepts a custom fetcher.
It groups inputs into a single options object with query, headers, body, and cookies fields.
Path params are positional arguments.
Router Spec Endpoint (Optional)
Expose the RouterSpec JSON only when explicitly enabled:
from nestipy.core import NestipyFactory, NestipyConfig
app = NestipyFactory.create(
AppModule,
config=NestipyConfig(router_spec_enabled=True),
)
By default the endpoint is disabled.
You can also protect it with a token:
The endpoint defaults to /_router/spec and accepts the token via:
- x-router-spec-token header
- ?token=... query param
You can override the path with router_spec_path="/internal/router-spec".
CLI Codegen (Optional)
Enable codegen explicitly via the commander entrypoint:
import asyncio
import sys
from nestipy.commander import CommandFactory
from app_module import AppModule
if __name__ == "__main__":
command = CommandFactory.create(AppModule)
asyncio.run(command.run(sys.argv[1], tuple(sys.argv[2:])))
Then run:
Generate TypeScript:
Support us
Nestipy is a project released under the MIT license, meaning it's open source and freely available for use and modification. Its development thrives with the generous contributions of these fantastic individuals.