vega-framework 0.2.3__tar.gz → 0.2.5__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 (103) hide show
  1. {vega_framework-0.2.3 → vega_framework-0.2.5}/PKG-INFO +1 -1
  2. {vega_framework-0.2.3 → vega_framework-0.2.5}/pyproject.toml +1 -1
  3. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/commands/generate.py +24 -83
  4. vega_framework-0.2.5/vega/cli/templates/web/middleware.py.j2 +56 -0
  5. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/web/openapi.py +6 -9
  6. vega_framework-0.2.3/vega/cli/templates/web/middleware.py.j2 +0 -65
  7. {vega_framework-0.2.3 → vega_framework-0.2.5}/LICENSE +0 -0
  8. {vega_framework-0.2.3 → vega_framework-0.2.5}/README.md +0 -0
  9. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/__init__.py +0 -0
  10. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/__init__.py +0 -0
  11. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/commands/__init__.py +0 -0
  12. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/commands/add.py +0 -0
  13. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/commands/init.py +0 -0
  14. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/commands/migrate.py +0 -0
  15. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/commands/update.py +0 -0
  16. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/commands/web.py +0 -0
  17. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/main.py +0 -0
  18. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/scaffolds/__init__.py +0 -0
  19. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/scaffolds/fastapi.py +0 -0
  20. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/scaffolds/sqlalchemy.py +0 -0
  21. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/scaffolds/vega_web.py +0 -0
  22. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/__init__.py +0 -0
  23. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/cli/command.py.j2 +0 -0
  24. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/cli/command_simple.py.j2 +0 -0
  25. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/cli/commands_init.py.j2 +0 -0
  26. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/components.py +0 -0
  27. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/domain/entity.py.j2 +0 -0
  28. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/domain/event.py.j2 +0 -0
  29. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/domain/event_handler.py.j2 +0 -0
  30. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/domain/interactor.py.j2 +0 -0
  31. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/domain/mediator.py.j2 +0 -0
  32. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/domain/repository_interface.py.j2 +0 -0
  33. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/domain/service_interface.py.j2 +0 -0
  34. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/infrastructure/model.py.j2 +0 -0
  35. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/infrastructure/repository_impl.py.j2 +0 -0
  36. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/infrastructure/service_impl.py.j2 +0 -0
  37. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/loader.py +0 -0
  38. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/project/.env.example +0 -0
  39. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/project/.gitignore +0 -0
  40. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/project/ARCHITECTURE.md.j2 +0 -0
  41. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/project/README.md.j2 +0 -0
  42. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/project/config.py.j2 +0 -0
  43. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/project/events_init.py.j2 +0 -0
  44. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/project/main.py.j2 +0 -0
  45. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/project/main_fastapi.py.j2 +0 -0
  46. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/project/main_standard.py.j2 +0 -0
  47. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/project/pyproject.toml.j2 +0 -0
  48. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/project/settings.py.j2 +0 -0
  49. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/sqlalchemy/alembic.ini.j2 +0 -0
  50. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/sqlalchemy/database_manager.py.j2 +0 -0
  51. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/sqlalchemy/env.py.j2 +0 -0
  52. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/sqlalchemy/script.py.mako +0 -0
  53. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/web/__init__.py.j2 +0 -0
  54. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/web/app.py.j2 +0 -0
  55. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/web/health_route.py.j2 +0 -0
  56. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/web/main.py.j2 +0 -0
  57. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/web/models_init.py.j2 +0 -0
  58. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/web/request_model.py.j2 +0 -0
  59. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/web/response_model.py.j2 +0 -0
  60. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/web/router.py.j2 +0 -0
  61. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/web/routes_init.py.j2 +0 -0
  62. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/web/routes_init_autodiscovery.py.j2 +0 -0
  63. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/web/user_models.py.j2 +0 -0
  64. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/templates/web/users_route.py.j2 +0 -0
  65. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/utils/__init__.py +0 -0
  66. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/utils/async_support.py +0 -0
  67. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/utils/messages.py +0 -0
  68. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/utils/naming.py +0 -0
  69. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/cli/utils/validators.py +0 -0
  70. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/di/__init__.py +0 -0
  71. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/di/container.py +0 -0
  72. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/di/decorators.py +0 -0
  73. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/di/errors.py +0 -0
  74. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/di/scope.py +0 -0
  75. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/discovery/__init__.py +0 -0
  76. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/discovery/commands.py +0 -0
  77. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/discovery/events.py +0 -0
  78. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/discovery/routes.py +0 -0
  79. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/events/README.md +0 -0
  80. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/events/SYNTAX_GUIDE.md +0 -0
  81. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/events/__init__.py +0 -0
  82. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/events/bus.py +0 -0
  83. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/events/decorators.py +0 -0
  84. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/events/event.py +0 -0
  85. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/events/middleware.py +0 -0
  86. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/patterns/__init__.py +0 -0
  87. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/patterns/interactor.py +0 -0
  88. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/patterns/mediator.py +0 -0
  89. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/patterns/repository.py +0 -0
  90. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/patterns/service.py +0 -0
  91. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/settings/__init__.py +0 -0
  92. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/settings/base.py +0 -0
  93. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/web/__init__.py +0 -0
  94. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/web/application.py +0 -0
  95. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/web/builtin_middlewares.py +0 -0
  96. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/web/docs.py +0 -0
  97. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/web/exceptions.py +0 -0
  98. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/web/middleware.py +0 -0
  99. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/web/request.py +0 -0
  100. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/web/response.py +0 -0
  101. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/web/route_middleware.py +0 -0
  102. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/web/router.py +0 -0
  103. {vega_framework-0.2.3 → vega_framework-0.2.5}/vega/web/routing.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vega-framework
3
- Version: 0.2.3
3
+ Version: 0.2.5
4
4
  Summary: Enterprise-ready Python framework that enforces Clean Architecture for building maintainable and scalable applications.
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "vega-framework"
3
- version = "0.2.3"
3
+ version = "0.2.5"
4
4
  description = "Enterprise-ready Python framework that enforces Clean Architecture for building maintainable and scalable applications."
5
5
  authors = ["Roberto Ferro"]
6
6
  license = "MIT"
@@ -569,92 +569,33 @@ def _generate_middleware(project_root: Path, project_name: str, class_name: str,
569
569
 
570
570
  click.echo(f"+ Created {click.style(str(middleware_file.relative_to(project_root)), fg='green')}")
571
571
 
572
- # Register the middleware in app.py
573
- _register_middleware_in_app(project_root, class_name, file_name)
572
+ # Warn if legacy app-level registration is present
573
+ app_file = project_root / "presentation" / "web" / "app.py"
574
+ if app_file.exists():
575
+ app_content = app_file.read_text()
576
+ legacy_call = f"app.add_middleware({class_name}Middleware"
577
+ if legacy_call in app_content:
578
+ click.echo(click.style(
579
+ f"WARNING: Detected legacy app-level registration for {class_name}Middleware in presentation/web/app.py.",
580
+ fg='yellow'
581
+ ))
582
+ click.echo(click.style(
583
+ " Route middleware should be applied with the @middleware decorator per route.",
584
+ fg='yellow'
585
+ ))
574
586
 
575
587
  # Instructions for next steps
576
588
  click.echo(f"\nNext steps:")
577
- click.echo(f" 1. Implement your middleware logic in {class_name}Middleware.dispatch()")
578
- click.echo(f" 2. The middleware has been registered in app.py")
579
- click.echo(f" 3. Restart your server to apply changes")
580
-
581
-
582
- def _register_middleware_in_app(project_root: Path, class_name: str, file_name: str) -> None:
583
- """Register a new middleware in app.py"""
584
- app_file = project_root / "presentation" / "web" / "app.py"
585
-
586
- if not app_file.exists():
587
- click.echo(click.style("WARNING: app.py not found", fg='yellow'))
588
- click.echo(f"\nTo register manually, add to app.py:")
589
- click.echo(click.style(f'''
590
- from .middleware.{file_name} import {class_name}Middleware
591
-
592
- def create_app() -> VegaApp:
593
- app = VegaApp(...)
594
- app.add_middleware({class_name}Middleware)
595
- app.include_router(get_api_router())
596
- return app
597
- ''', fg='cyan'))
598
- return
599
-
600
- content = app_file.read_text()
601
- lines = content.split('\n')
602
-
603
- # Check if already registered
604
- middleware_import = f"from .middleware.{file_name} import {class_name}Middleware"
605
- middleware_call = f"app.add_middleware({class_name}Middleware)"
606
-
607
- if any(middleware_import in line for line in lines):
608
- click.echo(click.style(f"WARNING: Middleware {class_name} already imported in app.py", fg='yellow'))
609
- return
610
-
611
- # Find import section and add middleware import
612
- import_added = False
613
- for i, line in enumerate(lines):
614
- if line.startswith('from .routes import'):
615
- # Add import before routes import
616
- lines.insert(i, middleware_import)
617
- lines.insert(i + 1, '')
618
- import_added = True
619
- break
620
-
621
- if not import_added:
622
- # Fallback: add after VegaApp import
623
- for i, line in enumerate(lines):
624
- if 'from vega.web import' in line:
625
- lines.insert(i + 1, middleware_import)
626
- lines.insert(i + 2, '')
627
- break
628
-
629
- # Find create_app function and add middleware registration
630
- middleware_added = False
631
- for i, line in enumerate(lines):
632
- if 'app = VegaApp(' in line:
633
- # Find the end of VegaApp initialization
634
- j = i + 1
635
- while j < len(lines) and not lines[j].strip().startswith('app.include_router'):
636
- j += 1
637
-
638
- # Add middleware registration before include_router
639
- lines.insert(j, f' {middleware_call}')
640
- middleware_added = True
641
- break
642
-
643
- if import_added or middleware_added:
644
- app_file.write_text('\n'.join(lines))
645
- click.echo(f"+ Updated {click.style(str(app_file.relative_to(project_root)), fg='green')}")
646
- else:
647
- click.echo(click.style("WARNING: Could not auto-register middleware in app.py", fg='yellow'))
648
- click.echo(f"\nTo register manually, add to app.py:")
649
- click.echo(click.style(f'''
650
- from .middleware.{file_name} import {class_name}Middleware
651
-
652
- def create_app() -> VegaApp:
653
- app = VegaApp(...)
654
- app.add_middleware({class_name}Middleware)
655
- app.include_router(get_api_router())
656
- return app
657
- ''', fg='cyan'))
589
+ click.echo(f" 1. Implement your middleware logic in {class_name}Middleware.before/after().")
590
+ click.echo(f" 2. Apply it to routes using the @middleware decorator, for example:")
591
+ click.echo(click.style(f''' from vega.web import middleware
592
+ from .middleware.{file_name} import {class_name}Middleware
593
+
594
+ @router.get("/example")
595
+ @middleware({class_name}Middleware())
596
+ async def example():
597
+ return {{"status": "ok"}}''', fg='cyan'))
598
+ click.echo(f" 3. Restart your server to load the updated route middleware.")
658
599
 
659
600
 
660
601
 
@@ -0,0 +1,56 @@
1
+ """{{ class_name }} middleware for Vega Web application"""
2
+ from typing import Optional
3
+
4
+ from vega.web import MiddlewarePhase, Request, Response, RouteMiddleware
5
+
6
+
7
+ class {{ class_name }}Middleware(RouteMiddleware):
8
+ """
9
+ {{ class_name }} middleware.
10
+
11
+ This middleware runs in the Vega route middleware pipeline.
12
+
13
+ Usage:
14
+ from vega.web import middleware
15
+ from .middleware.{{ file_name }} import {{ class_name }}Middleware
16
+
17
+ @router.get("/example")
18
+ @middleware({{ class_name }}Middleware())
19
+ async def example_endpoint():
20
+ return {"message": "ok"}
21
+ """
22
+
23
+ def __init__(self):
24
+ super().__init__(phase=MiddlewarePhase.BOTH)
25
+ # Add any initialization logic here
26
+ # Example: self.audit_header = "X-Audit-ID"
27
+
28
+ async def before(self, request: Request) -> Optional[Response]:
29
+ """
30
+ Execute code before the route handler.
31
+
32
+ Return a Response to short-circuit the pipeline, or None to continue.
33
+ """
34
+ # Example: validate header and stop request
35
+ # from vega.web import JSONResponse, status
36
+ # if not request.headers.get("x-custom"):
37
+ # return JSONResponse(
38
+ # {"detail": "Missing X-Custom header"},
39
+ # status_code=status.HTTP_400_BAD_REQUEST,
40
+ # )
41
+
42
+ # Example: store data on request state for later middleware/handler
43
+ # request.state.audit_id = generate_request_id()
44
+ return None
45
+
46
+ async def after(self, request: Request, response: Response) -> Response:
47
+ """
48
+ Execute code after the route handler.
49
+
50
+ Always return the (modified) response object.
51
+ """
52
+ # Example: add header using previously stored state
53
+ # if hasattr(request.state, "audit_id") and hasattr(response, "headers"):
54
+ # response.headers[self.audit_header] = request.state.audit_id
55
+
56
+ return response
@@ -93,15 +93,9 @@ def get_openapi_schema(
93
93
  operation["parameters"] = params
94
94
 
95
95
  # Analyze request body
96
- request_body = _get_request_body(route)
96
+ request_body = _get_request_body(route, components)
97
97
  if request_body:
98
98
  operation["requestBody"] = request_body
99
- # Add request body schemas to components
100
- if PYDANTIC_AVAILABLE and "content" in request_body:
101
- for content_type, content_schema in request_body["content"].items():
102
- if "schema" in content_schema and "$ref" in content_schema["schema"]:
103
- model_name = content_schema["schema"]["$ref"].split("/")[-1]
104
- # Model will be added when processing response_model
105
99
 
106
100
  # Analyze response model
107
101
  if route.response_model:
@@ -192,7 +186,7 @@ def _get_parameters(route: Any) -> List[Dict[str, Any]]:
192
186
  return parameters
193
187
 
194
188
 
195
- def _get_request_body(route: Any) -> Optional[Dict[str, Any]]:
189
+ def _get_request_body(route: Any, components: Dict[str, Any]) -> Optional[Dict[str, Any]]:
196
190
  """Extract request body schema from route."""
197
191
  if not PYDANTIC_AVAILABLE:
198
192
  return None
@@ -212,9 +206,12 @@ def _get_request_body(route: Any) -> Optional[Dict[str, Any]]:
212
206
 
213
207
  # Check if it's a Pydantic model
214
208
  if param_type and isinstance(param_type, type) and issubclass(param_type, BaseModel):
215
- model_schema = param_type.model_json_schema()
216
209
  model_name = param_type.__name__
217
210
 
211
+ # Add model schema to components
212
+ if model_name not in components["schemas"]:
213
+ components["schemas"][model_name] = param_type.model_json_schema()
214
+
218
215
  return {
219
216
  "required": True,
220
217
  "content": {
@@ -1,65 +0,0 @@
1
- """{{ class_name }} middleware for Vega Web application"""
2
- from vega.web import Request, Response
3
- from starlette.middleware.base import BaseHTTPMiddleware
4
- from starlette.types import ASGIApp
5
- import time
6
- from typing import Callable
7
-
8
-
9
- class {{ class_name }}Middleware(BaseHTTPMiddleware):
10
- """
11
- {{ class_name }} middleware
12
-
13
- This middleware processes requests before they reach your endpoints
14
- and responses before they're returned to clients.
15
-
16
- Usage:
17
- Add to your Vega Web app in app.py:
18
- from .middleware.{{ file_name }} import {{ class_name }}Middleware
19
- app.add_middleware({{ class_name }}Middleware)
20
- """
21
-
22
- def __init__(self, app: ASGIApp):
23
- super().__init__(app)
24
- # Add any initialization logic here
25
- # Example: self.config = load_config()
26
-
27
- async def dispatch(self, request: Request, call_next: Callable) -> Response:
28
- """
29
- Process the request and response
30
-
31
- Args:
32
- request: The incoming request
33
- call_next: Function to call the next middleware or endpoint
34
-
35
- Returns:
36
- Response object
37
- """
38
- # ==========================================
39
- # BEFORE REQUEST - Add your logic here
40
- # ==========================================
41
- # Example: Log request
42
- # print(f"Incoming request: {request.method} {request.url}")
43
-
44
- # Example: Add custom headers
45
- # request.state.custom_data = "some value"
46
-
47
- # Example: Measure request time
48
- start_time = time.time()
49
-
50
- # ==========================================
51
- # PROCESS REQUEST
52
- # ==========================================
53
- response = await call_next(request)
54
-
55
- # ==========================================
56
- # AFTER REQUEST - Add your logic here
57
- # ==========================================
58
- # Example: Add custom response headers
59
- # response.headers["X-Process-Time"] = str(time.time() - start_time)
60
-
61
- # Example: Log response
62
- process_time = time.time() - start_time
63
- # print(f"Request completed in {process_time:.4f}s")
64
-
65
- return response
File without changes
File without changes