fastapi-rtk 2.1.2__tar.gz → 2.1.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.
Files changed (297) hide show
  1. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/PKG-INFO +1 -1
  2. fastapi_rtk-2.1.4/fastapi_rtk/_version.py +1 -0
  3. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/api/base_api.py +20 -12
  4. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/api/model_rest_api/__init__.py +18 -12
  5. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/api/model_rest_api/_columns.py +3 -1
  6. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/api/model_rest_api/_info_mixin.py +2 -6
  7. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/auth/strategies/db.py +1 -3
  8. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/backends/sqla/db.py +6 -3
  9. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/backends/sqla/extensions/audit/_decorators_mixin.py +2 -6
  10. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/backends/sqla/extensions/audit/_processing_mixin.py +2 -6
  11. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/bases/interface.py +8 -10
  12. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/cli/commands/security.py +14 -11
  13. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/db.py +9 -19
  14. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/decorators.py +3 -1
  15. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/manager.py +3 -1
  16. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/schemas.py +6 -2
  17. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/security/sqla/apis.py +1 -0
  18. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/security/sqla/security_manager/_user_mixin.py +3 -1
  19. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/conftest.py +0 -1
  20. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/integration/api/test_model_rest_api.py +27 -6
  21. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/integration/apis/test_info_contract.py +1 -3
  22. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/integration/auth/test_oauth.py +17 -25
  23. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/integration/conftest.py +0 -1
  24. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/integration/file_managers/test_file_routes.py +4 -12
  25. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/api/conftest.py +0 -1
  26. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/api/model_rest_api/test_columns.py +3 -9
  27. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/api/model_rest_api/test_file_mixin.py +0 -2
  28. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/api/model_rest_api/test_init.py +24 -10
  29. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/api/test_base_api.py +24 -3
  30. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/auth/password_helpers/test_fab.py +1 -2
  31. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/auth/strategies/test_config.py +2 -3
  32. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/auth/strategies/test_db.py +1 -2
  33. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/auth/strategies/test_jwt.py +2 -5
  34. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/auth/test_auth.py +9 -9
  35. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/backends/generic/test_column.py +0 -1
  36. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/backends/generic/test_db.py +2 -7
  37. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/backends/generic/test_filters.py +0 -1
  38. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/backends/generic/test_interface.py +1 -2
  39. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/backends/generic/test_model.py +3 -2
  40. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/backends/generic/test_session.py +2 -7
  41. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/backends/sqla/conftest.py +1 -2
  42. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/backends/sqla/test_audit.py +2 -7
  43. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/backends/sqla/test_column.py +5 -6
  44. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/backends/sqla/test_db.py +11 -26
  45. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/backends/sqla/test_filters.py +1 -3
  46. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/backends/sqla/test_geoalchemy2.py +49 -39
  47. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/backends/sqla/test_interface.py +1 -2
  48. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/backends/sqla/test_model.py +2 -5
  49. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/backends/sqla/test_session.py +4 -5
  50. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/bases/test_db.py +0 -1
  51. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/bases/test_file_manager.py +0 -1
  52. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/bases/test_filter.py +0 -1
  53. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/bases/test_interface.py +0 -2
  54. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/bases/test_model.py +0 -1
  55. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/cli/commands/conftest.py +0 -1
  56. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/cli/commands/test_export.py +1 -6
  57. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/cli/commands/test_security.py +21 -39
  58. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/cli/commands/test_security_crypto.py +0 -1
  59. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/cli/conftest.py +0 -1
  60. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/cli/test_cli.py +1 -2
  61. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/cli/test_decorators.py +0 -1
  62. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/cli/test_utils.py +0 -1
  63. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/file_managers/conftest.py +0 -1
  64. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/file_managers/test_file_manager.py +0 -1
  65. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/file_managers/test_image_manager.py +0 -1
  66. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/file_managers/test_s3_file_manager.py +0 -1
  67. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/lang/test_babel_cli.py +0 -1
  68. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/lang/test_babel_config.py +0 -1
  69. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/lang/test_lazy_text.py +0 -1
  70. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/security/sqla/conftest.py +1 -2
  71. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/security/sqla/test_apis.py +10 -4
  72. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/security/sqla/test_models.py +1 -4
  73. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/security/sqla/test_security_manager.py +1 -5
  74. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/test_config.py +0 -1
  75. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/test_const.py +0 -1
  76. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/test_db.py +9 -21
  77. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/test_decorators.py +11 -12
  78. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/test_dependencies.py +2 -5
  79. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/test_exceptions.py +0 -1
  80. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/test_globals.py +0 -1
  81. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/test_manager.py +3 -4
  82. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/test_middlewares.py +1 -4
  83. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/test_registry.py +0 -1
  84. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/test_routers.py +29 -34
  85. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/test_schemas.py +2 -4
  86. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/test_setting.py +0 -1
  87. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/test_types.py +3 -2
  88. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/utils/test_extender_mixin.py +0 -1
  89. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/utils/test_flask_appbuilder_utils.py +0 -1
  90. fastapi_rtk-2.1.2/fastapi_rtk/_version.py +0 -1
  91. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/.gitignore +0 -0
  92. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/LICENSE +0 -0
  93. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/README.md +0 -0
  94. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/__init__.py +0 -0
  95. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/api/__init__.py +0 -0
  96. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/api/model_rest_api/_add_mixin.py +0 -0
  97. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/api/model_rest_api/_bulk_mixin.py +0 -0
  98. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/api/model_rest_api/_delete_mixin.py +0 -0
  99. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/api/model_rest_api/_download_mixin.py +0 -0
  100. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/api/model_rest_api/_edit_mixin.py +0 -0
  101. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/api/model_rest_api/_file_mixin.py +0 -0
  102. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/api/model_rest_api/_list_mixin.py +0 -0
  103. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/api/model_rest_api/_params.py +0 -0
  104. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/api/model_rest_api/_show_mixin.py +0 -0
  105. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/api/model_rest_api/_upload_mixin.py +0 -0
  106. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/apis/__init__.py +0 -0
  107. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/apis/info.py +0 -0
  108. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/apis/license.py +0 -0
  109. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/auth/__init__.py +0 -0
  110. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/auth/auth.py +0 -0
  111. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/auth/hashers/__init__.py +0 -0
  112. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/auth/hashers/pbkdf2.py +0 -0
  113. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/auth/hashers/scrypt.py +0 -0
  114. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/auth/ldap.py +0 -0
  115. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/auth/password_helpers/__init__.py +0 -0
  116. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/auth/password_helpers/fab.py +0 -0
  117. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/auth/strategies/__init__.py +0 -0
  118. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/auth/strategies/config.py +0 -0
  119. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/auth/strategies/jwt.py +0 -0
  120. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/backends/__init__.py +0 -0
  121. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/backends/generic/__init__.py +0 -0
  122. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/backends/generic/column.py +0 -0
  123. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/backends/generic/db.py +0 -0
  124. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/backends/generic/exceptions.py +0 -0
  125. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/backends/generic/filters.py +0 -0
  126. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/backends/generic/interface.py +0 -0
  127. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/backends/generic/model.py +0 -0
  128. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/backends/generic/session.py +0 -0
  129. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/backends/sqla/__init__.py +0 -0
  130. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/backends/sqla/column.py +0 -0
  131. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/backends/sqla/exceptions.py +0 -0
  132. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/backends/sqla/extensions/__init__.py +0 -0
  133. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/backends/sqla/extensions/audit/__init__.py +0 -0
  134. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/backends/sqla/extensions/audit/_lifecycle_mixin.py +0 -0
  135. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/backends/sqla/extensions/audit/_logger.py +0 -0
  136. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/backends/sqla/extensions/audit/audit.py +0 -0
  137. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/backends/sqla/extensions/audit/types.py +0 -0
  138. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/backends/sqla/extensions/geoalchemy2/__init__.py +0 -0
  139. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/backends/sqla/extensions/geoalchemy2/filters.py +0 -0
  140. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/backends/sqla/extensions/geoalchemy2/geometry_converter.py +0 -0
  141. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/backends/sqla/filters.py +0 -0
  142. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/backends/sqla/interface.py +0 -0
  143. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/backends/sqla/model.py +0 -0
  144. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/backends/sqla/session.py +0 -0
  145. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/bases/__init__.py +0 -0
  146. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/bases/db.py +0 -0
  147. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/bases/file_manager.py +0 -0
  148. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/bases/filter.py +0 -0
  149. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/bases/model.py +0 -0
  150. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/bases/session.py +0 -0
  151. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/cli/__init__.py +0 -0
  152. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/cli/cli.py +0 -0
  153. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/cli/commands/__init__.py +0 -0
  154. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/cli/commands/_security_crypto.py +0 -0
  155. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/cli/commands/db/__init__.py +0 -0
  156. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/cli/commands/db/templates/fastapi/README +0 -0
  157. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/cli/commands/db/templates/fastapi/alembic.ini.mako +0 -0
  158. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/cli/commands/db/templates/fastapi/env.py +0 -0
  159. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/cli/commands/db/templates/fastapi/script.py.mako +0 -0
  160. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/README +0 -0
  161. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/alembic.ini.mako +0 -0
  162. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/env.py +0 -0
  163. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/script.py.mako +0 -0
  164. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/cli/commands/export.py +0 -0
  165. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/cli/commands/translate.py +0 -0
  166. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/cli/const.py +0 -0
  167. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/cli/decorators.py +0 -0
  168. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/cli/types.py +0 -0
  169. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/cli/utils.py +0 -0
  170. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/config.py +0 -0
  171. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/const.py +0 -0
  172. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/dependencies.py +0 -0
  173. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/exceptions.py +0 -0
  174. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/fastapi_react_toolkit.py +0 -0
  175. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/file_managers/__init__.py +0 -0
  176. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/file_managers/file_manager.py +0 -0
  177. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/file_managers/image_manager.py +0 -0
  178. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/file_managers/s3_file_manager.py +0 -0
  179. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/file_managers/s3_image_manager.py +0 -0
  180. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/filters.py +0 -0
  181. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/globals.py +0 -0
  182. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/lang/__init__.py +0 -0
  183. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/lang/babel/__init__.py +0 -0
  184. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/lang/babel/cli.py +0 -0
  185. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/lang/babel/config.py +0 -0
  186. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/lang/babel.cfg +0 -0
  187. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/lang/lazy_text.py +0 -0
  188. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/lang/messages.pot +0 -0
  189. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/lang/translations/de/LC_MESSAGES/messages.mo +0 -0
  190. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/lang/translations/de/LC_MESSAGES/messages.po +0 -0
  191. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/lang/translations/en/LC_MESSAGES/messages.mo +0 -0
  192. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/lang/translations/en/LC_MESSAGES/messages.po +0 -0
  193. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/middlewares.py +0 -0
  194. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/mixins.py +0 -0
  195. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/models.py +0 -0
  196. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/py.typed +0 -0
  197. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/registry.py +0 -0
  198. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/routers.py +0 -0
  199. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/security/__init__.py +0 -0
  200. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/security/sqla/__init__.py +0 -0
  201. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/security/sqla/models.py +0 -0
  202. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/security/sqla/security_manager/__init__.py +0 -0
  203. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/security/sqla/security_manager/_association_mixin.py +0 -0
  204. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/security/sqla/security_manager/_builtin_role_mixin.py +0 -0
  205. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/security/sqla/security_manager/_cleanup_mixin.py +0 -0
  206. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/security/sqla/security_manager/_exception_filters.py +0 -0
  207. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/security/sqla/security_manager/_export.py +0 -0
  208. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/security/sqla/security_manager/_import.py +0 -0
  209. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/security/sqla/security_manager/_role_mixin.py +0 -0
  210. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/setting.py +0 -0
  211. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/types.py +0 -0
  212. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/utils/__init__.py +0 -0
  213. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/utils/async_task_runner.py +0 -0
  214. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/utils/class_factory.py +0 -0
  215. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/utils/csv_json_converter.py +0 -0
  216. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/utils/deep_merge.py +0 -0
  217. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/utils/extender_mixin.py +0 -0
  218. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/utils/flask_appbuilder_utils.py +0 -0
  219. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/utils/formatter.py +0 -0
  220. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/utils/hooks.py +0 -0
  221. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/utils/lazy.py +0 -0
  222. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/utils/merge_schema.py +0 -0
  223. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/utils/multiple_async_contexts.py +0 -0
  224. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/utils/pydantic.py +0 -0
  225. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/utils/run_utils.py +0 -0
  226. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/utils/self_dependencies.py +0 -0
  227. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/utils/smartdefaultdict.py +0 -0
  228. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/utils/sqla.py +0 -0
  229. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/utils/timezone.py +0 -0
  230. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/utils/update_signature.py +0 -0
  231. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/utils/use_default_when_none.py +0 -0
  232. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/fastapi_rtk/version.py +0 -0
  233. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/pyproject.toml +0 -0
  234. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/docker-compose.gis.yml +0 -0
  235. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/integration/__init__.py +0 -0
  236. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/integration/api/__init__.py +0 -0
  237. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/integration/apis/__init__.py +0 -0
  238. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/integration/auth/__init__.py +0 -0
  239. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/integration/auth/test_auth_flow.py +0 -0
  240. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/integration/file_managers/__init__.py +0 -0
  241. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/integration/security/__init__.py +0 -0
  242. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/integration/security/sqla/__init__.py +0 -0
  243. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/integration/security/sqla/test_security_manager.py +1 -1
  244. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/integration/test_app_smoke.py +0 -0
  245. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/__init__.py +0 -0
  246. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/api/__init__.py +0 -0
  247. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/api/model_rest_api/__init__.py +0 -0
  248. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/apis/__init__.py +0 -0
  249. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/apis/test_info.py +0 -0
  250. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/apis/test_license.py +0 -0
  251. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/auth/__init__.py +0 -0
  252. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/auth/hashers/__init__.py +0 -0
  253. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/auth/hashers/test_pbkdf2.py +0 -0
  254. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/auth/hashers/test_scrypt.py +0 -0
  255. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/auth/password_helpers/__init__.py +0 -0
  256. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/auth/strategies/__init__.py +0 -0
  257. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/backends/__init__.py +0 -0
  258. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/backends/generic/__init__.py +0 -0
  259. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/backends/generic/test_exceptions.py +0 -0
  260. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/backends/sqla/__init__.py +0 -0
  261. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/backends/sqla/test_audit_types.py +0 -0
  262. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/bases/__init__.py +0 -0
  263. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/bases/test_session.py +0 -0
  264. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/cli/__init__.py +0 -0
  265. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/cli/commands/__init__.py +0 -0
  266. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/cli/commands/test_db.py +0 -0
  267. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/cli/commands/test_translate.py +0 -0
  268. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/cli/test_types.py +0 -0
  269. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/file_managers/__init__.py +0 -0
  270. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/file_managers/test_s3_image_manager.py +0 -0
  271. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/lang/__init__.py +0 -0
  272. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/security/__init__.py +0 -0
  273. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/security/sqla/__init__.py +0 -0
  274. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/test_fastapi_react_toolkit.py +0 -0
  275. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/test_filters.py +0 -0
  276. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/test_mixins.py +0 -0
  277. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/test_models.py +0 -0
  278. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/test_version.py +0 -0
  279. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/utils/__init__.py +0 -0
  280. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/utils/test_async_task_runner.py +0 -0
  281. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/utils/test_class_factory.py +0 -0
  282. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/utils/test_csv_json_converter.py +0 -0
  283. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/utils/test_deep_merge.py +0 -0
  284. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/utils/test_formatter.py +0 -0
  285. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/utils/test_hooks.py +0 -0
  286. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/utils/test_lazy.py +0 -0
  287. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/utils/test_merge_schema.py +0 -0
  288. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/utils/test_multiple_async_contexts.py +0 -0
  289. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/utils/test_pydantic.py +0 -0
  290. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/utils/test_run_utils.py +0 -0
  291. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/utils/test_self_dependencies.py +0 -0
  292. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/utils/test_smartdefaultdict.py +0 -0
  293. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/utils/test_sqla.py +0 -0
  294. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/utils/test_timezone.py +0 -0
  295. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/utils/test_update_signature.py +0 -0
  296. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/tests/unit/utils/test_use_default_when_none.py +0 -0
  297. {fastapi_rtk-2.1.2 → fastapi_rtk-2.1.4}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi-rtk
3
- Version: 2.1.2
3
+ Version: 2.1.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.1.4"
@@ -201,24 +201,27 @@ class BaseApi:
201
201
  self, metadata["response_model_str"]
202
202
  )
203
203
 
204
- extra_dependencies = []
205
- if metadata.get("dependencies"):
206
- extra_dependencies = metadata["dependencies"]
207
- if extra_dependencies and not data.get("dependencies"):
208
- data["dependencies"] = []
209
- for dep in extra_dependencies:
204
+ resolved_dependencies = []
205
+ for dep in metadata.get("dependencies") or []:
210
206
  func, kwargs = dep
211
207
  if kwargs:
208
+ # Resolve into a fresh dict; the source kwargs live in
209
+ # the shared registry and must stay un-mutated so other
210
+ # instances of the same Api class can resolve them too.
211
+ resolved_kwargs = {}
212
212
  for key, val in kwargs.items():
213
213
  if val == ":self":
214
- kwargs[key] = self
215
- elif val.startswith(":f"):
214
+ resolved_kwargs[key] = self
215
+ elif isinstance(val, str) and val.startswith(":f"):
216
216
  prop = val.split(".")[1]
217
- kwargs[key] = metadata[prop]
218
- func = Depends(func(**kwargs))
217
+ resolved_kwargs[key] = metadata[prop]
218
+ else:
219
+ resolved_kwargs[key] = val
220
+ resolved_dependencies.append(
221
+ Depends(func(**resolved_kwargs))
222
+ )
219
223
  else:
220
- func = Depends(func)
221
- data["dependencies"].append(func)
224
+ resolved_dependencies.append(Depends(func))
222
225
 
223
226
  path, methods, rest_data = (
224
227
  data["path"],
@@ -226,6 +229,11 @@ class BaseApi:
226
229
  {k: v for k, v in data.items() if k != "methods"},
227
230
  )
228
231
 
232
+ if resolved_dependencies:
233
+ rest_data["dependencies"] = (
234
+ list(data.get("dependencies") or []) + resolved_dependencies
235
+ )
236
+
229
237
  self.messages.append(
230
238
  f"Registering route {self.router.prefix}{path} {methods}"
231
239
  )
@@ -32,11 +32,11 @@ from pydantic import BaseModel, Field
32
32
 
33
33
  from ...backends.sqla.filters import BaseFilter, BaseOprFilter
34
34
  from ...backends.sqla.interface import SQLAInterface
35
+ from ...bases import DBQueryParams
35
36
  from ...const import AVAILABLE_ROUTES
36
37
  from ...dependencies import current_permissions
37
38
  from ...exceptions import HTTPWithValidationException, raise_exception
38
39
  from ...lang.lazy_text import translate
39
- from ...bases import DBQueryParams
40
40
  from ...schemas import (
41
41
  BaseResponseMany,
42
42
  BaseResponseSingle,
@@ -59,13 +59,7 @@ from ._edit_mixin import EditMixin
59
59
  from ._file_mixin import FileMixin
60
60
  from ._info_mixin import InfoMixin
61
61
  from ._list_mixin import ListMixin
62
- from ._upload_mixin import UploadMixin
63
62
  from ._params import (
64
- PARAM_BODY_SESSION,
65
- PARAM_ID_SESSION,
66
- PARAM_ID_SESSION_ITEM,
67
- PARAM_IDS_Q_SESSION_ITEMS,
68
- PARAM_Q,
69
63
  P_BODY,
70
64
  P_ID,
71
65
  P_IDS,
@@ -73,9 +67,15 @@ from ._params import (
73
67
  P_ITEMS,
74
68
  P_Q,
75
69
  P_SESSION,
70
+ PARAM_BODY_SESSION,
71
+ PARAM_ID_SESSION,
72
+ PARAM_ID_SESSION_ITEM,
73
+ PARAM_IDS_Q_SESSION_ITEMS,
74
+ PARAM_Q,
76
75
  Params,
77
76
  )
78
77
  from ._show_mixin import ShowMixin
78
+ from ._upload_mixin import UploadMixin
79
79
 
80
80
  __all__ = ["ModelRestApi"]
81
81
 
@@ -208,7 +208,9 @@ class ModelRestApi(
208
208
  base_order = ("name", "asc")
209
209
  ```
210
210
  """
211
- base_filters: typing.List[typing.Tuple[str, typing.Type[BaseFilter], typing.Any]] | None = None
211
+ base_filters: (
212
+ typing.List[typing.Tuple[str, typing.Type[BaseFilter], typing.Any]] | None
213
+ ) = None
212
214
  """
213
215
  The default filters to apply for the following endpoints: `download`, `list`, `show`, `add`, and `edit`. Defaults to None.
214
216
 
@@ -219,7 +221,9 @@ class ModelRestApi(
219
221
  ]
220
222
  ```
221
223
  """
222
- base_opr_filters: typing.List[typing.Tuple[typing.Type[BaseOprFilter], typing.Any]] | None = None
224
+ base_opr_filters: (
225
+ typing.List[typing.Tuple[typing.Type[BaseOprFilter], typing.Any]] | None
226
+ ) = None
223
227
  """
224
228
  The default opr filters to apply for the following endpoints: `download`, `list`, `show`, `add`, and `edit`. Defaults to None.
225
229
 
@@ -659,7 +663,8 @@ class ModelRestApi(
659
663
  | typing.Callable[[ColumnInfo | ColumnEnumInfo | ColumnRelationInfo], bool]
660
664
  | dict[
661
665
  str,
662
- bool | typing.Callable[[ColumnInfo | ColumnEnumInfo | ColumnRelationInfo], bool],
666
+ bool
667
+ | typing.Callable[[ColumnInfo | ColumnEnumInfo | ColumnRelationInfo], bool],
663
668
  ]
664
669
  ) = lazy(lambda: lambda info: len(info.values) > 100)
665
670
  """
@@ -700,7 +705,8 @@ class ModelRestApi(
700
705
  | typing.Callable[[ColumnInfo | ColumnEnumInfo | ColumnRelationInfo], bool]
701
706
  | dict[
702
707
  str,
703
- bool | typing.Callable[[ColumnInfo | ColumnEnumInfo | ColumnRelationInfo], bool],
708
+ bool
709
+ | typing.Callable[[ColumnInfo | ColumnEnumInfo | ColumnRelationInfo], bool],
704
710
  ]
705
711
  ) = lazy(lambda: lambda info: len(info.values) > 100)
706
712
  """
@@ -1172,7 +1178,7 @@ class ModelRestApi(
1172
1178
  filter_classes=self.base_filters,
1173
1179
  opr_filters=q.opr_filters,
1174
1180
  opr_filter_classes=self.base_opr_filters,
1175
- global_filter=(self.list_columns, q.global_filter)
1181
+ global_filter=(q.columns or self.list_columns, q.global_filter)
1176
1182
  if q.global_filter
1177
1183
  else None,
1178
1184
  )
@@ -94,7 +94,9 @@ class ColumnsMixin:
94
94
  return re.sub("[._]", " ", name).title()
95
95
 
96
96
  def _init_filters(
97
- self, datamodel: SQLAInterface, filters: typing.List[typing.Tuple[str, typing.Type[BaseFilter], typing.Any]]
97
+ self,
98
+ datamodel: SQLAInterface,
99
+ filters: typing.List[typing.Tuple[str, typing.Type[BaseFilter], typing.Any]],
98
100
  ):
99
101
  """
100
102
  Initialize the filter for the API.
@@ -48,9 +48,7 @@ class InfoMixin:
48
48
  add_obj_schema: typing.Type[BaseModel]
49
49
  add_jsonforms_use_enum: (
50
50
  bool
51
- | typing.Callable[
52
- [ColumnInfo | ColumnEnumInfo | ColumnRelationInfo], bool
53
- ]
51
+ | typing.Callable[[ColumnInfo | ColumnEnumInfo | ColumnRelationInfo], bool]
54
52
  | dict[
55
53
  str,
56
54
  bool
@@ -64,9 +62,7 @@ class InfoMixin:
64
62
  edit_obj_schema: typing.Type[BaseModel]
65
63
  edit_jsonforms_use_enum: (
66
64
  bool
67
- | typing.Callable[
68
- [ColumnInfo | ColumnEnumInfo | ColumnRelationInfo], bool
69
- ]
65
+ | typing.Callable[[ColumnInfo | ColumnEnumInfo | ColumnRelationInfo], bool]
70
66
  | dict[
71
67
  str,
72
68
  bool
@@ -89,9 +89,7 @@ class AccessToken(SQLAlchemyBaseAccessTokenTable[int], Model):
89
89
 
90
90
 
91
91
  async def get_access_token_db(
92
- session: SQLASession = Depends(
93
- get_session_factory(AccessToken.__bind_key__)
94
- ),
92
+ session: SQLASession = Depends(get_session_factory(AccessToken.__bind_key__)),
95
93
  ):
96
94
  yield SQLAlchemyAccessTokenDatabase(session, AccessToken)
97
95
 
@@ -117,7 +117,9 @@ class SQLAQueryBuilder(AbstractQueryBuilder[Select[tuple[T]]]):
117
117
  col = order_column
118
118
 
119
119
  #! If the order column comes from a request, it will be in the format ClassName.column_name
120
- if col.startswith(self.datamodel.obj.__class__.__name__): # pragma: no cover - obj.__class__.__name__ is metaclass name (DeclarativeMeta), almost never matches
120
+ if col.startswith(
121
+ self.datamodel.obj.__class__.__name__
122
+ ): # pragma: no cover - obj.__class__.__name__ is metaclass name (DeclarativeMeta), almost never matches
121
123
  col = col.split(".", 1)[1]
122
124
 
123
125
  statement, col = self._retrieve_column(statement, col)
@@ -430,8 +432,9 @@ class SQLAQueryBuilder(AbstractQueryBuilder[Select[tuple[T]]]):
430
432
  [sub_col],
431
433
  ),
432
434
  rules={
433
- "type": lambda x1, x2: LOAD_TYPE_MAPPING[x2]
434
- > LOAD_TYPE_MAPPING[x1]
435
+ "type": lambda x1, x2: (
436
+ LOAD_TYPE_MAPPING[x2] > LOAD_TYPE_MAPPING[x1]
437
+ )
435
438
  },
436
439
  )
437
440
 
@@ -22,12 +22,8 @@ class DecoratorsMixin:
22
22
  # Attributes supplied by the composed ``Audit`` class via MRO.
23
23
  models: list[typing.Type[SQLAModel]]
24
24
  excluded_models: list[typing.Type[SQLAModel]]
25
- included_properties: collections.defaultdict[
26
- typing.Type[SQLAModel], list[str]
27
- ]
28
- excluded_properties: collections.defaultdict[
29
- typing.Type[SQLAModel], list[str]
30
- ]
25
+ included_properties: collections.defaultdict[typing.Type[SQLAModel], list[str]]
26
+ excluded_properties: collections.defaultdict[typing.Type[SQLAModel], list[str]]
31
27
  mapping_insert_updates_when_no_changes: collections.defaultdict[
32
28
  typing.Type[SQLAModel], bool | None
33
29
  ]
@@ -33,12 +33,8 @@ class ProcessingMixin:
33
33
  schemas: dict[str, typing.Type[pydantic.BaseModel]]
34
34
  models: list[typing.Type[SQLAModel]]
35
35
  excluded_models: list[typing.Type[SQLAModel]]
36
- included_properties: collections.defaultdict[
37
- typing.Type[SQLAModel], list[str]
38
- ]
39
- excluded_properties: collections.defaultdict[
40
- typing.Type[SQLAModel], list[str]
41
- ]
36
+ included_properties: collections.defaultdict[typing.Type[SQLAModel], list[str]]
37
+ excluded_properties: collections.defaultdict[typing.Type[SQLAModel], list[str]]
42
38
  mapping_insert_updates_when_no_changes: collections.defaultdict[
43
39
  typing.Type[SQLAModel], bool | None
44
40
  ]
@@ -89,7 +89,7 @@ class MissingGreenletError(FastAPIReactToolkitException):
89
89
  f"raised MissingGreenlet while pydantic accessed an attribute. "
90
90
  f"Fix by eager-loading the missing relationship "
91
91
  f"(`selectinload` / `joinedload`), by calling "
92
- f"`await instance.load(\"<col>\")` before the instance leaves "
92
+ f'`await instance.load("<col>")` before the instance leaves '
93
93
  f"the async context, or by adding the column to "
94
94
  f"`list_columns` / `show_columns` (or the narrower "
95
95
  f"`list_select_columns` / `show_select_columns`, or "
@@ -106,8 +106,8 @@ class MissingGreenletError(FastAPIReactToolkitException):
106
106
  f"underlying relationship "
107
107
  f"(e.g. add `selectinload({model_label}.{col})` or "
108
108
  f"`joinedload({model_label}.{col})` to the query), by "
109
- f"calling `await instance.load(\"{col}\")` before the instance "
110
- f"leaves the async context, or by adding `\"{col}\"` to "
109
+ f'calling `await instance.load("{col}")` before the instance '
110
+ f'leaves the async context, or by adding `"{col}"` to '
111
111
  f"`list_columns` / `show_columns` (or the narrower "
112
112
  f"`list_select_columns` / `show_select_columns`, or "
113
113
  f"`extra_list_fetch_columns` / `extra_show_fetch_columns` "
@@ -1098,20 +1098,18 @@ class AbstractInterface(abc.ABC, typing.Generic[T, C, CT]):
1098
1098
  pass
1099
1099
  return value
1100
1100
 
1101
- schema_dict["__validators__"]["raise_on_greenlet"] = (
1102
- pydantic.model_validator(mode="before")(classmethod(raise_on_greenlet))
1103
- )
1101
+ schema_dict["__validators__"]["raise_on_greenlet"] = pydantic.model_validator(
1102
+ mode="before"
1103
+ )(classmethod(raise_on_greenlet))
1104
1104
 
1105
1105
  if async_columns:
1106
-
1107
1106
  interface_self = self
1108
1107
 
1109
1108
  def populate_async_columns(self):
1110
1109
  for col in async_columns:
1111
1110
  AsyncTaskRunner.add_task(
1112
- lambda col=col,
1113
- interface_self=interface_self: interface_self._populate_async_column(
1114
- self, col
1111
+ lambda col=col, interface_self=interface_self: (
1112
+ interface_self._populate_async_column(self, col)
1115
1113
  )
1116
1114
  )
1117
1115
  return self
@@ -548,7 +548,9 @@ async def promote(
548
548
 
549
549
  sm = g.current_app.sm
550
550
  async with db.session() as session:
551
- user = await sm.get_user(email_or_username, session=session, raise_exception=True)
551
+ user = await sm.get_user(
552
+ email_or_username, session=session, raise_exception=True
553
+ )
552
554
  current = [r.name for r in user.roles]
553
555
  if g.admin_role in current:
554
556
  typer.echo(f"User {user.username} already has role {g.admin_role}.")
@@ -577,7 +579,9 @@ async def demote(
577
579
 
578
580
  sm = g.current_app.sm
579
581
  async with db.session() as session:
580
- user = await sm.get_user(email_or_username, session=session, raise_exception=True)
582
+ user = await sm.get_user(
583
+ email_or_username, session=session, raise_exception=True
584
+ )
581
585
  current = [r.name for r in user.roles]
582
586
  if g.admin_role not in current:
583
587
  typer.echo(f"User {user.username} does not have role {g.admin_role}.")
@@ -801,9 +805,7 @@ async def rename_role(
801
805
  old_name: Annotated[
802
806
  str, typer.Option(..., help="The current name of the role.")
803
807
  ] = "",
804
- new_name: Annotated[
805
- str, typer.Option(..., help="The new name for the role.")
806
- ] = "",
808
+ new_name: Annotated[str, typer.Option(..., help="The new name for the role.")] = "",
807
809
  ):
808
810
  """
809
811
  Rename a role. The members of the role are preserved.
@@ -818,9 +820,12 @@ async def rename_role(
818
820
 
819
821
  sm = g.current_app.sm
820
822
  async with db.session() as session:
821
- existing = await sm.get_roles(
822
- [old_name, new_name], session=session, raise_exception=False
823
- ) or []
823
+ existing = (
824
+ await sm.get_roles(
825
+ [old_name, new_name], session=session, raise_exception=False
826
+ )
827
+ or []
828
+ )
824
829
  by_name = {r.name: r for r in existing}
825
830
  if old_name not in by_name:
826
831
  raise typer.BadParameter(f"Role {old_name!r} does not exist.")
@@ -951,9 +956,7 @@ async def list_permissions(
951
956
  roles = await sm.get_roles([role], session=session, raise_exception=False)
952
957
  if not roles:
953
958
  raise typer.BadParameter(f"Role {role!r} does not exist.")
954
- filters.append(
955
- {"col": "roles", "opr": "rel_m_m", "value": [roles[0].id]}
956
- )
959
+ filters.append({"col": "roles", "opr": "rel_m_m", "value": [roles[0].id]})
957
960
  if api:
958
961
  filters.append({"col": "api.name", "opr": "eq", "value": api})
959
962
  if filters:
@@ -196,28 +196,18 @@ class DatabaseSessionManager:
196
196
  """
197
197
 
198
198
  _engine: SQLAEngine | None = None
199
- _sessionmaker: SQLASessionMaker | None = (
200
- None
201
- )
199
+ _sessionmaker: SQLASessionMaker | None = None
202
200
  _engine_binds: dict[str, SQLAEngine] = None
203
- _sessionmaker_binds: dict[
204
- str, SQLASessionMaker
205
- ] = None
206
- _scoped_session_maker: (
207
- SQLAScopedSession | None
208
- ) = None
209
- _scoped_session_maker_binds: dict[
210
- str, SQLAScopedSession
211
- ] = None
201
+ _sessionmaker_binds: dict[str, SQLASessionMaker] = None
202
+ _scoped_session_maker: SQLAScopedSession | None = None
203
+ _scoped_session_maker_binds: dict[str, SQLAScopedSession] = None
212
204
  _scoped_session: SQLASession | None = None
213
205
  _scoped_session_binds: dict[str, SQLASession] = None
214
206
 
215
207
  _session_context = contextvars.ContextVar[SQLASession](
216
208
  "DatabaseSessionManager:current_session"
217
209
  )
218
- _sessions_context = smartdefaultdict[
219
- str, contextvars.ContextVar[SQLASession]
220
- ](
210
+ _sessions_context = smartdefaultdict[str, contextvars.ContextVar[SQLASession]](
221
211
  lambda key: contextvars.ContextVar[SQLASession](
222
212
  f"DatabaseSessionManager:current_session:{key}"
223
213
  )
@@ -295,7 +285,9 @@ class DatabaseSessionManager:
295
285
  copy_metadata = MetaData()
296
286
  for table_name in FASTAPI_RTK_TABLES:
297
287
  table = metadata.tables.get(table_name)
298
- if table is None: # pragma: no cover - defensive; FASTAPI_RTK_TABLES are always registered
288
+ if (
289
+ table is None
290
+ ): # pragma: no cover - defensive; FASTAPI_RTK_TABLES are always registered
299
291
  continue
300
292
  table.to_metadata(copy_metadata)
301
293
  await self._create_all(conn, copy_metadata)
@@ -571,9 +563,7 @@ class DatabaseSessionManager:
571
563
  expire_on_commit=False,
572
564
  )
573
565
 
574
- def _init_scoped_session(
575
- self, sessionmaker: SQLASessionMaker
576
- ):
566
+ def _init_scoped_session(self, sessionmaker: SQLASessionMaker):
577
567
  """
578
568
  Initializes the scoped session.
579
569
 
@@ -338,7 +338,9 @@ def relationship_filter(attr: str | _RelationshipDeclared):
338
338
  if isinstance(attr, _RelationshipDeclared):
339
339
  caller_locals = inspect.currentframe().f_back.f_locals
340
340
  caller_locals = {k: v for k, v in caller_locals.items() if v is attr}
341
- if not caller_locals: # pragma: no cover - requires impossible caller stack inspection
341
+ if (
342
+ not caller_locals
343
+ ): # pragma: no cover - requires impossible caller stack inspection
342
344
  raise Exception(
343
345
  "relationship_filter decorator could not find the attribute for the relationship."
344
346
  )
@@ -26,7 +26,9 @@ from .setting import Setting
26
26
  from .utils import T, call_with_valid_kwargs, lazy_self, safe_call
27
27
 
28
28
  if typing.TYPE_CHECKING:
29
- from .security.sqla.security_manager import SecurityManager # noqa: F401 # forward-ref target for `lazy`
29
+ from .security.sqla.security_manager import (
30
+ SecurityManager, # noqa: F401 # forward-ref target for `lazy`
31
+ )
30
32
 
31
33
  __all__ = ["UserManager"]
32
34
 
@@ -434,7 +434,9 @@ class QuerySchema(BaseModel):
434
434
  translate("Invalid columns: Not a valid JSON string"),
435
435
  input=v,
436
436
  )
437
- except ValidationError as e: # pragma: no cover - defensive; str() cast can't raise ValidationError
437
+ except (
438
+ ValidationError
439
+ ) as e: # pragma: no cover - defensive; str() cast can't raise ValidationError
438
440
  raise HTTPWithValidationException(
439
441
  fastapi.status.HTTP_400_BAD_REQUEST,
440
442
  "literal_error",
@@ -527,7 +529,9 @@ class QuerySchema(BaseModel):
527
529
  )
528
530
  new_filters = []
529
531
  for index, filter in enumerate(filters):
530
- if isinstance(filter, OprFilterSchema): # pragma: no cover - QuerySchema.opr_filters is str-typed; pre-built schema instances unreachable
532
+ if isinstance(
533
+ filter, OprFilterSchema
534
+ ): # pragma: no cover - QuerySchema.opr_filters is str-typed; pre-built schema instances unreachable
531
535
  new_filters.append(filter)
532
536
  elif isinstance(filter, dict):
533
537
  new_filters.append(OprFilterSchema(**filter))
@@ -3,6 +3,7 @@ from typing import List
3
3
  import sqlalchemy
4
4
  from fastapi import Depends, HTTPException, Request, status
5
5
  from pydantic import BaseModel, EmailStr, Field
6
+
6
7
  from ...api import BaseApi, ModelRestApi
7
8
  from ...backends.sqla.interface import SQLAInterface
8
9
  from ...backends.sqla.session import SQLASession
@@ -8,11 +8,13 @@ from pydantic import BaseModel
8
8
  from ....backends.sqla.session import SQLASession
9
9
  from ....db import UserDatabase, db
10
10
  from ....globals import g
11
+ from ..models import Role, User
11
12
  from ._exception_filters import (
12
13
  SecurityExceptionFilter,
14
+ )
15
+ from ._exception_filters import (
13
16
  should_reraise as _should_reraise,
14
17
  )
15
- from ..models import Role, User
16
18
 
17
19
  __all__ = ["UserMixin"]
18
20
 
@@ -13,7 +13,6 @@ import sys
13
13
  from typing import Any, Callable, Iterable
14
14
 
15
15
  import pytest
16
-
17
16
  from fastapi_rtk.globals import g
18
17
 
19
18
  _MISSING = object()
@@ -13,7 +13,6 @@ import json
13
13
  import types
14
14
 
15
15
  import pytest
16
-
17
16
  from fastapi_rtk.schemas import GeneralResponse
18
17
 
19
18
  pytestmark = pytest.mark.asyncio
@@ -585,6 +584,31 @@ class TestListWithFilters:
585
584
  names = [r["name"] for r in body["result"]]
586
585
  assert "Beta" in names
587
586
 
587
+ async def test_list_global_filter_spans_only_shown_columns(
588
+ self, client, admin_token, seeded_widgets
589
+ ):
590
+ # "second" is the description of the Beta widget. With only `name`
591
+ # shown, global search must not match it; once `description` is shown
592
+ # it must. Proves the search span follows the columns query param.
593
+ hidden = await client.get(
594
+ "/api/v1/widgets/",
595
+ params={"columns": json.dumps(["name"]), "global_filter": "second"},
596
+ headers={"Authorization": f"Bearer {admin_token}"},
597
+ )
598
+ assert hidden.status_code == 200
599
+ assert [r["name"] for r in hidden.json()["result"]] == []
600
+
601
+ shown = await client.get(
602
+ "/api/v1/widgets/",
603
+ params={
604
+ "columns": json.dumps(["name", "description"]),
605
+ "global_filter": "second",
606
+ },
607
+ headers={"Authorization": f"Bearer {admin_token}"},
608
+ )
609
+ assert shown.status_code == 200
610
+ assert "Beta" in [r["name"] for r in shown.json()["result"]]
611
+
588
612
  async def test_list_invalid_column_raises_400(
589
613
  self, client, admin_token, seeded_widgets
590
614
  ):
@@ -650,9 +674,8 @@ class TestBulk:
650
674
  self, client, admin_token, widgets_api, seeded_widgets
651
675
  ):
652
676
  async def bulk_count(self, body, query, session):
653
- from sqlalchemy import func, select
654
-
655
677
  from fastapi_rtk.utils import smart_run
678
+ from sqlalchemy import func, select
656
679
 
657
680
  stmt = select(func.count()).select_from(query.obj)
658
681
  result = await smart_run(session.scalar, stmt)
@@ -845,9 +868,7 @@ class TestPreDeleteModelSwap:
845
868
  class TestPostDeleteModelSwap:
846
869
  """post_delete returning a Model swaps the response item."""
847
870
 
848
- async def test_post_delete_returns_model(
849
- self, client, admin_token, widgets_api
850
- ):
871
+ async def test_post_delete_returns_model(self, client, admin_token, widgets_api):
851
872
  post = await client.post(
852
873
  "/api/v1/widgets/",
853
874
  headers={"Authorization": f"Bearer {admin_token}"},
@@ -84,9 +84,7 @@ class TestRelationsInInfo:
84
84
  add_cols = [c["name"] for c in body["add_columns"]]
85
85
  assert "country" in add_cols or "country_id" in add_cols
86
86
 
87
- async def test_post_widget_with_country_relation(
88
- self, client, admin_token
89
- ):
87
+ async def test_post_widget_with_country_relation(self, client, admin_token):
90
88
  # Create a country first.
91
89
  country_resp = await client.post(
92
90
  "/api/v1/countries/",