fastapi-rtk 1.0.21__tar.gz → 1.0.23__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.
Files changed (136) hide show
  1. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/PKG-INFO +3 -2
  2. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/__init__.py +9 -1
  3. fastapi_rtk-1.0.23/fastapi_rtk/_version.py +1 -0
  4. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/auth/hashers/pbkdf2.py +1 -2
  5. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/auth/hashers/scrypt.py +1 -2
  6. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/config.py +3 -1
  7. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/file_managers/file_manager.py +3 -1
  8. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/globals.py +29 -5
  9. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/routers.py +49 -13
  10. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/security/sqla/models.py +4 -0
  11. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/utils/__init__.py +0 -5
  12. fastapi_rtk-1.0.23/fastapi_rtk/utils/flask_appbuilder_utils.py +16 -0
  13. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/pyproject.toml +2 -1
  14. fastapi_rtk-1.0.23/uv.lock +2011 -0
  15. fastapi_rtk-1.0.21/fastapi_rtk/_version.py +0 -1
  16. fastapi_rtk-1.0.21/fastapi_rtk/auth/hashers/utils.py +0 -122
  17. fastapi_rtk-1.0.21/fastapi_rtk/utils/flask_appbuilder_utils.py +0 -76
  18. fastapi_rtk-1.0.21/fastapi_rtk/utils/werkzeug.py +0 -91
  19. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/.gitignore +0 -0
  20. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/LICENSE +0 -0
  21. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/README.md +0 -0
  22. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/api/__init__.py +0 -0
  23. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/api/base_api.py +0 -0
  24. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/api/model_rest_api.py +0 -0
  25. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/apis.py +0 -0
  26. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/auth/__init__.py +0 -0
  27. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/auth/auth.py +0 -0
  28. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/auth/hashers/__init__.py +0 -0
  29. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/auth/password_helpers/__init__.py +0 -0
  30. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/auth/password_helpers/fab.py +0 -0
  31. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/auth/strategies/__init__.py +0 -0
  32. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/auth/strategies/config.py +0 -0
  33. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/auth/strategies/db.py +0 -0
  34. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/auth/strategies/jwt.py +0 -0
  35. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/backends/__init__.py +0 -0
  36. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/backends/generic/__init__.py +0 -0
  37. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/backends/generic/column.py +0 -0
  38. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/backends/generic/db.py +0 -0
  39. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/backends/generic/exceptions.py +0 -0
  40. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/backends/generic/filters.py +0 -0
  41. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/backends/generic/interface.py +0 -0
  42. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/backends/generic/model.py +0 -0
  43. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/backends/generic/session.py +0 -0
  44. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/backends/sqla/__init__.py +0 -0
  45. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/backends/sqla/column.py +0 -0
  46. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/backends/sqla/db.py +0 -0
  47. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/backends/sqla/exceptions.py +0 -0
  48. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/backends/sqla/extensions/__init__.py +0 -0
  49. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/backends/sqla/extensions/audit/__init__.py +0 -0
  50. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/backends/sqla/extensions/audit/audit.py +0 -0
  51. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/backends/sqla/extensions/audit/types.py +0 -0
  52. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/backends/sqla/extensions/geoalchemy2/__init__.py +0 -0
  53. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/backends/sqla/extensions/geoalchemy2/filters.py +0 -0
  54. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/backends/sqla/extensions/geoalchemy2/geometry_converter.py +0 -0
  55. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/backends/sqla/filters.py +0 -0
  56. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/backends/sqla/interface.py +0 -0
  57. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/backends/sqla/model.py +0 -0
  58. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/backends/sqla/session.py +0 -0
  59. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/bases/__init__.py +0 -0
  60. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/bases/db.py +0 -0
  61. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/bases/file_manager.py +0 -0
  62. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/bases/filter.py +0 -0
  63. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/bases/interface.py +0 -0
  64. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/bases/model.py +0 -0
  65. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/bases/session.py +0 -0
  66. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/cli/__init__.py +0 -0
  67. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/cli/cli.py +0 -0
  68. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/cli/commands/__init__.py +0 -0
  69. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/cli/commands/db/__init__.py +0 -0
  70. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/cli/commands/db/templates/fastapi/README +0 -0
  71. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/cli/commands/db/templates/fastapi/alembic.ini.mako +0 -0
  72. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/cli/commands/db/templates/fastapi/env.py +0 -0
  73. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/cli/commands/db/templates/fastapi/script.py.mako +0 -0
  74. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/README +0 -0
  75. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/alembic.ini.mako +0 -0
  76. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/env.py +0 -0
  77. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/script.py.mako +0 -0
  78. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/cli/commands/export.py +0 -0
  79. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/cli/commands/security.py +0 -0
  80. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/cli/commands/translate.py +0 -0
  81. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/cli/const.py +0 -0
  82. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/cli/decorators.py +0 -0
  83. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/cli/types.py +0 -0
  84. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/cli/utils.py +0 -0
  85. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/const.py +0 -0
  86. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/db.py +0 -0
  87. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/decorators.py +0 -0
  88. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/dependencies.py +0 -0
  89. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/exceptions.py +0 -0
  90. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/fastapi_react_toolkit.py +0 -0
  91. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/file_managers/__init__.py +0 -0
  92. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/file_managers/image_manager.py +0 -0
  93. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/file_managers/s3_file_manager.py +0 -0
  94. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/file_managers/s3_image_manager.py +0 -0
  95. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/filters.py +0 -0
  96. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/lang/__init__.py +0 -0
  97. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/lang/babel/__init__.py +0 -0
  98. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/lang/babel/cli.py +0 -0
  99. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/lang/babel/config.py +0 -0
  100. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/lang/babel.cfg +0 -0
  101. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/lang/lazy_text.py +0 -0
  102. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/lang/messages.pot +0 -0
  103. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/lang/translations/de/LC_MESSAGES/messages.mo +0 -0
  104. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/lang/translations/de/LC_MESSAGES/messages.po +0 -0
  105. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/lang/translations/en/LC_MESSAGES/messages.mo +0 -0
  106. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/lang/translations/en/LC_MESSAGES/messages.po +0 -0
  107. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/manager.py +0 -0
  108. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/middlewares.py +0 -0
  109. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/mixins.py +0 -0
  110. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/models.py +0 -0
  111. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/schemas.py +0 -0
  112. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/security/__init__.py +0 -0
  113. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/security/sqla/__init__.py +0 -0
  114. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/security/sqla/apis.py +0 -0
  115. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/security/sqla/security_manager.py +0 -0
  116. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/setting.py +0 -0
  117. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/types.py +0 -0
  118. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/utils/async_task_runner.py +0 -0
  119. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/utils/class_factory.py +0 -0
  120. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/utils/csv_json_converter.py +0 -0
  121. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/utils/deep_merge.py +0 -0
  122. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/utils/extender_mixin.py +0 -0
  123. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/utils/formatter.py +0 -0
  124. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/utils/hooks.py +0 -0
  125. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/utils/lazy.py +0 -0
  126. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/utils/merge_schema.py +0 -0
  127. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/utils/multiple_async_contexts.py +0 -0
  128. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/utils/pydantic.py +0 -0
  129. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/utils/run_utils.py +0 -0
  130. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/utils/self_dependencies.py +0 -0
  131. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/utils/smartdefaultdict.py +0 -0
  132. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/utils/sqla.py +0 -0
  133. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/utils/timezone.py +0 -0
  134. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/utils/update_signature.py +0 -0
  135. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/fastapi_rtk/utils/use_default_when_none.py +0 -0
  136. {fastapi_rtk-1.0.21 → fastapi_rtk-1.0.23}/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.21
3
+ Version: 1.0.23
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]>=14.0.1
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.23"
@@ -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
 
@@ -6,7 +6,9 @@ import os
6
6
  import types
7
7
  import typing as t
8
8
 
9
- from .utils import deep_merge, import_string
9
+ from werkzeug.utils import import_string
10
+
11
+ from .utils import deep_merge
10
12
 
11
13
  __all__ = ["Config"]
12
14
 
@@ -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, secure_filename, smart_run
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: typing.Optional[str] = None,
103
- redirect_url_factory: typing.Optional[
104
- typing.Callable[[Request, list[str]], str]
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(status_code=status.HTTP_400_BAD_REQUEST)
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: typing.Optional[str] = None,
275
- redirect_url_factory: typing.Optional[
276
- typing.Callable[[Request, list[str]], str]
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(status_code=status.HTTP_400_BAD_REQUEST)
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 schemas.model_validate(user_schema, user)
443
+ return user_schema.model_validate(user)
408
444
 
409
445
  return router
410
446
 
@@ -232,6 +232,10 @@ class User(Model):
232
232
  if hasattr(self, "verified"):
233
233
  self.verified = value
234
234
 
235
+ @property
236
+ def is_authenticated(self):
237
+ return self.is_active
238
+
235
239
  @property
236
240
  def is_superuser(self):
237
241
  from ...globals import g
@@ -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]>=14.0.1",
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" }