Tenchi
A contract-first Python framework for humans and agents.
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.
The same development workflow lets you inspect a feature, preview its structure, implement behavior, and review checks and compatibility evidence.
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 · Development workflow
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,
tests, and OpenAPI checks. It also includes AGENTS.md, project-local MCP
configuration, and tenchi.toml so people, agents, and CI share the
same application conventions and verification requirements.
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.
Make a reviewable change
- Inspect the affected feature with
uv run tenchi map --feature todosand read the source and tests it identifies. - Declare the boundary in a contract and preview generated files with
tenchi make ... --dry-runbefore creating them. - Implement behavior in plain Python, wire dependencies explicitly, and write tests for the requirement.
- Run
uv run tenchi checkfor formatting, lint, types, tests, architecture, and snapshot drift. Review compatibility changes before accepting new snapshots. - Run
uv run tenchi verify --base-ref <historical-ref>against the commit before the change, then review its receipt alongside the code and tests.
Use the pull-request base, previous push, or previous release for the
historical ref. verify needs committed baseline snapshots. A passing result
records the configured checks and compatibility evidence; reviewers still
judge whether the behavior and assertions meet the requirement.
Agents use these same commands with
--json, or access inspection, previews, and verification through the
agent MCP server. You choose the agent and
model provider.
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.
Continue with Secure the todos API to add authentication, owner-scoped storage, and tests for cross-user isolation.
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, serve them through application MCP, or add evaluations when the application runs AI behavior.
Adopt these runtime capabilities individually. Select optional feature modules
with tenchi make feature invoices --with jobs --with tools. Preview tools
adoption with tenchi make capability tools --dry-run --json, then follow its
composition and verification-policy instructions. tenchi new --full includes
all optional composition modules when you need that starting point.
Jobs, tasks, tools, and execute() call functions with request and context.
For a use case that also requires HTTP-specific params, query, or headers,
add an input adapter to reuse its
behavior from those entrypoints.
When Tenchi fits
Choose Tenchi when you want humans and agents to make backend changes through explicit contracts, predictable source structure, directly testable behavior, and reviewable verification evidence. The application model stays small, while development tooling is part of the framework's main workflow.
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
Contributors should read AGENTS.md for repository rules and PRODUCT.md for the framework's goals and design tradeoffs. Tenchi prioritizes a development workflow that humans and agents can understand and verify, built on a small, contract-first Python application model.
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.
Metadata
Release files for tenchi 0.19.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| tenchi-0.19.0.tar.gz | 1.1 MB | Without provenance | Details for tenchi-0.19.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| tenchi-0.19.0-py3-none-any.whl | Python 3 | none | any | Details for tenchi-0.19.0-py3-none-any.whl |
Total release size: 1.4 MB
Release files / tenchi-0.19.0.tar.gz
| Download URL | tenchi-0.19.0.tar.gz |
|---|---|
| Size | 1.1 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
59732998875fb6a183837d49fce8e7a51ed91c723b830e39e830fe0c8149f86b
|
|
BLAKE2b-256 checksum How to use checksums |
9c4c8d615565f11cbcd8c82b1db4b807816958fb15a0afbb5a5085772e1d607c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","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 / tenchi-0.19.0-py3-none-any.whl
| Download URL | tenchi-0.19.0-py3-none-any.whl |
|---|---|
| Size | 283.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7b49e9681768c0e51510a454169f55848c25e3d44913d360efebf9397dacef6e
|
|
BLAKE2b-256 checksum How to use checksums |
cd6282c0f9d791fb3e889c1ced0571034649f05c2c30c62cabab88b7cd0d86d6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","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}
|
Security for tenchi 0.19.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.