fastapi-rtk 2.20.0__tar.gz → 2.21.0__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 (345) hide show
  1. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/PKG-INFO +14 -4
  2. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/README.md +13 -3
  3. fastapi_rtk-2.21.0/fastapi_rtk/_version.py +1 -0
  4. fastapi_rtk-2.21.0/fastapi_rtk/agent_docs/adapters/claude/skill.frontmatter +2 -0
  5. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/agent_docs/guide/backend.md +21 -20
  6. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/agent_docs/guide/frontend.md +22 -12
  7. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/agent_docs/guide/jsonforms.md +1 -1
  8. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/cli/test_cli.py +13 -0
  9. fastapi_rtk-2.20.0/fastapi_rtk/_version.py +0 -1
  10. fastapi_rtk-2.20.0/fastapi_rtk/agent_docs/adapters/claude/skill.frontmatter +0 -2
  11. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/.gitignore +0 -0
  12. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/LICENSE +0 -0
  13. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/__init__.py +0 -0
  14. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/agent_docs/adapters/agents-md/AGENTS.md +0 -0
  15. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/agent_docs/guide/legacy.md +0 -0
  16. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/agent_docs/guide/overview.md +0 -0
  17. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/api/__init__.py +0 -0
  18. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/api/base_api.py +0 -0
  19. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/api/model_rest_api/__init__.py +0 -0
  20. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/api/model_rest_api/model_rest_api.py +0 -0
  21. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/api/model_rest_api/params.py +0 -0
  22. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/api/model_rest_api/services/__init__.py +0 -0
  23. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/api/model_rest_api/services/_add_service.py +0 -0
  24. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/api/model_rest_api/services/_bulk_service.py +0 -0
  25. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/api/model_rest_api/services/_delete_service.py +0 -0
  26. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/api/model_rest_api/services/_download_service.py +0 -0
  27. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/api/model_rest_api/services/_edit_service.py +0 -0
  28. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/api/model_rest_api/services/_file_service.py +0 -0
  29. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/api/model_rest_api/services/_info_service.py +0 -0
  30. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/api/model_rest_api/services/_list_service.py +0 -0
  31. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/api/model_rest_api/services/_lookup_service.py +0 -0
  32. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/api/model_rest_api/services/_schema_service.py +0 -0
  33. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/api/model_rest_api/services/_show_service.py +0 -0
  34. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/apis/__init__.py +0 -0
  35. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/apis/info.py +0 -0
  36. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/apis/license.py +0 -0
  37. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/auth/__init__.py +0 -0
  38. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/auth/auth.py +0 -0
  39. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/auth/hashers/__init__.py +0 -0
  40. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/auth/hashers/pbkdf2.py +0 -0
  41. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/auth/hashers/scrypt.py +0 -0
  42. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/auth/ldap.py +0 -0
  43. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/auth/password_helpers/__init__.py +0 -0
  44. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/auth/password_helpers/fab.py +0 -0
  45. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/auth/strategies/__init__.py +0 -0
  46. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/auth/strategies/config.py +0 -0
  47. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/auth/strategies/db.py +0 -0
  48. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/auth/strategies/jwt.py +0 -0
  49. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/backends/__init__.py +0 -0
  50. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/backends/generic/__init__.py +0 -0
  51. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/backends/generic/column.py +0 -0
  52. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/backends/generic/db.py +0 -0
  53. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/backends/generic/exceptions.py +0 -0
  54. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/backends/generic/filters.py +0 -0
  55. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/backends/generic/interface.py +0 -0
  56. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/backends/generic/model.py +0 -0
  57. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/backends/generic/session.py +0 -0
  58. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/backends/sqla/__init__.py +0 -0
  59. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/backends/sqla/column.py +0 -0
  60. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/backends/sqla/db.py +0 -0
  61. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/backends/sqla/exceptions.py +0 -0
  62. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/backends/sqla/extensions/__init__.py +0 -0
  63. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/backends/sqla/extensions/audit/__init__.py +0 -0
  64. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/backends/sqla/extensions/audit/_decorators_service.py +0 -0
  65. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/backends/sqla/extensions/audit/_lifecycle_service.py +0 -0
  66. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/backends/sqla/extensions/audit/_logger.py +0 -0
  67. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/backends/sqla/extensions/audit/_processing_service.py +0 -0
  68. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/backends/sqla/extensions/audit/audit.py +0 -0
  69. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/backends/sqla/extensions/audit/types.py +0 -0
  70. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/backends/sqla/extensions/geoalchemy2/__init__.py +0 -0
  71. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/backends/sqla/extensions/geoalchemy2/filters.py +0 -0
  72. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/backends/sqla/extensions/geoalchemy2/geometry_converter.py +0 -0
  73. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/backends/sqla/filters.py +0 -0
  74. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/backends/sqla/interface.py +0 -0
  75. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/backends/sqla/model.py +0 -0
  76. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/backends/sqla/session.py +0 -0
  77. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/bases/__init__.py +0 -0
  78. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/bases/cache.py +0 -0
  79. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/bases/db.py +0 -0
  80. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/bases/file_manager.py +0 -0
  81. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/bases/filter.py +0 -0
  82. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/bases/interface.py +0 -0
  83. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/bases/loop_manager.py +0 -0
  84. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/bases/model.py +0 -0
  85. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/bases/session.py +0 -0
  86. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/bases/user_cache.py +0 -0
  87. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/caches/__init__.py +0 -0
  88. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/caches/cache.py +0 -0
  89. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/caches/serializers.py +0 -0
  90. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/caches/storages.py +0 -0
  91. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/cli/__init__.py +0 -0
  92. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/cli/cli.py +0 -0
  93. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/cli/commands/__init__.py +0 -0
  94. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/cli/commands/_security_crypto.py +0 -0
  95. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/cli/commands/agent/__init__.py +0 -0
  96. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/cli/commands/agent/adapters/__init__.py +0 -0
  97. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/cli/commands/agent/adapters/agents_md.py +0 -0
  98. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/cli/commands/agent/adapters/claude.py +0 -0
  99. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/cli/commands/agent/base.py +0 -0
  100. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/cli/commands/agent/docs.py +0 -0
  101. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/cli/commands/db/__init__.py +0 -0
  102. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/cli/commands/db/templates/fastapi/README +0 -0
  103. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/cli/commands/db/templates/fastapi/alembic.ini.mako +0 -0
  104. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/cli/commands/db/templates/fastapi/env.py +0 -0
  105. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/cli/commands/db/templates/fastapi/script.py.mako +0 -0
  106. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/README +0 -0
  107. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/alembic.ini.mako +0 -0
  108. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/env.py +0 -0
  109. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/cli/commands/db/templates/fastapi-multidb/script.py.mako +0 -0
  110. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/cli/commands/export.py +0 -0
  111. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/cli/commands/security.py +0 -0
  112. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/cli/commands/translate.py +0 -0
  113. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/cli/const.py +0 -0
  114. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/cli/decorators.py +0 -0
  115. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/cli/types.py +0 -0
  116. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/cli/utils.py +0 -0
  117. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/config.py +0 -0
  118. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/const.py +0 -0
  119. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/db.py +0 -0
  120. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/decorators.py +0 -0
  121. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/dependencies.py +0 -0
  122. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/exceptions.py +0 -0
  123. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/fastapi_react_toolkit.py +0 -0
  124. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/file_managers/__init__.py +0 -0
  125. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/file_managers/file_manager.py +0 -0
  126. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/file_managers/image_manager.py +0 -0
  127. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/file_managers/s3_file_manager.py +0 -0
  128. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/file_managers/s3_image_manager.py +0 -0
  129. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/filters.py +0 -0
  130. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/globals.py +0 -0
  131. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/lang/__init__.py +0 -0
  132. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/lang/babel/__init__.py +0 -0
  133. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/lang/babel/cli.py +0 -0
  134. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/lang/babel/config.py +0 -0
  135. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/lang/babel.cfg +0 -0
  136. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/lang/lazy_text.py +0 -0
  137. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/lang/messages.pot +0 -0
  138. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/lang/translations/de/LC_MESSAGES/messages.mo +0 -0
  139. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/lang/translations/de/LC_MESSAGES/messages.po +0 -0
  140. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/lang/translations/en/LC_MESSAGES/messages.mo +0 -0
  141. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/lang/translations/en/LC_MESSAGES/messages.po +0 -0
  142. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/loop_managers/__init__.py +0 -0
  143. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/loop_managers/loop_manager.py +0 -0
  144. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/manager.py +0 -0
  145. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/middlewares.py +0 -0
  146. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/mixins.py +0 -0
  147. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/models.py +0 -0
  148. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/py.typed +0 -0
  149. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/registry.py +0 -0
  150. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/routers.py +0 -0
  151. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/schemas.py +0 -0
  152. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/security/__init__.py +0 -0
  153. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/security/sqla/__init__.py +0 -0
  154. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/security/sqla/apis.py +0 -0
  155. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/security/sqla/models.py +0 -0
  156. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/security/sqla/security_manager/__init__.py +0 -0
  157. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/security/sqla/security_manager/_builtin_role_service.py +0 -0
  158. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/security/sqla/security_manager/_entities.py +0 -0
  159. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/security/sqla/security_manager/_exception_filters.py +0 -0
  160. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/security/sqla/security_manager/_export.py +0 -0
  161. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/security/sqla/security_manager/_import.py +0 -0
  162. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/security/sqla/security_manager/_permission_service.py +0 -0
  163. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/security/sqla/security_manager/_results.py +0 -0
  164. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/security/sqla/security_manager/_role_service.py +0 -0
  165. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/security/sqla/security_manager/_user_service.py +0 -0
  166. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/security/sqla/security_manager/security_manager.py +0 -0
  167. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/security/sqla/user_cache.py +0 -0
  168. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/setting.py +0 -0
  169. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/types.py +0 -0
  170. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/utils/__init__.py +0 -0
  171. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/utils/async_task_runner.py +0 -0
  172. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/utils/class_factory.py +0 -0
  173. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/utils/csv_json_converter.py +0 -0
  174. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/utils/deep_merge.py +0 -0
  175. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/utils/extender_mixin.py +0 -0
  176. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/utils/flask_appbuilder_utils.py +0 -0
  177. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/utils/formatter.py +0 -0
  178. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/utils/hooks.py +0 -0
  179. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/utils/lazy.py +0 -0
  180. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/utils/merge_schema.py +0 -0
  181. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/utils/multiple_async_contexts.py +0 -0
  182. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/utils/pydantic.py +0 -0
  183. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/utils/run_utils.py +0 -0
  184. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/utils/self_dependencies.py +0 -0
  185. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/utils/smartdefaultdict.py +0 -0
  186. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/utils/sqla.py +0 -0
  187. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/utils/timezone.py +0 -0
  188. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/utils/update_signature.py +0 -0
  189. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/utils/use_default_when_none.py +0 -0
  190. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/fastapi_rtk/version.py +0 -0
  191. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/pyproject.toml +0 -0
  192. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/conftest.py +0 -0
  193. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/docker-compose.gis.yml +0 -0
  194. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/integration/__init__.py +0 -0
  195. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/integration/api/__init__.py +0 -0
  196. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/integration/api/test_add_edit_relation_response.py +0 -0
  197. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/integration/api/test_lookup.py +0 -0
  198. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/integration/api/test_model_rest_api.py +0 -0
  199. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/integration/apis/__init__.py +0 -0
  200. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/integration/apis/test_info_callable_schema.py +0 -0
  201. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/integration/apis/test_info_contract.py +0 -0
  202. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/integration/auth/__init__.py +0 -0
  203. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/integration/auth/test_auth_flow.py +0 -0
  204. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/integration/auth/test_oauth.py +0 -0
  205. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/integration/conftest.py +0 -0
  206. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/integration/file_managers/__init__.py +0 -0
  207. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/integration/file_managers/test_file_routes.py +0 -0
  208. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/integration/security/__init__.py +0 -0
  209. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/integration/security/sqla/__init__.py +0 -0
  210. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/integration/security/sqla/conftest.py +0 -0
  211. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/integration/security/sqla/test_permission_service.py +0 -0
  212. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/integration/security/sqla/test_role_service.py +0 -0
  213. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/integration/security/sqla/test_security_manager.py +0 -0
  214. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/integration/security/sqla/test_user_service.py +0 -0
  215. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/integration/test_app_smoke.py +0 -0
  216. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/__init__.py +0 -0
  217. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/api/__init__.py +0 -0
  218. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/api/conftest.py +0 -0
  219. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/api/model_rest_api/__init__.py +0 -0
  220. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/api/model_rest_api/test_columns.py +0 -0
  221. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/api/model_rest_api/test_download_service.py +0 -0
  222. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/api/model_rest_api/test_file_mixin.py +0 -0
  223. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/api/model_rest_api/test_init.py +0 -0
  224. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/api/model_rest_api/test_lookup_service.py +0 -0
  225. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/api/model_rest_api/test_service_delegators.py +0 -0
  226. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/api/test_base_api.py +0 -0
  227. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/apis/__init__.py +0 -0
  228. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/apis/test_info.py +0 -0
  229. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/apis/test_license.py +0 -0
  230. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/auth/__init__.py +0 -0
  231. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/auth/hashers/__init__.py +0 -0
  232. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/auth/hashers/test_pbkdf2.py +0 -0
  233. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/auth/hashers/test_scrypt.py +0 -0
  234. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/auth/password_helpers/__init__.py +0 -0
  235. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/auth/password_helpers/test_fab.py +0 -0
  236. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/auth/strategies/__init__.py +0 -0
  237. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/auth/strategies/test_config.py +0 -0
  238. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/auth/strategies/test_db.py +0 -0
  239. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/auth/strategies/test_jwt.py +0 -0
  240. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/auth/test_auth.py +0 -0
  241. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/backends/__init__.py +0 -0
  242. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/backends/generic/__init__.py +0 -0
  243. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/backends/generic/test_column.py +0 -0
  244. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/backends/generic/test_db.py +0 -0
  245. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/backends/generic/test_exceptions.py +0 -0
  246. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/backends/generic/test_filters.py +0 -0
  247. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/backends/generic/test_interface.py +0 -0
  248. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/backends/generic/test_model.py +0 -0
  249. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/backends/generic/test_session.py +0 -0
  250. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/backends/sqla/__init__.py +0 -0
  251. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/backends/sqla/conftest.py +0 -0
  252. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/backends/sqla/test_audit.py +0 -0
  253. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/backends/sqla/test_audit_service_delegators.py +0 -0
  254. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/backends/sqla/test_audit_types.py +0 -0
  255. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/backends/sqla/test_column.py +0 -0
  256. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/backends/sqla/test_db.py +0 -0
  257. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/backends/sqla/test_filters.py +0 -0
  258. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/backends/sqla/test_geoalchemy2.py +0 -0
  259. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/backends/sqla/test_interface.py +0 -0
  260. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/backends/sqla/test_model.py +0 -0
  261. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/backends/sqla/test_session.py +0 -0
  262. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/bases/__init__.py +0 -0
  263. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/bases/test_db.py +0 -0
  264. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/bases/test_file_manager.py +0 -0
  265. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/bases/test_filter.py +0 -0
  266. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/bases/test_interface.py +0 -0
  267. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/bases/test_model.py +0 -0
  268. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/bases/test_session.py +0 -0
  269. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/cli/__init__.py +0 -0
  270. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/cli/commands/__init__.py +0 -0
  271. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/cli/commands/conftest.py +0 -0
  272. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/cli/commands/test_db.py +0 -0
  273. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/cli/commands/test_export.py +0 -0
  274. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/cli/commands/test_security.py +0 -0
  275. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/cli/commands/test_security_crypto.py +0 -0
  276. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/cli/commands/test_translate.py +0 -0
  277. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/cli/conftest.py +0 -0
  278. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/cli/test_decorators.py +0 -0
  279. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/cli/test_types.py +0 -0
  280. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/cli/test_utils.py +0 -0
  281. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/file_managers/__init__.py +0 -0
  282. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/file_managers/conftest.py +0 -0
  283. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/file_managers/test_file_manager.py +0 -0
  284. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/file_managers/test_image_manager.py +0 -0
  285. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/file_managers/test_s3_file_manager.py +0 -0
  286. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/file_managers/test_s3_image_manager.py +0 -0
  287. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/lang/__init__.py +0 -0
  288. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/lang/test_babel_cli.py +0 -0
  289. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/lang/test_babel_config.py +0 -0
  290. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/lang/test_lazy_text.py +0 -0
  291. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/security/__init__.py +0 -0
  292. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/security/sqla/__init__.py +0 -0
  293. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/security/sqla/conftest.py +0 -0
  294. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/security/sqla/security_manager/__init__.py +0 -0
  295. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/security/sqla/security_manager/test_builtin_role_service.py +0 -0
  296. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/security/sqla/security_manager/test_entities.py +0 -0
  297. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/security/sqla/security_manager/test_permission_service.py +0 -0
  298. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/security/sqla/security_manager/test_results.py +0 -0
  299. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/security/sqla/security_manager/test_role_service.py +0 -0
  300. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/security/sqla/security_manager/test_user_service.py +0 -0
  301. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/security/sqla/test_apis.py +0 -0
  302. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/security/sqla/test_models.py +0 -0
  303. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/security/sqla/test_security_manager.py +0 -0
  304. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/test_caches.py +0 -0
  305. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/test_config.py +0 -0
  306. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/test_const.py +0 -0
  307. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/test_db.py +0 -0
  308. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/test_decorators.py +0 -0
  309. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/test_dependencies.py +0 -0
  310. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/test_exceptions.py +0 -0
  311. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/test_fastapi_react_toolkit.py +0 -0
  312. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/test_filters.py +0 -0
  313. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/test_globals.py +0 -0
  314. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/test_manager.py +0 -0
  315. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/test_middlewares.py +0 -0
  316. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/test_mixins.py +0 -0
  317. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/test_models.py +0 -0
  318. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/test_registry.py +0 -0
  319. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/test_routers.py +0 -0
  320. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/test_schemas.py +0 -0
  321. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/test_setting.py +0 -0
  322. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/test_types.py +0 -0
  323. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/test_user_cache.py +0 -0
  324. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/test_version.py +0 -0
  325. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/utils/__init__.py +0 -0
  326. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/utils/test_async_task_runner.py +0 -0
  327. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/utils/test_class_factory.py +0 -0
  328. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/utils/test_csv_json_converter.py +0 -0
  329. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/utils/test_deep_merge.py +0 -0
  330. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/utils/test_extender_mixin.py +0 -0
  331. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/utils/test_flask_appbuilder_utils.py +0 -0
  332. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/utils/test_formatter.py +0 -0
  333. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/utils/test_hooks.py +0 -0
  334. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/utils/test_lazy.py +0 -0
  335. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/utils/test_merge_schema.py +0 -0
  336. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/utils/test_multiple_async_contexts.py +0 -0
  337. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/utils/test_pydantic.py +0 -0
  338. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/utils/test_run_utils.py +0 -0
  339. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/utils/test_self_dependencies.py +0 -0
  340. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/utils/test_smartdefaultdict.py +0 -0
  341. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/utils/test_sqla.py +0 -0
  342. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/utils/test_timezone.py +0 -0
  343. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/utils/test_update_signature.py +0 -0
  344. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/tests/unit/utils/test_use_default_when_none.py +0 -0
  345. {fastapi_rtk-2.20.0 → fastapi_rtk-2.21.0}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: fastapi-rtk
3
- Version: 2.20.0
3
+ Version: 2.21.0
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
@@ -119,7 +119,7 @@ project/
119
119
  1. Install FastAPI React Toolkit:
120
120
 
121
121
  ```bash
122
- pip install fastapi-rtk
122
+ pip install fastapi-rtk aiosqlite # aiosqlite: async driver for the sqlite URI below (asyncpg for Postgres)
123
123
  mkdir -p app
124
124
  touch run.py app/__init__.py app/app.py app/config.py app/models.py app/apis.py
125
125
  ```
@@ -231,6 +231,7 @@ project/
231
231
  - `GET /api/v1/items/_image/{filename}` - Serve image files (If image column is present)
232
232
  - `GET /api/v1/items/_file/{filename}` - Serve file downloads (If file column is present)
233
233
  - `GET /api/v1/items/_info` - Get metadata about the model, including which columns can be added, edited, filtered, etc.
234
+ - `GET /api/v1/items/_lookup/{column}` - Search a column's values, or resolve ids to labels, for form and filter inputs (If the column is enabled in `lookup_columns`)
234
235
  - `POST /api/v1/items/bulk/{handler}` - Bulk operations, if set on the API class
235
236
  - `GET /api/v1/items/download` - Download items as CSV
236
237
  - `GET /api/v1/items/` - List items
@@ -249,6 +250,14 @@ project/
249
250
 
250
251
  2. Project files:
251
252
 
253
+ **webapp/.env**
254
+
255
+ The path the app is served under, with a trailing slash; `index.html` reads it as `%VITE_BASE_PATH%`.
256
+
257
+ ```bash
258
+ VITE_BASE_PATH=/
259
+ ```
260
+
252
261
  **webapp/index.html**
253
262
 
254
263
  ```html
@@ -295,7 +304,7 @@ project/
295
304
 
296
305
  createRoot(document.getElementById("root")).render(
297
306
  <StrictMode>
298
- <MantineProvider>
307
+ <MantineProvider getStyleNonce={() => window.nonce}>
299
308
  <Provider baseUrl={BASE_PATH + "api/v1"}>
300
309
  <BrowserRouter basename={BASE_PATH}>
301
310
  <App />
@@ -326,8 +335,9 @@ import { createReactNativeAdapters } from "fastapi-rtk/react-native-adapters";
326
335
  const rnAdapters = createReactNativeAdapters({
327
336
  asyncStorage,
328
337
  fileSystem,
329
- sharing,
338
+ sharing, // optional
330
339
  webBrowser,
340
+ oauthRedirectUrl: "myapp://oauth", // required for OAuth sign-in; one URL or a map per provider
331
341
  });
332
342
 
333
343
  <Provider baseUrl="https://api.example.com/api/v1" adapters={rnAdapters}>
@@ -60,7 +60,7 @@ project/
60
60
  1. Install FastAPI React Toolkit:
61
61
 
62
62
  ```bash
63
- pip install fastapi-rtk
63
+ pip install fastapi-rtk aiosqlite # aiosqlite: async driver for the sqlite URI below (asyncpg for Postgres)
64
64
  mkdir -p app
65
65
  touch run.py app/__init__.py app/app.py app/config.py app/models.py app/apis.py
66
66
  ```
@@ -172,6 +172,7 @@ project/
172
172
  - `GET /api/v1/items/_image/{filename}` - Serve image files (If image column is present)
173
173
  - `GET /api/v1/items/_file/{filename}` - Serve file downloads (If file column is present)
174
174
  - `GET /api/v1/items/_info` - Get metadata about the model, including which columns can be added, edited, filtered, etc.
175
+ - `GET /api/v1/items/_lookup/{column}` - Search a column's values, or resolve ids to labels, for form and filter inputs (If the column is enabled in `lookup_columns`)
175
176
  - `POST /api/v1/items/bulk/{handler}` - Bulk operations, if set on the API class
176
177
  - `GET /api/v1/items/download` - Download items as CSV
177
178
  - `GET /api/v1/items/` - List items
@@ -190,6 +191,14 @@ project/
190
191
 
191
192
  2. Project files:
192
193
 
194
+ **webapp/.env**
195
+
196
+ The path the app is served under, with a trailing slash; `index.html` reads it as `%VITE_BASE_PATH%`.
197
+
198
+ ```bash
199
+ VITE_BASE_PATH=/
200
+ ```
201
+
193
202
  **webapp/index.html**
194
203
 
195
204
  ```html
@@ -236,7 +245,7 @@ project/
236
245
 
237
246
  createRoot(document.getElementById("root")).render(
238
247
  <StrictMode>
239
- <MantineProvider>
248
+ <MantineProvider getStyleNonce={() => window.nonce}>
240
249
  <Provider baseUrl={BASE_PATH + "api/v1"}>
241
250
  <BrowserRouter basename={BASE_PATH}>
242
251
  <App />
@@ -267,8 +276,9 @@ import { createReactNativeAdapters } from "fastapi-rtk/react-native-adapters";
267
276
  const rnAdapters = createReactNativeAdapters({
268
277
  asyncStorage,
269
278
  fileSystem,
270
- sharing,
279
+ sharing, // optional
271
280
  webBrowser,
281
+ oauthRedirectUrl: "myapp://oauth", // required for OAuth sign-in; one URL or a map per provider
272
282
  });
273
283
 
274
284
  <Provider baseUrl="https://api.example.com/api/v1" adapters={rnAdapters}>
@@ -0,0 +1 @@
1
+ __version__ = "2.21.0"
@@ -0,0 +1,2 @@
1
+ name: rtk-developer
2
+ description: 'Use when building, modifying or debugging anything in a fastapi-rtk project: Python models, ModelRestApi or BaseApi endpoints, pre/post hooks, permissions, migrations, file uploads, bulk operations, or the React side (Provider setup, ApiProvider, useApi, NextGenDataGrid, useForms, dialogs, JsonForms). Also on any mention of fastapi-rtk or "rtk backend" / "rtk frontend", and in any project importing from `fastapi_rtk` or the `fastapi-rtk` JS package, where it is preferred over plain FastAPI or React guidance.'
@@ -39,7 +39,7 @@ FILE_ALLOWED_EXTENSIONS = ["pdf", "csv", "docx", "xlsx"] # optional
39
39
  IMG_ALLOWED_EXTENSIONS = ["jpg", "jpeg", "png", "gif"] # optional
40
40
  ```
41
41
 
42
- Always use an **async** driver (`aiosqlite`, `asyncpg`). The toolkit is async-first and sync drivers will raise at runtime.
42
+ Prefer an **async** driver (`aiosqlite`, `asyncpg`): the toolkit is async-first and the async path is the tested one. A sync URL falls back to a sync engine and session, and `SQLAInterface` runs the sync session calls through `smart_run`.
43
43
 
44
44
  ## 3. App initialization (`app/app.py`)
45
45
 
@@ -142,18 +142,18 @@ class Item(Model):
142
142
 
143
143
  ## 5. REST APIs: `ModelRestApi`
144
144
 
145
- Registers a full CRUD surface:
145
+ Registers a full CRUD surface under `/api/{version}/{resource_name}` (`version` defaults to `v1`):
146
146
 
147
- - `GET /items`: list (supports pagination, filters, sort via query params)
148
- - `POST /items`: create
149
- - `GET /items/{id}`: detail
150
- - `PUT /items/{id}`: update
151
- - `DELETE /items/{id}`: delete
152
- - `GET /items/_info`: metadata (columns, filters, permissions), which the frontend uses
153
- - `GET /items/_lookup/{column}?mode=add|edit|search`: paged values of one column (see "Column lookup" in §8)
154
- - `GET /items/download`: CSV export
155
- - `POST /items/bulk/{handler}`: bulk operations (see §12)
156
- - `GET /items/_file/{filename}` / `_image/{filename}`: served when the model has file/image columns
147
+ - `GET /api/v1/items`: list (supports pagination, filters, sort via query params)
148
+ - `POST /api/v1/items`: create
149
+ - `GET /api/v1/items/{id}`: detail
150
+ - `PUT /api/v1/items/{id}`: update
151
+ - `DELETE /api/v1/items/{id}`: delete
152
+ - `GET /api/v1/items/_info`: metadata (columns, filters, permissions), which the frontend uses
153
+ - `GET /api/v1/items/_lookup/{column}?mode=add|edit|search`: paged values of one column (see "Column lookup" in §8)
154
+ - `GET /api/v1/items/download`: CSV export
155
+ - `POST /api/v1/items/bulk/{handler}`: bulk operations (see §12)
156
+ - `GET /api/v1/items/_file/{filename}` / `_image/{filename}`: served when the model has file/image columns
157
157
 
158
158
  ```python
159
159
  from fastapi_rtk import ModelRestApi, SQLAInterface, g
@@ -260,7 +260,7 @@ By default every column is listed, shown, added, edited. Override per-operation:
260
260
  class ItemApi(ModelRestApi):
261
261
  datamodel = SQLAInterface(Item)
262
262
 
263
- list_columns = ["id", "name", "category.name"] # GET /items
263
+ list_columns = ["id", "name", "category.name"] # GET /api/v1/items
264
264
  show_columns = ["id", "name", "description", "category"]
265
265
  add_columns = ["name", "description", "category"]
266
266
  edit_columns = ["name", "description"] # can't reassign category
@@ -297,7 +297,7 @@ More per-Api knobs:
297
297
 
298
298
  ### Column lookup
299
299
 
300
- `/_info` ships only the first `max_page_size` options of a relation; `GET /items/_lookup/{column}` searches and pages the values of one column instead. Query params, bound as one `LookupQuerySchema` (per-Api `lookup_query_schema`): `mode` (required: `add`, `edit` or `search`; any other value is 422), `search` (text the values must contain, matched by `FilterSearch` like the list route's `search` param), `page` (zero-based, default 0), `page_size` (default and cap `max_page_size`), `ids` (a JSON list of primary keys to resolve, default `[]`). The response is `LookupResponse`, `{"count": int, "values": [...]}`: `{"id", "value"}` entries for a relation (`value` is `str(item)`), distinct non-null scalars in ascending order for a plain column. The route is dropped from `routes` when no column is lookup-enabled in any mode.
300
+ `/_info` ships only the first `max_page_size` options of a relation; `GET /api/v1/items/_lookup/{column}` searches and pages the values of one column instead. Query params, bound as one `LookupQuerySchema` (per-Api `lookup_query_schema`): `mode` (required: `add`, `edit` or `search`; any other value is 422), `search` (text the values must contain, matched by `FilterSearch` like the list route's `search` param), `page` (zero-based, default 0), `page_size` (default and cap `max_page_size`), `ids` (a JSON list of primary keys to resolve, default `[]`). The response is `LookupResponse`, `{"count": int, "values": [...]}`: `{"id", "value"}` entries for a relation (`value` is `str(item)`), distinct non-null scalars in ascending order for a plain column. The route is dropped from `routes` when no column is lookup-enabled in any mode.
301
301
 
302
302
  - Query validation (400, before access): `ids` that is not JSON (`json_invalid`) or not a list (`list_type`), a negative `page` (`greater_than_equal`), a `page_size` below 1 (`greater_than`).
303
303
  - Gating order: 401 (route protected, no user), 404 `COLUMN_NOT_FOUND` (column not lookup-enabled in that mode), 403 (user lacks `can_post` for `add`, `can_put` for `edit`, `can_get` for `search`). There is no `can_lookup` permission; `"lookup"` in `exclude_protected_routes` skips the 401 and 403 checks.
@@ -414,7 +414,7 @@ class Item(Model):
414
414
  When these columns exist, `ModelRestApi` automatically:
415
415
 
416
416
  - switches POST/PUT to `multipart/form-data`
417
- - exposes `GET /items/_file/{filename}` and `GET /items/_image/{filename}`
417
+ - exposes `GET /api/v1/items/_file/{filename}` and `GET /api/v1/items/_image/{filename}`
418
418
  - grants `can_file` / `can_image` permissions
419
419
 
420
420
  ### File managers
@@ -574,12 +574,13 @@ class ReadingApi(ModelRestApi):
574
574
  download_page_size = 5000
575
575
  ```
576
576
 
577
- Set it to a resolver when the size depends on the query. It receives the Api, the session, and the `DBQueryParams` the export runs with. Sync and async both work, resolved through `safe_call`, so a sync one runs inline rather than on a worker thread:
577
+ Set it to a resolver when the size depends on the query. It receives the Api, the session, and the `DBQueryParams` the export runs with. Sync and async both work, resolved through `safe_call`, so a sync one runs inline rather than on a worker thread. Declare it in the class body as a `@staticmethod`: a plain method is called with `self` prepended and raises `TypeError`.
578
578
 
579
579
  ```python
580
580
  class ReadingApi(ModelRestApi):
581
581
  datamodel = SQLAInterface(Reading)
582
582
 
583
+ @staticmethod
583
584
  def download_page_size(api, session, params):
584
585
  return 1000 if params.get("filters") else 250
585
586
  ```
@@ -619,9 +620,9 @@ Top-level shape: `dict[role_name, list[[api_glob, permission_glob]]]`. Both fiel
619
620
 
620
621
  ### The admin role sits outside `ROLES`
621
622
 
622
- `Setting.AUTH_ROLE_ADMIN` (`setting.py:368`, default `DEFAULT_ADMIN_ROLE = "Admin"` from `const.py:71`) names a role that is deliberately absent from `ROLES`, reachable as `g.admin_role` (`globals.py:141-147`). It holds **every permission of every registered Api**, and a `ROLES` edit cannot narrow that: `_associate_permission_with_api` (`fastapi_react_toolkit.py:506`) writes one `PermissionApi` row per `(permission, api)` taken from each Api's exposed routes plus one per `ROLES` entry, then `_associate_role_with_permission_api` (`:545`) grants the admin role every one of those rows except the ones whose permission name contains `|` (`:566-576`). The per-route row for the same permission is a different row and is never excluded, so piping a `ROLES` entry to hide something from the admin role is a no-op. The cleanup pass also exempts that role from disassociation by name, so an existing grant row survives every restart.
623
+ `Setting.AUTH_ROLE_ADMIN` (`setting.py:368`, default `DEFAULT_ADMIN_ROLE = "Admin"` from `const.py:74`) names a role that is deliberately absent from `ROLES`, reachable as `g.admin_role` (`globals.py:142-149`). It holds **every permission of every registered Api**, and a `ROLES` edit cannot narrow that: `_associate_permission_with_api` (`fastapi_react_toolkit.py:506`) writes one `PermissionApi` row per `(permission, api)` taken from each Api's exposed routes plus one per `ROLES` entry, then `_associate_role_with_permission_api` (`:545`) grants the admin role every one of those rows except the ones whose permission name contains `|` and that a `ROLES` role other than the public role lists (`:562-577`; a piped entry listed only under the public role is still granted to admin). The per-route row for the same permission is a different row and is never excluded, so piping a `ROLES` entry to hide something from the admin role is a no-op. The cleanup pass also exempts that role from disassociation by name, so an existing grant row survives every restart.
623
624
 
624
- Revoking a permission from it means setting `AUTH_ROLE_ADMIN` to `None` or to an existing `ROLES` role name (which strips the blanket grant entirely, since `if g.admin_role:` guards it), or checking inside the route.
625
+ Revoking a permission from it means setting `AUTH_ROLE_ADMIN` to `None` (which strips the blanket grant entirely, since `if g.admin_role:` guards it), or checking inside the route. Pointing `AUTH_ROLE_ADMIN` at an existing `ROLES` role name revokes nothing: that role becomes the admin role, receives the blanket grant, and is exempt from cleanup.
625
626
 
626
627
  ### Asking whether a user holds a permission
627
628
 
@@ -661,7 +662,7 @@ A name listed in an Api's `base_permissions` that no exposed route carries becom
661
662
 
662
663
  ### What the browser gets
663
664
 
664
- `GET auth/user` sets `permissions` to the **Api names** the user holds any grant on, not permission names: `select(Api.name).join(PermissionApi).join(PermissionApi.roles).where(Role.id.in_(user role ids)).distinct()` (`security/sqla/apis.py:134-151`), typed as `AuthUser.permissions: string[]` in the JS client. So a browser-side gate can ask "any grant on Api A" and cannot distinguish `can_get` from `can_post`; per-permission detail reaches the frontend through an Api's `_info` response instead (`permissions`, `schemas.py:83`). Prefer that Api-level fact over publishing a role list in the frontend config, and keep the enforcing check server-side.
665
+ `GET auth/user` sets `permissions` to the **Api names** the user holds any grant on, not permission names: `select(Api.name).join(PermissionApi).join(PermissionApi.roles).where(Role.id.in_(user role ids)).distinct()` (`security/sqla/apis.py:155-166`), typed as `AuthUser.permissions: string[]` in the JS client. So a browser-side gate can ask "any grant on Api A" and cannot distinguish `can_get` from `can_post`; per-permission detail reaches the frontend through an Api's `_info` response instead (`InfoResponse.permissions`, `schemas.py:302`). Prefer that Api-level fact over publishing a role list in the frontend config, and keep the enforcing check server-side.
665
666
 
666
667
  ### Route guards
667
668
 
@@ -717,7 +718,7 @@ A `"backend": "jwt"` client (for clients without a browser cookie store, such as
717
718
 
718
719
  ```bash
719
720
  fastapi-rtk db init
720
- fastapi-rtk db migrate -m "add items"
721
+ fastapi-rtk db migrate --message "add items"
721
722
  fastapi-rtk db upgrade
722
723
  fastapi-rtk db downgrade
723
724
 
@@ -10,7 +10,7 @@ The toolkit expects Mantine as the UI kit. Use `Stack`, `Group`, `Grid`, `Simple
10
10
  pnpm add fastapi-rtk @mantine/core @mantine/dates @mantine/form @mantine/hooks dayjs react-router
11
11
  ```
12
12
 
13
- Peer deps: the four `@mantine/*` packages (`^9.0.0`), `react` / `react-dom` (`^19.2.3`), `dayjs` (`^1.11.0`) and `react-router` (`^7.5.3 || ^8.0.0`). Everything else (mantine-react-table, TanStack Query, zustand, i18next, JsonForms) is bundled inside `fastapi-rtk`. Mantine >= 9.4.1 requires fastapi-rtk >= 2.8.0; older releases loop forever in the grid's `useColumns` ("Maximum update depth exceeded").
13
+ Peer deps: the four `@mantine/*` packages (`^9.4.0`), `react` / `react-dom` (`^19.2.3`), `dayjs` (`^1.11.0`) and `react-router` (`^7.5.3 || ^8.0.0`), plus the optional `@jsonforms/core` / `@jsonforms/react` (`^3.6.0`), needed only when importing from `fastapi-rtk/jsonforms` (every other subpath, its types included, works without them). TanStack Query (`^5.52.1`), zustand, i18next, react-i18next, yup, lodash, clsx and dompurify are regular dependencies, installed with `fastapi-rtk`; only mantine-react-table (patched), mantine-form-yup-resolver and the JsonForms copy behind the built-in forms are bundled inside it. When the app's own TanStack Query or react-i18next resolves to the same copy, its `useQuery` / `useQueryClient` / `useTranslation` inside a `Provider` read the Provider's `QueryClient` and i18next instance, since `Provider` always creates its own `QueryClient`; `rq` / `i18nr` / `useTranslation` imported from `fastapi-rtk` always do. Outside a `Provider`, the app's `useTranslation` keeps the app's own i18next instance. To keep the app's own instance inside a `Provider` as well, pass it as `langProps.i18n`. Mantine >= 9.4.1 requires fastapi-rtk >= 2.8.0; older releases loop forever in the grid's `useColumns` ("Maximum update depth exceeded").
14
14
 
15
15
  **Provider order is load-bearing.** Mantine must wrap the fastapi-rtk `Provider`, and the stylesheet order matters: Mantine CSS first, fastapi-rtk CSS last (RTK overrides).
16
16
 
@@ -105,7 +105,7 @@ function ItemsPage() {
105
105
  | `data` | Current list/page payload for the bound resource |
106
106
  | `info` | The `/_info` response for the resource (`add_columns`, `edit_columns`, `permissions`, …) |
107
107
  | `loading` / `dataLoading` / `infoLoading` | Aggregate + per-stream fetch flags |
108
- | `error` / `dataError` / `infoError` | Aggregate + per-stream error objects (`{message, originalError}`) |
108
+ | `error` / `dataError` / `infoError` | Aggregate `{message, originalError}` object + the per-stream raw query `Error` objects |
109
109
  | `getEntry(id)` | `GET /{resource}/{id}` |
110
110
  | `addEntry(item)` | `POST /{resource}` |
111
111
  | `updateEntry(id, item)` | `PUT /{resource}/{id}` |
@@ -147,7 +147,7 @@ await addEntry({ name: "x" }); // POST /{resource}
147
147
  await updateEntry(id, { name: "y" }); // PUT /{resource}/{id}
148
148
  ```
149
149
 
150
- **Option B, use the TanStack Query namespace `rq`.** `fastapi-rtk` re-exports `@tanstack/react-query` as `rq` (`export * as rq from '@tanstack/react-query'` in `api/src/index.ts:38`, surfaced by `core/src/index.ts:94`; the sibling `mrt` namespace re-exports `mantine-react-table` from `core/src/index.ts:95`, with long-form aliases `reactQuery` / `mantineReactTable`). Wrap a `useApi` action (or any toolkit-provided async function) in `rq.useQuery` / `rq.useMutation` so the result participates in the shared query cache (invalidation, refetch-on-focus, devtools). Never call raw `fetch` from the `queryFn` / `mutationFn`, since that re-introduces the exact problems `useCustomFetch` has.
150
+ **Option B, use the TanStack Query namespace `rq`.** `fastapi-rtk` re-exports its `@tanstack/react-query` as `rq` (`export * as rq from './rq'` in `externals/src/index.ts`, surfaced by `core/src/index.ts:94`; import it from there rather than from `@tanstack/react-query`, since an app's own copy sees the Provider's `QueryClient` only when it resolves to the same install; the sibling `mrt` namespace re-exports the bundled `mantine-react-table` the same way, with long-form aliases `reactQuery` / `mantineReactTable` at `core/src/index.ts:96`). The same namespaces, plus `ld` (lodash), `zs` (zustand), `yup` and `i18nr` (react-i18next), are importable from `fastapi-rtk` or `fastapi-rtk/externals`; importing them from `fastapi-rtk/api`, `/utils`, `/zustand` or `/contexts` is deprecated. Wrap a `useApi` action (or any toolkit-provided async function) in `rq.useQuery` / `rq.useMutation` so the result participates in the shared query cache (invalidation, refetch-on-focus, devtools). Never call raw `fetch` from the `queryFn` / `mutationFn`, since that re-introduces the exact problems `useCustomFetch` has.
151
151
 
152
152
  ```jsx
153
153
  import { useApi, rq } from "fastapi-rtk";
@@ -169,7 +169,7 @@ function ReportsPanel({ id }) {
169
169
  }
170
170
  ```
171
171
 
172
- **Combine with `useApi` for cross-resource updates.** Use a `useApi` action for the bound resource and `rq.useMutation` wrapping a sibling `useApi` action for the second resource. To refresh the bound resource's grid after a mutation, call `refetch({ force: true })` from `useApi()` inside `onSuccess`, which hits the same query the grid renders from (`['data', path, queryParamsJSON, lang]` in `useProvideApi.js`). Toolkit-internal key shape is an implementation detail; use the `useApi` helpers to invalidate rather than constructing the key yourself.
172
+ **Combine with `useApi` for cross-resource updates.** Use a `useApi` action for the bound resource and `rq.useMutation` wrapping a sibling `useApi` action for the second resource. To refresh the bound resource's grid after a mutation, call `refetch({ force: true })` from `useApi()` inside `onSuccess`, which hits the same query the grid renders from (`['data', path, queryParamsJSON, lang]` in `useProvideApi.ts`). Toolkit-internal key shape is an implementation detail; use the `useApi` helpers to invalidate rather than constructing the key yourself.
173
173
 
174
174
  **Last resort: `useCustomFetch`.** Still exported for legacy call sites. Signature: `useCustomFetch(url, { autoInvoke, initialLoading, clearDataOnRefetch, ...fetchOptions })`; returns `{ data, loading, error, refetch, abort, resetError }`. `refetch()` re-runs the request with the URL + options bound at hook creation; there is no `execute(...)` and no per-call body override. If you need either, switch to `rq.useMutation`.
175
175
 
@@ -202,12 +202,22 @@ info?.forEach((api) => /* render menu entry for api.path */);
202
202
  ```jsx
203
203
  import { useAuth } from "fastapi-rtk";
204
204
 
205
- const { user, signin, signout, oauth_signin, update, resetPassword, refetch } =
206
- useAuth();
207
-
208
- await signin(username, password); // positional args, NOT an object
209
- await oauth_signin("google", /* popup */ false);
205
+ const {
206
+ user,
207
+ error,
208
+ signin,
209
+ signout,
210
+ oauthSignin,
211
+ oauthCallback,
212
+ update,
213
+ resetPassword,
214
+ refetch,
215
+ } = useAuth();
216
+
217
+ await signin({ username, password }); // a single credentials object
218
+ await oauthSignin("google", /* popup */ false); // oauth_signin is the deprecated alias
210
219
  await signout();
220
+ error?.message; // { message, originalError } of the last failed action, or undefined
211
221
 
212
222
  user?.username;
213
223
  user?.roles; // string[] of role names
@@ -216,7 +226,7 @@ user?.permissions; // string[] of API NAMES the user holds any grant on
216
226
 
217
227
  Gate routes/components on `user` and `user.roles`. The Provider keeps the session via cookie, so `user` is populated on every page load automatically.
218
228
 
219
- An OAuth provider configured with `"backend": "jwt"` is for clients without a browser cookie store (React Native on `createReactNativeAdapters`, whose bearer transport stores the token); web apps default to `cookie` providers, since a bearer transport on web keeps the token in `localStorage`, readable by any script on the origin. A web app can still opt into JWT: `adapters={{ authTransport: createBearerTransport(webAdapters.storage) }}`, the provider's `redirect_url` at an app route, and `oauthCallback("google", window.location.search)` on that route. On React Native: point the provider's `redirect_url` at the app's deep link (`myapp://oauth/google`), pass the same URL as `createReactNativeAdapters({ ..., oauthRedirectUrl })` (a string for every provider, or `{ google: "myapp://oauth/google", github: "..." }` keyed by provider name), and call `oauthSignin("google", false)` (no popup). A provider missing from that map fails before any browser opens (`error` is `Could not sign in`, `originalError` names the provider). iOS ends the session on any URL with the redirect URL's scheme (so `myapp://oauth/google` and `myapp://oauth/github` are not told apart there), Android on the first deep link starting with it; for an `https` redirect on iOS 17.4+ pass `oauthPreferUniversalLinks: true` (needs the Associated Domains entitlement) to match host and path instead. The RN opener runs `webBrowser.openAuthSessionAsync(loginUrl, oauthRedirectUrl, { preferUniversalLinks })` and hands the redirected URL back, and `oauthSignin` forwards its `code` / `state` to `auth/oauth-authorized/<provider>`, stores the returned token through `authTransport.persistLogin`, and refetches the user; a failure sets `error` to `Could not sign in`. An app that receives the redirect another way calls `oauthCallback("google", redirectQuery)` from `useAuth()` with that URL's query string.
229
+ An OAuth provider configured with `"backend": "jwt"` is for clients without a browser cookie store (React Native on `createReactNativeAdapters`, whose bearer transport stores the token); web apps default to `cookie` providers, since a bearer transport on web keeps the token in `localStorage`, readable by any script on the origin. A web app can still opt into JWT: `adapters={{ authTransport: createBearerTransport(webAdapters.storage) }}`, the provider's `redirect_url` at an app route, and `oauthCallback("google", window.location.search)` on that route. On React Native: point the provider's `redirect_url` at the app's deep link (`myapp://oauth/google`), pass the same URL as `createReactNativeAdapters({ ..., oauthRedirectUrl })` (a string for every provider, or `{ google: "myapp://oauth/google", github: "..." }` keyed by provider name), and call `oauthSignin("google", false)` (no popup). A provider missing from that map fails before any browser opens (`error.message` is `Could not sign in`, `error.originalError` names the provider). iOS ends the session on any URL with the redirect URL's scheme (so `myapp://oauth/google` and `myapp://oauth/github` are not told apart there), Android on the first deep link starting with it; for an `https` redirect on iOS 17.4+ pass `oauthPreferUniversalLinks: true` (needs the Associated Domains entitlement) to match host and path instead. The RN opener runs `webBrowser.openAuthSessionAsync(loginUrl, oauthRedirectUrl, { preferUniversalLinks })` and hands the redirected URL back, and `oauthSignin` forwards its `code` / `state` to `auth/oauth-authorized/<provider>`, stores the returned token through `authTransport.persistLogin`, and refetches the user; a failure sets `error.message` to `Could not sign in`. An app that receives the redirect another way calls `oauthCallback("google", redirectQuery)` from `useAuth()` with that URL's query string.
220
230
 
221
231
  **`user.permissions` holds Api names, not permission names.** `auth/user` builds it as `select(Api.name)` joined through the user's roles (backend reference §14, "What the browser gets"), so `user.permissions.includes("ItemApi")` answers "has any grant on that Api" and nothing finer: `can_get` and `can_post` are indistinguishable there. It is the right gate for "may this user reach this resource at all", and it beats shipping a role list through the frontend config, since it follows the grants themselves and leaves no second list to keep in step. For per-verb detail read `useApi().info.permissions` (§5), which is that Api's `/_info` intersected with the user's grants.
222
232
 
@@ -403,7 +413,7 @@ const { t } = useTranslation(); // or: translation.t
403
413
  <LanguageSelector />;
404
414
  ```
405
415
 
406
- `useLang` reads/writes the selected language to localStorage. The translation function `t(key)` comes from react-i18next via `useTranslation()` (also re-exported from `fastapi-rtk`) or via the `translation` field on `useLang()`. Source strings double as the English keys; a German dictionary ships built-in. Extend or override through the `Provider`'s `langProps` prop: `langProps.getI18nProps.translations` takes `{locale: {key: value}}`, `langProps.i18n` accepts a full i18next instance, and `langProps.MRTLocalization` overrides the grid's Mantine React Table strings.
416
+ `useLang` reads/writes the selected language to localStorage. The translation function `t(key)` comes from the `useTranslation()` exported by `fastapi-rtk` (the react-i18next one, which the Provider wires to its i18next instance, as it does `i18nr.Trans`; the one imported from `react-i18next` itself sees it only when the app's react-i18next resolves to the same install) or via the `translation` field on `useLang()`. Source strings double as the English keys; a German dictionary ships built-in. Extend or override through the `Provider`'s `langProps` prop: `langProps.getI18nProps.translations` takes `{locale: {key: value}}`, `langProps.i18n` accepts a full i18next instance, and `langProps.MRTLocalization` overrides the grid's Mantine React Table strings.
407
417
 
408
418
  ## 13. Standard routes: `UserMenu`
409
419
 
@@ -473,7 +483,7 @@ Cookie login is on by default on the backend; the JWT endpoint exists only when
473
483
 
474
484
  ## 15. Other notable exports
475
485
 
476
- - Every context hook accepts safe-context options: `useApi({ throwOnError: false })` returns `undefined` instead of throwing outside its provider (same option on the other hooks).
486
+ - Every context hook accepts safe-context options: `useApi({ throwOnError: false })` returns the `defaultValue` option (an empty object `{}` unless you pass one) instead of throwing outside its provider (same option on the other hooks).
477
487
  - Headless fetcher layer for code outside any provider: `buildRequest`, `getItems` / `getItem` / `createItem` / `updateItem` / `deleteItem` / `getInfo`, `formCreateItem` / `formUpdateItem`, `uploadItems` / `downloadItems`, `postBulk`, plus `useAdapters` / `webAdapters`.
478
488
  - Legacy `DataGrid` is still exported alongside `NextGenDataGrid`; standalone `ActionIcons` (`Actions`, `Add`, `Delete`, `Download`, `Edit`, `Refresh`, `Upload`, `View`) and `Filter` compose custom layouts.
479
489
  - Utilities: `deepMerge`, `parseFromValuesOrFunc`, `createSafeContext`, `getItemId`, `urlJoin`, `Memoizer`, `FastAPIRTKLogger`; hooks `useActionIcon`, `useSyncValues`, `useTrueOnce`.
@@ -92,7 +92,7 @@ const customizer = {
92
92
  - `componentProps` : the fully computed Mantine props the built-in would have used: `value`, `onChange` (already wired to JsonForms `handleChange(path, value)`), `onBlur`, `label`, `description`, `required`, `disabled`, `error`, plus `uischema.options.props` and `ifProps` (§2). Spread it onto a value-based Mantine input and the field is controlled and validated for free.
93
93
  - `jsonFormsProps` : the raw control props (`data`, `handleChange`, `path`, `schema`, `uischema`, `enabled`, `errors`, `visible`, `id`). Reach here when `componentProps` is not enough, or call `useCommonProps(jsonFormsProps)` (from `fastapi-rtk`) to have the library rebuild the `handleChange(path, value)` wrapper for you.
94
94
 
95
- `key` is a **renderer name** (`Text`, `Number`, `Integer`, `Boolean`, `Date`, `DateTime`, `Time`, `Enum`, `EnumArray`, `OneOfEnum`, `File`, `Image`, `Json`, `Object`, `Label`, `Table`, `Array`, `Array.Accordion`), a **JsonForms path / field name** (`status`, `details.category`), or `all`. Precedence when several match: `all` < renderer-name < path (slots deep-merge in that order, most specific wins). Since 2.8.0 every structural wrapper is addressable too: `Table.Thead` / `Table.Tbody` / `Table.Empty`, `Table.Header.*` (`Tr`, `Actions`, `Validation`, `Toolbar`, `Wrapper`, `Flex`), `Table.Row.*` (`Tr`, `Td`, `Actions`, `Grid`, `Up`, `Down`, `Remove`), per-row / per-cell addressing (`Table.Row.{index}`, `Table.Row.{index}.{subPath}`, `Table.Row.{subPath}`), `Array.Stack` / `Array.Items` / `Array.Empty` / `Array.Header.*` / `Array.Item.*` / `Array.DeleteDialog`, `File.Box` / `Image.Box`, and `Label.{text}`. (Collision escape: when a real field is named `all`, the wildcard moves to the exported `specialKey.all`.)
95
+ `key` is a **renderer name** (`Text`, `Number`, `Integer`, `Boolean`, `Date`, `DateTime`, `Time`, `Enum`, `EnumArray`, `OneOfEnum`, `File`, `Image`, `Json`, `Object`, `Label`, `Table`, `Array`, `Array.Accordion`), a **JsonForms path / field name** (`status`, `details.category`), or `all`. Precedence when several match: `all` < renderer-name < path (slots deep-merge in that order, most specific wins). Since 2.8.0 every structural wrapper is addressable too: `Table.Thead` / `Table.Tbody` / `Table.Empty`, `Table.Header.*` (`Tr`, `Actions`, `Validation`, `Toolbar`, `Wrapper`, `Flex`), `Table.Row.*` (`Tr`, `Td`, `Actions`, `Grid`, `Up`, `Down`, `Remove`), per-row / per-cell addressing (`Table.Row.{index}`, `Table.Row.{index}.{subPath}`, `Table.Row.{subPath}`), `Array.Stack` / `Array.Items` / `Array.Empty` / `Array.Header.*` / `Array.Item.*` / `Array.DeleteDialog`, `File.Box` / `Image.Box`, and `Label.{text}`. (Collision escape: when the resource's `list_columns` contains a column named `all`, the wildcard key becomes `_all`; read it at runtime as `useApi().specialKey.all`, which is `all` outside an `ApiProvider`.)
96
96
 
97
97
  **Write the component** as a plain Mantine component. For a blob field, `JSON.parse` on read and `JSON.stringify` on write; keep spreading `{...componentProps}` so the label / description / error wrapper still renders:
98
98
 
@@ -7,6 +7,8 @@ import zipfile
7
7
 
8
8
  import typer.main
9
9
  import typer.testing
10
+ import yaml
11
+
10
12
  from fastapi_rtk.cli.cli import app, main
11
13
  from fastapi_rtk.cli.commands.agent.adapters import AgentsMDAdapter, ClaudeAdapter
12
14
  from fastapi_rtk.cli.commands.agent.base import AbstractAgentAdapter
@@ -290,6 +292,17 @@ class TestInstallAgentDocs:
290
292
  assert skill.startswith("---\nname: rtk-developer\n")
291
293
  assert GUIDE_TARGET in skill
292
294
 
295
+ def test_skill_frontmatter_is_valid_yaml(self, tmp_path):
296
+ runner.invoke(
297
+ app, ["agent", "install", "--directory", str(tmp_path), "--claude"]
298
+ )
299
+ skill = (tmp_path / SKILL_TARGET / "SKILL.md").read_text()
300
+ frontmatter = yaml.safe_load(skill.split("---\n")[1])
301
+ assert frontmatter["name"] == "rtk-developer"
302
+ assert frontmatter["description"].startswith(
303
+ "Use when building, modifying or debugging anything in a fastapi-rtk project: "
304
+ )
305
+
293
306
  def test_guide_and_skill_carry_the_same_pointers(self, tmp_path):
294
307
  runner.invoke(
295
308
  app, ["agent", "install", "--directory", str(tmp_path), "--claude"]
@@ -1 +0,0 @@
1
- __version__ = "2.20.0"
@@ -1,2 +0,0 @@
1
- name: rtk-developer
2
- description: Use when building, modifying or debugging anything in a fastapi-rtk project: Python models, ModelRestApi or BaseApi endpoints, pre/post hooks, permissions, migrations, file uploads, bulk operations, or the React side (Provider setup, ApiProvider, useApi, NextGenDataGrid, useForms, dialogs, JsonForms). Also on any mention of fastapi-rtk or "rtk backend" / "rtk frontend", and in any project importing from `fastapi_rtk` or the `fastapi-rtk` JS package, where it is preferred over plain FastAPI or React guidance.
File without changes
File without changes