hexastack-fastapi 0.0.0__tar.gz → 0.1.0__tar.gz

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.
Files changed (27) hide show
  1. {hexastack_fastapi-0.0.0 → hexastack_fastapi-0.1.0}/PKG-INFO +10 -3
  2. {hexastack_fastapi-0.0.0 → hexastack_fastapi-0.1.0}/README.md +7 -1
  3. {hexastack_fastapi-0.0.0 → hexastack_fastapi-0.1.0}/pyproject.toml +2 -1
  4. {hexastack_fastapi-0.0.0 → hexastack_fastapi-0.1.0}/pyproject.toml.orig +2 -1
  5. {hexastack_fastapi-0.0.0 → hexastack_fastapi-0.1.0}/src/hexastack_fastapi/adapters/ui.py +26 -15
  6. {hexastack_fastapi-0.0.0 → hexastack_fastapi-0.1.0}/src/hexastack_fastapi/infra/exception_handlers.py +11 -1
  7. {hexastack_fastapi-0.0.0 → hexastack_fastapi-0.1.0}/src/hexastack_fastapi/__init__.py +0 -0
  8. {hexastack_fastapi-0.0.0 → hexastack_fastapi-0.1.0}/src/hexastack_fastapi/adapters/__init__.py +0 -0
  9. {hexastack_fastapi-0.0.0 → hexastack_fastapi-0.1.0}/src/hexastack_fastapi/adapters/app.py +0 -0
  10. {hexastack_fastapi-0.0.0 → hexastack_fastapi-0.1.0}/src/hexastack_fastapi/adapters/db_session.py +0 -0
  11. {hexastack_fastapi-0.0.0 → hexastack_fastapi-0.1.0}/src/hexastack_fastapi/adapters/dependencies.py +0 -0
  12. {hexastack_fastapi-0.0.0 → hexastack_fastapi-0.1.0}/src/hexastack_fastapi/adapters/docs.py +0 -0
  13. {hexastack_fastapi-0.0.0 → hexastack_fastapi-0.1.0}/src/hexastack_fastapi/adapters/health.py +0 -0
  14. {hexastack_fastapi-0.0.0 → hexastack_fastapi-0.1.0}/src/hexastack_fastapi/adapters/routing.py +0 -0
  15. {hexastack_fastapi-0.0.0 → hexastack_fastapi-0.1.0}/src/hexastack_fastapi/infra/__init__.py +0 -0
  16. {hexastack_fastapi-0.0.0 → hexastack_fastapi-0.1.0}/src/hexastack_fastapi/infra/autodiscovery.py +0 -0
  17. {hexastack_fastapi-0.0.0 → hexastack_fastapi-0.1.0}/src/hexastack_fastapi/infra/bootstrap.py +0 -0
  18. {hexastack_fastapi-0.0.0 → hexastack_fastapi-0.1.0}/src/hexastack_fastapi/infra/config.py +0 -0
  19. {hexastack_fastapi-0.0.0 → hexastack_fastapi-0.1.0}/src/hexastack_fastapi/infra/decorators.py +0 -0
  20. {hexastack_fastapi-0.0.0 → hexastack_fastapi-0.1.0}/src/hexastack_fastapi/infra/middleware/__init__.py +0 -0
  21. {hexastack_fastapi-0.0.0 → hexastack_fastapi-0.1.0}/src/hexastack_fastapi/infra/middleware/correlation.py +0 -0
  22. {hexastack_fastapi-0.0.0 → hexastack_fastapi-0.1.0}/src/hexastack_fastapi/infra/middleware/logging.py +0 -0
  23. {hexastack_fastapi-0.0.0 → hexastack_fastapi-0.1.0}/src/hexastack_fastapi/py.typed +0 -0
  24. {hexastack_fastapi-0.0.0 → hexastack_fastapi-0.1.0}/src/hexastack_fastapi/testing/__init__.py +0 -0
  25. {hexastack_fastapi-0.0.0 → hexastack_fastapi-0.1.0}/src/hexastack_fastapi/testing/cursor.py +0 -0
  26. {hexastack_fastapi-0.0.0 → hexastack_fastapi-0.1.0}/src/hexastack_fastapi/testing/recorder.py +0 -0
  27. {hexastack_fastapi-0.0.0 → hexastack_fastapi-0.1.0}/src/hexastack_fastapi/testing/server.py +0 -0
@@ -1,9 +1,10 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: hexastack-fastapi
3
- Version: 0.0.0
3
+ Version: 0.1.0
4
4
  Summary: FastAPI presentation adapter for Hexastack
5
5
  Author: Richard West
6
6
  Author-email: Richard West <dopplereffect.us@gmail.com>
7
+ License-Expression: Apache-2.0
7
8
  Requires-Dist: fastapi>=0.141.1
8
9
  Requires-Dist: hexastack-core
9
10
  Requires-Dist: hexastack-cqrs
@@ -19,12 +20,18 @@ Provides-Extra: testing
19
20
  Provides-Extra: ui
20
21
  Description-Content-Type: text/markdown
21
22
 
23
+ ![hexastack-fastapi](../../docs/assets/static/logos/packages/hexastack_fastapi.png)
24
+
22
25
  # hexastack-fastapi
23
26
 
24
27
  > FastAPI presentation adapter for Hexastack: automatic CQRS routing, database session middleware, exception mapping, and health check endpoints.
25
28
 
29
+ [![PyPI: hexastack-fastapi](https://img.shields.io/pypi/v/hexastack-fastapi.svg)](https://pypi.org/project/hexastack-fastapi/)
26
30
  [![Python 3.13+](https://img.shields.io/badge/python-3.13+-blue.svg)](https://www.python.org/downloads/)
27
-
31
+ [![Coverage](https://codecov.io/github/TheTrueSCU/hexastack/graph/badge.svg?component=hexastack_fastapi)](https://codecov.io/github/TheTrueSCU/hexastack)
32
+ [![License: Apache 2.0](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](../../LICENSE)
33
+ [![Accessibility: WCAG 2.1 AA](https://img.shields.io/badge/accessibility-WCAG%202.1%20AA-brightgreen.svg)](https://www.w3.org/WAI/WCAG21/quickref/?levels=aa)
34
+ [![Tested with: axe--core](https://img.shields.io/badge/tested%20with-axe--core-4353ff.svg?logo=deque)](https://github.com/dequelabs/axe-core)
28
35
  ---
29
36
 
30
37
  ## 1. Overview & Capabilities
@@ -1,9 +1,15 @@
1
+ ![hexastack-fastapi](../../docs/assets/static/logos/packages/hexastack_fastapi.png)
2
+
1
3
  # hexastack-fastapi
2
4
 
3
5
  > FastAPI presentation adapter for Hexastack: automatic CQRS routing, database session middleware, exception mapping, and health check endpoints.
4
6
 
7
+ [![PyPI: hexastack-fastapi](https://img.shields.io/pypi/v/hexastack-fastapi.svg)](https://pypi.org/project/hexastack-fastapi/)
5
8
  [![Python 3.13+](https://img.shields.io/badge/python-3.13+-blue.svg)](https://www.python.org/downloads/)
6
-
9
+ [![Coverage](https://codecov.io/github/TheTrueSCU/hexastack/graph/badge.svg?component=hexastack_fastapi)](https://codecov.io/github/TheTrueSCU/hexastack)
10
+ [![License: Apache 2.0](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](../../LICENSE)
11
+ [![Accessibility: WCAG 2.1 AA](https://img.shields.io/badge/accessibility-WCAG%202.1%20AA-brightgreen.svg)](https://www.w3.org/WAI/WCAG21/quickref/?levels=aa)
12
+ [![Tested with: axe--core](https://img.shields.io/badge/tested%20with-axe--core-4353ff.svg?logo=deque)](https://github.com/dequelabs/axe-core)
7
13
  ---
8
14
 
9
15
  ## 1. Overview & Capabilities
@@ -1,8 +1,9 @@
1
1
  [project]
2
2
  name = "hexastack-fastapi"
3
- version = "0.0.0"
3
+ version = "0.1.0"
4
4
  description = "FastAPI presentation adapter for Hexastack"
5
5
  readme = "README.md"
6
+ license = "Apache-2.0"
6
7
  requires-python = ">=3.13"
7
8
  dependencies = [
8
9
  "fastapi>=0.141.1",
@@ -1,8 +1,9 @@
1
1
  [project]
2
2
  name = "hexastack-fastapi"
3
- version = "0.0.0"
3
+ version = "0.1.0"
4
4
  description = "FastAPI presentation adapter for Hexastack"
5
5
  readme = "README.md"
6
+ license = "Apache-2.0"
6
7
  authors = [
7
8
  { name = "Richard West", email = "dopplereffect.us@gmail.com" }
8
9
  ]
@@ -229,15 +229,22 @@ def _render_middleware_chain(middlewares: list[Any]) -> None:
229
229
  ui.chip(
230
230
  f"{idx}. {mw_name}",
231
231
  icon="security" if "Auth" in mw_name else "filter_alt",
232
- ).classes(
233
- "bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200"
234
- )
232
+ color="blue-9",
233
+ text_color="white",
234
+ ).classes("font-medium")
235
235
  if idx < len(middlewares):
236
- ui.icon("arrow_forward", size="sm").classes("text-slate-400")
237
- ui.icon("arrow_forward", size="sm").classes("text-slate-400")
238
- ui.chip("Handler Execution", icon="play_circle").classes(
239
- "bg-emerald-100 text-emerald-800 dark:bg-emerald-900 dark:text-emerald-200 font-bold"
236
+ ui.icon("arrow_forward", size="sm").classes(
237
+ "text-slate-600 dark:text-slate-300"
238
+ )
239
+ ui.icon("arrow_forward", size="sm").classes(
240
+ "text-slate-600 dark:text-slate-300"
240
241
  )
242
+ ui.chip(
243
+ "Handler Execution",
244
+ icon="play_circle",
245
+ color="green-9",
246
+ text_color="white",
247
+ ).classes("font-bold")
241
248
  else:
242
249
  ui.label("No active middlewares attached to CommandBus.").classes(
243
250
  "text-slate-500 italic mb-6"
@@ -315,9 +322,9 @@ def _render_live_runner(
315
322
  except Exception as exc:
316
323
  log_output.push(f"❌ [ERROR] Execution failed: {exc}")
317
324
 
318
- ui.button("Dispatch Ping Command", on_click=_run_ping, icon="send").classes(
319
- "bg-blue-600 text-white"
320
- )
325
+ ui.button(
326
+ "Dispatch Ping Command", on_click=_run_ping, icon="send", color="blue-9"
327
+ ).classes("text-white font-medium shadow-sm")
321
328
 
322
329
 
323
330
  def _render_cqrs_tab(
@@ -366,15 +373,16 @@ def _render_flags_tab(container: Container) -> None:
366
373
  ],
367
374
  rows=flag_rows,
368
375
  row_key="flag",
376
+ pagination={"rowsPerPage": 10},
369
377
  ).classes("w-full")
370
378
  else:
371
379
  ui.label("No feature flags currently configured in provider.").classes(
372
- "text-slate-500 italic"
380
+ "text-slate-600 dark:text-slate-400 italic"
373
381
  )
374
382
  else:
375
383
  ui.label(
376
384
  "Feature flag provider not available or does not support listing."
377
- ).classes("text-slate-500 italic")
385
+ ).classes("text-slate-600 dark:text-slate-400 italic")
378
386
 
379
387
 
380
388
  def _render_container_tab(container: Container) -> None:
@@ -427,10 +435,11 @@ def _render_container_tab(container: Container) -> None:
427
435
  ],
428
436
  rows=services,
429
437
  row_key="service",
438
+ pagination={"rowsPerPage": 10},
430
439
  ).classes("w-full")
431
440
  else:
432
441
  ui.label("No direct services found in container introspection.").classes(
433
- "text-slate-500 italic"
442
+ "text-slate-600 dark:text-slate-400 italic"
434
443
  )
435
444
 
436
445
 
@@ -465,7 +474,7 @@ def mount_devtools_dashboard(
465
474
 
466
475
  @ui.page(path, title=title)
467
476
  def devtools_page():
468
- ui.colors(primary="#3B82F6", secondary="#10B981", accent="#8B5CF6")
477
+ ui.colors(primary="#1E40AF", secondary="#065F46", accent="#5B21B6")
469
478
 
470
479
  with ui.header().classes(
471
480
  "items-center justify-between bg-slate-900 text-white px-6 py-3"
@@ -473,7 +482,9 @@ def mount_devtools_dashboard(
473
482
  with ui.row().classes("items-center gap-3"):
474
483
  ui.icon("layers", size="md").classes("text-blue-400")
475
484
  ui.label(title).classes("text-xl font-bold tracking-tight")
476
- ui.badge("v0.1.0", color="blue").classes("text-xs")
485
+ ui.badge("v0.1.0", color="blue-10").classes(
486
+ "text-xs font-semibold text-white"
487
+ )
477
488
 
478
489
  with ui.tabs().classes("w-full bg-slate-100 dark:bg-slate-800") as tabs:
479
490
  tab_cqrs = ui.tab("CQRS Registry", icon="bolt")
@@ -47,7 +47,17 @@ def register_exception_handlers(
47
47
  status_code = 404
48
48
  elif "conflict" in exc_name or "duplicate" in exc_name:
49
49
  status_code = 409
50
- elif "unauthorized" in exc_name or "forbidden" in exc_name:
50
+ elif (
51
+ "permission" in exc_name
52
+ or "forbidden" in exc_name
53
+ or "accessdenied" in exc_name
54
+ ):
55
+ status_code = 403
56
+ elif (
57
+ "unauthorized" in exc_name
58
+ or "unauthenticated" in exc_name
59
+ or "invalidcredential" in exc_name
60
+ ):
51
61
  status_code = 401
52
62
  elif "validation" in exc_name:
53
63
  status_code = 422