fastapi-rtk 1.0.0__tar.gz → 1.0.2__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 (132) hide show
  1. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/.gitignore +0 -4
  2. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/PKG-INFO +1 -1
  3. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/api/model_rest_api.py +101 -58
  4. fastapi_rtk-1.0.2/fastapi_rtk/lang/messages.pot +238 -0
  5. fastapi_rtk-1.0.2/fastapi_rtk/lang/translations/de/LC_MESSAGES/messages.mo +0 -0
  6. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/lang/translations/de/LC_MESSAGES/messages.po +12 -12
  7. fastapi_rtk-1.0.2/fastapi_rtk/lang/translations/en/LC_MESSAGES/messages.mo +0 -0
  8. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/lang/translations/en/LC_MESSAGES/messages.po +12 -12
  9. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/manager.py +2 -0
  10. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/LICENSE +0 -0
  11. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/README.md +0 -0
  12. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/__init__.py +0 -0
  13. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/api/__init__.py +0 -0
  14. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/api/base_api.py +0 -0
  15. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/apis.py +0 -0
  16. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/auth/__init__.py +0 -0
  17. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/auth/auth.py +0 -0
  18. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/auth/hashers/__init__.py +0 -0
  19. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/auth/hashers/pbkdf2.py +0 -0
  20. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/auth/hashers/scrypt.py +0 -0
  21. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/auth/hashers/utils.py +0 -0
  22. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/auth/password_helpers/__init__.py +0 -0
  23. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/auth/password_helpers/fab.py +0 -0
  24. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/auth/strategies/__init__.py +0 -0
  25. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/auth/strategies/config.py +0 -0
  26. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/auth/strategies/db.py +0 -0
  27. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/auth/strategies/jwt.py +0 -0
  28. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/backends/__init__.py +0 -0
  29. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/backends/generic/__init__.py +0 -0
  30. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/backends/generic/column.py +0 -0
  31. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/backends/generic/db.py +0 -0
  32. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/backends/generic/exceptions.py +0 -0
  33. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/backends/generic/filters.py +0 -0
  34. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/backends/generic/interface.py +0 -0
  35. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/backends/generic/model.py +0 -0
  36. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/backends/generic/session.py +0 -0
  37. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/backends/sqla/__init__.py +0 -0
  38. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/backends/sqla/column.py +0 -0
  39. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/backends/sqla/db.py +0 -0
  40. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/backends/sqla/exceptions.py +0 -0
  41. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/backends/sqla/extensions/__init__.py +0 -0
  42. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/backends/sqla/extensions/audit/__init__.py +0 -0
  43. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/backends/sqla/extensions/audit/audit.py +0 -0
  44. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/backends/sqla/extensions/audit/types.py +0 -0
  45. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/backends/sqla/extensions/geoalchemy2/__init__.py +0 -0
  46. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/backends/sqla/extensions/geoalchemy2/filters.py +0 -0
  47. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/backends/sqla/extensions/geoalchemy2/geometry_converter.py +0 -0
  48. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/backends/sqla/filters.py +0 -0
  49. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/backends/sqla/interface.py +0 -0
  50. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/backends/sqla/model.py +0 -0
  51. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/backends/sqla/session.py +0 -0
  52. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/bases/__init__.py +0 -0
  53. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/bases/db.py +0 -0
  54. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/bases/file_manager.py +0 -0
  55. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/bases/filter.py +0 -0
  56. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/bases/interface.py +0 -0
  57. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/bases/model.py +0 -0
  58. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/bases/session.py +0 -0
  59. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/cli/__init__.py +0 -0
  60. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/cli/cli.py +0 -0
  61. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/cli/commands/__init__.py +0 -0
  62. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/cli/commands/db/__init__.py +0 -0
  63. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/cli/commands/db/templates/fastapi/README +0 -0
  64. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/cli/commands/db/templates/fastapi/alembic.ini.mako +0 -0
  65. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/cli/commands/db/templates/fastapi/env.py +0 -0
  66. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/cli/commands/db/templates/fastapi/script.py.mako +0 -0
  67. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/README +0 -0
  68. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/alembic.ini.mako +0 -0
  69. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/env.py +0 -0
  70. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/script.py.mako +0 -0
  71. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/cli/commands/export.py +0 -0
  72. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/cli/commands/security.py +0 -0
  73. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/cli/commands/translate.py +0 -0
  74. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/cli/const.py +0 -0
  75. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/cli/decorators.py +0 -0
  76. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/cli/types.py +0 -0
  77. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/cli/utils.py +0 -0
  78. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/config.py +0 -0
  79. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/const.py +0 -0
  80. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/db.py +0 -0
  81. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/decorators.py +0 -0
  82. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/dependencies.py +0 -0
  83. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/exceptions.py +0 -0
  84. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/fastapi_react_toolkit.py +0 -0
  85. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/file_managers/__init__.py +0 -0
  86. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/file_managers/file_manager.py +0 -0
  87. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/file_managers/image_manager.py +0 -0
  88. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/file_managers/s3_file_manager.py +0 -0
  89. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/file_managers/s3_image_manager.py +0 -0
  90. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/filters.py +0 -0
  91. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/globals.py +0 -0
  92. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/lang/__init__.py +0 -0
  93. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/lang/babel/__init__.py +0 -0
  94. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/lang/babel/cli.py +0 -0
  95. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/lang/babel/config.py +0 -0
  96. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/lang/babel.cfg +0 -0
  97. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/lang/lazy_text.py +0 -0
  98. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/middlewares.py +0 -0
  99. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/mixins.py +0 -0
  100. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/models.py +0 -0
  101. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/routers.py +0 -0
  102. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/schemas.py +0 -0
  103. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/security/__init__.py +0 -0
  104. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/security/sqla/__init__.py +0 -0
  105. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/security/sqla/apis.py +0 -0
  106. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/security/sqla/models.py +0 -0
  107. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/security/sqla/security_manager.py +0 -0
  108. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/setting.py +0 -0
  109. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/types.py +0 -0
  110. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/utils/__init__.py +0 -0
  111. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/utils/async_task_runner.py +0 -0
  112. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/utils/class_factory.py +0 -0
  113. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/utils/csv_json_converter.py +0 -0
  114. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/utils/deep_merge.py +0 -0
  115. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/utils/extender_mixin.py +0 -0
  116. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/utils/flask_appbuilder_utils.py +0 -0
  117. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/utils/hooks.py +0 -0
  118. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/utils/lazy.py +0 -0
  119. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/utils/merge_schema.py +0 -0
  120. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/utils/multiple_async_contexts.py +0 -0
  121. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/utils/prettify_dict.py +0 -0
  122. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/utils/pydantic.py +0 -0
  123. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/utils/run_utils.py +0 -0
  124. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/utils/self_dependencies.py +0 -0
  125. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/utils/smartdefaultdict.py +0 -0
  126. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/utils/sqla.py +0 -0
  127. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/utils/timezone.py +0 -0
  128. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/utils/update_signature.py +0 -0
  129. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/utils/use_default_when_none.py +0 -0
  130. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/utils/werkzeug.py +0 -0
  131. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/fastapi_rtk/version.py +0 -0
  132. {fastapi_rtk-1.0.0 → fastapi_rtk-1.0.2}/pyproject.toml +0 -0
@@ -52,10 +52,6 @@ coverage.xml
52
52
  .pytest_cache/
53
53
  cover/
54
54
 
55
- # Translations
56
- *.mo
57
- *.pot
58
-
59
55
  # Django stuff:
60
56
  *.log
61
57
  local_settings.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi-rtk
3
- Version: 1.0.0
3
+ Version: 1.0.2
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
@@ -206,6 +206,19 @@ class ModelRestApi(BaseApi):
206
206
  """
207
207
  The list of routes to exclude from protection. Defaults to `[]`.
208
208
  """
209
+ expose_params: dict[AVAILABLE_ROUTES, dict[str, Any]] = lazy(lambda: dict())
210
+ """
211
+ Additional parameters to pass to the `expose` decorator for each route. See `expose` decorator for more information.
212
+
213
+ Example:
214
+ ```python
215
+ expose_params = {
216
+ 'image': {
217
+ 'description': 'Custom description for image endpoint',
218
+ },
219
+ }
220
+ ```
221
+ """
209
222
  base_order: Tuple[str, Literal["asc", "desc"]] | None = None
210
223
  """
211
224
  The default order for the list endpoint. Set this to set the default order for the list endpoint.
@@ -1040,12 +1053,15 @@ class ModelRestApi(BaseApi):
1040
1053
  expose(
1041
1054
  "/_image/{filename}",
1042
1055
  methods=["GET"],
1043
- name="Get Image",
1044
- description="Get an image from the application.",
1045
- response_class=FileResponse,
1046
- dependencies=[Depends(has_access_dependency(self, "image"))]
1047
- if "image" in self.protected_routes
1048
- else None,
1056
+ **{
1057
+ "name": "Get Image",
1058
+ "description": f"Get an image associated with an existing {self.datamodel.obj.__name__} item.",
1059
+ "response_class": FileResponse,
1060
+ "dependencies": [Depends(has_access_dependency(self, "image"))]
1061
+ if "image" in self.protected_routes
1062
+ else None,
1063
+ **self.expose_params.get("image", {}),
1064
+ },
1049
1065
  )(self.image_headless)
1050
1066
 
1051
1067
  def file(self):
@@ -1062,12 +1078,15 @@ class ModelRestApi(BaseApi):
1062
1078
  expose(
1063
1079
  "/_file/{filename}",
1064
1080
  methods=["GET"],
1065
- name="Get File",
1066
- description="Get a file from the application.",
1067
- response_class=FileResponse,
1068
- dependencies=[Depends(has_access_dependency(self, "file"))]
1069
- if "file" in self.protected_routes
1070
- else None,
1081
+ **{
1082
+ "name": "Get File",
1083
+ "description": f"Get a file associated with an existing {self.datamodel.obj.__name__} item.",
1084
+ "response_class": FileResponse,
1085
+ "dependencies": [Depends(has_access_dependency(self, "file"))]
1086
+ if "file" in self.protected_routes
1087
+ else None,
1088
+ **self.expose_params.get("file", {}),
1089
+ },
1071
1090
  )(self.file_headless)
1072
1091
 
1073
1092
  def info(self):
@@ -1079,12 +1098,15 @@ class ModelRestApi(BaseApi):
1079
1098
  expose(
1080
1099
  "/_info",
1081
1100
  methods=["GET"],
1082
- name="Get Info",
1083
- description="Get the info for this API's Model.",
1084
- response_model=self.info_return_schema | typing.Any,
1085
- dependencies=[Depends(has_access_dependency(self, "info"))]
1086
- if "info" in self.protected_routes
1087
- else None,
1101
+ **{
1102
+ "name": "Get Info",
1103
+ "description": f"Get metadata information about the model {self.datamodel.obj.__name__}. such as add/edit columns, filter options, titles, and JSONForms schemas.",
1104
+ "response_model": self.info_return_schema | typing.Any,
1105
+ "dependencies": [Depends(has_access_dependency(self, "info"))]
1106
+ if "info" in self.protected_routes
1107
+ else None,
1108
+ **self.expose_params.get("info", {}),
1109
+ },
1088
1110
  )(self.info_headless)
1089
1111
 
1090
1112
  def download(self):
@@ -1096,11 +1118,14 @@ class ModelRestApi(BaseApi):
1096
1118
  expose(
1097
1119
  "/download",
1098
1120
  methods=["GET"],
1099
- name="Download",
1100
- description="Download list of items in CSV format.",
1101
- dependencies=[Depends(has_access_dependency(self, "download"))]
1102
- if "download" in self.protected_routes
1103
- else None,
1121
+ **{
1122
+ "name": "Download",
1123
+ "description": f"Download list of {self.datamodel.obj.__name__} items as a CSV file with support for filtering, ordering, and global search.",
1124
+ "dependencies": [Depends(has_access_dependency(self, "download"))]
1125
+ if "download" in self.protected_routes
1126
+ else None,
1127
+ **self.expose_params.get("download", {}),
1128
+ },
1104
1129
  )(self.download_headless)
1105
1130
 
1106
1131
  #! Disabled until further notice
@@ -1127,11 +1152,14 @@ class ModelRestApi(BaseApi):
1127
1152
  expose(
1128
1153
  "/bulk/{handler}",
1129
1154
  methods=["POST"],
1130
- name="Bulk",
1131
- description="Handle bulk operations.",
1132
- dependencies=[Depends(has_access_dependency(self, "bulk"))]
1133
- if "bulk" in self.protected_routes
1134
- else None,
1155
+ **{
1156
+ "name": "Bulk",
1157
+ "description": f"Handle bulk operations for the model {self.datamodel.obj.__name__} that are set in the API.",
1158
+ "dependencies": [Depends(has_access_dependency(self, "bulk"))]
1159
+ if "bulk" in self.protected_routes
1160
+ else None,
1161
+ **self.expose_params.get("bulk", {}),
1162
+ },
1135
1163
  )(self.bulk_headless)
1136
1164
 
1137
1165
  def get_list(self):
@@ -1143,12 +1171,15 @@ class ModelRestApi(BaseApi):
1143
1171
  expose(
1144
1172
  "/",
1145
1173
  methods=["GET"],
1146
- name="Get items",
1147
- description="Get a list of items.",
1148
- response_model=self.list_return_schema | typing.Any,
1149
- dependencies=[Depends(has_access_dependency(self, "get"))]
1150
- if "get_list" in self.protected_routes
1151
- else None,
1174
+ **{
1175
+ "name": "Get items",
1176
+ "description": f"Get a list of {self.datamodel.obj.__name__} items with support for column selection, filtering, ordering, pagination, and global search.",
1177
+ "response_model": self.list_return_schema | typing.Any,
1178
+ "dependencies": [Depends(has_access_dependency(self, "get"))]
1179
+ if "get_list" in self.protected_routes
1180
+ else None,
1181
+ **self.expose_params.get("get_list", {}),
1182
+ },
1152
1183
  )(self.get_list_headless)
1153
1184
 
1154
1185
  def get(self):
@@ -1160,12 +1191,15 @@ class ModelRestApi(BaseApi):
1160
1191
  expose(
1161
1192
  "/{id}",
1162
1193
  methods=["GET"],
1163
- name="Get item",
1164
- description="Get a single item.",
1165
- response_model=self.show_return_schema | typing.Any,
1166
- dependencies=[Depends(has_access_dependency(self, "get"))]
1167
- if "get" in self.protected_routes
1168
- else None,
1194
+ **{
1195
+ "name": "Get item",
1196
+ "description": f"Get a single {self.datamodel.obj.__name__} item.",
1197
+ "response_model": self.show_return_schema | typing.Any,
1198
+ "dependencies": [Depends(has_access_dependency(self, "get"))]
1199
+ if "get" in self.protected_routes
1200
+ else None,
1201
+ **self.expose_params.get("get", {}),
1202
+ },
1169
1203
  )(self.get_headless)
1170
1204
 
1171
1205
  def post(self):
@@ -1177,12 +1211,15 @@ class ModelRestApi(BaseApi):
1177
1211
  expose(
1178
1212
  "/",
1179
1213
  methods=["POST"],
1180
- name="Add item",
1181
- description="Add a new item.",
1182
- response_model=self.add_return_schema | typing.Any,
1183
- dependencies=[Depends(has_access_dependency(self, "post"))]
1184
- if "post" in self.protected_routes
1185
- else None,
1214
+ **{
1215
+ "name": "Add item",
1216
+ "description": f"Add a new {self.datamodel.obj.__name__} item.",
1217
+ "response_model": self.add_return_schema | typing.Any,
1218
+ "dependencies": [Depends(has_access_dependency(self, "post"))]
1219
+ if "post" in self.protected_routes
1220
+ else None,
1221
+ **self.expose_params.get("post", {}),
1222
+ },
1186
1223
  )(self.post_headless)
1187
1224
 
1188
1225
  def put(self):
@@ -1194,12 +1231,15 @@ class ModelRestApi(BaseApi):
1194
1231
  expose(
1195
1232
  "/{id}",
1196
1233
  methods=["PUT"],
1197
- name="Update item",
1198
- description="Update an item.",
1199
- response_model=self.edit_return_schema | typing.Any,
1200
- dependencies=[Depends(has_access_dependency(self, "put"))]
1201
- if "put" in self.protected_routes
1202
- else None,
1234
+ **{
1235
+ "name": "Update item",
1236
+ "description": f"Update an existing {self.datamodel.obj.__name__} item.",
1237
+ "response_model": self.edit_return_schema | typing.Any,
1238
+ "dependencies": [Depends(has_access_dependency(self, "put"))]
1239
+ if "put" in self.protected_routes
1240
+ else None,
1241
+ **self.expose_params.get("put", {}),
1242
+ },
1203
1243
  )(self.put_headless)
1204
1244
 
1205
1245
  def delete(self):
@@ -1211,12 +1251,15 @@ class ModelRestApi(BaseApi):
1211
1251
  expose(
1212
1252
  "/{id}",
1213
1253
  methods=["DELETE"],
1214
- response_model=GeneralResponse | typing.Any,
1215
- name="Delete item",
1216
- description="Delete an item.",
1217
- dependencies=[Depends(has_access_dependency(self, "delete"))]
1218
- if "delete" in self.protected_routes
1219
- else None,
1254
+ **{
1255
+ "name": "Delete item",
1256
+ "description": f"Delete an existing {self.datamodel.obj.__name__} item.",
1257
+ "response_model": GeneralResponse | typing.Any,
1258
+ "dependencies": [Depends(has_access_dependency(self, "delete"))]
1259
+ if "delete" in self.protected_routes
1260
+ else None,
1261
+ **self.expose_params.get("delete", {}),
1262
+ },
1220
1263
  )(self.delete_headless)
1221
1264
 
1222
1265
  """
@@ -0,0 +1,238 @@
1
+ # Translations template for PROJECT.
2
+ # Copyright (C) 2025 ORGANIZATION
3
+ # This file is distributed under the same license as the PROJECT project.
4
+ # FIRST AUTHOR <EMAIL@ADDRESS>, 2025.
5
+ #
6
+ #, fuzzy
7
+ msgid ""
8
+ msgstr ""
9
+ "Project-Id-Version: PROJECT VERSION\n"
10
+ "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
11
+ "POT-Creation-Date: 2025-10-30 10:07+0100\n"
12
+ "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
+ "Language-Team: LANGUAGE <LL@li.org>\n"
15
+ "MIME-Version: 1.0\n"
16
+ "Content-Type: text/plain; charset=utf-8\n"
17
+ "Content-Transfer-Encoding: 8bit\n"
18
+ "Generated-By: Babel 2.17.0\n"
19
+
20
+ #: fastapi_rtk/schemas.py:419
21
+ msgid "Columns must be a list"
22
+ msgstr ""
23
+
24
+ #: fastapi_rtk/schemas.py:429
25
+ msgid "Invalid columns: Not a valid JSON string"
26
+ msgstr ""
27
+
28
+ #: fastapi_rtk/schemas.py:452
29
+ msgid "Both 'order_column' and 'order_direction' must be filled or empty"
30
+ msgstr ""
31
+
32
+ #: fastapi_rtk/schemas.py:470
33
+ msgid "Filters must be a list"
34
+ msgstr ""
35
+
36
+ #: fastapi_rtk/schemas.py:485
37
+ msgid "Filter must be an object"
38
+ msgstr ""
39
+
40
+ #: fastapi_rtk/schemas.py:495
41
+ msgid "Invalid filters: Not a valid JSON string"
42
+ msgstr ""
43
+
44
+ #: fastapi_rtk/schemas.py:520
45
+ msgid "Opr Filters must be a list"
46
+ msgstr ""
47
+
48
+ #: fastapi_rtk/schemas.py:535
49
+ msgid "Opr Filter must be an object"
50
+ msgstr ""
51
+
52
+ #: fastapi_rtk/schemas.py:545
53
+ msgid "Invalid opr_filters: Not a valid JSON string"
54
+ msgstr ""
55
+
56
+ #: fastapi_rtk/api/model_rest_api.py:476
57
+ #, python-brace-format
58
+ msgid "List {ModelName}"
59
+ msgstr ""
60
+
61
+ #: fastapi_rtk/api/model_rest_api.py:485
62
+ #, python-brace-format
63
+ msgid "Show {ModelName}"
64
+ msgstr ""
65
+
66
+ #: fastapi_rtk/api/model_rest_api.py:494
67
+ #, python-brace-format
68
+ msgid "Add {ModelName}"
69
+ msgstr ""
70
+
71
+ #: fastapi_rtk/api/model_rest_api.py:503
72
+ #, python-brace-format
73
+ msgid "Edit {ModelName}"
74
+ msgstr ""
75
+
76
+ #: fastapi_rtk/api/model_rest_api.py:1395
77
+ msgid "OK"
78
+ msgstr ""
79
+
80
+ #: fastapi_rtk/api/model_rest_api.py:2411
81
+ #: fastapi_rtk/api/model_rest_api.py:2810
82
+ #, python-brace-format
83
+ msgid "Number of items in '{column}' does not match the number of items found."
84
+ msgstr ""
85
+
86
+ #: fastapi_rtk/api/model_rest_api.py:2432
87
+ #, python-brace-format
88
+ msgid "Could not find related item for column '{column}'"
89
+ msgstr ""
90
+
91
+ #: fastapi_rtk/api/model_rest_api.py:2464
92
+ #, python-brace-format
93
+ msgid "File type from '{filename}' is not allowed."
94
+ msgstr ""
95
+
96
+ #: fastapi_rtk/api/model_rest_api.py:2872
97
+ #, python-brace-format
98
+ msgid "Invalid column: {column}"
99
+ msgstr ""
100
+
101
+ #: fastapi_rtk/api/model_rest_api.py:2882
102
+ #, python-brace-format
103
+ msgid "Invalid filter: {column}"
104
+ msgstr ""
105
+
106
+ #: fastapi_rtk/backends/generic/db.py:66 fastapi_rtk/backends/sqla/db.py:163
107
+ #, python-brace-format
108
+ msgid "Invalid filter operator: {operator}"
109
+ msgstr ""
110
+
111
+ #: fastapi_rtk/backends/generic/db.py:90 fastapi_rtk/backends/sqla/db.py:194
112
+ #, python-brace-format
113
+ msgid "Invalid opr_filter operator: {operator}"
114
+ msgstr ""
115
+
116
+ #: fastapi_rtk/backends/generic/filters.py:81
117
+ #: fastapi_rtk/backends/sqla/filters.py:243
118
+ msgid "Text contains"
119
+ msgstr ""
120
+
121
+ #: fastapi_rtk/backends/generic/filters.py:89
122
+ #: fastapi_rtk/backends/sqla/filters.py:259
123
+ msgid "Equal to"
124
+ msgstr ""
125
+
126
+ #: fastapi_rtk/backends/generic/filters.py:117
127
+ #: fastapi_rtk/backends/sqla/filters.py:277
128
+ msgid "Starts with"
129
+ msgstr ""
130
+
131
+ #: fastapi_rtk/backends/generic/filters.py:126
132
+ #: fastapi_rtk/backends/sqla/filters.py:286
133
+ msgid "Not Starts with"
134
+ msgstr ""
135
+
136
+ #: fastapi_rtk/backends/generic/filters.py:135
137
+ #: fastapi_rtk/backends/sqla/filters.py:295
138
+ msgid "Ends with"
139
+ msgstr ""
140
+
141
+ #: fastapi_rtk/backends/generic/filters.py:144
142
+ #: fastapi_rtk/backends/sqla/filters.py:304
143
+ msgid "Not Ends with"
144
+ msgstr ""
145
+
146
+ #: fastapi_rtk/backends/generic/filters.py:153
147
+ #: fastapi_rtk/backends/sqla/filters.py:313
148
+ msgid "Contains"
149
+ msgstr ""
150
+
151
+ #: fastapi_rtk/backends/generic/filters.py:162
152
+ msgid "Contains (insensitive)"
153
+ msgstr ""
154
+
155
+ #: fastapi_rtk/backends/generic/filters.py:171
156
+ #: fastapi_rtk/backends/sqla/filters.py:322
157
+ msgid "Not Contains"
158
+ msgstr ""
159
+
160
+ #: fastapi_rtk/backends/generic/filters.py:180
161
+ #: fastapi_rtk/backends/sqla/filters.py:331
162
+ msgid "Greater than"
163
+ msgstr ""
164
+
165
+ #: fastapi_rtk/backends/generic/filters.py:189
166
+ #: fastapi_rtk/backends/sqla/filters.py:340
167
+ msgid "Smaller than"
168
+ msgstr ""
169
+
170
+ #: fastapi_rtk/backends/generic/filters.py:198
171
+ #: fastapi_rtk/backends/sqla/filters.py:349
172
+ msgid "Greater equal"
173
+ msgstr ""
174
+
175
+ #: fastapi_rtk/backends/generic/filters.py:207
176
+ #: fastapi_rtk/backends/sqla/filters.py:358
177
+ msgid "Smaller equal"
178
+ msgstr ""
179
+
180
+ #: fastapi_rtk/backends/generic/filters.py:216
181
+ #: fastapi_rtk/backends/sqla/filters.py:367
182
+ msgid "One of"
183
+ msgstr ""
184
+
185
+ #: fastapi_rtk/backends/generic/filters.py:225
186
+ #: fastapi_rtk/backends/sqla/filters.py:470
187
+ msgid "Global Filter"
188
+ msgstr ""
189
+
190
+ #: fastapi_rtk/backends/sqla/filters.py:268
191
+ msgid "Not equal to"
192
+ msgstr ""
193
+
194
+ #: fastapi_rtk/backends/sqla/filters.py:376
195
+ msgid "Between"
196
+ msgstr ""
197
+
198
+ #: fastapi_rtk/backends/sqla/filters.py:389
199
+ msgid "Between filter requires 2 values"
200
+ msgstr ""
201
+
202
+ #: fastapi_rtk/backends/sqla/filters.py:434
203
+ msgid "In"
204
+ msgstr ""
205
+
206
+ #: fastapi_rtk/backends/sqla/filters.py:452
207
+ msgid "Not In"
208
+ msgstr ""
209
+
210
+ #: fastapi_rtk/backends/sqla/extensions/geoalchemy2/filters.py:83
211
+ msgid "Intersects"
212
+ msgstr ""
213
+
214
+ #: fastapi_rtk/backends/sqla/extensions/geoalchemy2/filters.py:93
215
+ msgid "Not Intersects"
216
+ msgstr ""
217
+
218
+ #: fastapi_rtk/backends/sqla/extensions/geoalchemy2/filters.py:103
219
+ msgid "Overlaps"
220
+ msgstr ""
221
+
222
+ #: fastapi_rtk/backends/sqla/extensions/geoalchemy2/filters.py:113
223
+ msgid "Not Overlaps"
224
+ msgstr ""
225
+
226
+ #: fastapi_rtk/bases/db.py:463
227
+ #, python-brace-format
228
+ msgid "Invalid ID: {id}, expected {count} values"
229
+ msgstr ""
230
+
231
+ #: fastapi_rtk/bases/db.py:476
232
+ msgid "Invalid ID"
233
+ msgstr ""
234
+
235
+ #: fastapi_rtk/security/sqla/apis.py:299
236
+ msgid "User updated successfully."
237
+ msgstr ""
238
+
@@ -7,7 +7,7 @@ msgid ""
7
7
  msgstr ""
8
8
  "Project-Id-Version: PROJECT VERSION\n"
9
9
  "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
10
- "POT-Creation-Date: 2025-10-16 13:49+0200\n"
10
+ "POT-Creation-Date: 2025-10-30 10:07+0100\n"
11
11
  "PO-Revision-Date: 2025-07-16 18:01+0200\n"
12
12
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
13
  "Language: de\n"
@@ -61,54 +61,54 @@ msgstr "Opr Filter muss ein Objekt sein"
61
61
  msgid "Invalid opr_filters: Not a valid JSON string"
62
62
  msgstr "Ungültige opr_filters: Kein gültiger JSON-String"
63
63
 
64
- #: fastapi_rtk/api/model_rest_api.py:461
64
+ #: fastapi_rtk/api/model_rest_api.py:476
65
65
  #, python-brace-format
66
66
  msgid "List {ModelName}"
67
67
  msgstr "Liste von {ModelName}"
68
68
 
69
- #: fastapi_rtk/api/model_rest_api.py:470
69
+ #: fastapi_rtk/api/model_rest_api.py:485
70
70
  #, python-brace-format
71
71
  msgid "Show {ModelName}"
72
72
  msgstr "Anzeigen von {ModelName}"
73
73
 
74
- #: fastapi_rtk/api/model_rest_api.py:479
74
+ #: fastapi_rtk/api/model_rest_api.py:494
75
75
  #, python-brace-format
76
76
  msgid "Add {ModelName}"
77
77
  msgstr "Hinzufügen von {ModelName}"
78
78
 
79
- #: fastapi_rtk/api/model_rest_api.py:488
79
+ #: fastapi_rtk/api/model_rest_api.py:503
80
80
  #, python-brace-format
81
81
  msgid "Edit {ModelName}"
82
82
  msgstr "Bearbeiten von {ModelName}"
83
83
 
84
- #: fastapi_rtk/api/model_rest_api.py:1338
84
+ #: fastapi_rtk/api/model_rest_api.py:1395
85
85
  msgid "OK"
86
86
  msgstr "OK"
87
87
 
88
- #: fastapi_rtk/api/model_rest_api.py:2354
89
- #: fastapi_rtk/api/model_rest_api.py:2753
88
+ #: fastapi_rtk/api/model_rest_api.py:2411
89
+ #: fastapi_rtk/api/model_rest_api.py:2810
90
90
  #, python-brace-format
91
91
  msgid "Number of items in '{column}' does not match the number of items found."
92
92
  msgstr ""
93
93
  "Anzahl der Elemente in '{column}' stimmt nicht mit der Anzahl der "
94
94
  "gefundenen Elemente überein."
95
95
 
96
- #: fastapi_rtk/api/model_rest_api.py:2375
96
+ #: fastapi_rtk/api/model_rest_api.py:2432
97
97
  #, python-brace-format
98
98
  msgid "Could not find related item for column '{column}'"
99
99
  msgstr "Konnte kein zugehöriges Element für die Spalte '{column}' finden"
100
100
 
101
- #: fastapi_rtk/api/model_rest_api.py:2407
101
+ #: fastapi_rtk/api/model_rest_api.py:2464
102
102
  #, python-brace-format
103
103
  msgid "File type from '{filename}' is not allowed."
104
104
  msgstr "Dateityp von '{filename}' ist nicht erlaubt."
105
105
 
106
- #: fastapi_rtk/api/model_rest_api.py:2815
106
+ #: fastapi_rtk/api/model_rest_api.py:2872
107
107
  #, fuzzy, python-brace-format
108
108
  msgid "Invalid column: {column}"
109
109
  msgstr "Ungültige Spalte: {column}"
110
110
 
111
- #: fastapi_rtk/api/model_rest_api.py:2825
111
+ #: fastapi_rtk/api/model_rest_api.py:2882
112
112
  #, python-brace-format
113
113
  msgid "Invalid filter: {column}"
114
114
  msgstr "Ungültiger Filter: {column}"
@@ -7,7 +7,7 @@ msgid ""
7
7
  msgstr ""
8
8
  "Project-Id-Version: PROJECT VERSION\n"
9
9
  "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
10
- "POT-Creation-Date: 2025-10-16 13:49+0200\n"
10
+ "POT-Creation-Date: 2025-10-30 10:07+0100\n"
11
11
  "PO-Revision-Date: 2025-07-16 18:01+0200\n"
12
12
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
13
  "Language: en\n"
@@ -59,52 +59,52 @@ msgstr "Opr Filter must be an object"
59
59
  msgid "Invalid opr_filters: Not a valid JSON string"
60
60
  msgstr "Invalid opr_filters: Not a valid JSON string"
61
61
 
62
- #: fastapi_rtk/api/model_rest_api.py:461
62
+ #: fastapi_rtk/api/model_rest_api.py:476
63
63
  #, python-brace-format
64
64
  msgid "List {ModelName}"
65
65
  msgstr "List of {ModelName}"
66
66
 
67
- #: fastapi_rtk/api/model_rest_api.py:470
67
+ #: fastapi_rtk/api/model_rest_api.py:485
68
68
  #, python-brace-format
69
69
  msgid "Show {ModelName}"
70
70
  msgstr "Show {ModelName}"
71
71
 
72
- #: fastapi_rtk/api/model_rest_api.py:479
72
+ #: fastapi_rtk/api/model_rest_api.py:494
73
73
  #, python-brace-format
74
74
  msgid "Add {ModelName}"
75
75
  msgstr "Add {ModelName}"
76
76
 
77
- #: fastapi_rtk/api/model_rest_api.py:488
77
+ #: fastapi_rtk/api/model_rest_api.py:503
78
78
  #, python-brace-format
79
79
  msgid "Edit {ModelName}"
80
80
  msgstr "Edit {ModelName}"
81
81
 
82
- #: fastapi_rtk/api/model_rest_api.py:1338
82
+ #: fastapi_rtk/api/model_rest_api.py:1395
83
83
  msgid "OK"
84
84
  msgstr "OK"
85
85
 
86
- #: fastapi_rtk/api/model_rest_api.py:2354
87
- #: fastapi_rtk/api/model_rest_api.py:2753
86
+ #: fastapi_rtk/api/model_rest_api.py:2411
87
+ #: fastapi_rtk/api/model_rest_api.py:2810
88
88
  #, python-brace-format
89
89
  msgid "Number of items in '{column}' does not match the number of items found."
90
90
  msgstr "Number of items in '{column}' does not match the number of items found."
91
91
 
92
- #: fastapi_rtk/api/model_rest_api.py:2375
92
+ #: fastapi_rtk/api/model_rest_api.py:2432
93
93
  #, python-brace-format
94
94
  msgid "Could not find related item for column '{column}'"
95
95
  msgstr "Could not find related item for column '{column}'"
96
96
 
97
- #: fastapi_rtk/api/model_rest_api.py:2407
97
+ #: fastapi_rtk/api/model_rest_api.py:2464
98
98
  #, python-brace-format
99
99
  msgid "File type from '{filename}' is not allowed."
100
100
  msgstr "File type from '{filename}' is not allowed."
101
101
 
102
- #: fastapi_rtk/api/model_rest_api.py:2815
102
+ #: fastapi_rtk/api/model_rest_api.py:2872
103
103
  #, fuzzy, python-brace-format
104
104
  msgid "Invalid column: {column}"
105
105
  msgstr "Invalid column: {column}"
106
106
 
107
- #: fastapi_rtk/api/model_rest_api.py:2825
107
+ #: fastapi_rtk/api/model_rest_api.py:2882
108
108
  #, python-brace-format
109
109
  msgid "Invalid filter: {column}"
110
110
  msgstr "Invalid filter: {column}"
@@ -500,6 +500,7 @@ class UserManager(IDParser, BaseUserManager[User, int]):
500
500
  # Associate account
501
501
  user = await self.get_by_email(account_email)
502
502
  if not associate_by_email:
503
+ await self.on_after_authenticate(user, False)
503
504
  raise exceptions.UserAlreadyExists()
504
505
  user = await self.user_db.add_oauth_account(user, oauth_account_dict)
505
506
  except exceptions.UserNotExists:
@@ -557,6 +558,7 @@ class UserManager(IDParser, BaseUserManager[User, int]):
557
558
  user = await self._handle_role_keys(
558
559
  user, oauth_callback_params["user_dict"].pop("role_keys", None)
559
560
  )
561
+ await self.on_after_authenticate(user)
560
562
  return user
561
563
 
562
564
  @overload
File without changes
File without changes
File without changes