fastapi-rtk 2.1.4__tar.gz → 2.2.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.1.4 → fastapi_rtk-2.2.0}/.gitignore +3 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/PKG-INFO +1 -1
- fastapi_rtk-2.2.0/fastapi_rtk/_version.py +1 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/api/base_api.py +5 -10
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/api/model_rest_api/__init__.py +10 -10
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/api/model_rest_api/_add_mixin.py +1 -2
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/api/model_rest_api/_bulk_mixin.py +1 -2
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/api/model_rest_api/_columns.py +2 -2
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/api/model_rest_api/_delete_mixin.py +0 -1
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/api/model_rest_api/_download_mixin.py +2 -3
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/api/model_rest_api/_edit_mixin.py +4 -5
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/api/model_rest_api/_file_mixin.py +6 -6
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/api/model_rest_api/_info_mixin.py +2 -2
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/api/model_rest_api/_list_mixin.py +1 -1
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/api/model_rest_api/_show_mixin.py +1 -1
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/api/model_rest_api/_upload_mixin.py +3 -3
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/apis/license.py +1 -1
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/auth/auth.py +21 -58
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/auth/ldap.py +6 -25
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/auth/password_helpers/fab.py +1 -1
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/auth/strategies/db.py +3 -3
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/backends/generic/column.py +7 -5
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/backends/generic/filters.py +1 -1
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/backends/generic/interface.py +3 -3
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/backends/generic/model.py +2 -2
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/backends/generic/session.py +9 -13
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/backends/sqla/db.py +24 -24
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/backends/sqla/extensions/audit/_decorators_mixin.py +5 -5
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/backends/sqla/extensions/audit/_lifecycle_mixin.py +2 -2
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/backends/sqla/extensions/audit/_processing_mixin.py +1 -1
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/backends/sqla/extensions/audit/audit.py +6 -6
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/backends/sqla/extensions/audit/types.py +1 -1
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/backends/sqla/interface.py +1 -4
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/backends/sqla/model.py +9 -13
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/bases/db.py +2 -2
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/bases/file_manager.py +2 -3
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/bases/filter.py +1 -1
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/bases/interface.py +25 -12
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/bases/model.py +2 -2
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/cli/cli.py +0 -3
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/cli/commands/__init__.py +0 -1
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/cli/commands/export.py +0 -15
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/cli/commands/security.py +1 -1
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/cli/commands/translate.py +3 -6
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/cli/types.py +0 -28
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/cli/utils.py +5 -5
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/config.py +1 -1
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/db.py +8 -12
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/decorators.py +4 -4
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/fastapi_react_toolkit.py +9 -9
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/file_managers/file_manager.py +2 -2
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/file_managers/image_manager.py +1 -1
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/file_managers/s3_file_manager.py +3 -3
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/file_managers/s3_image_manager.py +1 -2
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/globals.py +4 -16
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/lang/babel/cli.py +2 -6
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/lang/lazy_text.py +5 -5
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/manager.py +1 -2
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/middlewares.py +13 -19
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/mixins.py +1 -3
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/registry.py +3 -3
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/schemas.py +1 -1
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/security/sqla/security_manager/__init__.py +2 -2
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/security/sqla/security_manager/_association_mixin.py +8 -8
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/security/sqla/security_manager/_builtin_role_mixin.py +5 -5
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/security/sqla/security_manager/_cleanup_mixin.py +2 -2
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/security/sqla/security_manager/_role_mixin.py +4 -4
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/security/sqla/security_manager/_user_mixin.py +5 -5
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/setting.py +2 -2
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/types.py +4 -4
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/utils/async_task_runner.py +21 -29
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/utils/csv_json_converter.py +2 -8
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/utils/deep_merge.py +1 -1
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/utils/extender_mixin.py +3 -3
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/utils/lazy.py +13 -14
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/utils/run_utils.py +32 -18
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/utils/self_dependencies.py +8 -10
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/utils/timezone.py +1 -1
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/utils/update_signature.py +2 -4
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/backends/sqla/test_db.py +73 -7
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/bases/test_interface.py +105 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/test_fastapi_react_toolkit.py +23 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/test_globals.py +0 -18
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/utils/test_async_task_runner.py +1 -1
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/utils/test_run_utils.py +51 -0
- fastapi_rtk-2.1.4/fastapi_rtk/_version.py +0 -1
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/LICENSE +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/README.md +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/api/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/api/model_rest_api/_params.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/apis/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/apis/info.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/auth/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/auth/hashers/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/auth/hashers/pbkdf2.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/auth/hashers/scrypt.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/auth/password_helpers/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/auth/strategies/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/auth/strategies/config.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/auth/strategies/jwt.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/backends/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/backends/generic/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/backends/generic/db.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/backends/generic/exceptions.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/backends/sqla/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/backends/sqla/column.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/backends/sqla/exceptions.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/backends/sqla/extensions/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/backends/sqla/extensions/audit/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/backends/sqla/extensions/audit/_logger.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/backends/sqla/extensions/geoalchemy2/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/backends/sqla/extensions/geoalchemy2/filters.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/backends/sqla/extensions/geoalchemy2/geometry_converter.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/backends/sqla/filters.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/backends/sqla/session.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/bases/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/bases/session.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/cli/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/cli/commands/_security_crypto.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/cli/commands/db/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/cli/commands/db/templates/fastapi/README +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/cli/commands/db/templates/fastapi/alembic.ini.mako +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/cli/commands/db/templates/fastapi/env.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/cli/commands/db/templates/fastapi/script.py.mako +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/README +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/alembic.ini.mako +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/env.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/script.py.mako +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/cli/const.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/cli/decorators.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/const.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/dependencies.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/exceptions.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/file_managers/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/filters.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/lang/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/lang/babel/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/lang/babel/config.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/lang/babel.cfg +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/lang/messages.pot +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/lang/translations/de/LC_MESSAGES/messages.mo +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/lang/translations/de/LC_MESSAGES/messages.po +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/lang/translations/en/LC_MESSAGES/messages.mo +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/lang/translations/en/LC_MESSAGES/messages.po +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/models.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/py.typed +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/routers.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/security/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/security/sqla/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/security/sqla/apis.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/security/sqla/models.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/security/sqla/security_manager/_exception_filters.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/security/sqla/security_manager/_export.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/security/sqla/security_manager/_import.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/utils/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/utils/class_factory.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/utils/flask_appbuilder_utils.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/utils/formatter.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/utils/hooks.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/utils/merge_schema.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/utils/multiple_async_contexts.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/utils/pydantic.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/utils/smartdefaultdict.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/utils/sqla.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/utils/use_default_when_none.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/fastapi_rtk/version.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/pyproject.toml +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/conftest.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/docker-compose.gis.yml +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/integration/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/integration/api/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/integration/api/test_model_rest_api.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/integration/apis/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/integration/apis/test_info_contract.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/integration/auth/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/integration/auth/test_auth_flow.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/integration/auth/test_oauth.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/integration/conftest.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/integration/file_managers/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/integration/file_managers/test_file_routes.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/integration/security/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/integration/security/sqla/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/integration/security/sqla/test_security_manager.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/integration/test_app_smoke.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/api/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/api/conftest.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/api/model_rest_api/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/api/model_rest_api/test_columns.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/api/model_rest_api/test_file_mixin.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/api/model_rest_api/test_init.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/api/test_base_api.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/apis/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/apis/test_info.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/apis/test_license.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/auth/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/auth/hashers/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/auth/hashers/test_pbkdf2.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/auth/hashers/test_scrypt.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/auth/password_helpers/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/auth/password_helpers/test_fab.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/auth/strategies/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/auth/strategies/test_config.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/auth/strategies/test_db.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/auth/strategies/test_jwt.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/auth/test_auth.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/backends/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/backends/generic/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/backends/generic/test_column.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/backends/generic/test_db.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/backends/generic/test_exceptions.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/backends/generic/test_filters.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/backends/generic/test_interface.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/backends/generic/test_model.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/backends/generic/test_session.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/backends/sqla/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/backends/sqla/conftest.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/backends/sqla/test_audit.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/backends/sqla/test_audit_types.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/backends/sqla/test_column.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/backends/sqla/test_filters.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/backends/sqla/test_geoalchemy2.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/backends/sqla/test_interface.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/backends/sqla/test_model.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/backends/sqla/test_session.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/bases/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/bases/test_db.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/bases/test_file_manager.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/bases/test_filter.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/bases/test_model.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/bases/test_session.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/cli/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/cli/commands/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/cli/commands/conftest.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/cli/commands/test_db.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/cli/commands/test_export.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/cli/commands/test_security.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/cli/commands/test_security_crypto.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/cli/commands/test_translate.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/cli/conftest.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/cli/test_cli.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/cli/test_decorators.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/cli/test_types.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/cli/test_utils.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/file_managers/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/file_managers/conftest.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/file_managers/test_file_manager.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/file_managers/test_image_manager.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/file_managers/test_s3_file_manager.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/file_managers/test_s3_image_manager.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/lang/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/lang/test_babel_cli.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/lang/test_babel_config.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/lang/test_lazy_text.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/security/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/security/sqla/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/security/sqla/conftest.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/security/sqla/test_apis.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/security/sqla/test_models.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/security/sqla/test_security_manager.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/test_config.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/test_const.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/test_db.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/test_decorators.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/test_dependencies.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/test_exceptions.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/test_filters.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/test_manager.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/test_middlewares.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/test_mixins.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/test_models.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/test_registry.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/test_routers.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/test_schemas.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/test_setting.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/test_types.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/test_version.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/utils/__init__.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/utils/test_class_factory.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/utils/test_csv_json_converter.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/utils/test_deep_merge.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/utils/test_extender_mixin.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/utils/test_flask_appbuilder_utils.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/utils/test_formatter.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/utils/test_hooks.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/utils/test_lazy.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/utils/test_merge_schema.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/utils/test_multiple_async_contexts.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/utils/test_pydantic.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/utils/test_self_dependencies.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/utils/test_smartdefaultdict.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/utils/test_sqla.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/utils/test_timezone.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/utils/test_update_signature.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/tests/unit/utils/test_use_default_when_none.py +0 -0
- {fastapi_rtk-2.1.4 → fastapi_rtk-2.2.0}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastapi-rtk
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.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.2.0"
|
|
@@ -21,11 +21,10 @@ class BaseApi:
|
|
|
21
21
|
"""
|
|
22
22
|
Base API class for FastAPI.
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
secure and extensible APIs.
|
|
24
|
+
Exposes API routes with integrated permission and authentication support,
|
|
25
|
+
handling route registration, permission management, and toolkit integration.
|
|
27
26
|
|
|
28
|
-
See [FastAPI path]("https://fastapi.tiangolo.com/tutorial/path-params/") and [FastAPI query]("https://fastapi.tiangolo.com/tutorial/query-params/") for
|
|
27
|
+
See [FastAPI path]("https://fastapi.tiangolo.com/tutorial/path-params/") and [FastAPI query]("https://fastapi.tiangolo.com/tutorial/query-params/") for details on path and query parameters in your API endpoints.
|
|
29
28
|
|
|
30
29
|
Usage:
|
|
31
30
|
|
|
@@ -130,17 +129,13 @@ class BaseApi:
|
|
|
130
129
|
|
|
131
130
|
async def on_startup(self):
|
|
132
131
|
"""
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
This will be called by `FastAPIReactToolkit` when the application starts.
|
|
132
|
+
Called by `FastAPIReactToolkit` when the application starts.
|
|
136
133
|
"""
|
|
137
134
|
pass
|
|
138
135
|
|
|
139
136
|
async def on_shutdown(self):
|
|
140
137
|
"""
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
This will be called by `FastAPIReactToolkit` when the application shuts down.
|
|
138
|
+
Called by `FastAPIReactToolkit` when the application shuts down.
|
|
144
139
|
"""
|
|
145
140
|
pass
|
|
146
141
|
|
|
@@ -100,9 +100,9 @@ class ModelRestApi(
|
|
|
100
100
|
"""
|
|
101
101
|
Base API class for FastAPI with built-in RESTful endpoints for common data operations.
|
|
102
102
|
|
|
103
|
-
|
|
103
|
+
Delivers standard routes for CRUD (Create, Read, Update, Delete),
|
|
104
104
|
file and image management, data download, bulk operations, filtering, and pagination.
|
|
105
|
-
Each route is extensible with
|
|
105
|
+
Each route is extensible with pre- and post-processing methods for custom logic
|
|
106
106
|
before and after the main operation.
|
|
107
107
|
|
|
108
108
|
Usage:
|
|
@@ -170,11 +170,11 @@ class ModelRestApi(
|
|
|
170
170
|
]
|
|
171
171
|
)
|
|
172
172
|
"""
|
|
173
|
-
The list of routes to expose.
|
|
173
|
+
The list of routes to expose. Available routes: `info`, `download`, `bulk`, `get_list`, `get`, `post`, `put`, `delete`.
|
|
174
174
|
"""
|
|
175
175
|
exclude_routes: typing.List[AVAILABLE_ROUTES] = lazy(lambda: [])
|
|
176
176
|
"""
|
|
177
|
-
The list of routes to exclude.
|
|
177
|
+
The list of routes to exclude. Available routes: `info`, `download`, `bulk`, `get_list`, `get`, `post`, `put`, `delete`.
|
|
178
178
|
"""
|
|
179
179
|
protected_routes: typing.List[AVAILABLE_ROUTES] = lazy(
|
|
180
180
|
lambda self: [x for x in self.routes if x not in self.exclude_protected_routes]
|
|
@@ -475,7 +475,7 @@ class ModelRestApi(
|
|
|
475
475
|
cache=False,
|
|
476
476
|
)
|
|
477
477
|
"""
|
|
478
|
-
The title for the list endpoint. If not provided,
|
|
478
|
+
The title for the list endpoint. If not provided, defaults to "List {ModelName}".
|
|
479
479
|
"""
|
|
480
480
|
show_title = lazy(
|
|
481
481
|
lambda self: translate(
|
|
@@ -484,7 +484,7 @@ class ModelRestApi(
|
|
|
484
484
|
cache=False,
|
|
485
485
|
)
|
|
486
486
|
"""
|
|
487
|
-
The title for the show endpoint. If not provided,
|
|
487
|
+
The title for the show endpoint. If not provided, defaults to "Show {ModelName}".
|
|
488
488
|
"""
|
|
489
489
|
add_title = lazy(
|
|
490
490
|
lambda self: translate(
|
|
@@ -493,7 +493,7 @@ class ModelRestApi(
|
|
|
493
493
|
cache=False,
|
|
494
494
|
)
|
|
495
495
|
"""
|
|
496
|
-
The title for the add endpoint. If not provided,
|
|
496
|
+
The title for the add endpoint. If not provided, defaults to "Add {ModelName}".
|
|
497
497
|
"""
|
|
498
498
|
edit_title = lazy(
|
|
499
499
|
lambda self: translate(
|
|
@@ -502,7 +502,7 @@ class ModelRestApi(
|
|
|
502
502
|
cache=False,
|
|
503
503
|
)
|
|
504
504
|
"""
|
|
505
|
-
The title for the edit endpoint. If not provided,
|
|
505
|
+
The title for the edit endpoint. If not provided, defaults to "Edit {ModelName}".
|
|
506
506
|
"""
|
|
507
507
|
|
|
508
508
|
"""
|
|
@@ -617,7 +617,7 @@ class ModelRestApi(
|
|
|
617
617
|
|
|
618
618
|
extra_list_fetch_columns = lazy(lambda: list[str]())
|
|
619
619
|
"""
|
|
620
|
-
The list of columns to be
|
|
620
|
+
The list of columns to be fetched from the database alongside the `list_columns`. Useful if you don't want some columns to be shown but still want to fetch them.
|
|
621
621
|
"""
|
|
622
622
|
list_select_columns = lazy(
|
|
623
623
|
lambda self: self.list_columns + self.extra_list_fetch_columns
|
|
@@ -629,7 +629,7 @@ class ModelRestApi(
|
|
|
629
629
|
"""
|
|
630
630
|
extra_show_fetch_columns = lazy(lambda: list[str]())
|
|
631
631
|
"""
|
|
632
|
-
The list of columns to be
|
|
632
|
+
The list of columns to be fetched from the database alongside the `show_columns`. Useful if you don't want some columns to be shown but still want to fetch them.
|
|
633
633
|
"""
|
|
634
634
|
show_select_columns = lazy(
|
|
635
635
|
lambda self: self.show_columns + self.extra_show_fetch_columns
|
|
@@ -134,8 +134,7 @@ class AddMixin:
|
|
|
134
134
|
self, item: Model, params: PARAM_BODY_SESSION
|
|
135
135
|
) -> None | Model | typing.Any:
|
|
136
136
|
"""
|
|
137
|
-
Post-process the item after adding it to the database.
|
|
138
|
-
But before sending the response.
|
|
137
|
+
Post-process the item after adding it to the database, before sending the response.
|
|
139
138
|
|
|
140
139
|
- When a `Model` is returned, it will replace the current `item`.
|
|
141
140
|
- When any other value is returned, it is assumed to be a response to be returned directly.
|
|
@@ -127,7 +127,7 @@ class ColumnsMixin:
|
|
|
127
127
|
):
|
|
128
128
|
"""
|
|
129
129
|
Handle the schema extra fields for the API.
|
|
130
|
-
|
|
130
|
+
Transforms non-tuple fields into a dictionary mapping field name to field type.
|
|
131
131
|
|
|
132
132
|
Args:
|
|
133
133
|
schema_extra_fields (dict[str, type | tuple[type, pydantic.fields.FieldInfo]]): The schema extra fields to handle.
|
|
@@ -183,7 +183,7 @@ class ColumnsMixin:
|
|
|
183
183
|
name: str | None = None,
|
|
184
184
|
):
|
|
185
185
|
"""
|
|
186
|
-
Create a request schema
|
|
186
|
+
Create a request schema from `schema` for add and edit endpoints, transforming relation columns into the appropriate schema.
|
|
187
187
|
|
|
188
188
|
Args:
|
|
189
189
|
schema (typing.Type[BaseModel]): The base schema to create the request schema from.
|
|
@@ -73,7 +73,7 @@ class DownloadMixin:
|
|
|
73
73
|
Downloads a file in a headless mode.
|
|
74
74
|
|
|
75
75
|
Args:
|
|
76
|
-
|
|
76
|
+
q (QuerySchema): The query schema.
|
|
77
77
|
session (SQLASession): A database scoped session.
|
|
78
78
|
export_mode (ExportMode): The export mode. Can be "simplified" or "detailed". Defaults to "simplified".
|
|
79
79
|
delimiter (str): The delimiter for the CSV file. Defaults to ",".
|
|
@@ -193,11 +193,10 @@ class DownloadMixin:
|
|
|
193
193
|
quotechar: str = '"',
|
|
194
194
|
):
|
|
195
195
|
"""
|
|
196
|
-
Import data from CSV format
|
|
196
|
+
Import data from CSV format, parsing it and resolving any relationships.
|
|
197
197
|
|
|
198
198
|
Args:
|
|
199
199
|
data (str | bytes): The CSV data to import.
|
|
200
|
-
query (QueryManager): The query manager object.
|
|
201
200
|
session (SQLASession): The session object for the database connection.
|
|
202
201
|
delimiter (str, optional): Delimiter for the CSV file. Defaults to ",".
|
|
203
202
|
quotechar (str): Quote character for the CSV file. Defaults to '"'.
|
|
@@ -68,7 +68,7 @@ class EditMixin:
|
|
|
68
68
|
session: SQLASession = SelfDepends().datamodel.get_session_factory,
|
|
69
69
|
):
|
|
70
70
|
"""
|
|
71
|
-
Updates an item in
|
|
71
|
+
Updates an item in headless mode.
|
|
72
72
|
|
|
73
73
|
Args:
|
|
74
74
|
id (str): The id of the item.
|
|
@@ -76,7 +76,7 @@ class EditMixin:
|
|
|
76
76
|
session (SQLASession): A database scoped session.
|
|
77
77
|
|
|
78
78
|
Returns:
|
|
79
|
-
|
|
79
|
+
edit_return_schema: The edit return schema.
|
|
80
80
|
|
|
81
81
|
### Note:
|
|
82
82
|
If you are overriding this method, make sure to copy all the decorators too.
|
|
@@ -159,7 +159,7 @@ class EditMixin:
|
|
|
159
159
|
Args:
|
|
160
160
|
item (Model): The item that will be updated in the database.
|
|
161
161
|
data (dict[str, typing.Any]): The data to merge with the item.
|
|
162
|
-
params (
|
|
162
|
+
params (PARAM_BODY_SESSION): Additional data passed to the handler.
|
|
163
163
|
"""
|
|
164
164
|
pass
|
|
165
165
|
|
|
@@ -182,8 +182,7 @@ class EditMixin:
|
|
|
182
182
|
self, item: Model, params: PARAM_BODY_SESSION
|
|
183
183
|
) -> None | Model | typing.Any:
|
|
184
184
|
"""
|
|
185
|
-
Post-process the item after updating it in the database.
|
|
186
|
-
But before sending the response.
|
|
185
|
+
Post-process the item after updating it in the database, before sending the response.
|
|
187
186
|
|
|
188
187
|
- When a `Model` is returned, it will replace the current `item`.
|
|
189
188
|
- When any other value is returned, it is assumed to be a response to be returned directly.
|
|
@@ -27,9 +27,9 @@ class FileMixin:
|
|
|
27
27
|
|
|
28
28
|
def image(self):
|
|
29
29
|
"""
|
|
30
|
-
Image endpoint for the API.
|
|
30
|
+
Image endpoint for the API.
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
Only available if the model has image columns.
|
|
33
33
|
"""
|
|
34
34
|
if not self.datamodel.get_image_column_list():
|
|
35
35
|
return
|
|
@@ -50,9 +50,9 @@ class FileMixin:
|
|
|
50
50
|
|
|
51
51
|
def file(self):
|
|
52
52
|
"""
|
|
53
|
-
File endpoint for the API.
|
|
53
|
+
File endpoint for the API.
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
Only available if the model has file columns.
|
|
56
56
|
"""
|
|
57
57
|
if not self.datamodel.get_file_column_list():
|
|
58
58
|
return
|
|
@@ -73,7 +73,7 @@ class FileMixin:
|
|
|
73
73
|
|
|
74
74
|
async def image_headless(self, filename: str):
|
|
75
75
|
"""
|
|
76
|
-
Retrieves an image
|
|
76
|
+
Retrieves an image by filename.
|
|
77
77
|
"""
|
|
78
78
|
async with AsyncTaskRunner():
|
|
79
79
|
pre_image = await smart_run(self.pre_image, filename)
|
|
@@ -91,7 +91,7 @@ class FileMixin:
|
|
|
91
91
|
|
|
92
92
|
async def file_headless(self, filename: str):
|
|
93
93
|
"""
|
|
94
|
-
Retrieves a file
|
|
94
|
+
Retrieves a file by filename.
|
|
95
95
|
"""
|
|
96
96
|
async with AsyncTaskRunner():
|
|
97
97
|
pre_file = await smart_run(self.pre_file, filename)
|
|
@@ -100,7 +100,7 @@ class InfoMixin:
|
|
|
100
100
|
session_count: SQLASession = SelfDepends().datamodel.get_session_factory,
|
|
101
101
|
):
|
|
102
102
|
"""
|
|
103
|
-
Retrieves information in
|
|
103
|
+
Retrieves information in headless mode.
|
|
104
104
|
|
|
105
105
|
Args:
|
|
106
106
|
permissions (typing.List[str]): A list of permissions.
|
|
@@ -151,7 +151,7 @@ class InfoMixin:
|
|
|
151
151
|
session_count: SQLASession,
|
|
152
152
|
):
|
|
153
153
|
"""
|
|
154
|
-
Generates the information schema for the API
|
|
154
|
+
Generates the information schema for the API.
|
|
155
155
|
|
|
156
156
|
Args:
|
|
157
157
|
permissions (typing.List[str]): The list of permissions for the API.
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
Upload route mixin for ``ModelRestApi``.
|
|
3
3
|
|
|
4
4
|
The ``upload`` registration and ``upload_headless`` implementation are
|
|
5
|
-
disabled (commented out) until further notice. The mixin
|
|
6
|
-
``ModelRestApi`` so the route can be re-enabled by uncommenting the
|
|
7
|
-
|
|
5
|
+
disabled (commented out) until further notice. The mixin stays wired into
|
|
6
|
+
``ModelRestApi`` so the route can be re-enabled by uncommenting the blocks
|
|
7
|
+
below.
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
|
|
@@ -16,7 +16,7 @@ from ..utils import lazy, prettify_dict
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
class LicenseParserError(Exception):
|
|
19
|
-
"""
|
|
19
|
+
"""Raised on license parsing failures."""
|
|
20
20
|
|
|
21
21
|
def __init__(
|
|
22
22
|
self, data: typing.Any, message: str = "Error processing license data"
|
|
@@ -90,7 +90,6 @@ class Authenticator(BaseAuthenticator):
|
|
|
90
90
|
:param optional: If `True`, `None` is returned if there is no authenticated user
|
|
91
91
|
or if it doesn't pass the other requirements.
|
|
92
92
|
Otherwise, throw `401 Unauthorized`. Defaults to `False`.
|
|
93
|
-
Otherwise, an exception is raised. Defaults to `False`.
|
|
94
93
|
:param active: If `True`, throw `401 Unauthorized` if
|
|
95
94
|
the authenticated user is inactive. Defaults to `False`.
|
|
96
95
|
:param verified: If `True`, throw `401 Unauthorized` if
|
|
@@ -103,7 +102,7 @@ class Authenticator(BaseAuthenticator):
|
|
|
103
102
|
Useful if you want to dynamically enable some authentication backends
|
|
104
103
|
based on external logic, like a configuration in database.
|
|
105
104
|
By default, all specified authentication backends are enabled.
|
|
106
|
-
Please
|
|
105
|
+
Please note however that every backend will appear in the OpenAPI documentation,
|
|
107
106
|
as FastAPI resolves it statically.
|
|
108
107
|
"""
|
|
109
108
|
signature = self._get_dependency_signature(get_enabled_backends)
|
|
@@ -127,9 +126,7 @@ class Authenticator(BaseAuthenticator):
|
|
|
127
126
|
self, get_enabled_backends: Optional[EnabledBackendsDependency] = None
|
|
128
127
|
):
|
|
129
128
|
"""
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
Return a dependency callable to retrieve parameters of enabled authentication backends.
|
|
129
|
+
Return a dependency callable that retrieves the enabled authentication backends without performing authentication.
|
|
133
130
|
|
|
134
131
|
Args:
|
|
135
132
|
get_enabled_backends (Optional[EnabledBackendsDependency], optional): Optional dependency callable returning a list of enabled authentication backends.
|
|
@@ -162,7 +159,7 @@ class Authenticator(BaseAuthenticator):
|
|
|
162
159
|
strategy_params: tuple[tuple, dict[str, typing.Any]] | None = None,
|
|
163
160
|
):
|
|
164
161
|
"""
|
|
165
|
-
|
|
162
|
+
Perform authentication without using it as a dependency, such as in a custom route or in the startup event.
|
|
166
163
|
|
|
167
164
|
`strategy_params` is usually generated from the `get_enabled_backends` dependency.
|
|
168
165
|
|
|
@@ -280,9 +277,7 @@ class AuthConfigurator:
|
|
|
280
277
|
@property
|
|
281
278
|
def user_manager(self):
|
|
282
279
|
"""
|
|
283
|
-
Get the user manager.
|
|
284
|
-
|
|
285
|
-
if the user manager is not set, it will default to the UserManager class.
|
|
280
|
+
Get the user manager. Defaults to the `UserManager` class if not set.
|
|
286
281
|
|
|
287
282
|
Returns:
|
|
288
283
|
The user manager.
|
|
@@ -294,9 +289,7 @@ class AuthConfigurator:
|
|
|
294
289
|
@user_manager.setter
|
|
295
290
|
def user_manager(self, value: Type[UserManager]):
|
|
296
291
|
"""
|
|
297
|
-
Set
|
|
298
|
-
|
|
299
|
-
Use this to use a custom user manager.
|
|
292
|
+
Set a custom user manager.
|
|
300
293
|
|
|
301
294
|
Args:
|
|
302
295
|
value (Type[UserManager]): The user manager value.
|
|
@@ -306,9 +299,7 @@ class AuthConfigurator:
|
|
|
306
299
|
@property
|
|
307
300
|
def cookie_transport(self):
|
|
308
301
|
"""
|
|
309
|
-
Get the cookie transport.
|
|
310
|
-
|
|
311
|
-
if the cookie transport is not set, it will default to the cookie_transport global variable.
|
|
302
|
+
Get the cookie transport. Built from `cookie_config` if not set.
|
|
312
303
|
|
|
313
304
|
Returns:
|
|
314
305
|
The cookie transport.
|
|
@@ -322,9 +313,7 @@ class AuthConfigurator:
|
|
|
322
313
|
@cookie_transport.setter
|
|
323
314
|
def cookie_transport(self, value: CookieTransport):
|
|
324
315
|
"""
|
|
325
|
-
Set
|
|
326
|
-
|
|
327
|
-
Use this to use a custom cookie transport.
|
|
316
|
+
Set a custom cookie transport.
|
|
328
317
|
|
|
329
318
|
Args:
|
|
330
319
|
value (CookieTransport): The cookie transport value.
|
|
@@ -339,9 +328,7 @@ class AuthConfigurator:
|
|
|
339
328
|
@property
|
|
340
329
|
def bearer_transport(self):
|
|
341
330
|
"""
|
|
342
|
-
Get the bearer transport.
|
|
343
|
-
|
|
344
|
-
if the bearer transport is not set, it will default to the bearer_transport global variable.
|
|
331
|
+
Get the bearer transport. Built from `bearer_config` if not set.
|
|
345
332
|
|
|
346
333
|
Returns:
|
|
347
334
|
The bearer transport.
|
|
@@ -355,9 +342,7 @@ class AuthConfigurator:
|
|
|
355
342
|
@bearer_transport.setter
|
|
356
343
|
def bearer_transport(self, value: BearerTransport):
|
|
357
344
|
"""
|
|
358
|
-
Set
|
|
359
|
-
|
|
360
|
-
Use this to use a custom bearer transport.
|
|
345
|
+
Set a custom bearer transport.
|
|
361
346
|
|
|
362
347
|
Args:
|
|
363
348
|
value (BearerTransport): The bearer transport value.
|
|
@@ -372,9 +357,7 @@ class AuthConfigurator:
|
|
|
372
357
|
@property
|
|
373
358
|
def cookie_backend(self):
|
|
374
359
|
"""
|
|
375
|
-
Get the cookie backend.
|
|
376
|
-
|
|
377
|
-
if the cookie backend is not set, it will default to the cookie_backend global variable.
|
|
360
|
+
Get the cookie backend. Built from the cookie transport and strategy if not set.
|
|
378
361
|
|
|
379
362
|
Returns:
|
|
380
363
|
The cookie backend.
|
|
@@ -390,9 +373,7 @@ class AuthConfigurator:
|
|
|
390
373
|
@cookie_backend.setter
|
|
391
374
|
def cookie_backend(self, value: AuthenticationBackend):
|
|
392
375
|
"""
|
|
393
|
-
Set
|
|
394
|
-
|
|
395
|
-
Use this to use a custom cookie backend.
|
|
376
|
+
Set a custom cookie backend.
|
|
396
377
|
|
|
397
378
|
Args:
|
|
398
379
|
value (AuthenticationBackend): The cookie backend value.
|
|
@@ -407,9 +388,7 @@ class AuthConfigurator:
|
|
|
407
388
|
@property
|
|
408
389
|
def bearer_backend(self):
|
|
409
390
|
"""
|
|
410
|
-
Get the bearer backend.
|
|
411
|
-
|
|
412
|
-
if the bearer backend is not set, it will default to the bearer_backend global variable.
|
|
391
|
+
Get the bearer backend. Built from the bearer transport and strategy if not set.
|
|
413
392
|
|
|
414
393
|
Returns:
|
|
415
394
|
The bearer backend.
|
|
@@ -425,9 +404,7 @@ class AuthConfigurator:
|
|
|
425
404
|
@bearer_backend.setter
|
|
426
405
|
def bearer_backend(self, value: AuthenticationBackend):
|
|
427
406
|
"""
|
|
428
|
-
Set
|
|
429
|
-
|
|
430
|
-
Use this to use a custom bearer backend.
|
|
407
|
+
Set a custom bearer backend.
|
|
431
408
|
|
|
432
409
|
Args:
|
|
433
410
|
value (AuthenticationBackend): The bearer backend value.
|
|
@@ -442,9 +419,7 @@ class AuthConfigurator:
|
|
|
442
419
|
@property
|
|
443
420
|
def authenticator(self):
|
|
444
421
|
"""
|
|
445
|
-
Get the authenticator.
|
|
446
|
-
|
|
447
|
-
if the authenticator is not set, it will default to the authenticator global variable.
|
|
422
|
+
Get the authenticator. Built from the cookie and bearer backends if not set.
|
|
448
423
|
|
|
449
424
|
Returns:
|
|
450
425
|
The authenticator.
|
|
@@ -458,9 +433,7 @@ class AuthConfigurator:
|
|
|
458
433
|
@authenticator.setter
|
|
459
434
|
def authenticator(self, value: Authenticator):
|
|
460
435
|
"""
|
|
461
|
-
Set
|
|
462
|
-
|
|
463
|
-
Use this to use a custom authenticator.
|
|
436
|
+
Set a custom authenticator.
|
|
464
437
|
|
|
465
438
|
Args:
|
|
466
439
|
value (Authenticator): The authenticator value.
|
|
@@ -475,9 +448,7 @@ class AuthConfigurator:
|
|
|
475
448
|
@property
|
|
476
449
|
def fastapi_users(self):
|
|
477
450
|
"""
|
|
478
|
-
Get the FastAPIUsers instance.
|
|
479
|
-
|
|
480
|
-
if the FastAPIUsers instance is not set, it will default to the fastapi_users global variable.
|
|
451
|
+
Get the FastAPIUsers instance. Built from the user manager and backends if not set.
|
|
481
452
|
|
|
482
453
|
Returns:
|
|
483
454
|
The FastAPIUsers instance.
|
|
@@ -493,9 +464,7 @@ class AuthConfigurator:
|
|
|
493
464
|
@fastapi_users.setter
|
|
494
465
|
def fastapi_users(self, value: FastAPIUsers):
|
|
495
466
|
"""
|
|
496
|
-
Set
|
|
497
|
-
|
|
498
|
-
Use this to use a custom FastAPIUsers instance.
|
|
467
|
+
Set a custom FastAPIUsers instance.
|
|
499
468
|
|
|
500
469
|
Args:
|
|
501
470
|
value (FastAPIUsers): The FastAPIUsers instance value.
|
|
@@ -507,9 +476,7 @@ class AuthConfigurator:
|
|
|
507
476
|
@property
|
|
508
477
|
def strategy_backend(self):
|
|
509
478
|
"""
|
|
510
|
-
Get the strategy backend generator.
|
|
511
|
-
|
|
512
|
-
if the strategy backend generator is not set, it will default to the get_jwt_strategy_generator function.
|
|
479
|
+
Get the strategy backend generator. Defaults to `get_jwt_strategy_generator` if not set.
|
|
513
480
|
|
|
514
481
|
Returns:
|
|
515
482
|
The strategy backend generator.
|
|
@@ -525,9 +492,7 @@ class AuthConfigurator:
|
|
|
525
492
|
| Literal["JWT", "DB"],
|
|
526
493
|
):
|
|
527
494
|
"""
|
|
528
|
-
Set
|
|
529
|
-
|
|
530
|
-
Use this to use a custom strategy backend generator, such as where the token is stored in the database.
|
|
495
|
+
Set a custom strategy backend generator, such as one where the token is stored in the database.
|
|
531
496
|
|
|
532
497
|
Args:
|
|
533
498
|
value (Callable[[StrategyConfig], Callable[[], Strategy]] | str): The strategy backend generator value or the name of the strategy generator function.
|
|
@@ -577,12 +542,10 @@ class AuthConfigurator:
|
|
|
577
542
|
|
|
578
543
|
def auth_config(self):
|
|
579
544
|
"""
|
|
580
|
-
|
|
581
|
-
from the Auth class annotations.
|
|
545
|
+
Map each `Auth` annotation name to its uppercased form.
|
|
582
546
|
|
|
583
547
|
Returns:
|
|
584
|
-
dict:
|
|
585
|
-
and each value is the original attribute name.
|
|
548
|
+
dict: Uppercase attribute name -> original attribute name, from the `Auth` class annotations.
|
|
586
549
|
"""
|
|
587
550
|
return {k.upper(): k for k in Auth.__annotations__.keys()}
|
|
588
551
|
|
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
"""
|
|
2
2
|
LDAP helpers for :class:`UserManager`.
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
register / authenticate / update flows and the LDAP search + role
|
|
6
|
-
reconciliation lives next to the rest of the auth machinery in
|
|
7
|
-
``fastapi_rtk.auth``.
|
|
8
|
-
|
|
9
|
-
``ldap3_search`` does the LDAP query against an already-bound connection;
|
|
4
|
+
``ldap3_search`` runs the LDAP query against an already-bound connection;
|
|
10
5
|
``ldap3_calculate_user`` applies ``AUTH_ROLES_MAPPING`` and
|
|
11
6
|
``AUTH_USER_REGISTRATION_ROLE`` to a freshly authenticated user.
|
|
12
7
|
|
|
13
|
-
Both
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
manager.
|
|
8
|
+
Both take the bound :class:`UserManager` as an argument rather than being
|
|
9
|
+
methods on it, so the LDAP flow can be tested as plain functions without a
|
|
10
|
+
full manager.
|
|
17
11
|
"""
|
|
18
12
|
|
|
19
13
|
import typing
|
|
@@ -41,22 +35,18 @@ def ldap3_search(conn, username: str):
|
|
|
41
35
|
"""
|
|
42
36
|
import ldap3.utils.conv
|
|
43
37
|
|
|
44
|
-
# Configuration check remains good practice
|
|
45
38
|
assert Setting.AUTH_LDAP_SEARCH
|
|
46
39
|
|
|
47
|
-
#
|
|
48
|
-
# ldap3 provides a utility to escape special characters to prevent LDAP injection
|
|
40
|
+
# Escape special characters to prevent LDAP injection
|
|
49
41
|
safe_username = ldap3.utils.conv.escape_filter_chars(username)
|
|
50
42
|
|
|
51
43
|
base_filter = f"({Setting.AUTH_LDAP_UID_FIELD}={safe_username})"
|
|
52
44
|
if Setting.AUTH_LDAP_SEARCH_FILTER:
|
|
53
|
-
# Combine the custom filter with the UID search
|
|
54
45
|
filter_str = f"(&{Setting.AUTH_LDAP_SEARCH_FILTER}{base_filter})"
|
|
55
46
|
else:
|
|
56
47
|
filter_str = base_filter
|
|
57
48
|
|
|
58
|
-
#
|
|
59
|
-
# Using a set to prevent duplicates if config fields overlap
|
|
49
|
+
# Set prevents duplicates if config fields overlap
|
|
60
50
|
attributes_to_fetch = {
|
|
61
51
|
Setting.AUTH_LDAP_FIRSTNAME_FIELD,
|
|
62
52
|
Setting.AUTH_LDAP_LASTNAME_FIELD,
|
|
@@ -72,8 +62,6 @@ def ldap3_search(conn, username: str):
|
|
|
72
62
|
Setting.AUTH_LDAP_SEARCH,
|
|
73
63
|
)
|
|
74
64
|
|
|
75
|
-
# 3. The Search Method
|
|
76
|
-
# The search operation is a method of the connection object
|
|
77
65
|
conn.search(
|
|
78
66
|
Setting.AUTH_LDAP_SEARCH,
|
|
79
67
|
filter_str,
|
|
@@ -82,24 +70,17 @@ def ldap3_search(conn, username: str):
|
|
|
82
70
|
)
|
|
83
71
|
logger.debug("LDAP search returned: %s", conn.entries)
|
|
84
72
|
|
|
85
|
-
# 4. Result Processing
|
|
86
|
-
# Results are stored in the conn.entries property
|
|
87
73
|
if len(conn.entries) > 1:
|
|
88
74
|
logger.error("LDAP search for '%s' returned multiple results.", username)
|
|
89
75
|
return None, None
|
|
90
76
|
|
|
91
77
|
if conn.entries:
|
|
92
|
-
# Get the first (and only) entry
|
|
93
78
|
user_entry = conn.entries[0]
|
|
94
|
-
|
|
95
|
-
# Extract DN and attributes
|
|
96
79
|
user_dn = user_entry.entry_dn
|
|
97
|
-
# .entry_attributes_as_dict provides a simple dict format
|
|
98
80
|
user_attributes = user_entry.entry_attributes_as_dict
|
|
99
81
|
|
|
100
82
|
return user_dn, user_attributes
|
|
101
83
|
else:
|
|
102
|
-
# No results found
|
|
103
84
|
return None, None
|
|
104
85
|
|
|
105
86
|
|