fastapi-rtk 2.12.4__tar.gz → 2.13.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/PKG-INFO +1 -1
- fastapi_rtk-2.13.0/fastapi_rtk/_version.py +1 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/generic/column.py +87 -18
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/generic/model.py +18 -5
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/backends/generic/test_column.py +94 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/backends/generic/test_model.py +79 -4
- fastapi_rtk-2.12.4/fastapi_rtk/_version.py +0 -1
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/.gitignore +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/LICENSE +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/README.md +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/api/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/api/base_api.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/api/model_rest_api/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/api/model_rest_api/_add_mixin.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/api/model_rest_api/_bulk_mixin.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/api/model_rest_api/_columns_mixin.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/api/model_rest_api/_delete_mixin.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/api/model_rest_api/_download_mixin.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/api/model_rest_api/_edit_mixin.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/api/model_rest_api/_file_mixin.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/api/model_rest_api/_info_mixin.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/api/model_rest_api/_list_mixin.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/api/model_rest_api/_params.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/api/model_rest_api/_show_mixin.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/api/model_rest_api/_typed_base.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/api/model_rest_api/_upload_mixin.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/apis/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/apis/info.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/apis/license.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/auth/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/auth/auth.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/auth/hashers/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/auth/hashers/pbkdf2.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/auth/hashers/scrypt.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/auth/ldap.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/auth/password_helpers/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/auth/password_helpers/fab.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/auth/strategies/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/auth/strategies/config.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/auth/strategies/db.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/auth/strategies/jwt.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/generic/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/generic/db.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/generic/exceptions.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/generic/filters.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/generic/interface.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/generic/session.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/sqla/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/sqla/column.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/sqla/db.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/sqla/exceptions.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/sqla/extensions/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/sqla/extensions/audit/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/sqla/extensions/audit/_decorators_mixin.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/sqla/extensions/audit/_lifecycle_mixin.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/sqla/extensions/audit/_logger.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/sqla/extensions/audit/_processing_mixin.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/sqla/extensions/audit/audit.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/sqla/extensions/audit/types.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/sqla/extensions/geoalchemy2/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/sqla/extensions/geoalchemy2/filters.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/sqla/extensions/geoalchemy2/geometry_converter.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/sqla/filters.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/sqla/interface.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/sqla/model.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/sqla/session.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/bases/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/bases/cache.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/bases/db.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/bases/file_manager.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/bases/filter.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/bases/interface.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/bases/loop_manager.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/bases/model.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/bases/session.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/bases/user_cache.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/caches/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/caches/cache.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/caches/serializers.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/caches/storages.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/cli/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/cli/cli.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/cli/commands/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/cli/commands/_security_crypto.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/cli/commands/db/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/cli/commands/db/templates/fastapi/README +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/cli/commands/db/templates/fastapi/alembic.ini.mako +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/cli/commands/db/templates/fastapi/env.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/cli/commands/db/templates/fastapi/script.py.mako +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/README +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/alembic.ini.mako +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/env.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/script.py.mako +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/cli/commands/export.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/cli/commands/security.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/cli/commands/translate.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/cli/const.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/cli/decorators.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/cli/types.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/cli/utils.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/config.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/const.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/db.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/decorators.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/dependencies.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/exceptions.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/fastapi_react_toolkit.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/file_managers/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/file_managers/file_manager.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/file_managers/image_manager.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/file_managers/s3_file_manager.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/file_managers/s3_image_manager.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/filters.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/globals.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/lang/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/lang/babel/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/lang/babel/cli.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/lang/babel/config.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/lang/babel.cfg +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/lang/lazy_text.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/lang/messages.pot +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/lang/translations/de/LC_MESSAGES/messages.mo +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/lang/translations/de/LC_MESSAGES/messages.po +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/lang/translations/en/LC_MESSAGES/messages.mo +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/lang/translations/en/LC_MESSAGES/messages.po +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/loop_managers/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/loop_managers/loop_manager.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/manager.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/middlewares.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/mixins.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/models.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/py.typed +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/registry.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/routers.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/schemas.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/security/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/security/sqla/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/security/sqla/apis.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/security/sqla/models.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/security/sqla/security_manager/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/security/sqla/security_manager/_association_mixin.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/security/sqla/security_manager/_builtin_role_mixin.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/security/sqla/security_manager/_cleanup_mixin.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/security/sqla/security_manager/_exception_filters.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/security/sqla/security_manager/_export.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/security/sqla/security_manager/_import.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/security/sqla/security_manager/_role_mixin.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/security/sqla/security_manager/_user_mixin.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/security/sqla/user_cache.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/setting.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/types.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/utils/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/utils/async_task_runner.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/utils/class_factory.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/utils/csv_json_converter.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/utils/deep_merge.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/utils/extender_mixin.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/utils/flask_appbuilder_utils.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/utils/formatter.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/utils/hooks.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/utils/lazy.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/utils/merge_schema.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/utils/multiple_async_contexts.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/utils/pydantic.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/utils/run_utils.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/utils/self_dependencies.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/utils/smartdefaultdict.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/utils/sqla.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/utils/timezone.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/utils/update_signature.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/utils/use_default_when_none.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/version.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/pyproject.toml +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/conftest.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/docker-compose.gis.yml +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/integration/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/integration/api/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/integration/api/test_model_rest_api.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/integration/apis/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/integration/apis/test_info_callable_schema.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/integration/apis/test_info_contract.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/integration/auth/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/integration/auth/test_auth_flow.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/integration/auth/test_oauth.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/integration/conftest.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/integration/file_managers/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/integration/file_managers/test_file_routes.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/integration/security/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/integration/security/sqla/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/integration/security/sqla/test_security_manager.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/integration/test_app_smoke.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/api/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/api/conftest.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/api/model_rest_api/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/api/model_rest_api/test_columns.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/api/model_rest_api/test_file_mixin.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/api/model_rest_api/test_init.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/api/model_rest_api/test_typed_base_consistency.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/api/test_base_api.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/apis/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/apis/test_info.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/apis/test_license.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/auth/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/auth/hashers/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/auth/hashers/test_pbkdf2.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/auth/hashers/test_scrypt.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/auth/password_helpers/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/auth/password_helpers/test_fab.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/auth/strategies/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/auth/strategies/test_config.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/auth/strategies/test_db.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/auth/strategies/test_jwt.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/auth/test_auth.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/backends/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/backends/generic/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/backends/generic/test_db.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/backends/generic/test_exceptions.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/backends/generic/test_filters.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/backends/generic/test_interface.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/backends/generic/test_session.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/backends/sqla/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/backends/sqla/conftest.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/backends/sqla/test_audit.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/backends/sqla/test_audit_types.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/backends/sqla/test_column.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/backends/sqla/test_db.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/backends/sqla/test_filters.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/backends/sqla/test_geoalchemy2.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/backends/sqla/test_interface.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/backends/sqla/test_model.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/backends/sqla/test_session.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/bases/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/bases/test_db.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/bases/test_file_manager.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/bases/test_filter.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/bases/test_interface.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/bases/test_model.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/bases/test_session.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/cli/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/cli/commands/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/cli/commands/conftest.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/cli/commands/test_db.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/cli/commands/test_export.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/cli/commands/test_security.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/cli/commands/test_security_crypto.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/cli/commands/test_translate.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/cli/conftest.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/cli/test_cli.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/cli/test_decorators.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/cli/test_types.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/cli/test_utils.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/file_managers/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/file_managers/conftest.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/file_managers/test_file_manager.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/file_managers/test_image_manager.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/file_managers/test_s3_file_manager.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/file_managers/test_s3_image_manager.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/lang/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/lang/test_babel_cli.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/lang/test_babel_config.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/lang/test_lazy_text.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/security/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/security/sqla/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/security/sqla/conftest.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/security/sqla/test_apis.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/security/sqla/test_models.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/security/sqla/test_security_manager.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/test_caches.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/test_config.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/test_const.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/test_db.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/test_decorators.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/test_dependencies.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/test_exceptions.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/test_fastapi_react_toolkit.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/test_filters.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/test_globals.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/test_manager.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/test_middlewares.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/test_mixins.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/test_models.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/test_registry.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/test_routers.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/test_schemas.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/test_setting.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/test_types.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/test_user_cache.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/test_version.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/utils/__init__.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/utils/test_async_task_runner.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/utils/test_class_factory.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/utils/test_csv_json_converter.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/utils/test_deep_merge.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/utils/test_extender_mixin.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/utils/test_flask_appbuilder_utils.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/utils/test_formatter.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/utils/test_hooks.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/utils/test_lazy.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/utils/test_merge_schema.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/utils/test_multiple_async_contexts.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/utils/test_pydantic.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/utils/test_run_utils.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/utils/test_self_dependencies.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/utils/test_smartdefaultdict.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/utils/test_sqla.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/utils/test_timezone.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/utils/test_update_signature.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/tests/unit/utils/test_use_default_when_none.py +0 -0
- {fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: fastapi-rtk
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.13.0
|
|
4
4
|
Summary: A package that provides a set of tools to build a FastAPI application with a Class-Based CRUD API.
|
|
5
5
|
Project-URL: Homepage, https://codeberg.org/datatactics/fastapi-rtk
|
|
6
6
|
Project-URL: Issues, https://codeberg.org/datatactics/fastapi-rtk/issues
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.13.0"
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import collections.abc
|
|
2
|
+
import copy
|
|
2
3
|
import inspect
|
|
3
4
|
import typing
|
|
4
5
|
|
|
@@ -6,7 +7,11 @@ import pydantic
|
|
|
6
7
|
|
|
7
8
|
from ...mixins import LoggerMixin
|
|
8
9
|
from ...utils import T
|
|
9
|
-
from .exceptions import
|
|
10
|
+
from .exceptions import (
|
|
11
|
+
ColumnInvalidTypeException,
|
|
12
|
+
ColumnNotSetException,
|
|
13
|
+
GenericColumnException,
|
|
14
|
+
)
|
|
10
15
|
|
|
11
16
|
if typing.TYPE_CHECKING:
|
|
12
17
|
from .model import GenericModel
|
|
@@ -45,7 +50,7 @@ class GenericColumn(typing.Generic[T], LoggerMixin):
|
|
|
45
50
|
auto_increment (bool, optional): Whether the column is auto incremented. Only works if the column is a primary key. Defaults to False.
|
|
46
51
|
unique (bool, optional): Whether the column is unique. Defaults to False.
|
|
47
52
|
nullable (bool, optional): Whether the column is nullable. Defaults to True.
|
|
48
|
-
default (T | collections.abc.Callable[[], T] | collections.abc.Callable[[GenericModel], T] | NoDefault, optional): The default value of the column. Will be used if the column is not set by the user. Defaults to NoDefault (no default value).
|
|
53
|
+
default (T | collections.abc.Callable[[], T] | collections.abc.Callable[[GenericModel], T] | NoDefault, optional): The default value of the column. Will be used if the column is not set by the user. It is resolved once, when the model is initialized: a callable taking no argument is called, and a mutable value is copied. Defaults to NoDefault (no default value).
|
|
49
54
|
"""
|
|
50
55
|
|
|
51
56
|
col_type: type[T]
|
|
@@ -78,7 +83,7 @@ class GenericColumn(typing.Generic[T], LoggerMixin):
|
|
|
78
83
|
auto_increment (bool, optional): Whether the column is auto incremented. Only works if the column is a primary key. Defaults to False.
|
|
79
84
|
unique (bool, optional): Whether the column is unique. Defaults to False.
|
|
80
85
|
nullable (bool, optional): Whether the column is nullable. Defaults to True.
|
|
81
|
-
default (T | collections.abc.Callable[[], T] | collections.abc.Callable[["GenericModel"], T] | _NoDefaultValue, optional): The default value of the column. Will be used if the column is not set by the user. Defaults to UNSET (no default value).
|
|
86
|
+
default (T | collections.abc.Callable[[], T] | collections.abc.Callable[["GenericModel"], T] | _NoDefaultValue, optional): The default value of the column. Will be used if the column is not set by the user. It is resolved once, when the model is initialized: a callable taking no argument is called, and a mutable value is copied. Defaults to UNSET (no default value).
|
|
82
87
|
|
|
83
88
|
Raises:
|
|
84
89
|
GenericColumnException: If auto increment is set on a non-primary key column or if the column type is not int when auto increment is set.
|
|
@@ -95,10 +100,8 @@ class GenericColumn(typing.Generic[T], LoggerMixin):
|
|
|
95
100
|
self.unique = True
|
|
96
101
|
self.nullable = False
|
|
97
102
|
|
|
98
|
-
if
|
|
99
|
-
|
|
100
|
-
if inspect.signature(self.default).parameters == {}:
|
|
101
|
-
self.default = lambda instance, func=self.default: func()
|
|
103
|
+
if self.default is not UNSET:
|
|
104
|
+
self.default = self._normalize_default(self.default)
|
|
102
105
|
|
|
103
106
|
if not self.primary_key and self.auto_increment:
|
|
104
107
|
raise GenericColumnException(
|
|
@@ -125,22 +128,30 @@ class GenericColumn(typing.Generic[T], LoggerMixin):
|
|
|
125
128
|
instance: "GenericModel | None",
|
|
126
129
|
owner: type["GenericModel"],
|
|
127
130
|
):
|
|
131
|
+
"""
|
|
132
|
+
Read the column value of the instance, or the descriptor itself when read on the class.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
instance (GenericModel | None): The instance to read from, or None when read on the class.
|
|
136
|
+
owner (type[GenericModel]): The model class owning the column.
|
|
137
|
+
|
|
138
|
+
Raises:
|
|
139
|
+
ColumnNotSetException: If a column that is neither nullable nor an auto incrementing primary key was never set.
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
GenericColumn | T | None: The descriptor on class access, else the value, None for an unset nullable column, or PK_AUTO_INCREMENT for an unset auto incrementing primary key.
|
|
143
|
+
"""
|
|
128
144
|
if not instance:
|
|
129
145
|
return self
|
|
130
146
|
|
|
131
|
-
|
|
132
|
-
if callable(default_value):
|
|
133
|
-
default_value = default_value(instance)
|
|
134
|
-
|
|
135
|
-
value: T | GenericUnset = instance.__dict__.get(
|
|
136
|
-
f"_{self._col_name}", default_value
|
|
137
|
-
)
|
|
147
|
+
value: T | GenericUnset = instance.__dict__.get(f"_{self._col_name}", UNSET)
|
|
138
148
|
|
|
139
|
-
if value is
|
|
140
|
-
if self.nullable
|
|
149
|
+
if value is UNSET:
|
|
150
|
+
if self.nullable:
|
|
141
151
|
return None
|
|
142
|
-
|
|
152
|
+
if self.primary_key and self.auto_increment:
|
|
143
153
|
return PK_AUTO_INCREMENT
|
|
154
|
+
raise ColumnNotSetException(instance, f"Column {self._col_name} is not set")
|
|
144
155
|
|
|
145
156
|
return value
|
|
146
157
|
|
|
@@ -161,7 +172,8 @@ class GenericColumn(typing.Generic[T], LoggerMixin):
|
|
|
161
172
|
if self.nullable:
|
|
162
173
|
validation_type = validation_type | None
|
|
163
174
|
if self.default is not UNSET:
|
|
164
|
-
|
|
175
|
+
if not callable(self.default):
|
|
176
|
+
validation_type = validation_type | type(self.default)
|
|
165
177
|
validation_field = pydantic.Field(default=self.default)
|
|
166
178
|
else:
|
|
167
179
|
validation_field = pydantic.Field
|
|
@@ -194,3 +206,60 @@ class GenericColumn(typing.Generic[T], LoggerMixin):
|
|
|
194
206
|
f"_{self._col_name}" in instance.__dict__
|
|
195
207
|
and getattr(instance, f"_{self._col_name}") is not UNSET
|
|
196
208
|
)
|
|
209
|
+
|
|
210
|
+
def apply_default(self, instance: "GenericModel") -> None:
|
|
211
|
+
"""
|
|
212
|
+
Write the column default into the instance, leaving an already set column untouched.
|
|
213
|
+
|
|
214
|
+
A default resolving to a sentinel is skipped, so a default reading a not yet assigned primary key leaves the column unset.
|
|
215
|
+
|
|
216
|
+
Args:
|
|
217
|
+
instance (GenericModel): The instance to write the default into.
|
|
218
|
+
"""
|
|
219
|
+
if self.default is UNSET or self.is_column_set(instance):
|
|
220
|
+
return
|
|
221
|
+
|
|
222
|
+
value = self.default(instance) if callable(self.default) else self.default
|
|
223
|
+
if isinstance(value, (GenericUnset, GenericPKAutoIncrement)):
|
|
224
|
+
return
|
|
225
|
+
|
|
226
|
+
instance.__dict__[f"_{self._col_name}"] = value
|
|
227
|
+
|
|
228
|
+
def _normalize_default(
|
|
229
|
+
self,
|
|
230
|
+
default: T | collections.abc.Callable[..., T],
|
|
231
|
+
) -> T | collections.abc.Callable[["GenericModel"], T]:
|
|
232
|
+
"""
|
|
233
|
+
Normalize a column default into either a plain value or a callable taking the model instance.
|
|
234
|
+
|
|
235
|
+
A mutable value becomes a copying callable, so one instance cannot mutate the default of every other instance.
|
|
236
|
+
|
|
237
|
+
Args:
|
|
238
|
+
default (T | collections.abc.Callable[..., T]): The default given to the column.
|
|
239
|
+
|
|
240
|
+
Returns:
|
|
241
|
+
T | collections.abc.Callable[[GenericModel], T]: The value itself, or a callable taking the instance.
|
|
242
|
+
"""
|
|
243
|
+
if not callable(default):
|
|
244
|
+
if isinstance(default, collections.abc.Hashable):
|
|
245
|
+
return default
|
|
246
|
+
return lambda instance, value=default: copy.deepcopy(value)
|
|
247
|
+
|
|
248
|
+
try:
|
|
249
|
+
parameters = inspect.signature(default).parameters.values()
|
|
250
|
+
except (TypeError, ValueError):
|
|
251
|
+
# A builtin without an introspectable signature (dict, str, ...) can only be a zero argument factory.
|
|
252
|
+
return lambda instance, func=default: func()
|
|
253
|
+
|
|
254
|
+
if any(
|
|
255
|
+
parameter.default is inspect.Parameter.empty
|
|
256
|
+
and parameter.kind
|
|
257
|
+
in (
|
|
258
|
+
inspect.Parameter.POSITIONAL_ONLY,
|
|
259
|
+
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
260
|
+
)
|
|
261
|
+
for parameter in parameters
|
|
262
|
+
):
|
|
263
|
+
return default
|
|
264
|
+
|
|
265
|
+
return lambda instance, func=default: func()
|
|
@@ -117,15 +117,20 @@ class GenericModel(BasicModel):
|
|
|
117
117
|
"""
|
|
118
118
|
Initialize the model with the given keyword arguments.
|
|
119
119
|
|
|
120
|
+
A column without a given value takes its default, like a dataclass mapped SQLAlchemy model does.
|
|
121
|
+
|
|
120
122
|
Args:
|
|
121
123
|
__check_on_init__ (bool, optional): Whether to check the model's validity on initialization. Defaults to True.
|
|
122
124
|
"""
|
|
123
|
-
if not kwargs:
|
|
124
|
-
return
|
|
125
125
|
for key, value in kwargs.items():
|
|
126
126
|
if key not in self.__mapper__.properties.keys():
|
|
127
127
|
continue
|
|
128
128
|
setattr(self, key, value)
|
|
129
|
+
|
|
130
|
+
# After the given values, so a default reading another column sees it.
|
|
131
|
+
for column in self.__mapper__.properties.values():
|
|
132
|
+
column.apply_default(self)
|
|
133
|
+
|
|
129
134
|
if __check_on_init__:
|
|
130
135
|
self.is_model_valid()
|
|
131
136
|
|
|
@@ -166,8 +171,10 @@ class GenericModel(BasicModel):
|
|
|
166
171
|
"""
|
|
167
172
|
errors: list[Exception] = []
|
|
168
173
|
for key in self.__mapper__.properties.keys():
|
|
169
|
-
|
|
170
|
-
|
|
174
|
+
try:
|
|
175
|
+
getattr(self, key)
|
|
176
|
+
except ColumnNotSetException as e:
|
|
177
|
+
errors.append(e)
|
|
171
178
|
|
|
172
179
|
if errors:
|
|
173
180
|
# Rollback to last valid state
|
|
@@ -186,4 +193,10 @@ class GenericModel(BasicModel):
|
|
|
186
193
|
return [cls.__mapper__.pk]
|
|
187
194
|
|
|
188
195
|
def __repr__(self):
|
|
189
|
-
|
|
196
|
+
values = []
|
|
197
|
+
for col in self.__mapper__.properties.keys():
|
|
198
|
+
try:
|
|
199
|
+
values.append(f"{col}={getattr(self, col)}")
|
|
200
|
+
except ColumnNotSetException:
|
|
201
|
+
values.append(f"{col}={UNSET}")
|
|
202
|
+
return f"{self.__class__.__name__}({';'.join(values)})"
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
|
|
1
3
|
import pytest
|
|
4
|
+
|
|
2
5
|
from fastapi_rtk.backends.generic.column import (
|
|
3
6
|
PK_AUTO_INCREMENT,
|
|
4
7
|
UNSET,
|
|
@@ -8,6 +11,7 @@ from fastapi_rtk.backends.generic.column import (
|
|
|
8
11
|
)
|
|
9
12
|
from fastapi_rtk.backends.generic.exceptions import (
|
|
10
13
|
ColumnInvalidTypeException,
|
|
14
|
+
ColumnNotSetException,
|
|
11
15
|
GenericColumnException,
|
|
12
16
|
)
|
|
13
17
|
from fastapi_rtk.backends.generic.model import GenericModel
|
|
@@ -54,6 +58,28 @@ class TestColumnInit:
|
|
|
54
58
|
col = GenericColumn(int, default=with_instance)
|
|
55
59
|
assert col.default is with_instance
|
|
56
60
|
|
|
61
|
+
def test_default_hashable_value_kept_as_is(self):
|
|
62
|
+
col = GenericColumn(int, default=99)
|
|
63
|
+
assert col.default == 99
|
|
64
|
+
|
|
65
|
+
def test_default_builtin_with_optional_arg_wrapped(self):
|
|
66
|
+
col = GenericColumn(list, default=list)
|
|
67
|
+
assert col.default(None) == []
|
|
68
|
+
|
|
69
|
+
def test_default_builtin_without_signature_wrapped(self):
|
|
70
|
+
col = GenericColumn(dict, default=dict)
|
|
71
|
+
assert col.default(None) == {}
|
|
72
|
+
|
|
73
|
+
def test_default_builtin_method_wrapped(self):
|
|
74
|
+
col = GenericColumn(datetime.datetime, default=datetime.datetime.now)
|
|
75
|
+
assert isinstance(col.default(None), datetime.datetime)
|
|
76
|
+
|
|
77
|
+
def test_default_mutable_value_wrapped(self):
|
|
78
|
+
col = GenericColumn(list, default=[])
|
|
79
|
+
first = col.default(None)
|
|
80
|
+
assert first == []
|
|
81
|
+
assert first is not col.default(None)
|
|
82
|
+
|
|
57
83
|
|
|
58
84
|
class TestColumnDescriptorAccess:
|
|
59
85
|
def _make_model(self, **column_kwargs):
|
|
@@ -94,6 +120,12 @@ class TestColumnDescriptorAccess:
|
|
|
94
120
|
m.x = 7
|
|
95
121
|
assert m.x == 7
|
|
96
122
|
|
|
123
|
+
def test_get_unset_not_nullable_raises(self):
|
|
124
|
+
M = self._make_model(nullable=False)
|
|
125
|
+
m = M(__check_on_init__=False)
|
|
126
|
+
with pytest.raises(ColumnNotSetException, match="is not set"):
|
|
127
|
+
m.x
|
|
128
|
+
|
|
97
129
|
def test_pk_auto_increment_returns_sentinel_when_not_set(self):
|
|
98
130
|
M = self._make_model()
|
|
99
131
|
m = M(__check_on_init__=False)
|
|
@@ -101,6 +133,40 @@ class TestColumnDescriptorAccess:
|
|
|
101
133
|
assert m.id is PK_AUTO_INCREMENT
|
|
102
134
|
|
|
103
135
|
|
|
136
|
+
class TestMutableDefault:
|
|
137
|
+
def _make_model(self, **column_kwargs):
|
|
138
|
+
class M(GenericModel):
|
|
139
|
+
id = GenericColumn(int, primary_key=True, auto_increment=True)
|
|
140
|
+
x = GenericColumn(list, **column_kwargs)
|
|
141
|
+
|
|
142
|
+
return M
|
|
143
|
+
|
|
144
|
+
def test_mutation_does_not_leak_between_instances(self):
|
|
145
|
+
M = self._make_model(default=[])
|
|
146
|
+
first = M(__check_on_init__=False)
|
|
147
|
+
second = M(__check_on_init__=False)
|
|
148
|
+
first.x.append("leak")
|
|
149
|
+
assert second.x == []
|
|
150
|
+
|
|
151
|
+
def test_nested_mutation_does_not_leak_between_instances(self):
|
|
152
|
+
M = self._make_model(default=[[]])
|
|
153
|
+
first = M(__check_on_init__=False)
|
|
154
|
+
second = M(__check_on_init__=False)
|
|
155
|
+
first.x[0].append("leak")
|
|
156
|
+
assert second.x == [[]]
|
|
157
|
+
|
|
158
|
+
def test_builtin_factory_default_is_read(self):
|
|
159
|
+
M = self._make_model(default=list)
|
|
160
|
+
m = M(__check_on_init__=False)
|
|
161
|
+
assert m.x == []
|
|
162
|
+
|
|
163
|
+
def test_callable_default_rejected_as_value(self):
|
|
164
|
+
M = self._make_model(default=[])
|
|
165
|
+
m = M(__check_on_init__=False)
|
|
166
|
+
with pytest.raises(ColumnInvalidTypeException):
|
|
167
|
+
m.x = list
|
|
168
|
+
|
|
169
|
+
|
|
104
170
|
class TestIsColumnSet:
|
|
105
171
|
def test_unset_returns_false(self):
|
|
106
172
|
class M(GenericModel):
|
|
@@ -120,6 +186,34 @@ class TestIsColumnSet:
|
|
|
120
186
|
assert M.x.is_column_set(m) is True
|
|
121
187
|
|
|
122
188
|
|
|
189
|
+
class TestApplyDefault:
|
|
190
|
+
def _make_model(self, **column_kwargs):
|
|
191
|
+
class M(GenericModel):
|
|
192
|
+
id = GenericColumn(int, primary_key=True, auto_increment=True)
|
|
193
|
+
x = GenericColumn(int, **column_kwargs)
|
|
194
|
+
|
|
195
|
+
return M
|
|
196
|
+
|
|
197
|
+
def test_no_default_writes_nothing(self):
|
|
198
|
+
M = self._make_model()
|
|
199
|
+
m = M(__check_on_init__=False)
|
|
200
|
+
M.x.apply_default(m)
|
|
201
|
+
assert M.x.is_column_set(m) is False
|
|
202
|
+
|
|
203
|
+
def test_set_column_is_not_overwritten(self):
|
|
204
|
+
M = self._make_model(default=99)
|
|
205
|
+
m = M(__check_on_init__=False)
|
|
206
|
+
m.x = 1
|
|
207
|
+
M.x.apply_default(m)
|
|
208
|
+
assert m.x == 1
|
|
209
|
+
|
|
210
|
+
def test_sentinel_result_is_not_written(self):
|
|
211
|
+
M = self._make_model(default=lambda instance: instance.id)
|
|
212
|
+
m = M(__check_on_init__=False)
|
|
213
|
+
M.x.apply_default(m)
|
|
214
|
+
assert M.x.is_column_set(m) is False
|
|
215
|
+
|
|
216
|
+
|
|
123
217
|
class TestRepr:
|
|
124
218
|
def test_repr_includes_attrs(self):
|
|
125
219
|
col = GenericColumn(int, primary_key=True)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
|
|
1
3
|
import pytest
|
|
2
4
|
from fastapi_rtk.backends.generic.column import GenericColumn
|
|
3
5
|
from fastapi_rtk.backends.generic.exceptions import (
|
|
@@ -73,10 +75,83 @@ class TestModelInit:
|
|
|
73
75
|
|
|
74
76
|
return M
|
|
75
77
|
|
|
76
|
-
def
|
|
77
|
-
M
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
def test_empty_kwargs_still_validates(self):
|
|
79
|
+
class M(GenericModel):
|
|
80
|
+
id = GenericColumn(int, primary_key=True)
|
|
81
|
+
required = GenericColumn(str, nullable=False)
|
|
82
|
+
|
|
83
|
+
with pytest.raises(MultipleColumnsException):
|
|
84
|
+
M()
|
|
85
|
+
|
|
86
|
+
def test_default_applied_on_init(self):
|
|
87
|
+
class M(GenericModel):
|
|
88
|
+
id = GenericColumn(int, primary_key=True, auto_increment=True)
|
|
89
|
+
name = GenericColumn(str, nullable=False, default="anon")
|
|
90
|
+
|
|
91
|
+
m = M()
|
|
92
|
+
assert m.name == "anon"
|
|
93
|
+
assert M.name.is_column_set(m) is True
|
|
94
|
+
|
|
95
|
+
def test_default_not_applied_when_value_given(self):
|
|
96
|
+
class M(GenericModel):
|
|
97
|
+
id = GenericColumn(int, primary_key=True, auto_increment=True)
|
|
98
|
+
name = GenericColumn(str, nullable=False, default="anon")
|
|
99
|
+
|
|
100
|
+
assert M(name="given").name == "given"
|
|
101
|
+
|
|
102
|
+
def test_callable_default_frozen_on_init(self):
|
|
103
|
+
class M(GenericModel):
|
|
104
|
+
id = GenericColumn(int, primary_key=True, auto_increment=True)
|
|
105
|
+
created = GenericColumn(datetime.datetime, default=datetime.datetime.now)
|
|
106
|
+
|
|
107
|
+
m = M()
|
|
108
|
+
assert m.created == m.created
|
|
109
|
+
|
|
110
|
+
def test_mutable_default_persists_mutation_per_instance(self):
|
|
111
|
+
class M(GenericModel):
|
|
112
|
+
id = GenericColumn(int, primary_key=True, auto_increment=True)
|
|
113
|
+
tags = GenericColumn(list, default=[])
|
|
114
|
+
|
|
115
|
+
m = M()
|
|
116
|
+
m.tags.append("x")
|
|
117
|
+
assert m.tags == ["x"]
|
|
118
|
+
assert M().tags == []
|
|
119
|
+
|
|
120
|
+
def test_default_reads_column_given_in_kwargs(self):
|
|
121
|
+
class M(GenericModel):
|
|
122
|
+
id = GenericColumn(int, primary_key=True, auto_increment=True)
|
|
123
|
+
first = GenericColumn(str, nullable=False)
|
|
124
|
+
slug = GenericColumn(str, default=lambda instance: instance.first.lower())
|
|
125
|
+
|
|
126
|
+
assert M(first="Ada").slug == "ada"
|
|
127
|
+
|
|
128
|
+
def test_default_reads_column_defaulted_earlier_in_class_body(self):
|
|
129
|
+
class M(GenericModel):
|
|
130
|
+
id = GenericColumn(int, primary_key=True, auto_increment=True)
|
|
131
|
+
first = GenericColumn(str, nullable=False, default="Ada")
|
|
132
|
+
slug = GenericColumn(str, default=lambda instance: instance.first.lower())
|
|
133
|
+
|
|
134
|
+
assert M().slug == "ada"
|
|
135
|
+
|
|
136
|
+
def test_default_reading_unassigned_pk_leaves_column_unset(self):
|
|
137
|
+
class M(GenericModel):
|
|
138
|
+
id = GenericColumn(int, primary_key=True, auto_increment=True)
|
|
139
|
+
from_pk = GenericColumn(int, default=lambda instance: instance.id)
|
|
140
|
+
|
|
141
|
+
m = M()
|
|
142
|
+
assert M.from_pk.is_column_set(m) is False
|
|
143
|
+
assert m.from_pk is None
|
|
144
|
+
m.id = 5
|
|
145
|
+
assert m.from_pk is None
|
|
146
|
+
|
|
147
|
+
def test_default_is_not_reapplied_after_init(self):
|
|
148
|
+
class M(GenericModel):
|
|
149
|
+
id = GenericColumn(int, primary_key=True, auto_increment=True)
|
|
150
|
+
name = GenericColumn(str, default="anon")
|
|
151
|
+
|
|
152
|
+
m = M()
|
|
153
|
+
del m.__dict__["_name"]
|
|
154
|
+
assert m.name is None
|
|
80
155
|
|
|
81
156
|
def test_kwargs_unknown_keys_skipped(self):
|
|
82
157
|
M = self._model()
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "2.12.4"
|
|
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_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/sqla/extensions/audit/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/sqla/extensions/audit/_logger.py
RENAMED
|
File without changes
|
|
File without changes
|
{fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/sqla/extensions/audit/audit.py
RENAMED
|
File without changes
|
{fastapi_rtk-2.12.4 → fastapi_rtk-2.13.0}/fastapi_rtk/backends/sqla/extensions/audit/types.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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|