fastapi-rtk 1.0.21__tar.gz → 1.0.22__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-1.0.21 → fastapi_rtk-1.0.22}/PKG-INFO +3 -2
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/__init__.py +9 -1
- fastapi_rtk-1.0.22/fastapi_rtk/_version.py +1 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/auth/hashers/pbkdf2.py +1 -2
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/auth/hashers/scrypt.py +1 -2
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/config.py +3 -1
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/file_managers/file_manager.py +3 -1
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/globals.py +29 -5
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/routers.py +49 -13
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/security/sqla/models.py +4 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/utils/__init__.py +0 -5
- fastapi_rtk-1.0.22/fastapi_rtk/utils/flask_appbuilder_utils.py +16 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/pyproject.toml +2 -1
- fastapi_rtk-1.0.22/uv.lock +2011 -0
- fastapi_rtk-1.0.21/fastapi_rtk/_version.py +0 -1
- fastapi_rtk-1.0.21/fastapi_rtk/auth/hashers/utils.py +0 -122
- fastapi_rtk-1.0.21/fastapi_rtk/utils/flask_appbuilder_utils.py +0 -76
- fastapi_rtk-1.0.21/fastapi_rtk/utils/werkzeug.py +0 -91
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/.gitignore +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/LICENSE +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/README.md +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/api/__init__.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/api/base_api.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/api/model_rest_api.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/apis.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/auth/__init__.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/auth/auth.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/auth/hashers/__init__.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/auth/password_helpers/__init__.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/auth/password_helpers/fab.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/auth/strategies/__init__.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/auth/strategies/config.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/auth/strategies/db.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/auth/strategies/jwt.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/backends/__init__.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/backends/generic/__init__.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/backends/generic/column.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/backends/generic/db.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/backends/generic/exceptions.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/backends/generic/filters.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/backends/generic/interface.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/backends/generic/model.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/backends/generic/session.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/backends/sqla/__init__.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/backends/sqla/column.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/backends/sqla/db.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/backends/sqla/exceptions.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/backends/sqla/extensions/__init__.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/backends/sqla/extensions/audit/__init__.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/backends/sqla/extensions/audit/audit.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/backends/sqla/extensions/audit/types.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/backends/sqla/extensions/geoalchemy2/__init__.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/backends/sqla/extensions/geoalchemy2/filters.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/backends/sqla/extensions/geoalchemy2/geometry_converter.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/backends/sqla/filters.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/backends/sqla/interface.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/backends/sqla/model.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/backends/sqla/session.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/bases/__init__.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/bases/db.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/bases/file_manager.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/bases/filter.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/bases/interface.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/bases/model.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/bases/session.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/cli/__init__.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/cli/cli.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/cli/commands/__init__.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/cli/commands/db/__init__.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/cli/commands/db/templates/fastapi/README +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/cli/commands/db/templates/fastapi/alembic.ini.mako +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/cli/commands/db/templates/fastapi/env.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/cli/commands/db/templates/fastapi/script.py.mako +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/README +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/alembic.ini.mako +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/env.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/script.py.mako +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/cli/commands/export.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/cli/commands/security.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/cli/commands/translate.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/cli/const.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/cli/decorators.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/cli/types.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/cli/utils.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/const.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/db.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/decorators.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/dependencies.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/exceptions.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/fastapi_react_toolkit.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/file_managers/__init__.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/file_managers/image_manager.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/file_managers/s3_file_manager.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/file_managers/s3_image_manager.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/filters.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/lang/__init__.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/lang/babel/__init__.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/lang/babel/cli.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/lang/babel/config.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/lang/babel.cfg +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/lang/lazy_text.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/lang/messages.pot +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/lang/translations/de/LC_MESSAGES/messages.mo +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/lang/translations/de/LC_MESSAGES/messages.po +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/lang/translations/en/LC_MESSAGES/messages.mo +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/lang/translations/en/LC_MESSAGES/messages.po +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/manager.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/middlewares.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/mixins.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/models.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/schemas.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/security/__init__.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/security/sqla/__init__.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/security/sqla/apis.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/security/sqla/security_manager.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/setting.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/types.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/utils/async_task_runner.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/utils/class_factory.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/utils/csv_json_converter.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/utils/deep_merge.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/utils/extender_mixin.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/utils/formatter.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/utils/hooks.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/utils/lazy.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/utils/merge_schema.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/utils/multiple_async_contexts.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/utils/pydantic.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/utils/run_utils.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/utils/self_dependencies.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/utils/smartdefaultdict.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/utils/sqla.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/utils/timezone.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/utils/update_signature.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/utils/use_default_when_none.py +0 -0
- {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.22}/fastapi_rtk/version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastapi-rtk
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.22
|
|
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
|
|
@@ -17,7 +17,7 @@ Requires-Python: >=3.10
|
|
|
17
17
|
Requires-Dist: alembic>=1.17.0
|
|
18
18
|
Requires-Dist: beautifulsoup4>=4.14.2
|
|
19
19
|
Requires-Dist: fastapi-babel>=1.0.0
|
|
20
|
-
Requires-Dist: fastapi-users[oauth,sqlalchemy]>=
|
|
20
|
+
Requires-Dist: fastapi-users[oauth,sqlalchemy]>=15.0.3
|
|
21
21
|
Requires-Dist: fastapi[standard]>=0.119.1
|
|
22
22
|
Requires-Dist: jsonschema2md>=1.7.0
|
|
23
23
|
Requires-Dist: marshmallow-sqlalchemy>=1.4.2
|
|
@@ -26,3 +26,4 @@ Requires-Dist: prometheus-fastapi-instrumentator>=7.1.0
|
|
|
26
26
|
Requires-Dist: secweb>=1.25.2
|
|
27
27
|
Requires-Dist: sqlalchemy-utils>=0.42.0
|
|
28
28
|
Requires-Dist: uvicorn==0.38.0
|
|
29
|
+
Requires-Dist: werkzeug>=3.1.5
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
# Import from werkzeug to keep compatibility
|
|
2
|
+
from werkzeug.utils import ImportStringError, import_string, secure_filename
|
|
3
|
+
|
|
1
4
|
# Import all submodules
|
|
2
5
|
from .api import *
|
|
3
6
|
from .auth import *
|
|
@@ -174,6 +177,10 @@ __all__ = [
|
|
|
174
177
|
"S3ImageManager",
|
|
175
178
|
# .globals
|
|
176
179
|
"g",
|
|
180
|
+
"current_app",
|
|
181
|
+
"current_user",
|
|
182
|
+
"request",
|
|
183
|
+
"background_tasks",
|
|
177
184
|
# .lang
|
|
178
185
|
"lazy_text",
|
|
179
186
|
"translate",
|
|
@@ -232,7 +239,6 @@ __all__ = [
|
|
|
232
239
|
"deep_merge",
|
|
233
240
|
"ExtenderMixin",
|
|
234
241
|
"uuid_namegen",
|
|
235
|
-
"secure_filename",
|
|
236
242
|
"prettify_dict",
|
|
237
243
|
"format_file_size",
|
|
238
244
|
"hooks",
|
|
@@ -258,6 +264,8 @@ __all__ = [
|
|
|
258
264
|
"validate_utc",
|
|
259
265
|
"update_signature",
|
|
260
266
|
"use_default_when_none",
|
|
267
|
+
# Re-exported from werkzeug.utils
|
|
261
268
|
"ImportStringError",
|
|
262
269
|
"import_string",
|
|
270
|
+
"secure_filename",
|
|
263
271
|
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.0.22"
|
|
@@ -2,8 +2,7 @@ import typing
|
|
|
2
2
|
|
|
3
3
|
from pwdlib.hashers import HasherProtocol
|
|
4
4
|
from pwdlib.hashers.base import ensure_str
|
|
5
|
-
|
|
6
|
-
from .utils import check_password_hash, generate_password_hash
|
|
5
|
+
from werkzeug.security import check_password_hash, generate_password_hash
|
|
7
6
|
|
|
8
7
|
__all__ = ["PBKDF2Hasher"]
|
|
9
8
|
|
|
@@ -2,8 +2,7 @@ import typing
|
|
|
2
2
|
|
|
3
3
|
from pwdlib.hashers import HasherProtocol
|
|
4
4
|
from pwdlib.hashers.base import ensure_str
|
|
5
|
-
|
|
6
|
-
from .utils import check_password_hash, generate_password_hash
|
|
5
|
+
from werkzeug.security import check_password_hash, generate_password_hash
|
|
7
6
|
|
|
8
7
|
__all__ = ["ScryptHasher"]
|
|
9
8
|
|
|
@@ -2,9 +2,11 @@ import os
|
|
|
2
2
|
import os.path as op
|
|
3
3
|
import shutil
|
|
4
4
|
|
|
5
|
+
from werkzeug.utils import secure_filename
|
|
6
|
+
|
|
5
7
|
from ..bases.file_manager import AbstractFileManager
|
|
6
8
|
from ..setting import Setting
|
|
7
|
-
from ..utils import lazy,
|
|
9
|
+
from ..utils import lazy, smart_run
|
|
8
10
|
|
|
9
11
|
__all__ = ["FileManager"]
|
|
10
12
|
|
|
@@ -44,6 +44,7 @@ import fastapi
|
|
|
44
44
|
from fastapi import Request, Response
|
|
45
45
|
from starlette.middleware.base import BaseHTTPMiddleware
|
|
46
46
|
from starlette.types import ASGIApp
|
|
47
|
+
from werkzeug.local import LocalProxy
|
|
47
48
|
|
|
48
49
|
from .config import Config
|
|
49
50
|
from .const import (
|
|
@@ -61,7 +62,7 @@ if TYPE_CHECKING:
|
|
|
61
62
|
from .fastapi_react_toolkit import FastAPIReactToolkit
|
|
62
63
|
from .security.sqla.models import User
|
|
63
64
|
|
|
64
|
-
__all__ = ["g"]
|
|
65
|
+
__all__ = ["g", "current_app", "current_user", "request", "background_tasks"]
|
|
65
66
|
|
|
66
67
|
|
|
67
68
|
class Globals:
|
|
@@ -71,9 +72,9 @@ class Globals:
|
|
|
71
72
|
_defaults: dict[str, Any]
|
|
72
73
|
|
|
73
74
|
# Type annotations for the attributes
|
|
74
|
-
user: "User"
|
|
75
|
+
user: "User | None"
|
|
75
76
|
"""
|
|
76
|
-
The current user object. It will be `None` when not used in a request context.
|
|
77
|
+
The current user object. It will be `None` when not used in a request context or if no user is authenticated.
|
|
77
78
|
"""
|
|
78
79
|
auth: "AuthConfigurator"
|
|
79
80
|
"""
|
|
@@ -91,11 +92,11 @@ class Globals:
|
|
|
91
92
|
"""
|
|
92
93
|
A dictionary used to store list of sensitive columns for each model that should not be returned in the list and get endpoints. Default is `{"User": ["password", "hashed_password"]}`.
|
|
93
94
|
"""
|
|
94
|
-
background_tasks: fastapi.BackgroundTasks
|
|
95
|
+
background_tasks: fastapi.BackgroundTasks | None
|
|
95
96
|
"""
|
|
96
97
|
The background tasks object to add tasks to be executed after the response is sent. It will be `None` when not used in a request context.
|
|
97
98
|
"""
|
|
98
|
-
request: Request
|
|
99
|
+
request: Request | None
|
|
99
100
|
"""
|
|
100
101
|
The current request object. It will be `None` when not used in a request context.
|
|
101
102
|
"""
|
|
@@ -108,6 +109,9 @@ class Globals:
|
|
|
108
109
|
The image manager object to manage images in the application. Defaults to `ImageManager` from `fastapi_rtk.file_managers.image_manager`.
|
|
109
110
|
"""
|
|
110
111
|
current_app: "FastAPIReactToolkit"
|
|
112
|
+
"""
|
|
113
|
+
The current FastAPI React Toolkit application instance.
|
|
114
|
+
"""
|
|
111
115
|
|
|
112
116
|
def __init__(self) -> None:
|
|
113
117
|
object.__setattr__(self, "_vars", {})
|
|
@@ -269,3 +273,23 @@ g.set_default(
|
|
|
269
273
|
),
|
|
270
274
|
)
|
|
271
275
|
g.config.add_callback(basic_callback)
|
|
276
|
+
|
|
277
|
+
# Local Proxies
|
|
278
|
+
current_app: "FastAPIReactToolkit" = LocalProxy(lambda: g.current_app)
|
|
279
|
+
"""
|
|
280
|
+
Proxy to the current FastAPI React Toolkit application instance.
|
|
281
|
+
"""
|
|
282
|
+
current_user: "User | None" = LocalProxy(lambda: g.user)
|
|
283
|
+
"""
|
|
284
|
+
Proxy to the current user object. It will be `None` when not used in a request context or if no user is authenticated.
|
|
285
|
+
"""
|
|
286
|
+
request: Request | None = LocalProxy(lambda: g.request)
|
|
287
|
+
"""
|
|
288
|
+
Proxy to the current request object. It will be `None` when not used in a request context.
|
|
289
|
+
"""
|
|
290
|
+
background_tasks: fastapi.BackgroundTasks | None = LocalProxy(
|
|
291
|
+
lambda: g.background_tasks
|
|
292
|
+
)
|
|
293
|
+
"""
|
|
294
|
+
Proxy to the background tasks object to add tasks to be executed after the response is sent. It will be `None` when not used in a request context.
|
|
295
|
+
"""
|
|
@@ -99,11 +99,9 @@ def get_oauth_router(
|
|
|
99
99
|
backend: AuthenticationBackend[models.UP, models.ID],
|
|
100
100
|
get_user_manager: UserManagerDependency[models.UP, models.ID],
|
|
101
101
|
state_secret: SecretType,
|
|
102
|
-
redirect_url:
|
|
103
|
-
redirect_url_factory: typing.
|
|
104
|
-
|
|
105
|
-
] = None,
|
|
106
|
-
redirect_url_after_callback: typing.Optional[str] = None,
|
|
102
|
+
redirect_url: str | None = None,
|
|
103
|
+
redirect_url_factory: typing.Callable[[Request, list[str]], str] | None = None,
|
|
104
|
+
redirect_url_after_callback: str | None = None,
|
|
107
105
|
associate_by_email: bool = False,
|
|
108
106
|
is_verified_by_default: bool = False,
|
|
109
107
|
**kwargs: dict[str, typing.Any],
|
|
@@ -185,6 +183,18 @@ def get_oauth_router(
|
|
|
185
183
|
"summary": "User is inactive.",
|
|
186
184
|
"value": {"detail": ErrorCode.LOGIN_BAD_CREDENTIALS},
|
|
187
185
|
},
|
|
186
|
+
ErrorCode.ACCESS_TOKEN_DECODE_ERROR: {
|
|
187
|
+
"summary": "Access token is error.",
|
|
188
|
+
"value": {
|
|
189
|
+
"detail": ErrorCode.ACCESS_TOKEN_DECODE_ERROR
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
ErrorCode.ACCESS_TOKEN_ALREADY_EXPIRED: {
|
|
193
|
+
"summary": "Access token is already expired.",
|
|
194
|
+
"value": {
|
|
195
|
+
"detail": ErrorCode.ACCESS_TOKEN_ALREADY_EXPIRED
|
|
196
|
+
},
|
|
197
|
+
},
|
|
188
198
|
}
|
|
189
199
|
}
|
|
190
200
|
},
|
|
@@ -216,7 +226,15 @@ def get_oauth_router(
|
|
|
216
226
|
try:
|
|
217
227
|
state_data = decode_jwt(state, state_secret, [STATE_TOKEN_AUDIENCE])
|
|
218
228
|
except jwt.DecodeError:
|
|
219
|
-
raise HTTPException(
|
|
229
|
+
raise HTTPException(
|
|
230
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
|
231
|
+
detail=ErrorCode.ACCESS_TOKEN_DECODE_ERROR,
|
|
232
|
+
)
|
|
233
|
+
except jwt.ExpiredSignatureError:
|
|
234
|
+
raise HTTPException(
|
|
235
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
|
236
|
+
detail=ErrorCode.ACCESS_TOKEN_ALREADY_EXPIRED,
|
|
237
|
+
)
|
|
220
238
|
|
|
221
239
|
try:
|
|
222
240
|
user = await user_manager.oauth_callback(
|
|
@@ -271,11 +289,9 @@ def get_oauth_associate_router(
|
|
|
271
289
|
get_user_manager: UserManagerDependency[models.UP, models.ID],
|
|
272
290
|
user_schema: type[schemas.U],
|
|
273
291
|
state_secret: SecretType,
|
|
274
|
-
redirect_url:
|
|
275
|
-
redirect_url_factory: typing.
|
|
276
|
-
|
|
277
|
-
] = None,
|
|
278
|
-
redirect_url_after_callback: typing.Optional[str] = None,
|
|
292
|
+
redirect_url: str | None = None,
|
|
293
|
+
redirect_url_factory: typing.Callable[[Request, list[str]], str] | None = None,
|
|
294
|
+
redirect_url_after_callback: str | None = None,
|
|
279
295
|
requires_verification: bool = False,
|
|
280
296
|
) -> APIRouter:
|
|
281
297
|
"""
|
|
@@ -354,6 +370,18 @@ def get_oauth_associate_router(
|
|
|
354
370
|
"summary": "Invalid state token.",
|
|
355
371
|
"value": None,
|
|
356
372
|
},
|
|
373
|
+
ErrorCode.ACCESS_TOKEN_DECODE_ERROR: {
|
|
374
|
+
"summary": "Access token is error.",
|
|
375
|
+
"value": {
|
|
376
|
+
"detail": ErrorCode.ACCESS_TOKEN_DECODE_ERROR
|
|
377
|
+
},
|
|
378
|
+
},
|
|
379
|
+
ErrorCode.ACCESS_TOKEN_ALREADY_EXPIRED: {
|
|
380
|
+
"summary": "Access token is already expired.",
|
|
381
|
+
"value": {
|
|
382
|
+
"detail": ErrorCode.ACCESS_TOKEN_ALREADY_EXPIRED
|
|
383
|
+
},
|
|
384
|
+
},
|
|
357
385
|
}
|
|
358
386
|
}
|
|
359
387
|
},
|
|
@@ -385,7 +413,15 @@ def get_oauth_associate_router(
|
|
|
385
413
|
try:
|
|
386
414
|
state_data = decode_jwt(state, state_secret, [STATE_TOKEN_AUDIENCE])
|
|
387
415
|
except jwt.DecodeError:
|
|
388
|
-
raise HTTPException(
|
|
416
|
+
raise HTTPException(
|
|
417
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
|
418
|
+
detail=ErrorCode.ACCESS_TOKEN_DECODE_ERROR,
|
|
419
|
+
)
|
|
420
|
+
except jwt.ExpiredSignatureError:
|
|
421
|
+
raise HTTPException(
|
|
422
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
|
423
|
+
detail=ErrorCode.ACCESS_TOKEN_ALREADY_EXPIRED,
|
|
424
|
+
)
|
|
389
425
|
|
|
390
426
|
if state_data["sub"] != str(user.id):
|
|
391
427
|
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST)
|
|
@@ -404,7 +440,7 @@ def get_oauth_associate_router(
|
|
|
404
440
|
if redirect_url_after_callback:
|
|
405
441
|
return RedirectResponse(redirect_url_after_callback)
|
|
406
442
|
|
|
407
|
-
return
|
|
443
|
+
return user_schema.model_validate(user)
|
|
408
444
|
|
|
409
445
|
return router
|
|
410
446
|
|
|
@@ -19,7 +19,6 @@ from .sqla import *
|
|
|
19
19
|
from .timezone import *
|
|
20
20
|
from .update_signature import *
|
|
21
21
|
from .use_default_when_none import *
|
|
22
|
-
from .werkzeug import *
|
|
23
22
|
|
|
24
23
|
__all__ = [
|
|
25
24
|
# .async_task_runner
|
|
@@ -35,7 +34,6 @@ __all__ = [
|
|
|
35
34
|
"ExtenderMixin",
|
|
36
35
|
# .flask_appbuilder_utils
|
|
37
36
|
"uuid_namegen",
|
|
38
|
-
"secure_filename",
|
|
39
37
|
# .formatter
|
|
40
38
|
"prettify_dict",
|
|
41
39
|
"format_file_size",
|
|
@@ -74,9 +72,6 @@ __all__ = [
|
|
|
74
72
|
"update_signature",
|
|
75
73
|
# .use_default_when_none
|
|
76
74
|
"use_default_when_none",
|
|
77
|
-
# .werkzeug
|
|
78
|
-
"ImportStringError",
|
|
79
|
-
"import_string",
|
|
80
75
|
]
|
|
81
76
|
|
|
82
77
|
P = typing.ParamSpec("P")
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import uuid
|
|
2
|
+
|
|
3
|
+
__all__ = ["uuid_namegen"]
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def uuid_namegen(filename: str) -> str:
|
|
7
|
+
"""
|
|
8
|
+
Generates a unique filename by combining a UUID and the original filename.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
filename (str): The original filename to be used in the unique name.
|
|
12
|
+
|
|
13
|
+
Returns:
|
|
14
|
+
str: The generated unique filename.
|
|
15
|
+
"""
|
|
16
|
+
return str(uuid.uuid1()) + "_sep_" + filename
|
|
@@ -30,7 +30,7 @@ dependencies = [
|
|
|
30
30
|
"alembic>=1.17.0",
|
|
31
31
|
"beautifulsoup4>=4.14.2",
|
|
32
32
|
"fastapi-babel>=1.0.0",
|
|
33
|
-
"fastapi-users[oauth,sqlalchemy]>=
|
|
33
|
+
"fastapi-users[oauth,sqlalchemy]>=15.0.3",
|
|
34
34
|
"fastapi[standard]>=0.119.1",
|
|
35
35
|
"jsonschema2md>=1.7.0",
|
|
36
36
|
"marshmallow-sqlalchemy>=1.4.2",
|
|
@@ -39,6 +39,7 @@ dependencies = [
|
|
|
39
39
|
"secweb>=1.25.2",
|
|
40
40
|
"sqlalchemy-utils>=0.42.0",
|
|
41
41
|
"uvicorn==0.38.0",
|
|
42
|
+
"werkzeug>=3.1.5",
|
|
42
43
|
]
|
|
43
44
|
urls = { Homepage = "https://codeberg.org/datatactics/fastapi-rtk", Issues = "https://codeberg.org/datatactics/fastapi-rtk/issues" }
|
|
44
45
|
scripts = { "fastapi-rtk" = "fastapi_rtk.cli:main" }
|