API Reference 📚

Complete API reference for all Tatami components.

Core Components

Router Classes

class tatami.router.BaseRouter(title=None, description=None, summary=None, version='0.0.1', path=None, tags=None)[source]

Bases: TatamiObject

Parameters:
  • title (str | None)

  • description (str | None)

  • summary (str | None)

  • version (str)

  • path (str | None)

  • tags (list[str] | None)

__init__(title=None, description=None, summary=None, version='0.0.1', path=None, tags=None)[source]
Parameters:
  • title (str | None)

  • description (str | None)

  • summary (str | None)

  • version (str)

  • path (str | None)

  • tags (list[str] | None)

add_middleware(middleware)[source]
Return type:

Self

add_route(route)[source]
Parameters:

route (Route)

Return type:

Self

get_openapi_spec()[source]

Get the OpenAPI specification for this router.

Return type:

dict

include_router(incl_router)[source]
Parameters:

incl_router (BaseRouter)

Return type:

Self

mount(path, app)[source]
Parameters:
  • path (str)

  • app (Any)

Return type:

Self

property routers: list[BaseRouter]
run(host='localhost', port=8000, openapi_url='/openapi.json', swagger_url='/docs/swagger', redoc_url='/docs/redoc', rapidoc_url='/docs/rapidoc', docs_landing_page=True)[source]

Run the Tatami application using Uvicorn, and optionally serve OpenAPI and documentation UIs.

This function: - Sets the app root path to ‘’. - Adds routes to serve the OpenAPI JSON spec and interactive API docs (Swagger UI, ReDoc, RapiDoc) at the specified URLs. - Starts the Uvicorn server on the specified host and port.

Parameters:
  • app (Tatami) – The Tatami application instance to run.

  • host (str) – Hostname to bind the server to. Defaults to ‘localhost’.

  • port (int) – Port to bind the server to. Defaults to 8000.

  • openapi_url (Optional[str]) – URL path to serve OpenAPI JSON spec. Defaults to ‘/openapi.json’. Set to None to disable.

  • swagger_url (Optional[str]) – URL path to serve Swagger UI. Defaults to ‘/docs/swagger’. Set to None to disable.

  • redoc_url (Optional[str]) – URL path to serve ReDoc UI. Defaults to ‘/docs/redoc’. Set to None to disable.

  • rapidoc_url (Optional[str]) – URL path to serve RapiDoc UI. Defaults to ‘/docs/rapidoc’. Set to None to disable.

  • docs_landing_page (bool)

Return type:

NoReturn

Usage example:

app = Tatami(title="My API")

# Run the app with default docs URLs
run(app, host="0.0.0.0", port=8080)

Note

Requires uvicorn to be installed.

class tatami.router.ConventionRouter[source]

Bases: BaseRouter

__init__()[source]
class tatami.router.DecoratedRouter(title=None, description=None, summary=None, version='0.0.1', path=None, tags=None)[source]

Bases: BaseRouter

Parameters:
  • title (str | None)

  • description (str | None)

  • summary (str | None)

  • version (str)

  • path (str | None)

  • tags (list[str] | None)

class tatami.router.ProjectIntrospection(*, config_file=None, routers=<factory>, services=<factory>, models=<factory>, models_source=None, middleware=<factory>, static_path=None, templates_path=None, favicon_path=None, mounts=<factory>)[source]

Bases: BaseModel

Comprehensive introspection data for a Tatami project.

Parameters:
  • config_file (str | None)

  • routers (list[dict])

  • services (list[dict])

  • models (dict[str, type])

  • models_source (str | None)

  • middleware (list[dict])

  • static_path (str | None)

  • templates_path (str | None)

  • favicon_path (str | None)

  • mounts (list[dict])

config_file: str | None
favicon_path: str | None
middleware: list[dict]
property middleware_count: int
model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

property model_count: int
models: dict[str, type]
models_source: str | None
property mount_count: int
mounts: list[dict]
property router_count: int
routers: list[dict]
services: list[dict]
static_path: str | None
templates_path: str | None
class tatami.router.Summary(*, config_file=None, routers=0, middleware=0, models=0, static=None, templates=None)[source]

Bases: BaseModel

Parameters:
  • config_file (str | None)

  • routers (int)

  • middleware (int)

  • models (int)

  • static (str | None)

  • templates (str | None)

config_file: str | None
middleware: int
model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

models: int
routers: int
static: str | None
templates: str | None
tatami.router.router(path)[source]
Parameters:

path (str)

Return type:

Type[DecoratedRouter]

Endpoint Decorators

class tatami.endpoint.BoundEndpoint(endpoint, instance)[source]

Bases: TatamiObject

Parameters:

endpoint (Endpoint)

__init__(endpoint, instance)[source]
Parameters:

endpoint (Endpoint)

property deprecated: bool
property docs: str
property endpoint_function
get_route()[source]
Return type:

Route

property request_type: Request | BaseModel | None
property response_type: Type[Response] | Type[BaseModel] | None
async run(request)[source]

Handle an incoming HTTP request by extracting path parameters, query parameters, headers, and request body based on function annotations, invoking the endpoint function, and returning an appropriate response.

The method: - Extracts path parameters from the request URL. - Extracts query parameters from the request query string. - Extracts headers from the request headers. - For POST, PUT, or PATCH methods, attempts to parse the JSON body and instantiate Pydantic models defined in function annotations. - Validates all parameters against their type annotations. - Calls the endpoint function (self.ep_fn) with the app instance and all extracted parameters. - Awaits the result if it is awaitable. - Wraps the result in a response using self.response_type if defined, otherwise uses a default wrapper.

Parameters:

request (Request) – The incoming HTTP request object.

Returns:

A Starlette Response instance, either directly returned or awaited.

Return type:

Union[Response, Awaitable[Response]]

Usage example:

# Assume `endpoint` is an instance with `run` method,
# and `request` is a Starlette Request object.

response = await endpoint.run(request)
# `response` is a Starlette Response object ready to be sent back to the client.
property signature: Signature
property summary: str
property tags: list[str]
class tatami.endpoint.Endpoint(method, func, path=None, request_type=None, response_type=None, tags=None)[source]

Bases: TatamiObject

Parameters:
  • method (str)

  • func (Callable)

  • path (str)

  • request_type (Type[Request] | Type[BaseModel] | None)

  • response_type (Type[Response] | None)

  • tags (list[str] | None)

__init__(method, func, path=None, request_type=None, response_type=None, tags=None)[source]
Parameters:
  • method (str)

  • func (Callable)

  • path (str)

  • request_type (Type[Request] | Type[BaseModel] | None)

  • response_type (Type[Response] | None)

  • tags (list[str] | None)

property deprecated: bool
tatami.endpoint.delete(func: F) F[source]
tatami.endpoint.delete(path: str, *, response_type: Type[Response] | None = None) Callable[[F], F]
tatami.endpoint.delete(*, response_type: Type[Response] | None = None) Callable[[F], F]
tatami.endpoint.get(func: F) F[source]
tatami.endpoint.get(path: str, *, response_type: Type[Response] | None = None) Callable[[F], F]
tatami.endpoint.get(*, response_type: Type[Response] | None = None) Callable[[F], F]

Registers a function as a GET endpoint. This decorator supports multiple forms:

  • @get: Registers the endpoint at the parent router’s path.

  • @get(“/subpath”): Registers the endpoint at a subpath relative to the parent router.

  • @get(response_type=”json”): Registers at the parent path with a specified response type.

  • @get(“/subpath”, response_type=”json”): Registers at a subpath with response type metadata.

The full route is composed by joining the parent router’s path with the provided subpath.

Parameters:
  • path_or_func – A subpath string (starting with ‘/’) or the function to decorate. If omitted, the endpoint is registered at the parent router’s path.

  • **kwargs – Optional metadata such as response_type.

Returns:

Either the original function or a decorator that wraps it.

tatami.endpoint.head(func: F) F[source]
tatami.endpoint.head(path: str, *, response_type: Type[Response] | None = None) Callable[[F], F]
tatami.endpoint.head(*, response_type: Type[Response] | None = None) Callable[[F], F]
tatami.endpoint.options(func: F) F[source]
tatami.endpoint.options(path: str, *, response_type: Type[Response] | None = None) Callable[[F], F]
tatami.endpoint.options(*, response_type: Type[Response] | None = None) Callable[[F], F]
tatami.endpoint.patch(func: F) F[source]
tatami.endpoint.patch(path: str, *, response_type: Type[Response] | None = None) Callable[[F], F]
tatami.endpoint.patch(*, response_type: Type[Response] | None = None) Callable[[F], F]
tatami.endpoint.post(func: F) F[source]
tatami.endpoint.post(path: str, *, response_type: Type[Response] | None = None) Callable[[F], F]
tatami.endpoint.post(*, response_type: Type[Response] | None = None) Callable[[F], F]
tatami.endpoint.put(func: F) F[source]
tatami.endpoint.put(path: str, *, response_type: Type[Response] | None = None) Callable[[F], F]
tatami.endpoint.put(*, response_type: Type[Response] | None = None) Callable[[F], F]
tatami.endpoint.request(method: Literal['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'], func: F) F[source]
tatami.endpoint.request(method: Literal['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'], path: str, *, response_type: Type[Response] | None = None) Callable[[F], F]
tatami.endpoint.request(method: Literal['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'], *, response_type: Type[Response] | None = None) Callable[[F], F]

Convenience factory function to create an Endpoint instance with the given HTTP method and path. Meant to be used as a decorator.

Parameters:
  • method (str) – The HTTP method for the endpoint (e.g., ‘GET’, ‘POST’, ‘PUT’, etc.).

  • path (str) – The URL path pattern for the endpoint (e.g., ‘/users/{user_id}’).

  • response_type (Optional[Type[Response]]) – Optional Starlette Response subclass to use for responses.

Returns:

An instance of Endpoint initialized with the specified method, path, and response type.

Return type:

Endpoint

Usage example:

@request('GET', '/users/{user_id}', response_type=JSONResponse)
def get_user_by_id(self, user_id):
    ...

Parameter Handling

class tatami.param.Header(name=None)[source]

Bases: object

Marks a parameter as a header parameter.

Parameters:

name (str | None) – The name of the header. If not provided, defaults to the parameter name. Underscores will be converted to hyphens and the name will be title-cased.

__init__(name=None)[source]
Parameters:

name (str | None)

class tatami.param.Path(name=None)[source]

Bases: object

Marks a parameter as a path parameter.

Parameters:

name (str | None) – The name of the path parameter. If not provided, defaults to the parameter name.

__init__(name=None)[source]
Parameters:

name (str | None)

class tatami.param.Query(name=None)[source]

Bases: object

Marks a parameter as a query parameter.

Parameters:

name (str | None) – The name of the query parameter. If not provided, defaults to the parameter name.

__init__(name=None)[source]
Parameters:

name (str | None)

Configuration

class tatami.config.Config(*, app_name='Tatami', version='0.0.0', database=False)[source]

Bases: BaseModel

Parameters:
app_name: str
database: bool | str | DatabaseConfig
model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

classmethod set_env_vars(value)[source]
Parameters:

value (Any)

Return type:

Any

version: str
exception tatami.config.ConfigConflictError[source]

Bases: ConfigError

exception tatami.config.ConfigError[source]

Bases: Exception

class tatami.config.DatabaseConfig(*, db_type='sqlite', driver=None, connection_string='sqlite:///tatami.db')[source]

Bases: BaseModel

Parameters:
  • db_type (Literal['postgres', 'postgresql', 'sqlite'])

  • driver (Literal['psycopg'] | None)

  • connection_string (str)

connection_string: str
db_type: Literal['postgres', 'postgresql', 'sqlite']
driver: Literal['psycopg'] | None
model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

exception tatami.config.InvalidFileError[source]

Bases: ConfigError

exception tatami.config.MissingEnvVarError[source]

Bases: ConfigError

tatami.config.find_config(project_path, mode=None)[source]

Find the configuration file for the given project

Parameters:
  • project_path (str) – Path to the project

  • mode (Optional[str]) – The config mode (dev, prod, test…). If None the default config will be looked for. Defaults to None.

Returns:

The path to the config if found, None if no config file was found

Return type:

Optional[str]

tatami.config.load_config(path)[source]

Load a config file

Parameters:

path (str) – Path to the config file

Returns:

The config object

Return type:

Config

tatami.config.load_dotenv_files(path)[source]

Load all the dotenv (.env) files found in a given directory. Files whose name starts with an underscore will be excluded.

This function is internally used by Tatami to load all the files on the project directory

Example usage

Supposing we have three files

  • path/to/project/secrets.env

  • path/to/project/_ignore.env

  • path/to/project/.env

Calling the function .. code-block:: python

load_dotenv_files(‘path/to/project’)

would load the values found at path/to/project/secrets.env and path/to/project/.env but would ignore the values at path/to/project/_ignore.env as it starts with an underscore

Parameters:

path (str) – The path where the files will be searched

Return type:

None

Dependency Injection

class tatami.di.Inject(factory=None, scope=Scope.SINGLETON)[source]

Bases: object

Parameters:
  • factory (Callable | None)

  • scope (Scope)

__init__(factory=None, scope=Scope.SINGLETON)[source]
Parameters:
  • factory (Callable | None)

  • scope (Scope)

class tatami.di.InjectableMetadata(scope: tatami.di.Scope, singleton: T | None = None)[source]

Bases: object

Parameters:
  • scope (Scope)

  • singleton (T | None)

__init__(scope, singleton=None)
Parameters:
  • scope (Scope)

  • singleton (T | None)

Return type:

None

scope: Scope
singleton: T | None = None
class tatami.di.Scope(*values)[source]

Bases: Enum

REQUEST = 'request'
SINGLETON = 'singleton'
class tatami.di.TatamiInternals[source]

Bases: object

tatami.di.get_tatami_metadata(cls)[source]
Parameters:

cls (type)

tatami.di.inject(fn)[source]
Parameters:

fn (Callable)

Return type:

Callable

tatami.di.injectable(cls: type[T]) T[source]
tatami.di.injectable(scope: Scope = Scope.SINGLETON) type
tatami.di.injectable(*, scope: Scope = Scope.SINGLETON) type
tatami.di.is_injectable(cls)[source]
Parameters:

cls (type)

Return type:

bool

tatami.di.is_tatami_object(cls)[source]
Parameters:

cls (type)

Return type:

bool

Validation

Data validation utilities for Tatami framework.

This module provides comprehensive validation for input parameters based on type annotations.

exception tatami.validation.ValidationException(field_name, value, expected_type, message=None)[source]

Bases: Exception

Custom exception for validation errors.

Parameters:
  • field_name (str)

  • value (Any)

  • expected_type (type)

  • message (str)

__init__(field_name, value, expected_type, message=None)[source]
Parameters:
  • field_name (str)

  • value (Any)

  • expected_type (type)

  • message (str)

tatami.validation.create_multiple_validation_errors_response(errors)[source]

Create a response for multiple validation errors using RFC 7807 Problem Details format.

Parameters:

errors (list[ValidationException]) – List of validation exceptions

Returns:

JSONResponse with all error details in RFC 7807 format

Return type:

JSONResponse

tatami.validation.create_validation_error_response(error)[source]

Create a standardized error response for validation failures using RFC 7807 Problem Details format.

Parameters:

error (ValidationException) – The validation exception

Returns:

JSONResponse with error details in RFC 7807 format

Return type:

JSONResponse

tatami.validation.validate_parameter(value, annotation, field_name, allow_none=False)[source]

Validate a parameter value against its type annotation.

Parameters:
  • value (Any) – The value to validate

  • annotation (type) – The type annotation

  • field_name (str) – Name of the field for error reporting

  • allow_none (bool) – Whether None values are allowed

Returns:

The validated and converted value

Raises:

ValidationException – If validation fails

Return type:

Any

CLI Commands

tatami.__main__.main()[source]

Utilities

tatami._utils.camel_to_snake(name)[source]
Parameters:

name (str)

Return type:

str

tatami._utils.get_request_type(fn)[source]
Parameters:

fn (Callable)

Return type:

dict[str, Type[BaseModel]]

tatami._utils.human_friendly_description_from_name(name)[source]
Parameters:

name (str)

Return type:

str

tatami._utils.import_from_path(path)[source]
Parameters:

path (str)

Return type:

ModuleType

tatami._utils.path_to_module(path)[source]
Parameters:

path (str)

Return type:

str

tatami._utils.route_priority(endpoint)[source]
Parameters:

endpoint (BoundEndpoint)

Return type:

tuple[int, int, int, str, str]

tatami._utils.update_dict(d, update_with)[source]
Parameters:
  • d (dict)

  • update_with (dict)

tatami._utils.with_new_base(cls, new_base)[source]
Parameters:
  • cls (Type)

  • new_base (Type)

Return type:

Type

tatami._utils.wrap_response(ep_fn, ep_result)[source]
Parameters:
  • ep_fn (Callable)

  • ep_result (Any)

Return type:

Response

Note

Auto-generated API documentation is coming soon! The autodoc system is being configured.