Tenchi
Typed Python APIs with explicit boundaries and plain application code.
Tenchi keeps Pydantic validation at the boundary, behavior in plain async
functions, and infrastructure behind typing.Protocol ports. A contract
describes an HTTP operation; route() binds it to a use case; your application
wires the dependencies.
There is no dependency-injection container, base controller, ORM, queue, scheduler, or model runtime hidden inside the framework.
Pre-1.0 software. Minor releases may change public APIs. Read stability and releases before adopting Tenchi for a long-lived service.
Documentation · First application · How Tenchi works
Build and run an application
Tenchi requires Python 3.12 or newer. Create a working application with uv:
uvx tenchi new my_app
cd my_app
uv sync
uv run tenchi check
uv run tenchi dev
The default starter includes the todos API, SQLite and memory adapters, and
OpenAPI checks. Use uvx tenchi new my_app --full to also generate composition
modules for jobs, operational tasks, application tools, evaluations, and
preflight checks, along with their supporting files. tenchi make feature
includes optional capability modules only when the application already composes
them.
Call the generated todos API from another terminal:
curl -i \
-H 'content-type: application/json' \
-d '{"title":"Buy milk"}' \
http://127.0.0.1:8000/todos
Open Swagger UI to inspect and call the same API in a browser. The first-application guide follows this request through the generated code and makes one behavior change.
The application model
Every HTTP operation follows the same path:
validated input -> contract + route -> async use case -> app-owned port -> adapter
A Pydantic model defines the boundary data:
# app/features/todos/schemas.py
from pydantic import BaseModel, Field
class CreateTodo(BaseModel):
title: str = Field(min_length=1)
class Todo(BaseModel):
id: str
title: str
completed: bool
A contract declares the HTTP operation:
# app/features/todos/contracts.py
from tenchi.contracts import contract
from .schemas import CreateTodo, Todo
create_todo_contract = contract(
method="POST",
path="/todos",
request=CreateTodo,
response=Todo,
status=201,
)
The use case contains the behavior. Its context is an application-owned frozen dataclass, so dependencies stay visible and type checked:
# app/features/todos/use_cases/create_todo.py
from app.server.context import AppContext
from ..schemas import CreateTodo, Todo
async def create_todo(request: CreateTodo, context: AppContext) -> Todo:
return await context.todos.create(title=request.title)
The route makes the binding explicit:
# app/features/todos/routes.py
from tenchi.routes import route, route_group
from .contracts import create_todo_contract
from .use_cases.create_todo import create_todo
routes = route_group(
route(create_todo_contract, create_todo),
)
route() checks the function signature during application composition. At
runtime, Tenchi validates input before the use case and validates its result
before the request scope commits. The same contract can also drive OpenAPI and
the typed Python client.
JSON responses are checked against their published schema and read back through
Pydantic before committing, including when a use case returns an existing model.
Response field aliases must be readable by that same model; use Field(alias=...)
for shared wire names. See successful responses.
Read How Tenchi works for the complete mental model or Build a feature to carry an operation through persistence and tests.
Add capabilities when you need them
The core model stays the same as the application grows:
- Add errors, authentication, or the typed client at the API boundary.
- Run the same use cases from workers and scripts, background jobs, or operational tasks.
- Add idempotency, observability, and deployment checks when preparing to ship.
- Expose selected use cases as application tools or use coding-agent workflows when those capabilities fit the project.
These features are independent. A Tenchi application does not need jobs, AI tools, evaluations, or historical compatibility checks to define and serve an HTTP API.
When Tenchi fits
Choose Tenchi when you want a long-lived typed JSON API with explicit dependencies, directly testable behavior, and boundary definitions that stay aligned with OpenAPI and client code.
Choose another framework when you need WebSockets, HTML templates, an ORM, admin UI, background runtime, or a large integration ecosystem as built-in features. The framework comparison describes the tradeoffs with FastAPI, Starlette, Litestar, and Django Ninja.
Development
uv sync
uv run ruff format --check .
uv run ruff check .
uv run pyright
uv run pytest
The documentation is a separate Next.js application in docs/. Run
bun install and bun run check from that directory to lint, type-check, test,
and build the static site.
Tenchi is available under the MIT License.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tenchi-0.18.0.tar.gz.
File metadata
- Download URL: tenchi-0.18.0.tar.gz
- Upload date:
- Size: 1.0 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.10 {"installer":{"name":"uv","version":"0.12.10","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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
84cd44d2577de56dcdd3bb7e51daf5fd3149d87d69c8d22f92b541a343286f25
|
|
| MD5 |
9620dc76280a2fde0e8ba0dcedf4b900
|
|
| BLAKE2b-256 |
4a803414279f46562ae50b0ac10813492abe8881d85c44ef6a370e5b838f4cdc
|
File details
Details for the file tenchi-0.18.0-py3-none-any.whl.
File metadata
- Download URL: tenchi-0.18.0-py3-none-any.whl
- Upload date:
- Size: 278.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.10 {"installer":{"name":"uv","version":"0.12.10","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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7ffe35eae54560f287615fc5b322456f14edf266067d03017163d82c47b04d1a
|
|
| MD5 |
58ce0c9084ebccc62022cdc54a0e503c
|
|
| BLAKE2b-256 |
62bb54adf6c5d4d9bc9772fc0a1e88e9cf2d689910cafe380d69f5adf92fa89a
|