fastapi-basekit 0.5.4__tar.gz → 0.5.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.
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/PKG-INFO +1 -1
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/beanie/repository/base.py +33 -2
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit.egg-info/PKG-INFO +1 -1
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit.egg-info/SOURCES.txt +1 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/pyproject.toml +1 -1
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_beanie_aggregation_hooks.py +5 -3
- fastapi_basekit-0.5.5/tests/test_beanie_search_regex.py +53 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/LICENSE +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/README.md +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/beanie/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/beanie/controller/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/beanie/controller/base.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/beanie/repository/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/beanie/service/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/beanie/service/base.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/controller/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/controller/base.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/permissions/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/permissions/base.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/sqlalchemy/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/sqlalchemy/controller/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/sqlalchemy/controller/base.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/sqlalchemy/repository/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/sqlalchemy/repository/base.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/sqlalchemy/service/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/sqlalchemy/service/base.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/sqlalchemy/session.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/sqlmodel/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/sqlmodel/controller/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/sqlmodel/controller/base.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/sqlmodel/repository/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/sqlmodel/repository/base.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/sqlmodel/service/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/sqlmodel/service/base.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/cli/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/cli/main.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/exceptions/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/exceptions/api_exceptions.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/exceptions/domain.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/exceptions/handler.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/openapi.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/py.typed +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/schema/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/schema/base.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/schema/jwt.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/schema/schema.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/servicios/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/servicios/thrid/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/servicios/thrid/jwt.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/cookiecutter.json +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/hooks/post_gen_project.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/hooks/pre_gen_project.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/.env.example +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/.gitignore +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/Dockerfile +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/LICENSE +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/Makefile +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/README.md +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/alembic/env.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/alembic/script.py.mako +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/alembic.ini +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/api/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/api/v1/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/api/v1/endpoints/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/api/v1/endpoints/auth/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/api/v1/endpoints/auth/auth.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/api/v1/endpoints/user/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/api/v1/endpoints/user/user.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/api/v1/routers.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/config/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/config/database.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/config/settings.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/main.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/middleware/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/middleware/auth.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/middleware/permissions.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/models/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/models/auth.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/models/base.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/models/enums.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/models/types.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/permissions/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/permissions/user.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/repositories/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/repositories/user/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/repositories/user/repository.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/schemas/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/schemas/auth.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/schemas/base.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/schemas/user.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/scripts/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/scripts/init.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/scripts/init_admin.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/services/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/services/auth_service.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/services/dependency.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/services/user_service.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/utils/__init__.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/utils/exception_handlers.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/app/utils/security.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/docker-compose.yml +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/pytest.ini +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/templates/project/{{cookiecutter.project_slug}}/requirements.txt +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit.egg-info/dependency_links.txt +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit.egg-info/entry_points.txt +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit.egg-info/requires.txt +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit.egg-info/top_level.txt +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/setup.cfg +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_action_param_leak.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_api_exceptions.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_base_response.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_base_service.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_beanie_aggregation_integration.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_beanie_keyset_pagination.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_beanie_repository_regression.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_beanie_service_mutable_defaults.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_beanie_service_regression.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_controller_auto_permissions.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_crud_beanie_controller.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_crud_controller.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_crud_sqlmodel_repository_service.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_exception_handlers.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_filter_operators.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_format_response_schema_override.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_generics_optional_and_cache.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_generics_wiring.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_jwt_config_robustness.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_jwt_service.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_openapi_simplify.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_owner_filter_helper.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_params_classification.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_params_coercion_matrix.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_params_coercion_unit.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_params_http_matrix_beanie.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_params_http_matrix_sqlalchemy.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_params_rich_type_coercion.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_path_filter_mixin_compat.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_post_process_list_hook.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_pulbot_cbv_pattern_beanie.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_repo_signature_aliases.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_sql_queryset_override.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_sqlalchemy_base_service_order.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_sqlalchemy_repository_regression.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_sqlalchemy_service_regression.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_sqlmodel_filter_operators.py +0 -0
- {fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_typed_filter_coercion.py +0 -0
{fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/beanie/repository/base.py
RENAMED
|
@@ -2,6 +2,8 @@ import logging
|
|
|
2
2
|
from typing import Any, Dict, Generic, List, Optional, Type, TypeVar, Union
|
|
3
3
|
from typing import get_args, get_origin
|
|
4
4
|
import re
|
|
5
|
+
import unicodedata
|
|
6
|
+
from functools import lru_cache
|
|
5
7
|
|
|
6
8
|
from bson import ObjectId
|
|
7
9
|
from pydantic import BaseModel
|
|
@@ -11,6 +13,35 @@ from beanie.operators import Or, RegEx
|
|
|
11
13
|
|
|
12
14
|
logger = logging.getLogger(__name__)
|
|
13
15
|
|
|
16
|
+
|
|
17
|
+
@lru_cache(maxsize=None)
|
|
18
|
+
def _accent_class(letter: str) -> str:
|
|
19
|
+
"""Clase regex que matchea `letter` con y sin tilde/diéresis, y en mayúscula."""
|
|
20
|
+
variants = {letter, letter.upper()}
|
|
21
|
+
for cp in range(0x00C0, 0x0100): # Latin-1: á é í ó ú ü ñ… (mantiene el patrón corto)
|
|
22
|
+
ch = chr(cp)
|
|
23
|
+
if unicodedata.normalize("NFD", ch)[0].lower() == letter:
|
|
24
|
+
variants.add(ch)
|
|
25
|
+
return "[" + "".join(sorted(variants)) + "]"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def build_search_regex(term: str) -> str:
|
|
29
|
+
"""Patrón regex para búsqueda de texto (usar con `options="i"`).
|
|
30
|
+
|
|
31
|
+
- Todo lo que escribe el usuario se escapa: `(`, `[`, `*`… son literales y
|
|
32
|
+
no rompen la query ni cambian el significado del patrón.
|
|
33
|
+
- Cada letra ASCII matchea también sus variantes acentuadas: `a` ↔ `á`,
|
|
34
|
+
`n` ↔ `ñ`, `o` ↔ `Ó`. Así "descripcion" encuentra "descripción".
|
|
35
|
+
"""
|
|
36
|
+
parts = []
|
|
37
|
+
for ch in term:
|
|
38
|
+
base = unicodedata.normalize("NFD", ch)[0]
|
|
39
|
+
if base.isascii() and base.isalpha():
|
|
40
|
+
parts.append(_accent_class(base.lower()))
|
|
41
|
+
else:
|
|
42
|
+
parts.append(re.escape(ch))
|
|
43
|
+
return ".*" + "".join(parts) + ".*"
|
|
44
|
+
|
|
14
45
|
#: Tipo del Document Beanie que gestiona el repositorio. Parametrízalo al
|
|
15
46
|
#: declarar la subclase — ``class UserRepository(BaseRepository[User])`` — para
|
|
16
47
|
#: que ``get_by_id``/``create``/``update``/``list_all`` devuelvan el Document
|
|
@@ -233,7 +264,7 @@ class BaseRepository(Generic[ModelT]):
|
|
|
233
264
|
*[
|
|
234
265
|
RegEx(
|
|
235
266
|
getattr(self.model, f),
|
|
236
|
-
|
|
267
|
+
build_search_regex(search),
|
|
237
268
|
options="i",
|
|
238
269
|
)
|
|
239
270
|
for f in search_fields
|
|
@@ -352,7 +383,7 @@ class BaseRepository(Generic[ModelT]):
|
|
|
352
383
|
|
|
353
384
|
if search and search_fields:
|
|
354
385
|
search_conditions = [
|
|
355
|
-
{field: {"$regex":
|
|
386
|
+
{field: {"$regex": build_search_regex(search), "$options": "i"}}
|
|
356
387
|
for field in search_fields
|
|
357
388
|
]
|
|
358
389
|
if search_conditions:
|
|
@@ -113,6 +113,7 @@ tests/test_beanie_aggregation_hooks.py
|
|
|
113
113
|
tests/test_beanie_aggregation_integration.py
|
|
114
114
|
tests/test_beanie_keyset_pagination.py
|
|
115
115
|
tests/test_beanie_repository_regression.py
|
|
116
|
+
tests/test_beanie_search_regex.py
|
|
116
117
|
tests/test_beanie_service_mutable_defaults.py
|
|
117
118
|
tests/test_beanie_service_regression.py
|
|
118
119
|
tests/test_controller_auto_permissions.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.5"
|
|
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"
|
|
@@ -13,6 +13,8 @@ Covers:
|
|
|
13
13
|
from unittest.mock import AsyncMock, MagicMock, patch
|
|
14
14
|
|
|
15
15
|
import pytest
|
|
16
|
+
|
|
17
|
+
from fastapi_basekit.aio.beanie.repository.base import build_search_regex
|
|
16
18
|
from beanie import Document
|
|
17
19
|
from pydantic import Field
|
|
18
20
|
|
|
@@ -97,8 +99,8 @@ class TestBuildListPipeline:
|
|
|
97
99
|
assert len(pipeline) == 1
|
|
98
100
|
match = pipeline[0]["$match"]
|
|
99
101
|
assert "$or" in match
|
|
100
|
-
assert {"name": {"$regex": "
|
|
101
|
-
assert {"email": {"$regex": "
|
|
102
|
+
assert {"name": {"$regex": build_search_regex("ana"), "$options": "i"}} in match["$or"]
|
|
103
|
+
assert {"email": {"$regex": build_search_regex("ana"), "$options": "i"}} in match["$or"]
|
|
102
104
|
|
|
103
105
|
def test_filters_plus_search_combined_with_and(self):
|
|
104
106
|
repo = FakeRepo()
|
|
@@ -110,7 +112,7 @@ class TestBuildListPipeline:
|
|
|
110
112
|
match = pipeline[0]["$match"]
|
|
111
113
|
assert "$and" in match
|
|
112
114
|
assert {"is_active": True} in match["$and"]
|
|
113
|
-
assert {"$or": [{"name": {"$regex": "
|
|
115
|
+
assert {"$or": [{"name": {"$regex": build_search_regex("ana"), "$options": "i"}}]} in match["$and"]
|
|
114
116
|
|
|
115
117
|
def test_simple_order_by_appends_sort_stage(self):
|
|
116
118
|
repo = FakeRepo()
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""build_search_regex: escape del término y búsqueda sin acentos (Beanie)."""
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
from fastapi_basekit.aio.beanie.repository.base import build_search_regex
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _matches(term: str, text: str) -> bool:
|
|
11
|
+
# Mismo significado que Mongo `$regex` con `$options: "i"`.
|
|
12
|
+
return re.search(build_search_regex(term), text, re.IGNORECASE) is not None
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@pytest.mark.parametrize(
|
|
16
|
+
"text",
|
|
17
|
+
["Descripción", "descripcion", "DESCRIPCIÓN", "Descripcíon"],
|
|
18
|
+
)
|
|
19
|
+
def test_sin_tilde_encuentra_con_tilde_y_viceversa(text):
|
|
20
|
+
assert _matches("descripcion", text)
|
|
21
|
+
assert _matches("descripción", text)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def test_enie_y_n_son_equivalentes():
|
|
25
|
+
assert _matches("ano", "Año nuevo")
|
|
26
|
+
assert _matches("año", "ANO")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_mayusculas_acentuadas_del_termino():
|
|
30
|
+
assert _matches("ÑANDÚ", "el ñandu corre")
|
|
31
|
+
assert _matches("ñandú", "NANDU")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@pytest.mark.parametrize("term", ["(", "[", "*", "+", "?", "\\", "a.*", "$", "^"])
|
|
35
|
+
def test_caracteres_especiales_son_literales(term):
|
|
36
|
+
# No deben romper la regex ni comportarse como metacaracteres.
|
|
37
|
+
assert re.compile(build_search_regex(term)) # compila
|
|
38
|
+
assert not _matches(term, "xyz")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def test_punto_asterisco_no_es_comodin():
|
|
42
|
+
assert not _matches("a.*", "abc")
|
|
43
|
+
assert _matches("a.*", "zza.*zz")
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_parentesis_se_busca_literal():
|
|
47
|
+
assert _matches("(beta)", "versión (beta) 2")
|
|
48
|
+
assert not _matches("(beta)", "versión beta 2")
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def test_termino_sin_acentos_no_cambia_el_resto_del_texto():
|
|
52
|
+
assert _matches("whats", "WhatsApp")
|
|
53
|
+
assert not _matches("telegram", "WhatsApp")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/beanie/controller/__init__.py
RENAMED
|
File without changes
|
{fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/beanie/controller/base.py
RENAMED
|
File without changes
|
{fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/beanie/repository/__init__.py
RENAMED
|
File without changes
|
{fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/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
|
|
File without changes
|
{fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/sqlalchemy/controller/base.py
RENAMED
|
File without changes
|
|
File without changes
|
{fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/sqlalchemy/repository/base.py
RENAMED
|
File without changes
|
{fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/sqlalchemy/service/__init__.py
RENAMED
|
File without changes
|
{fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/sqlalchemy/service/base.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/sqlmodel/controller/__init__.py
RENAMED
|
File without changes
|
{fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/sqlmodel/controller/base.py
RENAMED
|
File without changes
|
{fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/sqlmodel/repository/__init__.py
RENAMED
|
File without changes
|
{fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/sqlmodel/repository/base.py
RENAMED
|
File without changes
|
{fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/sqlmodel/service/__init__.py
RENAMED
|
File without changes
|
{fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/fastapi_basekit/aio/sqlmodel/service/base.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/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
|
|
File without changes
|
{fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/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
|
|
File without changes
|
{fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/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
|
{fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_beanie_aggregation_integration.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/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.4 → fastapi_basekit-0.5.5}/tests/test_crud_sqlmodel_repository_service.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_basekit-0.5.4 → fastapi_basekit-0.5.5}/tests/test_format_response_schema_override.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.4 → fastapi_basekit-0.5.5}/tests/test_sqlalchemy_repository_regression.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|