Skip to main content

Tenchi

CI PyPI Python

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:

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

tenchi-0.18.0.tar.gz (1.0 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tenchi-0.18.0-py3-none-any.whl (278.9 kB view details)

Uploaded Python 3

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

Hashes for tenchi-0.18.0.tar.gz
Algorithm Hash digest
SHA256 84cd44d2577de56dcdd3bb7e51daf5fd3149d87d69c8d22f92b541a343286f25
MD5 9620dc76280a2fde0e8ba0dcedf4b900
BLAKE2b-256 4a803414279f46562ae50b0ac10813492abe8881d85c44ef6a370e5b838f4cdc

See more details on using hashes here.

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

Hashes for tenchi-0.18.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7ffe35eae54560f287615fc5b322456f14edf266067d03017163d82c47b04d1a
MD5 58ce0c9084ebccc62022cdc54a0e503c
BLAKE2b-256 62bb54adf6c5d4d9bc9772fc0a1e88e9cf2d689910cafe380d69f5adf92fa89a

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.18.0 This release

2 files

0.17.0

2 files

0.16.0

2 files

0.15.0

2 files

0.14.0

2 files

0.13.0

2 files

0.12.0

2 files

0.11.0

2 files

0.10.0

2 files

0.9.0

2 files

0.8.0

2 files

0.7.0

2 files

0.6.0

2 files

0.5.0

2 files

0.4.0

2 files

0.3.0

2 files

0.2.0

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page