fastapi-basekit 0.5.2__tar.gz → 0.5.3__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.
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/PKG-INFO +1 -1
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/controller/base.py +27 -7
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/exceptions/handler.py +67 -18
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/utils/exception_handlers.py +27 -11
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit.egg-info/PKG-INFO +1 -1
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit.egg-info/SOURCES.txt +1 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/pyproject.toml +1 -1
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_exception_handlers.py +17 -0
- fastapi_basekit-0.5.3/tests/test_format_response_schema_override.py +79 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/LICENSE +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/README.md +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/beanie/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/beanie/controller/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/beanie/controller/base.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/beanie/repository/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/beanie/repository/base.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/beanie/service/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/beanie/service/base.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/controller/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/permissions/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/permissions/base.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/sqlalchemy/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/sqlalchemy/controller/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/sqlalchemy/controller/base.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/sqlalchemy/repository/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/sqlalchemy/repository/base.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/sqlalchemy/service/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/sqlalchemy/service/base.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/sqlalchemy/session.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/sqlmodel/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/sqlmodel/controller/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/sqlmodel/controller/base.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/sqlmodel/repository/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/sqlmodel/repository/base.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/sqlmodel/service/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/sqlmodel/service/base.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/cli/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/cli/main.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/exceptions/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/exceptions/api_exceptions.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/exceptions/domain.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/openapi.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/py.typed +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/schema/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/schema/base.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/schema/jwt.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/schema/schema.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/servicios/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/servicios/thrid/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/servicios/thrid/jwt.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/cookiecutter.json +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/hooks/post_gen_project.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/hooks/pre_gen_project.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/.env.example +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/.gitignore +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/Dockerfile +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/LICENSE +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/Makefile +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/README.md +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/alembic/env.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/alembic/script.py.mako +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/alembic.ini +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/api/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/api/v1/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/api/v1/endpoints/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/api/v1/endpoints/auth/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/api/v1/endpoints/auth/auth.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/api/v1/endpoints/user/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/api/v1/endpoints/user/user.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/api/v1/routers.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/config/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/config/database.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/config/settings.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/main.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/middleware/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/middleware/auth.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/middleware/permissions.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/models/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/models/auth.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/models/base.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/models/enums.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/models/types.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/permissions/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/permissions/user.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/repositories/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/repositories/user/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/repositories/user/repository.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/schemas/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/schemas/auth.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/schemas/base.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/schemas/user.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/scripts/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/scripts/init.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/scripts/init_admin.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/services/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/services/auth_service.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/services/dependency.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/services/user_service.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/utils/__init__.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/utils/security.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/docker-compose.yml +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/pytest.ini +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/requirements.txt +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit.egg-info/dependency_links.txt +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit.egg-info/entry_points.txt +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit.egg-info/requires.txt +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit.egg-info/top_level.txt +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/setup.cfg +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_action_param_leak.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_api_exceptions.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_base_response.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_base_service.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_beanie_aggregation_hooks.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_beanie_aggregation_integration.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_beanie_keyset_pagination.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_beanie_repository_regression.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_beanie_service_mutable_defaults.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_beanie_service_regression.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_controller_auto_permissions.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_crud_beanie_controller.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_crud_controller.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_crud_sqlmodel_repository_service.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_filter_operators.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_generics_optional_and_cache.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_generics_wiring.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_jwt_config_robustness.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_jwt_service.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_openapi_simplify.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_params_classification.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_params_coercion_matrix.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_params_coercion_unit.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_params_http_matrix_beanie.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_params_http_matrix_sqlalchemy.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_params_rich_type_coercion.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_path_filter_mixin_compat.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_post_process_list_hook.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_pulbot_cbv_pattern_beanie.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_repo_signature_aliases.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_sql_queryset_override.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_sqlalchemy_base_service_order.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_sqlalchemy_repository_regression.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_sqlalchemy_service_regression.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_sqlmodel_filter_operators.py +0 -0
- {fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_typed_filter_coercion.py +0 -0
|
@@ -264,13 +264,33 @@ class BaseController:
|
|
|
264
264
|
# raw value when the schema doesn't fit (custom-action endpoints
|
|
265
265
|
# often return ad-hoc dicts that don't match the controller's
|
|
266
266
|
# default schema_class — those should pass through untouched).
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
267
|
+
#
|
|
268
|
+
# Cuando un endpoint custom ya devuelve un modelo Pydantic específico
|
|
269
|
+
# (distinto a ``schema``), no lo re-casteeamos al schema por defecto:
|
|
270
|
+
# eso rompe el ``response_model`` declarado en la ruta y provoca
|
|
271
|
+
# ResponseValidationError. Se convierte a dict limpio y FastAPI se
|
|
272
|
+
# encarga de validar/serializar contra el response_model del endpoint.
|
|
273
|
+
if isinstance(data, BaseModel):
|
|
274
|
+
if isinstance(data, schema):
|
|
275
|
+
data_parsed = data
|
|
276
|
+
else:
|
|
277
|
+
data_parsed = self.to_dict(data)
|
|
278
|
+
|
|
279
|
+
elif isinstance(data, list):
|
|
280
|
+
# Si la lista contiene modelos Pydantic distintos al schema por
|
|
281
|
+
# defecto, respetarlos; de lo contrario validar normalmente.
|
|
282
|
+
if data and all(
|
|
283
|
+
isinstance(item, BaseModel) and not isinstance(item, schema)
|
|
284
|
+
for item in data
|
|
285
|
+
):
|
|
286
|
+
data_parsed = [self.to_dict(item) for item in data]
|
|
287
|
+
else:
|
|
288
|
+
data_dicts = [self.to_dict(item) for item in data]
|
|
289
|
+
try:
|
|
290
|
+
adapter = TypeAdapter(List[schema])
|
|
291
|
+
data_parsed = adapter.validate_python(data_dicts)
|
|
292
|
+
except Exception:
|
|
293
|
+
data_parsed = data_dicts
|
|
274
294
|
|
|
275
295
|
elif isinstance(data, dict):
|
|
276
296
|
try:
|
|
@@ -5,6 +5,34 @@ from fastapi.exceptions import RequestValidationError
|
|
|
5
5
|
from fastapi.responses import JSONResponse
|
|
6
6
|
from pydantic import ValidationError
|
|
7
7
|
|
|
8
|
+
|
|
9
|
+
def _get_cors_headers(request: Request) -> Dict[str, str]:
|
|
10
|
+
"""Extrae headers CORS del ``Origin`` del request para respuestas de error.
|
|
11
|
+
|
|
12
|
+
Cuando una respuesta se genera desde un handler que corre debajo del
|
|
13
|
+
CORSMiddleware los headers CORS se agregan automáticamente. Pero si la
|
|
14
|
+
respuesta se genera desde ServerErrorMiddleware (por encima de CORS) o
|
|
15
|
+
desde cualquier otro camino que no pase por el middleware, los headers
|
|
16
|
+
faltan y el browser reporta un falso error CORS. Esta función permite
|
|
17
|
+
agregarlos defensivamente desde cualquier handler.
|
|
18
|
+
"""
|
|
19
|
+
origin = request.headers.get("origin")
|
|
20
|
+
if not origin:
|
|
21
|
+
return {}
|
|
22
|
+
return {
|
|
23
|
+
"Access-Control-Allow-Origin": origin,
|
|
24
|
+
"Access-Control-Allow-Credentials": "true",
|
|
25
|
+
"Vary": "Origin",
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _apply_cors(request: Request, response: JSONResponse) -> JSONResponse:
|
|
30
|
+
"""Agrega headers CORS defensivos a una ``JSONResponse``."""
|
|
31
|
+
headers = _get_cors_headers(request)
|
|
32
|
+
if headers:
|
|
33
|
+
response.headers.update(headers)
|
|
34
|
+
return response
|
|
35
|
+
|
|
8
36
|
try: # pragma: no cover - dependencia opcional
|
|
9
37
|
from pymongo.errors import DuplicateKeyError # type: ignore
|
|
10
38
|
except ImportError: # pragma: no cover
|
|
@@ -35,7 +63,10 @@ async def api_exception_handler(request: Request, exc: APIException):
|
|
|
35
63
|
response = BaseResponse(
|
|
36
64
|
status=exc.status_code, message=exc.message, data=exc.data
|
|
37
65
|
)
|
|
38
|
-
return
|
|
66
|
+
return _apply_cors(
|
|
67
|
+
request,
|
|
68
|
+
JSONResponse(status_code=exc.status, content=response.model_dump()),
|
|
69
|
+
)
|
|
39
70
|
|
|
40
71
|
|
|
41
72
|
async def domain_error_handler(request: Request, exc: DomainError):
|
|
@@ -46,8 +77,11 @@ async def domain_error_handler(request: Request, exc: DomainError):
|
|
|
46
77
|
a `exc.http_status()` con el mismo envelope `BaseResponse` que el resto.
|
|
47
78
|
"""
|
|
48
79
|
response = BaseResponse(status=exc.code, message=exc.message, data=None)
|
|
49
|
-
return
|
|
50
|
-
|
|
80
|
+
return _apply_cors(
|
|
81
|
+
request,
|
|
82
|
+
JSONResponse(
|
|
83
|
+
status_code=exc.http_status(), content=response.model_dump()
|
|
84
|
+
),
|
|
51
85
|
)
|
|
52
86
|
|
|
53
87
|
|
|
@@ -81,9 +115,12 @@ async def document_not_found_handler(request: Request, exc: DocumentNotFound):
|
|
|
81
115
|
message="Documento no encontrado",
|
|
82
116
|
data={"detail": str(exc)},
|
|
83
117
|
)
|
|
84
|
-
return
|
|
85
|
-
|
|
86
|
-
|
|
118
|
+
return _apply_cors(
|
|
119
|
+
request,
|
|
120
|
+
JSONResponse(
|
|
121
|
+
status_code=status.HTTP_404_NOT_FOUND,
|
|
122
|
+
content=response.model_dump(),
|
|
123
|
+
),
|
|
87
124
|
)
|
|
88
125
|
|
|
89
126
|
|
|
@@ -96,9 +133,12 @@ async def global_exception_handler(request: Request, exc: Exception):
|
|
|
96
133
|
message="Ocurrió un error desconocido",
|
|
97
134
|
data={"detail": str(exc)},
|
|
98
135
|
)
|
|
99
|
-
return
|
|
100
|
-
|
|
101
|
-
|
|
136
|
+
return _apply_cors(
|
|
137
|
+
request,
|
|
138
|
+
JSONResponse(
|
|
139
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
140
|
+
content=response.model_dump(),
|
|
141
|
+
),
|
|
102
142
|
)
|
|
103
143
|
|
|
104
144
|
|
|
@@ -119,9 +159,12 @@ async def value_exception_handler(
|
|
|
119
159
|
data=str(error_details),
|
|
120
160
|
)
|
|
121
161
|
|
|
122
|
-
return
|
|
123
|
-
|
|
124
|
-
|
|
162
|
+
return _apply_cors(
|
|
163
|
+
request,
|
|
164
|
+
JSONResponse(
|
|
165
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
|
166
|
+
content=response.model_dump(mode="json"),
|
|
167
|
+
),
|
|
125
168
|
)
|
|
126
169
|
|
|
127
170
|
|
|
@@ -139,9 +182,12 @@ async def request_validation_handler(
|
|
|
139
182
|
message="Error de validación",
|
|
140
183
|
data=exc.errors(),
|
|
141
184
|
)
|
|
142
|
-
return
|
|
143
|
-
|
|
144
|
-
|
|
185
|
+
return _apply_cors(
|
|
186
|
+
request,
|
|
187
|
+
JSONResponse(
|
|
188
|
+
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
|
189
|
+
content=response.model_dump(mode="json"),
|
|
190
|
+
),
|
|
145
191
|
)
|
|
146
192
|
|
|
147
193
|
|
|
@@ -153,9 +199,12 @@ async def integrity_error_handler(request: Request, exc: Exception):
|
|
|
153
199
|
message="Registro ya existe o viola una restricción de integridad",
|
|
154
200
|
data={"detail": str(detail) if detail is not None else str(exc)},
|
|
155
201
|
)
|
|
156
|
-
return
|
|
157
|
-
|
|
158
|
-
|
|
202
|
+
return _apply_cors(
|
|
203
|
+
request,
|
|
204
|
+
JSONResponse(
|
|
205
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
|
206
|
+
content=response.model_dump(mode="json"),
|
|
207
|
+
),
|
|
159
208
|
)
|
|
160
209
|
|
|
161
210
|
|
|
@@ -10,6 +10,7 @@ from fastapi_basekit.exceptions.api_exceptions import (
|
|
|
10
10
|
DatabaseIntegrityException,
|
|
11
11
|
ValidationException,
|
|
12
12
|
)
|
|
13
|
+
from fastapi_basekit.exceptions.handler import _apply_cors # noqa: F401
|
|
13
14
|
from fastapi_basekit.schema.base import BaseResponse
|
|
14
15
|
from pydantic import ValidationError
|
|
15
16
|
{% if cookiecutter.orm == "sqlalchemy" -%}
|
|
@@ -19,7 +20,10 @@ from sqlalchemy.exc import IntegrityError
|
|
|
19
20
|
|
|
20
21
|
async def api_exception_handler(request: Request, exc: APIException):
|
|
21
22
|
response = BaseResponse(status=exc.status_code, message=exc.message, data=exc.data)
|
|
22
|
-
return
|
|
23
|
+
return _apply_cors(
|
|
24
|
+
request,
|
|
25
|
+
JSONResponse(status_code=exc.status, content=response.model_dump()),
|
|
26
|
+
)
|
|
23
27
|
|
|
24
28
|
|
|
25
29
|
async def validation_exception_handler(request: Request, exc: RequestValidationError):
|
|
@@ -28,7 +32,10 @@ async def validation_exception_handler(request: Request, exc: RequestValidationE
|
|
|
28
32
|
|
|
29
33
|
async def database_exception_handler(request: Request, exc: DatabaseIntegrityException):
|
|
30
34
|
response = BaseResponse(status=exc.status_code, message=exc.message, data=exc.data)
|
|
31
|
-
return
|
|
35
|
+
return _apply_cors(
|
|
36
|
+
request,
|
|
37
|
+
JSONResponse(status_code=exc.status, content=response.model_dump()),
|
|
38
|
+
)
|
|
32
39
|
|
|
33
40
|
|
|
34
41
|
async def value_exception_handler(request: Request, exc: Union[ValidationError, ValueError]):
|
|
@@ -42,9 +49,12 @@ async def value_exception_handler(request: Request, exc: Union[ValidationError,
|
|
|
42
49
|
message="Field validation error",
|
|
43
50
|
data=str(error_details),
|
|
44
51
|
)
|
|
45
|
-
return
|
|
46
|
-
|
|
47
|
-
|
|
52
|
+
return _apply_cors(
|
|
53
|
+
request,
|
|
54
|
+
JSONResponse(
|
|
55
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
|
56
|
+
content=response.model_dump(mode="json"),
|
|
57
|
+
),
|
|
48
58
|
)
|
|
49
59
|
|
|
50
60
|
|
|
@@ -65,9 +75,12 @@ async def integrity_error_handler(request: Request, exc: IntegrityError):
|
|
|
65
75
|
message = "Database integrity error"
|
|
66
76
|
|
|
67
77
|
response = BaseResponse(status="DATABASE_INTEGRITY_ERROR", message=message, data=None)
|
|
68
|
-
return
|
|
69
|
-
|
|
70
|
-
|
|
78
|
+
return _apply_cors(
|
|
79
|
+
request,
|
|
80
|
+
JSONResponse(
|
|
81
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
|
82
|
+
content=response.model_dump(),
|
|
83
|
+
),
|
|
71
84
|
)
|
|
72
85
|
{% endif %}
|
|
73
86
|
|
|
@@ -78,7 +91,10 @@ async def global_exception_handler(request: Request, exc: Exception):
|
|
|
78
91
|
message="Unknown error",
|
|
79
92
|
data={"detail": str(exc)},
|
|
80
93
|
)
|
|
81
|
-
return
|
|
82
|
-
|
|
83
|
-
|
|
94
|
+
return _apply_cors(
|
|
95
|
+
request,
|
|
96
|
+
JSONResponse(
|
|
97
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
98
|
+
content=response.model_dump(),
|
|
99
|
+
),
|
|
84
100
|
)
|
|
@@ -121,6 +121,7 @@ tests/test_crud_controller.py
|
|
|
121
121
|
tests/test_crud_sqlmodel_repository_service.py
|
|
122
122
|
tests/test_exception_handlers.py
|
|
123
123
|
tests/test_filter_operators.py
|
|
124
|
+
tests/test_format_response_schema_override.py
|
|
124
125
|
tests/test_generics_optional_and_cache.py
|
|
125
126
|
tests/test_generics_wiring.py
|
|
126
127
|
tests/test_jwt_config_robustness.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "fastapi-basekit"
|
|
7
|
-
version = "0.5.
|
|
7
|
+
version = "0.5.3"
|
|
8
8
|
description = "Utilities and base classes for FastAPI async projects (Beanie, SQLAlchemy or SQLModel)"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -39,6 +39,10 @@ def client():
|
|
|
39
39
|
# code sin mapeo → DEFAULT_STATUS (400)
|
|
40
40
|
raise DomainError("SOMETHING", "algo pasó")
|
|
41
41
|
|
|
42
|
+
@app.get("/boom-generic")
|
|
43
|
+
async def boom_generic():
|
|
44
|
+
raise RuntimeError("error inesperado")
|
|
45
|
+
|
|
42
46
|
@app.post("/echo")
|
|
43
47
|
async def echo(body: Body):
|
|
44
48
|
return {"n": body.n}
|
|
@@ -83,3 +87,16 @@ def test_domain_error_default_status(client):
|
|
|
83
87
|
r = client.get("/boom-domain-default")
|
|
84
88
|
assert r.status_code == 400 # DEFAULT_STATUS
|
|
85
89
|
assert r.json()["status"] == "SOMETHING"
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def test_cors_headers_injected_on_error(client):
|
|
93
|
+
"""Todas las respuestas de error incluyen headers CORS cuando el request
|
|
94
|
+
tiene un header ``Origin`` (defensa en profundidad)."""
|
|
95
|
+
r = client.get(
|
|
96
|
+
"/boom-generic",
|
|
97
|
+
headers={"Origin": "https://app.example.com"},
|
|
98
|
+
)
|
|
99
|
+
assert r.status_code == 500
|
|
100
|
+
assert r.headers.get("Access-Control-Allow-Origin") == "https://app.example.com"
|
|
101
|
+
assert r.headers.get("Access-Control-Allow-Credentials") == "true"
|
|
102
|
+
assert r.headers.get("Vary") == "Origin"
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""Regresión: format_response no debe re-castear modelos Pydantic específicos
|
|
2
|
+
a ``schema_class`` cuando un endpoint custom devuelve otro schema."""
|
|
3
|
+
|
|
4
|
+
import pytest
|
|
5
|
+
from pydantic import BaseModel
|
|
6
|
+
|
|
7
|
+
from fastapi_basekit.aio.controller.base import BaseController
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class _DefaultSchema(BaseModel):
|
|
11
|
+
id: int
|
|
12
|
+
name: str
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class _OtherSchema(BaseModel):
|
|
16
|
+
ok: bool
|
|
17
|
+
status: str
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class _Controller(BaseController):
|
|
21
|
+
schema_class = _DefaultSchema
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@pytest.fixture
|
|
25
|
+
def controller():
|
|
26
|
+
return _Controller()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_format_response_respects_other_pydantic_model(controller):
|
|
30
|
+
"""Un endpoint custom que devuelve otro schema no debe romperse al forzar
|
|
31
|
+
``schema_class`` (GatewayCheckoutResponseSchema vs GatewayChargeResponseSchema)."""
|
|
32
|
+
other = _OtherSchema(ok=True, status="paid")
|
|
33
|
+
resp = controller.format_response(other, message="OK")
|
|
34
|
+
|
|
35
|
+
# Se convierte a dict limpio y se deja pasar; FastAPI validará contra
|
|
36
|
+
# el response_model declarado en la ruta.
|
|
37
|
+
assert resp.data == {"ok": True, "status": "paid"}
|
|
38
|
+
assert isinstance(resp.data, dict)
|
|
39
|
+
assert resp.message == "OK"
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def test_format_response_keeps_default_model_instance(controller):
|
|
43
|
+
"""Si ``data`` ya es instancia de ``schema_class``, se usa tal cual."""
|
|
44
|
+
item = _DefaultSchema(id=1, name="foo")
|
|
45
|
+
resp = controller.format_response(item)
|
|
46
|
+
|
|
47
|
+
assert resp.data is item
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def test_format_response_validates_plain_dict(controller):
|
|
51
|
+
"""Los dicts planos siguen validándose contra ``schema_class``."""
|
|
52
|
+
resp = controller.format_response({"id": 2, "name": "bar"})
|
|
53
|
+
|
|
54
|
+
assert isinstance(resp.data, _DefaultSchema)
|
|
55
|
+
assert resp.data.id == 2
|
|
56
|
+
assert resp.data.name == "bar"
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def test_format_response_list_of_other_models(controller):
|
|
60
|
+
"""Una lista de modelos Pydantic distintos a ``schema_class`` se respeta."""
|
|
61
|
+
items = [
|
|
62
|
+
_OtherSchema(ok=True, status="paid"),
|
|
63
|
+
_OtherSchema(ok=False, status="failed"),
|
|
64
|
+
]
|
|
65
|
+
resp = controller.format_response(items)
|
|
66
|
+
|
|
67
|
+
assert resp.data == [
|
|
68
|
+
{"ok": True, "status": "paid"},
|
|
69
|
+
{"ok": False, "status": "failed"},
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def test_format_response_list_of_dicts_still_validates(controller):
|
|
74
|
+
"""Una lista de dicts sigue validándose contra ``List[schema_class]``."""
|
|
75
|
+
resp = controller.format_response([{"id": 3, "name": "baz"}])
|
|
76
|
+
|
|
77
|
+
assert isinstance(resp.data, list)
|
|
78
|
+
assert isinstance(resp.data[0], _DefaultSchema)
|
|
79
|
+
assert resp.data[0].id == 3
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/beanie/controller/__init__.py
RENAMED
|
File without changes
|
{fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/beanie/controller/base.py
RENAMED
|
File without changes
|
{fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/beanie/repository/__init__.py
RENAMED
|
File without changes
|
{fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/beanie/repository/base.py
RENAMED
|
File without changes
|
{fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/beanie/service/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/sqlalchemy/controller/base.py
RENAMED
|
File without changes
|
|
File without changes
|
{fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/sqlalchemy/repository/base.py
RENAMED
|
File without changes
|
{fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/sqlalchemy/service/__init__.py
RENAMED
|
File without changes
|
{fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/sqlalchemy/service/base.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/sqlmodel/controller/__init__.py
RENAMED
|
File without changes
|
{fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/sqlmodel/controller/base.py
RENAMED
|
File without changes
|
{fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/sqlmodel/repository/__init__.py
RENAMED
|
File without changes
|
{fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/sqlmodel/repository/base.py
RENAMED
|
File without changes
|
{fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/sqlmodel/service/__init__.py
RENAMED
|
File without changes
|
{fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/aio/sqlmodel/service/base.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/exceptions/api_exceptions.py
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
|
{fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit/templates/project/cookiecutter.json
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
|
|
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
|
{fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/fastapi_basekit.egg-info/dependency_links.txt
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
|
{fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_beanie_aggregation_integration.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_beanie_service_mutable_defaults.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_crud_sqlmodel_repository_service.py
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
|
{fastapi_basekit-0.5.2 → fastapi_basekit-0.5.3}/tests/test_sqlalchemy_repository_regression.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|