A shared OpenAPI abstraction layer for the Tiferet Framework.
Project description
Tiferet OpenAPI — A Shared OpenAPI Abstraction Layer for the Tiferet Framework
Introduction
Tiferet OpenAPI provides the shared abstraction layer that both tiferet-flask and tiferet-fast depend on for OpenAPI-style API development. It extracts the common domain objects, service interfaces, domain events, mappers, YAML-backed repository, and context classes that were previously duplicated across both framework adapters.
By unifying these components into a single package, tiferet-openapi eliminates code duplication, ensures behavioral consistency between Flask and FastAPI adapters, and provides a clean foundation for building new framework adapters.
Installation
From PyPI
pip install tiferet-openapi
For Development
git clone https://github.com/greatstrength/tiferet-openapi.git
cd tiferet-openapi
python3.10 -m venv .venv
source .venv/bin/activate
pip install -e ".[test]"
Architecture
Tiferet OpenAPI follows the Tiferet framework's layered Domain-Driven Design architecture:
tiferet_openapi/
├── __init__.py — Version and public exports
├── domain/ — ApiRoute, ApiRouter (DomainObject, Pydantic v2)
├── interfaces/ — OpenApiService (Service ABC)
├── events/ — GetRouters, GetRoute, GetStatusCode (DomainEvent)
├── mappers/ — Aggregates and TransferObjects for YAML round-trip
├── repos/ — OpenApiYamlRepository (YamlLoader-backed OpenApiService)
└── contexts/ — OpenApiContext (AppInterfaceContext), OpenApiRequestContext
Domain Objects
ApiRoute and ApiRouter are read-only Pydantic v2 domain models that represent API routing configuration:
ApiRoute— An individual route withid,endpoint(format:router_name.route_id),path,methods, andstatus_code.ApiRouter— A named group of routes with an optional URLprefix.
Service Interface
OpenApiService is the abstract contract for API configuration access:
get_routers()— Retrieve all configured routers.get_route(route_id, router_name=None)— Look up a single route.get_status_code(error_code)— Map an error code to an HTTP status code.
Domain Events
Three domain events encapsulate the service operations for use in the feature workflow:
GetRouters— Retrieves all routers via the injectedOpenApiService.GetRoute— Parses a dotted endpoint string (e.g.,calc.add) and retrieves the matching route.GetStatusCode— Looks up the HTTP status code for a given error code.
Mappers
Aggregates and TransferObjects bridge YAML configuration and runtime domain objects:
ApiRouteAggregate,ApiRouterAggregate— Mutable aggregates with route management methods.ApiRouteYamlObject,ApiRouterYamlObject— YAML serialization with_ROLES-based role control,map()for aggregate construction,from_model()for reverse mapping.
Repository
OpenApiYamlRepository is the YAML-backed implementation of OpenApiService. It accepts a parameterized root_key (defaults to "openapi") enabling compatibility with multiple YAML formats:
root_key="openapi"— unifiedopenapi.ymlformatroot_key="flask"— legacyflask.ymlformatroot_key="fast"— legacyfast.ymlformat
Contexts
OpenApiContext(AppInterfaceContext)— Shared API context that receivesDomainEventinstances for route and status code lookup. Providesparse_request,handle_error(with HTTP status code resolution), andhandle_response(returning(response, status_code)tuples).OpenApiRequestContext(RequestContext)— Pydantic-aware request context that serializesBaseModelresults viamodel_dump(), with support for lists, dicts,None, and primitives.
YAML Configuration Format
The repository reads configuration from a YAML file with the following structure:
openapi: # root_key (can be 'flask', 'fast', or any custom key)
routers:
calc:
prefix: /calc
routes:
add:
path: /add
methods:
- POST
status_code: 200
subtract:
path: /subtract
methods:
- POST
status_code: 200
health:
routes:
ping:
path: /ping
methods:
- GET
status_code: 200
errors:
INVALID_INPUT: 400
DIVISION_BY_ZERO: 422
NOT_FOUND: 404
Usage
Tiferet OpenAPI is consumed by framework-specific adapters. Here's how the shared components integrate:
In tiferet-flask / tiferet-fast
Framework adapters extend OpenApiContext and use OpenApiYamlRepository as their configuration backend:
# Framework adapter context (e.g., FlaskApiContext)
from tiferet_openapi import OpenApiContext, OpenApiRequestContext
class FlaskApiContext(OpenApiContext):
# Inherits parse_request, handle_error, handle_response
# Adds Flask-specific builder logic
pass
Direct Repository Usage
from tiferet_openapi import OpenApiYamlRepository
# Load configuration
repo = OpenApiYamlRepository(
openapi_yaml_file='app/configs/openapi.yml',
root_key='openapi',
)
# Retrieve all routers
routers = repo.get_routers()
for router in routers:
print(f"{router.name}: {router.prefix}")
for route in router.routes:
print(f" {route.endpoint} -> {route.path} [{', '.join(route.methods)}]")
# Look up a specific route
route = repo.get_route('add', router_name='calc')
print(f"Route: {route.endpoint}, Status: {route.status_code}")
# Map error code to HTTP status
status = repo.get_status_code('INVALID_INPUT') # Returns 400
status = repo.get_status_code('UNKNOWN') # Returns 500 (default)
Testing
Run the test suite:
pytest tiferet_openapi/ -v
Tests are co-located in <package>/tests/ directories:
- Domain/mapper tests use direct Pydantic constructors.
- Event tests use
DomainEvent.handle()with mockedOpenApiService. - Repo tests are integration tests using
tmp_pathwith real YAML files. - Context tests use
mock.Mock(spec=DomainEvent)for event dependencies.
License
MIT — see LICENSE for details.
Project details
Release history Release notifications | RSS feed
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 tiferet_openapi-0.1.2.tar.gz.
File metadata
- Download URL: tiferet_openapi-0.1.2.tar.gz
- Upload date:
- Size: 14.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c6b369085c9fdd014d91ec2d94cac2fc99312b54803219831809cedc6ad3a202
|
|
| MD5 |
0bedaac451ae393e2bad6fb40b3aeda4
|
|
| BLAKE2b-256 |
2bd097ea5f087c2aefbb87101e1b7d0e9d7384f2ff95b8970cc238e3bf4e9650
|
Provenance
The following attestation bundles were made for tiferet_openapi-0.1.2.tar.gz:
Publisher:
python-publish.yml on greatstrength/tiferet-openapi
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tiferet_openapi-0.1.2.tar.gz -
Subject digest:
c6b369085c9fdd014d91ec2d94cac2fc99312b54803219831809cedc6ad3a202 - Sigstore transparency entry: 1499407239
- Sigstore integration time:
-
Permalink:
greatstrength/tiferet-openapi@41d086c3edc12c0da650482d822f4625f22413d7 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/greatstrength
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@41d086c3edc12c0da650482d822f4625f22413d7 -
Trigger Event:
release
-
Statement type:
File details
Details for the file tiferet_openapi-0.1.2-py3-none-any.whl.
File metadata
- Download URL: tiferet_openapi-0.1.2-py3-none-any.whl
- Upload date:
- Size: 16.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c40796758fc372674ca0e8d72b8d6d31044d2baa1f07a9b158f1622fd9037636
|
|
| MD5 |
0c3124520ac0575779e3f13d0bc417f2
|
|
| BLAKE2b-256 |
5601c27b762642241f5bf3099949ee9985cdaeb2f17257ceb3aef60db5e1ae1b
|
Provenance
The following attestation bundles were made for tiferet_openapi-0.1.2-py3-none-any.whl:
Publisher:
python-publish.yml on greatstrength/tiferet-openapi
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tiferet_openapi-0.1.2-py3-none-any.whl -
Subject digest:
c40796758fc372674ca0e8d72b8d6d31044d2baa1f07a9b158f1622fd9037636 - Sigstore transparency entry: 1499407340
- Sigstore integration time:
-
Permalink:
greatstrength/tiferet-openapi@41d086c3edc12c0da650482d822f4625f22413d7 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/greatstrength
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@41d086c3edc12c0da650482d822f4625f22413d7 -
Trigger Event:
release
-
Statement type: