hexastack-fastapi 0.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of hexastack-fastapi might be problematic. Click here for more details.
- hexastack_fastapi/__init__.py +6 -0
- hexastack_fastapi/adapters/__init__.py +41 -0
- hexastack_fastapi/adapters/app.py +118 -0
- hexastack_fastapi/adapters/db_session.py +160 -0
- hexastack_fastapi/adapters/dependencies.py +190 -0
- hexastack_fastapi/adapters/docs.py +80 -0
- hexastack_fastapi/adapters/health.py +62 -0
- hexastack_fastapi/adapters/routing.py +203 -0
- hexastack_fastapi/adapters/ui.py +491 -0
- hexastack_fastapi/infra/__init__.py +41 -0
- hexastack_fastapi/infra/autodiscovery.py +103 -0
- hexastack_fastapi/infra/bootstrap.py +85 -0
- hexastack_fastapi/infra/config.py +113 -0
- hexastack_fastapi/infra/decorators.py +199 -0
- hexastack_fastapi/infra/exception_handlers.py +60 -0
- hexastack_fastapi/infra/middleware/__init__.py +11 -0
- hexastack_fastapi/infra/middleware/correlation.py +100 -0
- hexastack_fastapi/infra/middleware/logging.py +95 -0
- hexastack_fastapi/py.typed +0 -0
- hexastack_fastapi/testing/__init__.py +18 -0
- hexastack_fastapi/testing/cursor.py +115 -0
- hexastack_fastapi/testing/recorder.py +238 -0
- hexastack_fastapi/testing/server.py +120 -0
- hexastack_fastapi-0.0.0.dist-info/METADATA +169 -0
- hexastack_fastapi-0.0.0.dist-info/RECORD +27 -0
- hexastack_fastapi-0.0.0.dist-info/WHEEL +4 -0
- hexastack_fastapi-0.0.0.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: hexastack-fastapi
|
|
3
|
+
Version: 0.0.0
|
|
4
|
+
Summary: FastAPI presentation adapter for Hexastack
|
|
5
|
+
Author: Richard West
|
|
6
|
+
Author-email: Richard West <dopplereffect.us@gmail.com>
|
|
7
|
+
Requires-Dist: fastapi>=0.141.1
|
|
8
|
+
Requires-Dist: hexastack-core
|
|
9
|
+
Requires-Dist: hexastack-cqrs
|
|
10
|
+
Requires-Dist: hexastack-auth ; extra == 'auth'
|
|
11
|
+
Requires-Dist: zensical>=0.0.56 ; extra == 'docs'
|
|
12
|
+
Requires-Dist: playwright>=1.49.0 ; extra == 'testing'
|
|
13
|
+
Requires-Dist: schemathesis>=3.39.0 ; extra == 'testing'
|
|
14
|
+
Requires-Dist: nicegui>=2.0.0 ; extra == 'ui'
|
|
15
|
+
Requires-Python: >=3.13
|
|
16
|
+
Provides-Extra: auth
|
|
17
|
+
Provides-Extra: docs
|
|
18
|
+
Provides-Extra: testing
|
|
19
|
+
Provides-Extra: ui
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
# hexastack-fastapi
|
|
23
|
+
|
|
24
|
+
> FastAPI presentation adapter for Hexastack: automatic CQRS routing, database session middleware, exception mapping, and health check endpoints.
|
|
25
|
+
|
|
26
|
+
[](https://www.python.org/downloads/)
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 1. Overview & Capabilities
|
|
31
|
+
|
|
32
|
+
- **Automatic CQRS Routing & Feature Gating**: Map HTTP endpoints directly to `CommandBusPort` or `QueryBusPort` using `@api_command` and `@api_query`, with native feature flag route guards (`@feature_flag_route` and `require_feature(...)`).
|
|
33
|
+
- **Decoupled Database Session Middleware**: `DbSessionMiddleware` (sync) and `AsyncDbSessionMiddleware` (async) manage session-per-request lifecycles by consuming sessionmakers from DI without a hard dependency on `hexastack-db`.
|
|
34
|
+
- **Standardized Exception Handlers**: Automatically translates domain exceptions (`EntityNotFoundError`, `UniqueConstraintViolationError`, `HexastackError`) into appropriate HTTP status codes (404, 409, 500) and structured JSON error envelopes.
|
|
35
|
+
- **Observability & Correlation Middleware**: Injects `X-Correlation-ID` headers and logs HTTP request lifecycles.
|
|
36
|
+
- **Built-in Health Checks**: Configurable `/health` and `/ready` endpoints verifying container and subsystem readiness.
|
|
37
|
+
- **NiceGUI Reactive UI & DevTools Dashboard**: Optional `[ui]` presentation adapter providing `ui_page`, `dispatch_command`, `dispatch_query`, and a zero-config interactive developer console (`mount_devtools_dashboard`) for inspecting CQRS buses, feature flags, and DI services.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## 2. Package Anatomy & Key Components
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
hexastack_fastapi/
|
|
45
|
+
├── domain/ # HealthStatus, HTTP error envelope models
|
|
46
|
+
├── adapters/ # create_app, routing decorators, health endpoints, db_session middleware, dependencies, NiceGUI UI adapter
|
|
47
|
+
└── infra/ # FastApiBootstrapper (order=30), exception handlers, correlation/logging middlewares
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Key Exports
|
|
51
|
+
|
|
52
|
+
| Category | Exports |
|
|
53
|
+
|---|---|
|
|
54
|
+
| **Application Factory** | `create_app`, `FastApiBootstrapper` (order=30) |
|
|
55
|
+
| **Decorators** | `@api_command`, `@api_query`, `@feature_flag_route`, `RouteMetadata` |
|
|
56
|
+
| **Dependencies** | `get_container`, `get_pipeline`, `get_feature_flags`, `require_feature` |
|
|
57
|
+
| **Documentation Mounting** | `mount_zensical_docs`, `DocumentationNotFoundError`, `ZensicalDocsConfig` |
|
|
58
|
+
| **Exception Handlers** | `register_exception_handlers`, `domain_exception_handler` |
|
|
59
|
+
| **Middlewares** | `DbSessionMiddleware`, `AsyncDbSessionMiddleware`, `add_db_session_middleware`, `CorrelationMiddleware`, `HttpLoggingMiddleware` |
|
|
60
|
+
| **Reactive UI (NiceGUI)** | `dispatch_command`, `dispatch_query`, `mount_devtools_dashboard`, `mount_ui_app`, `ui_page` |
|
|
61
|
+
| **Routing** | `CqrsRouter`, `autodiscover_routes` |
|
|
62
|
+
| **Testing, E2E & Demo Narration** | `create_test_client`, `check_openapi_conformance`, `EphemeralServer`, `ephemeral_server`, `find_free_port`, `smart_click`, `DemoNarrator`, `VIRTUAL_CURSOR_SCRIPT` |
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## 3. Monorepo & Sibling Relationships
|
|
67
|
+
|
|
68
|
+
```mermaid
|
|
69
|
+
graph TD
|
|
70
|
+
subgraph ClientRequests ["Client HTTP Inbound"]
|
|
71
|
+
HTTP["HTTP Client Requests"]
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
subgraph FastApiLayer ["hexastack-fastapi"]
|
|
75
|
+
APP["FastAPI Application"]
|
|
76
|
+
MW["Middleware (Correlation, HTTP Logging, DB Session)"]
|
|
77
|
+
ROUTER["CQRS Route Dispatcher"]
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
subgraph CQRSExecution ["hexastack-cqrs"]
|
|
81
|
+
CBUS["CommandBusPort"]
|
|
82
|
+
QBUS["QueryBusPort"]
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
subgraph DecoupledProviders ["Decoupled Providers (via DI)"]
|
|
86
|
+
DB_FACTORY["sessionmaker / async_sessionmaker (from hexastack-db)"]
|
|
87
|
+
LOG_PORT["LoggerPort (from hexastack-logging)"]
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
HTTP --> APP
|
|
91
|
+
APP --> MW
|
|
92
|
+
MW --> ROUTER
|
|
93
|
+
ROUTER -->|dispatches to| CBUS
|
|
94
|
+
ROUTER -->|dispatches to| QBUS
|
|
95
|
+
|
|
96
|
+
MW -. consumes session factory from DI .-> DB_FACTORY
|
|
97
|
+
MW -. consumes LoggerPort from DI .-> LOG_PORT
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Explicit Dependencies (Direct)
|
|
101
|
+
- `hexastack-core`: DI container, core ports, exception registry, and context propagation.
|
|
102
|
+
- `hexastack-cqrs`: `CommandBusPort` and `QueryBusPort` for message dispatching.
|
|
103
|
+
- `fastapi>=0.141.1`: Web framework and ASGI routing.
|
|
104
|
+
|
|
105
|
+
### Implied / Behavioral Relationships (DI-Mediated)
|
|
106
|
+
- **Zero-Dependency DB Session Management**: `DbSessionMiddleware` dynamically resolves SQLAlchemy `sessionmaker` from DI without directly importing `hexastack-db`.
|
|
107
|
+
- **Telemetry Integration**: `HttpLoggingMiddleware` outputs structured request telemetry through `LoggerPort`.
|
|
108
|
+
- **Exception Mapping**: Registers global exception handlers translating core domain errors into standard HTTP error responses.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## 4. Installation
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
# Standalone install
|
|
116
|
+
pip install hexastack-fastapi
|
|
117
|
+
|
|
118
|
+
# With Uvicorn development server
|
|
119
|
+
pip install "hexastack-fastapi[web]" # or: pip install "hexastack[web]"
|
|
120
|
+
|
|
121
|
+
# Via umbrella package
|
|
122
|
+
pip install "hexastack[fastapi]"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## 5. Configuration Reference
|
|
128
|
+
|
|
129
|
+
```toml
|
|
130
|
+
[hexastack.fastapi]
|
|
131
|
+
title = "Hexastack API"
|
|
132
|
+
version = "1.0.0"
|
|
133
|
+
docs_url = "/docs"
|
|
134
|
+
openapi_url = "/openapi.json"
|
|
135
|
+
cors_origins = ["*"]
|
|
136
|
+
enable_correlation_header = true
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## 6. Quickstart Example
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
from dataclasses import dataclass
|
|
145
|
+
from fastapi.testclient import TestClient
|
|
146
|
+
from hexastack_core.infra.bootstrap import bootstrap
|
|
147
|
+
from hexastack_cqrs.domain.query import Query
|
|
148
|
+
from hexastack_cqrs.infra.decorators import query_handler
|
|
149
|
+
from hexastack_fastapi.adapters.app import create_app
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
@dataclass(frozen=True)
|
|
153
|
+
class GetGreetingQuery(Query):
|
|
154
|
+
name: str
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
@query_handler(GetGreetingQuery)
|
|
158
|
+
class GetGreetingHandler:
|
|
159
|
+
def __call__(self, qry: GetGreetingQuery) -> dict:
|
|
160
|
+
return {"message": f"Hello, {qry.name}!"}
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
runtime = bootstrap(packages_to_scan=[__name__])
|
|
164
|
+
app = create_app(runtime)
|
|
165
|
+
|
|
166
|
+
client = TestClient(app)
|
|
167
|
+
response = client.get("/health")
|
|
168
|
+
print(response.json()) # {"status": "healthy"}
|
|
169
|
+
```
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
hexastack_fastapi/__init__.py,sha256=vEVN5heoMwiE_5iKIDZsZlFLklY-ks9ceLZ-r65mwuc,90
|
|
2
|
+
hexastack_fastapi/adapters/__init__.py,sha256=ifOJZUNyt6G5BS721wMdT_dP6yIk338vSTJBJMky-RA,1042
|
|
3
|
+
hexastack_fastapi/adapters/app.py,sha256=9x5MED_7KW2cBtc9l-e9lEm0qGG70qb23sC3d4mNX7k,3880
|
|
4
|
+
hexastack_fastapi/adapters/db_session.py,sha256=iAve_x4JbLT9v6CYyigCFEG_IXZeVTQku23llqDTeJU,5390
|
|
5
|
+
hexastack_fastapi/adapters/dependencies.py,sha256=6KEgkpBVKuWmG6d-daR5VJOEC9XF9B2jGh5GmmjmSvQ,6499
|
|
6
|
+
hexastack_fastapi/adapters/docs.py,sha256=5tcYosVHbnXiWYbq1Gf-RxyEJI3Fx7AlcSRQ0YR6TdI,3039
|
|
7
|
+
hexastack_fastapi/adapters/health.py,sha256=2YfBfn7gtIJGFTqr3pyKW_PHSTNU4DqSoyhVk5thuyk,1979
|
|
8
|
+
hexastack_fastapi/adapters/routing.py,sha256=sNmugXV-rv-ZglHQzd0kWsh-q_HSYIlH6Kgtsje289c,6587
|
|
9
|
+
hexastack_fastapi/adapters/ui.py,sha256=gA8ME_ceauehDpFf5TxZUxm-osDeTC24kM0Kqg8p1r4,17118
|
|
10
|
+
hexastack_fastapi/infra/__init__.py,sha256=JAzdTuPDrB-0eA-u8M3m0-ZaTZ4yf199xKIAuNthAD4,1030
|
|
11
|
+
hexastack_fastapi/infra/autodiscovery.py,sha256=uqTcDDqiw4tLWeGhlISK3LbFGKTB9aDalfQY2uUKYJI,3013
|
|
12
|
+
hexastack_fastapi/infra/bootstrap.py,sha256=XN3wELW09TPSLA2bQMUzXgl5-mKcnS-bDKaL-fbUsfw,2761
|
|
13
|
+
hexastack_fastapi/infra/config.py,sha256=nMNgpGNH8VevlxROcfahOettRH8fBVLrpjVjiCxr5zI,3767
|
|
14
|
+
hexastack_fastapi/infra/decorators.py,sha256=3GcrzSLaBSMrQSy9LDupdff2xmeg76F-R_Gv2-iTYXc,6404
|
|
15
|
+
hexastack_fastapi/infra/exception_handlers.py,sha256=rKadHZBwlL27pC3qopxsh2XhaVSfex0cw0TMYbNI5Ng,2050
|
|
16
|
+
hexastack_fastapi/infra/middleware/__init__.py,sha256=YSt3QrcNRHgCJZ3jk8hcExVib0UvNkqvf8iu3CK5stQ,271
|
|
17
|
+
hexastack_fastapi/infra/middleware/correlation.py,sha256=p2q8zfDu3hz8cSsFBATmqWHRq1Xy_nu1ARX6nphRW_w,3652
|
|
18
|
+
hexastack_fastapi/infra/middleware/logging.py,sha256=oP0vwmyckKnDs7LHP3eUV38qT22KAJ-tPshfZc_l1wQ,3468
|
|
19
|
+
hexastack_fastapi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
|
+
hexastack_fastapi/testing/__init__.py,sha256=ElrjJCmJ-OeLUWOoZtDclxB8p6OeWBwRXFjyhx5iAV8,491
|
|
21
|
+
hexastack_fastapi/testing/cursor.py,sha256=0H96anKE7RJ5UnTMFqqT1XgbsQ3-9uKZ4kD0chYfyII,3633
|
|
22
|
+
hexastack_fastapi/testing/recorder.py,sha256=eDWzzgczTpsXUTaXVvQQSjXnkrFR7-_MQQdBAdOtZgo,8527
|
|
23
|
+
hexastack_fastapi/testing/server.py,sha256=xAp_05-zRnB393U3rdMfP6gYQ3QWN9TIlVC-JnKee5c,3639
|
|
24
|
+
hexastack_fastapi-0.0.0.dist-info/WHEEL,sha256=EmLkUISDECbcUx3FMCYOqokNOJqNp2r0d4mJzjErvvs,80
|
|
25
|
+
hexastack_fastapi-0.0.0.dist-info/entry_points.txt,sha256=g3Msc6yUpTnb9qpdwZPvEV92S4s4cBxC3tdHsUOqn0U,91
|
|
26
|
+
hexastack_fastapi-0.0.0.dist-info/METADATA,sha256=Cqal7vjyEU_bHxfSybNSRdJOK7PAn0GTHyWRTSzDxEM,6522
|
|
27
|
+
hexastack_fastapi-0.0.0.dist-info/RECORD,,
|