fastapi-rtk 2.3.2__tar.gz → 2.3.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/PKG-INFO +1 -1
- fastapi_rtk-2.3.4/fastapi_rtk/_version.py +1 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/api/base_api.py +11 -11
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/api/model_rest_api/__init__.py +114 -67
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/api/model_rest_api/_add_mixin.py +3 -21
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/api/model_rest_api/_bulk_mixin.py +9 -15
- fastapi_rtk-2.3.2/fastapi_rtk/api/model_rest_api/_columns.py → fastapi_rtk-2.3.4/fastapi_rtk/api/model_rest_api/_columns_mixin.py +29 -33
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/api/model_rest_api/_delete_mixin.py +4 -19
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/api/model_rest_api/_download_mixin.py +6 -20
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/api/model_rest_api/_edit_mixin.py +5 -30
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/api/model_rest_api/_file_mixin.py +14 -17
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/api/model_rest_api/_info_mixin.py +19 -78
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/api/model_rest_api/_list_mixin.py +3 -16
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/api/model_rest_api/_params.py +9 -9
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/api/model_rest_api/_show_mixin.py +4 -24
- fastapi_rtk-2.3.4/fastapi_rtk/api/model_rest_api/_typed_base.py +176 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/auth/auth.py +88 -71
- fastapi_rtk-2.3.4/fastapi_rtk/auth/hashers/pbkdf2.py +33 -0
- fastapi_rtk-2.3.4/fastapi_rtk/auth/hashers/scrypt.py +33 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/auth/password_helpers/fab.py +5 -6
- fastapi_rtk-2.3.4/fastapi_rtk/auth/strategies/config.py +25 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/auth/strategies/db.py +47 -32
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/auth/strategies/jwt.py +5 -5
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/backends/generic/column.py +20 -25
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/backends/generic/db.py +1 -1
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/backends/generic/exceptions.py +2 -2
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/backends/generic/filters.py +17 -9
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/backends/generic/interface.py +7 -8
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/backends/generic/session.py +10 -9
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/backends/sqla/db.py +34 -28
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/backends/sqla/extensions/audit/_decorators_mixin.py +25 -23
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/backends/sqla/extensions/audit/_lifecycle_mixin.py +15 -13
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/backends/sqla/extensions/audit/_processing_mixin.py +7 -7
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/backends/sqla/extensions/audit/audit.py +15 -16
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/backends/sqla/extensions/geoalchemy2/filters.py +51 -21
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/backends/sqla/filters.py +19 -16
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/backends/sqla/interface.py +88 -54
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/backends/sqla/model.py +35 -26
- fastapi_rtk-2.3.4/fastapi_rtk/backends/sqla/session.py +32 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/bases/file_manager.py +5 -4
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/bases/interface.py +10 -9
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/cli/cli.py +6 -7
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/cli/commands/_security_crypto.py +14 -9
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/cli/commands/db/__init__.py +103 -85
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/cli/commands/export.py +1 -1
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/cli/commands/security.py +87 -79
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/cli/commands/translate.py +9 -9
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/cli/decorators.py +7 -7
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/cli/utils.py +15 -8
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/config.py +2 -2
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/const.py +3 -3
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/db.py +671 -671
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/decorators.py +49 -45
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/dependencies.py +7 -8
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/exceptions.py +4 -4
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/fastapi_react_toolkit.py +69 -38
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/file_managers/file_manager.py +2 -2
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/file_managers/s3_file_manager.py +3 -2
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/globals.py +30 -29
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/lang/babel/cli.py +2 -2
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/manager.py +71 -63
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/middlewares.py +24 -24
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/registry.py +21 -11
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/routers.py +188 -141
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/schemas.py +50 -53
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/security/sqla/apis.py +16 -16
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/security/sqla/models.py +108 -60
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/security/sqla/security_manager/__init__.py +2 -2
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/security/sqla/security_manager/_export.py +4 -4
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/security/sqla/security_manager/_import.py +3 -2
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/security/sqla/security_manager/_role_mixin.py +7 -5
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/security/sqla/security_manager/_user_mixin.py +5 -5
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/setting.py +2 -2
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/types.py +7 -7
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/utils/async_task_runner.py +14 -12
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/utils/deep_merge.py +6 -5
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/utils/formatter.py +2 -2
- fastapi_rtk-2.3.4/fastapi_rtk/utils/hooks.py +42 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/utils/lazy.py +10 -7
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/utils/merge_schema.py +5 -6
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/utils/pydantic.py +4 -4
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/utils/run_utils.py +26 -21
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/utils/smartdefaultdict.py +3 -2
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/utils/sqla.py +3 -5
- fastapi_rtk-2.3.4/fastapi_rtk/utils/timezone.py +19 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/utils/update_signature.py +6 -3
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/conftest.py +8 -7
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/integration/api/test_model_rest_api.py +3 -2
- fastapi_rtk-2.3.4/tests/integration/apis/test_info_callable_schema.py +102 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/integration/auth/test_oauth.py +77 -61
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/integration/conftest.py +3 -6
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/integration/file_managers/test_file_routes.py +2 -2
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/integration/security/sqla/test_security_manager.py +6 -10
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/api/model_rest_api/test_columns.py +66 -7
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/api/model_rest_api/test_file_mixin.py +5 -5
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/api/model_rest_api/test_init.py +5 -3
- fastapi_rtk-2.3.4/tests/unit/api/model_rest_api/test_typed_base_consistency.py +104 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/api/test_base_api.py +12 -13
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/apis/test_info.py +10 -10
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/auth/password_helpers/test_fab.py +3 -2
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/auth/strategies/test_config.py +5 -4
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/auth/strategies/test_db.py +10 -4
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/auth/strategies/test_jwt.py +3 -2
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/auth/test_auth.py +28 -28
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/backends/generic/test_filters.py +8 -8
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/backends/generic/test_interface.py +0 -2
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/backends/generic/test_session.py +9 -6
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/backends/sqla/conftest.py +7 -6
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/backends/sqla/test_audit.py +21 -33
- fastapi_rtk-2.3.4/tests/unit/backends/sqla/test_column.py +27 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/backends/sqla/test_db.py +18 -22
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/backends/sqla/test_filters.py +28 -23
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/backends/sqla/test_geoalchemy2.py +41 -52
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/backends/sqla/test_interface.py +6 -8
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/backends/sqla/test_model.py +8 -11
- fastapi_rtk-2.3.4/tests/unit/backends/sqla/test_session.py +43 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/bases/test_db.py +0 -2
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/bases/test_file_manager.py +5 -7
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/cli/commands/conftest.py +9 -7
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/cli/commands/test_db.py +6 -5
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/cli/commands/test_export.py +34 -53
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/cli/commands/test_security.py +136 -111
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/cli/commands/test_translate.py +15 -25
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/cli/test_cli.py +7 -6
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/cli/test_decorators.py +33 -27
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/file_managers/test_file_manager.py +3 -2
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/file_managers/test_s3_file_manager.py +59 -37
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/file_managers/test_s3_image_manager.py +3 -3
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/lang/test_babel_cli.py +8 -7
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/lang/test_lazy_text.py +15 -8
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/security/sqla/conftest.py +5 -4
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/security/sqla/test_apis.py +5 -6
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/security/sqla/test_models.py +3 -2
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/security/sqla/test_security_manager.py +24 -26
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/test_db.py +31 -30
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/test_decorators.py +12 -10
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/test_dependencies.py +51 -51
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/test_fastapi_react_toolkit.py +49 -54
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/test_globals.py +3 -2
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/test_manager.py +131 -80
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/test_middlewares.py +20 -17
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/test_routers.py +265 -278
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/test_types.py +11 -8
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/utils/test_async_task_runner.py +5 -4
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/utils/test_csv_json_converter.py +11 -10
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/utils/test_flask_appbuilder_utils.py +3 -2
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/utils/test_lazy.py +3 -2
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/utils/test_pydantic.py +8 -8
- fastapi_rtk-2.3.4/tests/unit/utils/test_sqla.py +82 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/utils/test_timezone.py +21 -18
- fastapi_rtk-2.3.2/fastapi_rtk/_version.py +0 -1
- fastapi_rtk-2.3.2/fastapi_rtk/auth/hashers/pbkdf2.py +0 -34
- fastapi_rtk-2.3.2/fastapi_rtk/auth/hashers/scrypt.py +0 -34
- fastapi_rtk-2.3.2/fastapi_rtk/auth/strategies/config.py +0 -24
- fastapi_rtk-2.3.2/fastapi_rtk/backends/sqla/session.py +0 -29
- fastapi_rtk-2.3.2/fastapi_rtk/utils/hooks.py +0 -37
- fastapi_rtk-2.3.2/fastapi_rtk/utils/timezone.py +0 -19
- fastapi_rtk-2.3.2/tests/unit/backends/sqla/test_column.py +0 -29
- fastapi_rtk-2.3.2/tests/unit/backends/sqla/test_session.py +0 -37
- fastapi_rtk-2.3.2/tests/unit/utils/test_sqla.py +0 -81
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/.gitignore +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/LICENSE +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/README.md +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/api/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/api/model_rest_api/_upload_mixin.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/apis/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/apis/info.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/apis/license.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/auth/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/auth/hashers/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/auth/ldap.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/auth/password_helpers/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/auth/strategies/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/backends/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/backends/generic/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/backends/generic/model.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/backends/sqla/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/backends/sqla/column.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/backends/sqla/exceptions.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/backends/sqla/extensions/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/backends/sqla/extensions/audit/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/backends/sqla/extensions/audit/_logger.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/backends/sqla/extensions/audit/types.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/backends/sqla/extensions/geoalchemy2/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/backends/sqla/extensions/geoalchemy2/geometry_converter.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/bases/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/bases/db.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/bases/filter.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/bases/model.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/bases/session.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/cli/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/cli/commands/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/cli/commands/db/templates/fastapi/README +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/cli/commands/db/templates/fastapi/alembic.ini.mako +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/cli/commands/db/templates/fastapi/env.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/cli/commands/db/templates/fastapi/script.py.mako +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/README +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/alembic.ini.mako +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/env.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/script.py.mako +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/cli/const.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/cli/types.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/file_managers/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/file_managers/image_manager.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/file_managers/s3_image_manager.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/filters.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/lang/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/lang/babel/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/lang/babel/config.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/lang/babel.cfg +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/lang/lazy_text.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/lang/messages.pot +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/lang/translations/de/LC_MESSAGES/messages.mo +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/lang/translations/de/LC_MESSAGES/messages.po +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/lang/translations/en/LC_MESSAGES/messages.mo +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/lang/translations/en/LC_MESSAGES/messages.po +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/mixins.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/models.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/py.typed +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/security/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/security/sqla/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/security/sqla/security_manager/_association_mixin.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/security/sqla/security_manager/_builtin_role_mixin.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/security/sqla/security_manager/_cleanup_mixin.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/security/sqla/security_manager/_exception_filters.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/utils/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/utils/class_factory.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/utils/csv_json_converter.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/utils/extender_mixin.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/utils/flask_appbuilder_utils.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/utils/multiple_async_contexts.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/utils/self_dependencies.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/utils/use_default_when_none.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/fastapi_rtk/version.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/pyproject.toml +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/docker-compose.gis.yml +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/integration/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/integration/api/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/integration/apis/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/integration/apis/test_info_contract.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/integration/auth/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/integration/auth/test_auth_flow.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/integration/file_managers/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/integration/security/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/integration/security/sqla/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/integration/test_app_smoke.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/api/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/api/conftest.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/api/model_rest_api/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/apis/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/apis/test_license.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/auth/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/auth/hashers/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/auth/hashers/test_pbkdf2.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/auth/hashers/test_scrypt.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/auth/password_helpers/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/auth/strategies/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/backends/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/backends/generic/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/backends/generic/test_column.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/backends/generic/test_db.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/backends/generic/test_exceptions.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/backends/generic/test_model.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/backends/sqla/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/backends/sqla/test_audit_types.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/bases/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/bases/test_filter.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/bases/test_interface.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/bases/test_model.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/bases/test_session.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/cli/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/cli/commands/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/cli/commands/test_security_crypto.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/cli/conftest.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/cli/test_types.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/cli/test_utils.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/file_managers/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/file_managers/conftest.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/file_managers/test_image_manager.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/lang/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/lang/test_babel_config.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/security/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/security/sqla/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/test_config.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/test_const.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/test_exceptions.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/test_filters.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/test_mixins.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/test_models.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/test_registry.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/test_schemas.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/test_setting.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/test_version.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/utils/__init__.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/utils/test_class_factory.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/utils/test_deep_merge.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/utils/test_extender_mixin.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/utils/test_formatter.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/utils/test_hooks.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/utils/test_merge_schema.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/utils/test_multiple_async_contexts.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/utils/test_run_utils.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/utils/test_self_dependencies.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/utils/test_smartdefaultdict.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/utils/test_update_signature.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/tests/unit/utils/test_use_default_when_none.py +0 -0
- {fastapi_rtk-2.3.2 → fastapi_rtk-2.3.4}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastapi-rtk
|
|
3
|
-
Version: 2.3.
|
|
3
|
+
Version: 2.3.4
|
|
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.3.4"
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
+
import collections.abc
|
|
1
2
|
import typing
|
|
2
|
-
from typing import TYPE_CHECKING, Any, Dict
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
import fastapi
|
|
5
5
|
|
|
6
6
|
from ..const import PERMISSION_PREFIX, logger
|
|
7
7
|
from ..registry import APIRouteRegistry
|
|
8
8
|
from ..utils import T, lazy_self, update_signature
|
|
9
9
|
from ..utils import lazy as o_lazy
|
|
10
10
|
|
|
11
|
-
if TYPE_CHECKING:
|
|
11
|
+
if typing.TYPE_CHECKING:
|
|
12
12
|
from ..fastapi_react_toolkit import FastAPIReactToolkit
|
|
13
13
|
|
|
14
14
|
__all__ = ["BaseApi"]
|
|
@@ -88,9 +88,9 @@ class BaseApi:
|
|
|
88
88
|
"""
|
|
89
89
|
routes_to_register: list[
|
|
90
90
|
tuple[
|
|
91
|
-
|
|
91
|
+
collections.abc.Callable,
|
|
92
92
|
dict[str, typing.Any],
|
|
93
|
-
|
|
93
|
+
collections.abc.Callable,
|
|
94
94
|
dict[str, typing.Any],
|
|
95
95
|
]
|
|
96
96
|
] = lazy(lambda self: [])
|
|
@@ -103,14 +103,14 @@ class BaseApi:
|
|
|
103
103
|
"""
|
|
104
104
|
The FastAPIReactToolkit object. Automatically set when the API is added to the toolkit.
|
|
105
105
|
"""
|
|
106
|
-
cache:
|
|
106
|
+
cache: dict[str, typing.Any] = lazy(lambda self: dict())
|
|
107
107
|
"""
|
|
108
108
|
The cache for the API.
|
|
109
109
|
|
|
110
110
|
DO NOT MODIFY.
|
|
111
111
|
"""
|
|
112
112
|
router = lazy(
|
|
113
|
-
lambda self: APIRouter(
|
|
113
|
+
lambda self: fastapi.APIRouter(
|
|
114
114
|
prefix=f"/api/{self.version}/{self.resource_name}",
|
|
115
115
|
tags=[self.__class__.__name__],
|
|
116
116
|
)
|
|
@@ -139,7 +139,7 @@ class BaseApi:
|
|
|
139
139
|
"""
|
|
140
140
|
pass
|
|
141
141
|
|
|
142
|
-
def integrate_router(self, app: APIRouter):
|
|
142
|
+
def integrate_router(self, app: fastapi.APIRouter):
|
|
143
143
|
"""
|
|
144
144
|
Integrates the router into the FastAPI app.
|
|
145
145
|
|
|
@@ -157,7 +157,7 @@ class BaseApi:
|
|
|
157
157
|
if self.toolkit.global_user_dependency and not ignore_g_user:
|
|
158
158
|
from ..dependencies import set_global_user
|
|
159
159
|
|
|
160
|
-
rest_data["dependencies"] = [Depends(set_global_user())] + (
|
|
160
|
+
rest_data["dependencies"] = [fastapi.Depends(set_global_user())] + (
|
|
161
161
|
rest_data.get("dependencies") or []
|
|
162
162
|
)
|
|
163
163
|
|
|
@@ -213,10 +213,10 @@ class BaseApi:
|
|
|
213
213
|
else:
|
|
214
214
|
resolved_kwargs[key] = val
|
|
215
215
|
resolved_dependencies.append(
|
|
216
|
-
Depends(func(**resolved_kwargs))
|
|
216
|
+
fastapi.Depends(func(**resolved_kwargs))
|
|
217
217
|
)
|
|
218
218
|
else:
|
|
219
|
-
resolved_dependencies.append(Depends(func))
|
|
219
|
+
resolved_dependencies.append(fastapi.Depends(func))
|
|
220
220
|
|
|
221
221
|
path, methods, rest_data = (
|
|
222
222
|
data["path"],
|
|
@@ -22,13 +22,12 @@ remain on the composed class so they can be overridden in subclasses with
|
|
|
22
22
|
the usual ``class MyApi(ModelRestApi): list_columns = [...]`` idiom.
|
|
23
23
|
"""
|
|
24
24
|
|
|
25
|
+
import collections.abc
|
|
25
26
|
import enum
|
|
26
27
|
import typing
|
|
27
28
|
|
|
28
29
|
import fastapi
|
|
29
30
|
import pydantic
|
|
30
|
-
from fastapi import Depends
|
|
31
|
-
from pydantic import BaseModel, Field
|
|
32
31
|
|
|
33
32
|
from ...backends.sqla.filters import BaseFilter, BaseOprFilter
|
|
34
33
|
from ...backends.sqla.interface import SQLAInterface
|
|
@@ -52,7 +51,7 @@ from ...utils import T, lazy_self, merge_schema
|
|
|
52
51
|
from ..base_api import BaseApi
|
|
53
52
|
from ._add_mixin import AddMixin
|
|
54
53
|
from ._bulk_mixin import BulkMixin
|
|
55
|
-
from .
|
|
54
|
+
from ._columns_mixin import ColumnsMixin
|
|
56
55
|
from ._delete_mixin import DeleteMixin
|
|
57
56
|
from ._download_mixin import DownloadMixin
|
|
58
57
|
from ._edit_mixin import EditMixin
|
|
@@ -172,17 +171,17 @@ class ModelRestApi(
|
|
|
172
171
|
"""
|
|
173
172
|
The list of routes to expose. Available routes: `info`, `download`, `bulk`, `get_list`, `get`, `post`, `put`, `delete`.
|
|
174
173
|
"""
|
|
175
|
-
exclude_routes:
|
|
174
|
+
exclude_routes: list[AVAILABLE_ROUTES] = lazy(lambda: [])
|
|
176
175
|
"""
|
|
177
176
|
The list of routes to exclude. Available routes: `info`, `download`, `bulk`, `get_list`, `get`, `post`, `put`, `delete`.
|
|
178
177
|
"""
|
|
179
|
-
protected_routes:
|
|
178
|
+
protected_routes: list[AVAILABLE_ROUTES] = lazy(
|
|
180
179
|
lambda self: [x for x in self.routes if x not in self.exclude_protected_routes]
|
|
181
180
|
)
|
|
182
181
|
"""
|
|
183
182
|
The list of routes to protect. Defaults to all routes within `routes` property except those in `exclude_protected_routes`.
|
|
184
183
|
"""
|
|
185
|
-
exclude_protected_routes:
|
|
184
|
+
exclude_protected_routes: list[AVAILABLE_ROUTES] = lazy(lambda: [])
|
|
186
185
|
"""
|
|
187
186
|
The list of routes to exclude from protection. Defaults to `[]`.
|
|
188
187
|
"""
|
|
@@ -199,7 +198,7 @@ class ModelRestApi(
|
|
|
199
198
|
}
|
|
200
199
|
```
|
|
201
200
|
"""
|
|
202
|
-
base_order:
|
|
201
|
+
base_order: tuple[str, typing.Literal["asc", "desc"]] | None = None
|
|
203
202
|
"""
|
|
204
203
|
The default order for the list endpoint. Set this to set the default order for the list endpoint.
|
|
205
204
|
|
|
@@ -208,9 +207,7 @@ class ModelRestApi(
|
|
|
208
207
|
base_order = ("name", "asc")
|
|
209
208
|
```
|
|
210
209
|
"""
|
|
211
|
-
base_filters:
|
|
212
|
-
typing.List[typing.Tuple[str, typing.Type[BaseFilter], typing.Any]] | None
|
|
213
|
-
) = None
|
|
210
|
+
base_filters: list[tuple[str, type[BaseFilter], typing.Any]] | None = None
|
|
214
211
|
"""
|
|
215
212
|
The default filters to apply for the following endpoints: `download`, `list`, `show`, `add`, and `edit`. Defaults to None.
|
|
216
213
|
|
|
@@ -221,9 +218,7 @@ class ModelRestApi(
|
|
|
221
218
|
]
|
|
222
219
|
```
|
|
223
220
|
"""
|
|
224
|
-
base_opr_filters:
|
|
225
|
-
typing.List[typing.Tuple[typing.Type[BaseOprFilter], typing.Any]] | None
|
|
226
|
-
) = None
|
|
221
|
+
base_opr_filters: list[tuple[type[BaseOprFilter], typing.Any]] | None = None
|
|
227
222
|
"""
|
|
228
223
|
The default opr filters to apply for the following endpoints: `download`, `list`, `show`, `add`, and `edit`. Defaults to None.
|
|
229
224
|
|
|
@@ -234,7 +229,7 @@ class ModelRestApi(
|
|
|
234
229
|
]
|
|
235
230
|
```
|
|
236
231
|
"""
|
|
237
|
-
opr_filters:
|
|
232
|
+
opr_filters: list[type[BaseOprFilter]] | None = None
|
|
238
233
|
"""
|
|
239
234
|
The list of opr filters to be exposed to the user. Defaults to None, which means no opr filters will be exposed.
|
|
240
235
|
|
|
@@ -269,15 +264,15 @@ class ModelRestApi(
|
|
|
269
264
|
"""
|
|
270
265
|
The enum for the order columns in the list endpoint.
|
|
271
266
|
"""
|
|
272
|
-
query_schema:
|
|
267
|
+
query_schema: type[QuerySchema] = lazy(
|
|
273
268
|
lambda self: merge_schema(
|
|
274
269
|
QuerySchema,
|
|
275
270
|
{
|
|
276
271
|
"order_column": (
|
|
277
272
|
self.order_column_enum | None,
|
|
278
|
-
Field(default=None),
|
|
273
|
+
pydantic.Field(default=None),
|
|
279
274
|
),
|
|
280
|
-
"page_size": (int | None, Field(default=self.page_size)),
|
|
275
|
+
"page_size": (int | None, pydantic.Field(default=self.page_size)),
|
|
281
276
|
},
|
|
282
277
|
True,
|
|
283
278
|
f"{self.__class__.__name__}-QuerySchema",
|
|
@@ -288,12 +283,15 @@ class ModelRestApi(
|
|
|
288
283
|
|
|
289
284
|
DO NOT MODIFY UNLESS YOU KNOW WHAT YOU ARE DOING.
|
|
290
285
|
"""
|
|
291
|
-
download_body_schema:
|
|
286
|
+
download_body_schema: type[QueryBody] = lazy(
|
|
292
287
|
lambda self: merge_schema(
|
|
293
288
|
QueryBody,
|
|
294
289
|
{
|
|
295
|
-
"order_column": (
|
|
296
|
-
|
|
290
|
+
"order_column": (
|
|
291
|
+
self.order_column_enum | None,
|
|
292
|
+
pydantic.Field(default=None),
|
|
293
|
+
),
|
|
294
|
+
"page_size": (int | None, pydantic.Field(default=self.page_size)),
|
|
297
295
|
},
|
|
298
296
|
True,
|
|
299
297
|
f"{self.__class__.__name__}-DownloadBodySchema",
|
|
@@ -335,7 +333,7 @@ class ModelRestApi(
|
|
|
335
333
|
```
|
|
336
334
|
"""
|
|
337
335
|
add_query_rel_fields = lazy(
|
|
338
|
-
lambda: dict[str, list[tuple[str,
|
|
336
|
+
lambda: dict[str, list[tuple[str, type[BaseFilter], typing.Any]]]()
|
|
339
337
|
)
|
|
340
338
|
"""
|
|
341
339
|
The query fields for the related fields in the add_columns property.
|
|
@@ -350,7 +348,7 @@ class ModelRestApi(
|
|
|
350
348
|
```
|
|
351
349
|
"""
|
|
352
350
|
edit_query_rel_fields = lazy(
|
|
353
|
-
lambda: dict[str, list[tuple[str,
|
|
351
|
+
lambda: dict[str, list[tuple[str, type[BaseFilter], typing.Any]]]()
|
|
354
352
|
)
|
|
355
353
|
"""
|
|
356
354
|
The query fields for the related fields in the edit_columns property.
|
|
@@ -365,7 +363,7 @@ class ModelRestApi(
|
|
|
365
363
|
```
|
|
366
364
|
"""
|
|
367
365
|
search_query_rel_fields = lazy(
|
|
368
|
-
lambda: dict[str, list[tuple[str,
|
|
366
|
+
lambda: dict[str, list[tuple[str, type[BaseFilter], typing.Any]]]()
|
|
369
367
|
)
|
|
370
368
|
"""
|
|
371
369
|
The query fields for the related fields in the filters.
|
|
@@ -392,7 +390,7 @@ class ModelRestApi(
|
|
|
392
390
|
}
|
|
393
391
|
```
|
|
394
392
|
"""
|
|
395
|
-
search_filters = lazy(lambda: dict[str, list[
|
|
393
|
+
search_filters = lazy(lambda: dict[str, list[type[BaseFilter]]]())
|
|
396
394
|
"""
|
|
397
395
|
Add additional filters to the search columns.
|
|
398
396
|
|
|
@@ -403,9 +401,7 @@ class ModelRestApi(
|
|
|
403
401
|
}
|
|
404
402
|
```
|
|
405
403
|
"""
|
|
406
|
-
search_exclude_filters = lazy(
|
|
407
|
-
lambda: dict[str, list[typing.Type[BaseFilter] | str]]()
|
|
408
|
-
)
|
|
404
|
+
search_exclude_filters = lazy(lambda: dict[str, list[type[BaseFilter] | str]]())
|
|
409
405
|
"""
|
|
410
406
|
Exclude filters from the search columns.
|
|
411
407
|
|
|
@@ -418,28 +414,42 @@ class ModelRestApi(
|
|
|
418
414
|
}
|
|
419
415
|
```
|
|
420
416
|
"""
|
|
421
|
-
info_return_schema:
|
|
417
|
+
info_return_schema: type[InfoResponse] = lazy(
|
|
422
418
|
lambda self: merge_schema(
|
|
423
419
|
InfoResponse,
|
|
424
420
|
{
|
|
425
|
-
"add_title": (
|
|
426
|
-
|
|
427
|
-
|
|
421
|
+
"add_title": (
|
|
422
|
+
str,
|
|
423
|
+
pydantic.Field(default_factory=lambda: self.add_title),
|
|
424
|
+
),
|
|
425
|
+
"edit_title": (
|
|
426
|
+
str,
|
|
427
|
+
pydantic.Field(default_factory=lambda: self.edit_title),
|
|
428
|
+
),
|
|
429
|
+
"filter_options": (dict, pydantic.Field(default={})),
|
|
428
430
|
"add_translations": (
|
|
429
431
|
dict,
|
|
430
|
-
Field(
|
|
432
|
+
pydantic.Field(
|
|
433
|
+
default_factory=lambda: self.add_jsonforms_translations
|
|
434
|
+
),
|
|
431
435
|
),
|
|
432
436
|
"edit_translations": (
|
|
433
437
|
dict,
|
|
434
|
-
Field(
|
|
438
|
+
pydantic.Field(
|
|
439
|
+
default_factory=lambda: self.edit_jsonforms_translations
|
|
440
|
+
),
|
|
435
441
|
),
|
|
436
442
|
"add_type": (
|
|
437
443
|
typing.Literal["json"] | typing.Literal["form"],
|
|
438
|
-
Field(
|
|
444
|
+
pydantic.Field(
|
|
445
|
+
default="form" if self._is_form_data_add else "json"
|
|
446
|
+
),
|
|
439
447
|
),
|
|
440
448
|
"edit_type": (
|
|
441
449
|
typing.Literal["json"] | typing.Literal["form"],
|
|
442
|
-
Field(
|
|
450
|
+
pydantic.Field(
|
|
451
|
+
default="form" if self._is_form_data_edit else "json"
|
|
452
|
+
),
|
|
443
453
|
),
|
|
444
454
|
},
|
|
445
455
|
name=f"{self.__class__.__name__}-InfoResponse",
|
|
@@ -646,11 +656,15 @@ class ModelRestApi(
|
|
|
646
656
|
-------------
|
|
647
657
|
"""
|
|
648
658
|
|
|
649
|
-
add_jsonforms_schema:
|
|
659
|
+
add_jsonforms_schema: (
|
|
660
|
+
dict[str, typing.Any]
|
|
661
|
+
| collections.abc.Callable[[], dict | collections.abc.Awaitable[dict]]
|
|
662
|
+
| None
|
|
663
|
+
) = None
|
|
650
664
|
"""
|
|
651
|
-
The `JSONForms` schema for the add endpoint. If not provided, Defaults to the schema generated from the `add_columns` property.
|
|
665
|
+
The `JSONForms` schema for the add endpoint. If not provided, Defaults to the schema generated from the `add_columns` property. May also be a sync or async callable returning the schema, resolved via `smart_run`.
|
|
652
666
|
"""
|
|
653
|
-
add_jsonforms_uischema:
|
|
667
|
+
add_jsonforms_uischema: dict[str, typing.Any] | None = None
|
|
654
668
|
"""
|
|
655
669
|
The `JSONForms` uischema for the add endpoint. If not provided, it will let `JSONForms` generate the uischema.
|
|
656
670
|
"""
|
|
@@ -660,11 +674,15 @@ class ModelRestApi(
|
|
|
660
674
|
"""
|
|
661
675
|
add_jsonforms_use_enum: (
|
|
662
676
|
bool
|
|
663
|
-
|
|
|
677
|
+
| collections.abc.Callable[
|
|
678
|
+
[ColumnInfo | ColumnEnumInfo | ColumnRelationInfo], bool
|
|
679
|
+
]
|
|
664
680
|
| dict[
|
|
665
681
|
str,
|
|
666
682
|
bool
|
|
667
|
-
|
|
|
683
|
+
| collections.abc.Callable[
|
|
684
|
+
[ColumnInfo | ColumnEnumInfo | ColumnRelationInfo], bool
|
|
685
|
+
],
|
|
668
686
|
]
|
|
669
687
|
) = lazy(lambda: lambda info: len(info.values) > 100)
|
|
670
688
|
"""
|
|
@@ -688,11 +706,15 @@ class ModelRestApi(
|
|
|
688
706
|
A workaround for issue https://github.com/eclipsesource/jsonforms/issues/2271
|
|
689
707
|
"""
|
|
690
708
|
|
|
691
|
-
edit_jsonforms_schema:
|
|
709
|
+
edit_jsonforms_schema: (
|
|
710
|
+
dict[str, typing.Any]
|
|
711
|
+
| collections.abc.Callable[[], dict | collections.abc.Awaitable[dict]]
|
|
712
|
+
| None
|
|
713
|
+
) = None
|
|
692
714
|
"""
|
|
693
|
-
The `JSONForms` schema for the edit endpoint. If not provided, Defaults to the schema generated from the `edit_columns` property.
|
|
715
|
+
The `JSONForms` schema for the edit endpoint. If not provided, Defaults to the schema generated from the `edit_columns` property. May also be a sync or async callable returning the schema, resolved via `smart_run`.
|
|
694
716
|
"""
|
|
695
|
-
edit_jsonforms_uischema:
|
|
717
|
+
edit_jsonforms_uischema: dict[str, typing.Any] | None = None
|
|
696
718
|
"""
|
|
697
719
|
The `JSONForms` uischema for the edit endpoint. If not provided, it will let `JSONForms` generate the uischema.
|
|
698
720
|
"""
|
|
@@ -702,11 +724,15 @@ class ModelRestApi(
|
|
|
702
724
|
"""
|
|
703
725
|
edit_jsonforms_use_enum: (
|
|
704
726
|
bool
|
|
705
|
-
|
|
|
727
|
+
| collections.abc.Callable[
|
|
728
|
+
[ColumnInfo | ColumnEnumInfo | ColumnRelationInfo], bool
|
|
729
|
+
]
|
|
706
730
|
| dict[
|
|
707
731
|
str,
|
|
708
732
|
bool
|
|
709
|
-
|
|
|
733
|
+
| collections.abc.Callable[
|
|
734
|
+
[ColumnInfo | ColumnEnumInfo | ColumnRelationInfo], bool
|
|
735
|
+
],
|
|
710
736
|
]
|
|
711
737
|
) = lazy(lambda: lambda info: len(info.values) > 100)
|
|
712
738
|
"""
|
|
@@ -800,14 +826,14 @@ class ModelRestApi(
|
|
|
800
826
|
-------------
|
|
801
827
|
"""
|
|
802
828
|
|
|
803
|
-
add_schema:
|
|
829
|
+
add_schema: type[pydantic.BaseModel] = lazy(
|
|
804
830
|
lambda self: typing.Annotated[
|
|
805
|
-
|
|
806
|
-
|
|
831
|
+
merge_schema(
|
|
832
|
+
self._create_request_schema(
|
|
807
833
|
self.add_obj_schema,
|
|
808
|
-
self.
|
|
809
|
-
name=f"{self.__class__.__name__}-AddObjSchema-Merged",
|
|
834
|
+
name=f"{self.__class__.__name__}-AddObjSchema-Request",
|
|
810
835
|
),
|
|
836
|
+
self._handle_schema_extra_fields(self.add_schema_extra_fields),
|
|
811
837
|
name=f"{self.__class__.__name__}-AddSchema",
|
|
812
838
|
),
|
|
813
839
|
fastapi.Form(media_type="multipart/form-data")
|
|
@@ -820,15 +846,15 @@ class ModelRestApi(
|
|
|
820
846
|
|
|
821
847
|
DO NOT MODIFY UNLESS YOU KNOW WHAT YOU ARE DOING.
|
|
822
848
|
"""
|
|
823
|
-
edit_schema:
|
|
849
|
+
edit_schema: type[pydantic.BaseModel] = lazy(
|
|
824
850
|
lambda self: typing.Annotated[
|
|
825
|
-
|
|
826
|
-
|
|
851
|
+
merge_schema(
|
|
852
|
+
self._create_request_schema(
|
|
827
853
|
self.edit_obj_schema,
|
|
828
|
-
|
|
829
|
-
name=f"{self.__class__.__name__}-EditObjSchema-
|
|
854
|
+
optional=True,
|
|
855
|
+
name=f"{self.__class__.__name__}-EditObjSchema-Request",
|
|
830
856
|
),
|
|
831
|
-
|
|
857
|
+
self._handle_schema_extra_fields(self.edit_schema_extra_fields),
|
|
832
858
|
name=f"{self.__class__.__name__}-EditSchema",
|
|
833
859
|
),
|
|
834
860
|
fastapi.Form(media_type="multipart/form-data")
|
|
@@ -847,11 +873,13 @@ class ModelRestApi(
|
|
|
847
873
|
"""
|
|
848
874
|
Extra fields to add to the add schema. Useful when you want to add extra fields in the body of the add endpoint for your custom logic.
|
|
849
875
|
|
|
876
|
+
Keys must not collide with `add_columns`; a colliding name raises `ValueError` at API setup, since extra fields override the request body but not the JSONForms / object schema.
|
|
877
|
+
|
|
850
878
|
Example:
|
|
851
879
|
```python
|
|
852
880
|
add_schema_extra_fields = {
|
|
853
881
|
"extra_field": str,
|
|
854
|
-
"extra_field_with_field_info": (str, Field(default="default_value")),
|
|
882
|
+
"extra_field_with_field_info": (str, pydantic.Field(default="default_value")),
|
|
855
883
|
}
|
|
856
884
|
```
|
|
857
885
|
"""
|
|
@@ -861,11 +889,13 @@ class ModelRestApi(
|
|
|
861
889
|
"""
|
|
862
890
|
Extra fields to add to the edit schema. Useful when you want to add extra fields in the body of the edit endpoint for your custom logic.
|
|
863
891
|
|
|
892
|
+
Keys must not collide with `edit_columns`; a colliding name raises `ValueError` at API setup, since extra fields override the request body but not the JSONForms / object schema.
|
|
893
|
+
|
|
864
894
|
Example:
|
|
865
895
|
```python
|
|
866
896
|
edit_schema_extra_fields = {
|
|
867
897
|
"extra_field": str,
|
|
868
|
-
"extra_field_with_field_info": (str, Field(default="default_value")),
|
|
898
|
+
"extra_field_with_field_info": (str, pydantic.Field(default="default_value")),
|
|
869
899
|
}
|
|
870
900
|
```
|
|
871
901
|
"""
|
|
@@ -876,12 +906,12 @@ class ModelRestApi(
|
|
|
876
906
|
-------------
|
|
877
907
|
"""
|
|
878
908
|
|
|
879
|
-
list_return_schema:
|
|
909
|
+
list_return_schema: type[BaseResponseMany] = lazy(
|
|
880
910
|
lambda self: merge_schema(
|
|
881
911
|
BaseResponseMany,
|
|
882
912
|
{
|
|
883
913
|
**vars(self),
|
|
884
|
-
"result": (
|
|
914
|
+
"result": (list[self.list_obj_schema], ...),
|
|
885
915
|
},
|
|
886
916
|
True,
|
|
887
917
|
f"{self.__class__.__name__}-ListResponse",
|
|
@@ -892,7 +922,7 @@ class ModelRestApi(
|
|
|
892
922
|
|
|
893
923
|
DO NOT MODIFY UNLESS YOU KNOW WHAT YOU ARE DOING.
|
|
894
924
|
"""
|
|
895
|
-
show_return_schema:
|
|
925
|
+
show_return_schema: type[BaseResponseSingle] = lazy(
|
|
896
926
|
lambda self: merge_schema(
|
|
897
927
|
BaseResponseSingle,
|
|
898
928
|
{
|
|
@@ -908,7 +938,7 @@ class ModelRestApi(
|
|
|
908
938
|
|
|
909
939
|
DO NOT MODIFY UNLESS YOU KNOW WHAT YOU ARE DOING.
|
|
910
940
|
"""
|
|
911
|
-
add_return_schema:
|
|
941
|
+
add_return_schema: type[BaseResponseSingle] = lazy(
|
|
912
942
|
lambda self: merge_schema(
|
|
913
943
|
self.show_return_schema,
|
|
914
944
|
{},
|
|
@@ -920,7 +950,7 @@ class ModelRestApi(
|
|
|
920
950
|
|
|
921
951
|
DO NOT MODIFY UNLESS YOU KNOW WHAT YOU ARE DOING.
|
|
922
952
|
"""
|
|
923
|
-
edit_return_schema:
|
|
953
|
+
edit_return_schema: type[BaseResponseSingle] = lazy(
|
|
924
954
|
lambda self: merge_schema(
|
|
925
955
|
self.show_return_schema,
|
|
926
956
|
{},
|
|
@@ -1032,6 +1062,23 @@ class ModelRestApi(
|
|
|
1032
1062
|
f"Search columns with 2nd level relations are not supported: {not_supported_search_columns}"
|
|
1033
1063
|
)
|
|
1034
1064
|
|
|
1065
|
+
# Extra fields override the request schema but never the JSONForms /
|
|
1066
|
+
# object schema, so a name in both desyncs the form from the body.
|
|
1067
|
+
add_collisions = set(self.add_schema_extra_fields) & set(self.add_columns)
|
|
1068
|
+
if add_collisions:
|
|
1069
|
+
raise ValueError(
|
|
1070
|
+
f"add_schema_extra_fields keys collide with add_columns in "
|
|
1071
|
+
f"{self.__class__.__name__}: {sorted(add_collisions)}. Remove them "
|
|
1072
|
+
f"from add_columns or rename the extra fields."
|
|
1073
|
+
)
|
|
1074
|
+
edit_collisions = set(self.edit_schema_extra_fields) & set(self.edit_columns)
|
|
1075
|
+
if edit_collisions:
|
|
1076
|
+
raise ValueError(
|
|
1077
|
+
f"edit_schema_extra_fields keys collide with edit_columns in "
|
|
1078
|
+
f"{self.__class__.__name__}: {sorted(edit_collisions)}. Remove them "
|
|
1079
|
+
f"from edit_columns or rename the extra fields."
|
|
1080
|
+
)
|
|
1081
|
+
|
|
1035
1082
|
self._gen_labels_columns(self.list_columns)
|
|
1036
1083
|
self._gen_labels_columns(self.show_columns)
|
|
1037
1084
|
self._gen_labels_columns(self.search_columns)
|
|
@@ -1088,7 +1135,7 @@ class ModelRestApi(
|
|
|
1088
1135
|
Returns the current permissions dependency.
|
|
1089
1136
|
|
|
1090
1137
|
Returns:
|
|
1091
|
-
|
|
1138
|
+
collections.abc.Callable[..., Coroutine[typing.Any, typing.Any, typing.Any | list]]: The current permissions that the user has for the API dependency.
|
|
1092
1139
|
"""
|
|
1093
1140
|
return current_permissions(self)
|
|
1094
1141
|
|
|
@@ -1099,12 +1146,12 @@ class ModelRestApi(
|
|
|
1099
1146
|
If `list_query_count_enabled` is False or `q.with_count` is False, the session will be None.
|
|
1100
1147
|
|
|
1101
1148
|
Returns:
|
|
1102
|
-
|
|
1149
|
+
collections.abc.Callable[..., Coroutine[typing.Any, typing.Any, tuple[QuerySchema, SQLASession | None]]]: The dependency that yields the tuple.
|
|
1103
1150
|
"""
|
|
1104
1151
|
|
|
1105
1152
|
async def dependency(
|
|
1106
|
-
q: self.query_schema = Depends(), # type: ignore
|
|
1107
|
-
session=Depends(self.datamodel.get_session_factory()),
|
|
1153
|
+
q: self.query_schema = fastapi.Depends(), # type: ignore
|
|
1154
|
+
session=fastapi.Depends(self.datamodel.get_session_factory()),
|
|
1108
1155
|
):
|
|
1109
1156
|
q: QuerySchema = q
|
|
1110
1157
|
if not self.list_query_count_enabled or not q.with_count:
|
|
@@ -6,36 +6,18 @@ implementation, ``pre_add`` and ``post_add`` hooks.
|
|
|
6
6
|
import typing
|
|
7
7
|
|
|
8
8
|
import pydantic
|
|
9
|
-
from pydantic import BaseModel
|
|
10
9
|
|
|
11
|
-
from ...backends.sqla.filters import BaseFilter
|
|
12
|
-
from ...backends.sqla.interface import SQLAInterface
|
|
13
10
|
from ...backends.sqla.model import Model
|
|
14
11
|
from ...backends.sqla.session import SQLASession
|
|
15
|
-
from ...const import AVAILABLE_ROUTES
|
|
16
12
|
from ...decorators import expose, permission_name, priority, protect
|
|
17
|
-
from ...schemas import BaseResponseSingle
|
|
18
13
|
from ...utils import AsyncTaskRunner, SelfDepends, SelfType, smart_run
|
|
19
14
|
from ._params import PARAM_BODY_SESSION
|
|
15
|
+
from ._typed_base import _TypedModelRestApi
|
|
20
16
|
|
|
21
17
|
|
|
22
|
-
class AddMixin:
|
|
18
|
+
class AddMixin(_TypedModelRestApi):
|
|
23
19
|
"""Add endpoint methods for ``ModelRestApi``."""
|
|
24
20
|
|
|
25
|
-
if typing.TYPE_CHECKING:
|
|
26
|
-
# Attributes supplied by the composed ``ModelRestApi`` class via MRO.
|
|
27
|
-
datamodel: SQLAInterface
|
|
28
|
-
expose_params: dict[AVAILABLE_ROUTES, dict[str, typing.Any]]
|
|
29
|
-
add_return_schema: typing.Type[BaseResponseSingle]
|
|
30
|
-
add_query_rel_fields: dict[
|
|
31
|
-
str, list[tuple[str, typing.Type[BaseFilter], typing.Any]]
|
|
32
|
-
]
|
|
33
|
-
add_schema_extra_fields: dict[
|
|
34
|
-
str, type | tuple[type, pydantic.fields.FieldInfo]
|
|
35
|
-
]
|
|
36
|
-
add_schema: typing.Type[BaseModel]
|
|
37
|
-
protected_routes: typing.List[AVAILABLE_ROUTES]
|
|
38
|
-
|
|
39
21
|
def post(self):
|
|
40
22
|
"""
|
|
41
23
|
Post endpoint for the API.
|
|
@@ -54,7 +36,7 @@ class AddMixin:
|
|
|
54
36
|
|
|
55
37
|
async def post_headless(
|
|
56
38
|
self,
|
|
57
|
-
body: BaseModel = SelfType().add_schema,
|
|
39
|
+
body: pydantic.BaseModel = SelfType().add_schema,
|
|
58
40
|
session: SQLASession = SelfDepends().datamodel.get_session_factory,
|
|
59
41
|
):
|
|
60
42
|
"""
|
|
@@ -3,27 +3,21 @@ Bulk route mixin for ``ModelRestApi``: ``bulk`` registration, ``bulk_headless``
|
|
|
3
3
|
dispatcher, and the subclass-overridable ``bulk_handler``.
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
-
import
|
|
6
|
+
import collections.abc
|
|
7
7
|
|
|
8
8
|
import fastapi
|
|
9
|
-
from fastapi import Body, HTTPException, Response
|
|
10
9
|
|
|
11
10
|
from ...backends.sqla.interface import SQLAInterface
|
|
12
11
|
from ...backends.sqla.session import SQLASession
|
|
13
|
-
from ...const import
|
|
12
|
+
from ...const import ErrorCode
|
|
14
13
|
from ...decorators import expose, permission_name, priority, protect
|
|
15
14
|
from ...utils import AsyncTaskRunner, SelfDepends, smart_run
|
|
15
|
+
from ._typed_base import _TypedModelRestApi
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
class BulkMixin:
|
|
18
|
+
class BulkMixin(_TypedModelRestApi):
|
|
19
19
|
"""Bulk endpoint methods for ``ModelRestApi``."""
|
|
20
20
|
|
|
21
|
-
if typing.TYPE_CHECKING:
|
|
22
|
-
# Attributes supplied by the composed ``ModelRestApi`` class via MRO.
|
|
23
|
-
datamodel: SQLAInterface
|
|
24
|
-
expose_params: dict[AVAILABLE_ROUTES, dict[str, typing.Any]]
|
|
25
|
-
protected_routes: typing.List[AVAILABLE_ROUTES]
|
|
26
|
-
|
|
27
21
|
def bulk(self):
|
|
28
22
|
"""
|
|
29
23
|
Bulk endpoint for the API.
|
|
@@ -42,7 +36,7 @@ class BulkMixin:
|
|
|
42
36
|
async def bulk_headless(
|
|
43
37
|
self,
|
|
44
38
|
handler: str,
|
|
45
|
-
body: dict | list = Body(...),
|
|
39
|
+
body: dict | list = fastapi.Body(...),
|
|
46
40
|
session: SQLASession = SelfDepends().datamodel.get_session_factory,
|
|
47
41
|
):
|
|
48
42
|
"""
|
|
@@ -60,24 +54,24 @@ class BulkMixin:
|
|
|
60
54
|
If you are overriding this method, make sure to copy all the decorators too.
|
|
61
55
|
"""
|
|
62
56
|
async with AsyncTaskRunner():
|
|
63
|
-
bulk_handler:
|
|
57
|
+
bulk_handler: collections.abc.Callable | None = getattr(
|
|
64
58
|
self, f"bulk_{handler}", None
|
|
65
59
|
)
|
|
66
60
|
if not bulk_handler:
|
|
67
|
-
raise HTTPException(
|
|
61
|
+
raise fastapi.HTTPException(
|
|
68
62
|
fastapi.status.HTTP_404_NOT_FOUND, ErrorCode.HANDLER_NOT_FOUND
|
|
69
63
|
)
|
|
70
64
|
try:
|
|
71
65
|
return await smart_run(bulk_handler, body, self.datamodel, session)
|
|
72
66
|
except NotImplementedError as e:
|
|
73
|
-
raise HTTPException(fastapi.status.HTTP_404_NOT_FOUND, str(e))
|
|
67
|
+
raise fastapi.HTTPException(fastapi.status.HTTP_404_NOT_FOUND, str(e))
|
|
74
68
|
|
|
75
69
|
async def bulk_handler(
|
|
76
70
|
self,
|
|
77
71
|
body: dict | list,
|
|
78
72
|
query: SQLAInterface,
|
|
79
73
|
session: SQLASession,
|
|
80
|
-
) -> Response:
|
|
74
|
+
) -> fastapi.Response:
|
|
81
75
|
"""
|
|
82
76
|
Bulk handler for the API, to be implemented by the subclass.
|
|
83
77
|
|