vega-framework 0.2.2__tar.gz → 0.2.4__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.
- {vega_framework-0.2.2 → vega_framework-0.2.4}/PKG-INFO +1 -1
- {vega_framework-0.2.2 → vega_framework-0.2.4}/pyproject.toml +2 -6
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/web/openapi.py +6 -9
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/web/routing.py +49 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/LICENSE +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/README.md +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/__init__.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/__init__.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/commands/__init__.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/commands/add.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/commands/generate.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/commands/init.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/commands/migrate.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/commands/update.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/commands/web.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/main.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/scaffolds/__init__.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/scaffolds/fastapi.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/scaffolds/sqlalchemy.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/scaffolds/vega_web.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/__init__.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/cli/command.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/cli/command_simple.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/cli/commands_init.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/components.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/domain/entity.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/domain/event.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/domain/event_handler.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/domain/interactor.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/domain/mediator.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/domain/repository_interface.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/domain/service_interface.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/infrastructure/model.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/infrastructure/repository_impl.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/infrastructure/service_impl.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/loader.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/project/.env.example +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/project/.gitignore +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/project/ARCHITECTURE.md.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/project/README.md.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/project/config.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/project/events_init.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/project/main.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/project/main_fastapi.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/project/main_standard.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/project/pyproject.toml.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/project/settings.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/sqlalchemy/alembic.ini.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/sqlalchemy/database_manager.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/sqlalchemy/env.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/sqlalchemy/script.py.mako +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/web/__init__.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/web/app.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/web/health_route.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/web/main.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/web/middleware.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/web/models_init.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/web/request_model.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/web/response_model.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/web/router.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/web/routes_init.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/web/routes_init_autodiscovery.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/web/user_models.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/web/users_route.py.j2 +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/utils/__init__.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/utils/async_support.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/utils/messages.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/utils/naming.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/utils/validators.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/di/__init__.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/di/container.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/di/decorators.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/di/errors.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/di/scope.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/discovery/__init__.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/discovery/commands.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/discovery/events.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/discovery/routes.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/events/README.md +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/events/SYNTAX_GUIDE.md +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/events/__init__.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/events/bus.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/events/decorators.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/events/event.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/events/middleware.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/patterns/__init__.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/patterns/interactor.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/patterns/mediator.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/patterns/repository.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/patterns/service.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/settings/__init__.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/settings/base.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/web/__init__.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/web/application.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/web/builtin_middlewares.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/web/docs.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/web/exceptions.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/web/middleware.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/web/request.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/web/response.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/web/route_middleware.py +0 -0
- {vega_framework-0.2.2 → vega_framework-0.2.4}/vega/web/router.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
[tool.poetry]
|
2
2
|
name = "vega-framework"
|
3
|
-
version = "0.2.
|
3
|
+
version = "0.2.4"
|
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"
|
@@ -102,11 +102,7 @@ addopts = [
|
|
102
102
|
"--cov-report=xml",
|
103
103
|
]
|
104
104
|
# Filter warnings
|
105
|
-
filterwarnings = [
|
106
|
-
"error",
|
107
|
-
"ignore::UserWarning",
|
108
|
-
"ignore::DeprecationWarning",
|
109
|
-
]
|
105
|
+
filterwarnings = ["error", "ignore::UserWarning", "ignore::DeprecationWarning"]
|
110
106
|
|
111
107
|
[tool.ruff]
|
112
108
|
line-length = 100
|
@@ -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": {
|
@@ -6,6 +6,7 @@ from functools import wraps
|
|
6
6
|
|
7
7
|
from starlette.routing import Route as StarletteRoute, Mount
|
8
8
|
from starlette.requests import Request as StarletteRequest
|
9
|
+
from pydantic import BaseModel, ValidationError
|
9
10
|
|
10
11
|
from .exceptions import HTTPException
|
11
12
|
from .request import Request
|
@@ -13,6 +14,14 @@ from .response import JSONResponse, Response, create_response
|
|
13
14
|
from .route_middleware import MiddlewareChain
|
14
15
|
|
15
16
|
|
17
|
+
def _is_pydantic_model(type_hint: Any) -> bool:
|
18
|
+
"""Check if a type hint is a Pydantic BaseModel"""
|
19
|
+
try:
|
20
|
+
return inspect.isclass(type_hint) and issubclass(type_hint, BaseModel)
|
21
|
+
except (TypeError, AttributeError):
|
22
|
+
return False
|
23
|
+
|
24
|
+
|
16
25
|
class Route:
|
17
26
|
"""
|
18
27
|
Represents a single route in the application.
|
@@ -73,6 +82,12 @@ class Route:
|
|
73
82
|
sig = inspect.signature(self.endpoint)
|
74
83
|
params = sig.parameters
|
75
84
|
|
85
|
+
# Get type hints for the function
|
86
|
+
try:
|
87
|
+
type_hints = get_type_hints(self.endpoint)
|
88
|
+
except Exception:
|
89
|
+
type_hints = {}
|
90
|
+
|
76
91
|
# Prepare kwargs for function call
|
77
92
|
kwargs = {}
|
78
93
|
|
@@ -93,6 +108,37 @@ class Route:
|
|
93
108
|
if param_name in params:
|
94
109
|
kwargs[param_name] = param_value
|
95
110
|
|
111
|
+
# Check for Pydantic model parameters (body parsing)
|
112
|
+
# Only parse the first Pydantic model found
|
113
|
+
body_parsed = False
|
114
|
+
for param_name, param in params.items():
|
115
|
+
# Skip if already processed (request or path param)
|
116
|
+
if param_name in kwargs or param_name == "request":
|
117
|
+
continue
|
118
|
+
|
119
|
+
# Get type hint for this parameter
|
120
|
+
param_type = type_hints.get(param_name, param.annotation)
|
121
|
+
|
122
|
+
# If it's a Pydantic model, parse the request body (only once)
|
123
|
+
if _is_pydantic_model(param_type) and not body_parsed:
|
124
|
+
try:
|
125
|
+
body_data = await request.json()
|
126
|
+
# Validate and parse using Pydantic
|
127
|
+
kwargs[param_name] = param_type(**body_data)
|
128
|
+
body_parsed = True
|
129
|
+
except ValidationError as e:
|
130
|
+
# Return validation errors in a user-friendly format
|
131
|
+
return JSONResponse(
|
132
|
+
content={"detail": e.errors()},
|
133
|
+
status_code=422,
|
134
|
+
)
|
135
|
+
except Exception as e:
|
136
|
+
# Handle JSON parsing errors
|
137
|
+
return JSONResponse(
|
138
|
+
content={"detail": f"Invalid JSON body: {str(e)}"},
|
139
|
+
status_code=400,
|
140
|
+
)
|
141
|
+
|
96
142
|
# Execute middleware chain if present
|
97
143
|
if self.middlewares:
|
98
144
|
middleware_chain = MiddlewareChain(self.middlewares)
|
@@ -113,6 +159,9 @@ class Route:
|
|
113
159
|
# Handle different return types
|
114
160
|
if isinstance(result, (Response, JSONResponse)):
|
115
161
|
return result
|
162
|
+
elif isinstance(result, BaseModel):
|
163
|
+
# Serialize Pydantic models using model_dump()
|
164
|
+
return JSONResponse(content=result.model_dump(), status_code=self.status_code)
|
116
165
|
elif isinstance(result, dict):
|
117
166
|
return JSONResponse(content=result, status_code=self.status_code)
|
118
167
|
elif isinstance(result, (list, tuple)):
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/domain/repository_interface.py.j2
RENAMED
File without changes
|
{vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/domain/service_interface.py.j2
RENAMED
File without changes
|
File without changes
|
File without changes
|
{vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/infrastructure/service_impl.py.j2
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/project/main_standard.py.j2
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/sqlalchemy/database_manager.py.j2
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{vega_framework-0.2.2 → vega_framework-0.2.4}/vega/cli/templates/web/routes_init_autodiscovery.py.j2
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|