supython 0.1.5__tar.gz → 0.1.7__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 (253) hide show
  1. {supython-0.1.5 → supython-0.1.7}/PKG-INFO +31 -6
  2. {supython-0.1.5 → supython-0.1.7}/README.md +30 -5
  3. {supython-0.1.5 → supython-0.1.7}/pyproject.toml +1 -1
  4. {supython-0.1.5 → supython-0.1.7}/src/supython/app.py +0 -2
  5. {supython-0.1.5 → supython-0.1.7}/src/supython/auth/claims.py +5 -4
  6. {supython-0.1.5 → supython-0.1.7}/src/supython/functions/context.py +28 -6
  7. {supython-0.1.5 → supython-0.1.7}/.gitignore +0 -0
  8. {supython-0.1.5 → supython-0.1.7}/CHANGELOG.md +0 -0
  9. {supython-0.1.5 → supython-0.1.7}/LICENSE +0 -0
  10. {supython-0.1.5 → supython-0.1.7}/SECURITY.md +0 -0
  11. {supython-0.1.5 → supython-0.1.7}/src/supython/__init__.py +0 -0
  12. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/__init__.py +0 -0
  13. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/api/__init__.py +0 -0
  14. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/api/auth.py +0 -0
  15. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/api/auth_templates.py +0 -0
  16. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/api/auth_users.py +0 -0
  17. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/api/db.py +0 -0
  18. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/api/functions.py +0 -0
  19. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/api/jobs.py +0 -0
  20. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/api/ops.py +0 -0
  21. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/api/realtime.py +0 -0
  22. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/api/service_auth.py +0 -0
  23. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/api/service_auth_templates.py +0 -0
  24. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/api/service_auth_users.py +0 -0
  25. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/api/service_db.py +0 -0
  26. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/api/service_functions.py +0 -0
  27. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/api/service_jobs.py +0 -0
  28. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/api/service_ops.py +0 -0
  29. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/api/service_realtime.py +0 -0
  30. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/api/service_storage.py +0 -0
  31. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/api/storage.py +0 -0
  32. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/api/system.py +0 -0
  33. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/audit.py +0 -0
  34. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/deps.py +0 -0
  35. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/errors.py +0 -0
  36. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/schemas.py +0 -0
  37. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/session.py +0 -0
  38. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/spa.py +0 -0
  39. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Alert-dluGVkos.js +0 -0
  40. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Alert-dluGVkos.js.map +0 -0
  41. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Audit-Njung3HI.js +0 -0
  42. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Audit-Njung3HI.js.map +0 -0
  43. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Backups-DzPlFgrm.js +0 -0
  44. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Backups-DzPlFgrm.js.map +0 -0
  45. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Buckets-ByacGkU1.js +0 -0
  46. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Buckets-ByacGkU1.js.map +0 -0
  47. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Channels-BoIuTtam.js +0 -0
  48. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Channels-BoIuTtam.js.map +0 -0
  49. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/ChevronRight-CtQH1EQ1.js +0 -0
  50. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/ChevronRight-CtQH1EQ1.js.map +0 -0
  51. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/CodeViewer-Bqy7-wvH.js +0 -0
  52. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/CodeViewer-Bqy7-wvH.js.map +0 -0
  53. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Crons-B67vc39F.js +0 -0
  54. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Crons-B67vc39F.js.map +0 -0
  55. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/DashboardView-CUTFVL6k.js +0 -0
  56. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/DashboardView-CUTFVL6k.js.map +0 -0
  57. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/DataTable-COAAWEft.js +0 -0
  58. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/DataTable-COAAWEft.js.map +0 -0
  59. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/DescriptionsItem-P8JUDaBs.js +0 -0
  60. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/DescriptionsItem-P8JUDaBs.js.map +0 -0
  61. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/DrawerContent-TpYTFgF1.js +0 -0
  62. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/DrawerContent-TpYTFgF1.js.map +0 -0
  63. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Empty-cr2r7e2u.js +0 -0
  64. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Empty-cr2r7e2u.js.map +0 -0
  65. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/EmptyState-DeDck-OL.js +0 -0
  66. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/EmptyState-DeDck-OL.js.map +0 -0
  67. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Grid-hFkp9F4P.js +0 -0
  68. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Grid-hFkp9F4P.js.map +0 -0
  69. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Input-DppYTq9C.js +0 -0
  70. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Input-DppYTq9C.js.map +0 -0
  71. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Invoke-DW3Nveeh.js +0 -0
  72. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Invoke-DW3Nveeh.js.map +0 -0
  73. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/JsonField-DibyJgun.js +0 -0
  74. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/JsonField-DibyJgun.js.map +0 -0
  75. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/LoginView-BjLyE3Ds.css +0 -0
  76. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/LoginView-CoOjECT_.js +0 -0
  77. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/LoginView-CoOjECT_.js.map +0 -0
  78. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Logs-D9WYrnIT.js +0 -0
  79. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Logs-D9WYrnIT.js.map +0 -0
  80. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Logs-DS1XPa0h.css +0 -0
  81. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Migrations-DOSC2ddQ.js +0 -0
  82. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Migrations-DOSC2ddQ.js.map +0 -0
  83. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/ObjectBrowser-_5w8vOX8.js +0 -0
  84. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/ObjectBrowser-_5w8vOX8.js.map +0 -0
  85. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Queue-CywZs6vI.js +0 -0
  86. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Queue-CywZs6vI.js.map +0 -0
  87. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/RefreshTokens-Ccjr53jg.js +0 -0
  88. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/RefreshTokens-Ccjr53jg.js.map +0 -0
  89. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/RlsEditor-BSlH9vSc.js +0 -0
  90. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/RlsEditor-BSlH9vSc.js.map +0 -0
  91. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Routes-BiLXE49D.js +0 -0
  92. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Routes-BiLXE49D.js.map +0 -0
  93. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Routes-C-ianIGD.css +0 -0
  94. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/SchemaBrowser-DKy2_KQi.css +0 -0
  95. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/SchemaBrowser-XFvFbtDB.js +0 -0
  96. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/SchemaBrowser-XFvFbtDB.js.map +0 -0
  97. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Select-DIzZyRZb.js +0 -0
  98. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Select-DIzZyRZb.js.map +0 -0
  99. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Space-n5-XcguU.js +0 -0
  100. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Space-n5-XcguU.js.map +0 -0
  101. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/SqlEditor-b8pTsILY.js +0 -0
  102. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/SqlEditor-b8pTsILY.js.map +0 -0
  103. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/SqlWorkspace-BUS7IntH.js +0 -0
  104. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/SqlWorkspace-BUS7IntH.js.map +0 -0
  105. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/TableData-CQIagLKn.js +0 -0
  106. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/TableData-CQIagLKn.js.map +0 -0
  107. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Tag-D1fOKpTH.js +0 -0
  108. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Tag-D1fOKpTH.js.map +0 -0
  109. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Templates-BS-ugkdq.js +0 -0
  110. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Templates-BS-ugkdq.js.map +0 -0
  111. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Thing-CEAniuMg.js +0 -0
  112. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Thing-CEAniuMg.js.map +0 -0
  113. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Users-wzwajhlh.js +0 -0
  114. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/Users-wzwajhlh.js.map +0 -0
  115. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/_plugin-vue_export-helper-DGA9ry_j.js +0 -0
  116. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/dist-VXIJLCYq.js +0 -0
  117. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/dist-VXIJLCYq.js.map +0 -0
  118. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/format-length-CGCY1rMh.js +0 -0
  119. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/format-length-CGCY1rMh.js.map +0 -0
  120. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/get-Ca6unauB.js +0 -0
  121. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/get-Ca6unauB.js.map +0 -0
  122. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/index-CeE6v959.js +0 -0
  123. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/index-CeE6v959.js.map +0 -0
  124. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/pinia-COXwfrOX.js +0 -0
  125. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/pinia-COXwfrOX.js.map +0 -0
  126. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/resources-Bt6thQCD.js +0 -0
  127. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/resources-Bt6thQCD.js.map +0 -0
  128. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/use-locale-mtgM0a3a.js +0 -0
  129. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/use-locale-mtgM0a3a.js.map +0 -0
  130. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/use-merged-state-BvhkaHNX.js +0 -0
  131. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/use-merged-state-BvhkaHNX.js.map +0 -0
  132. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/useConfirm-tMjvBFXR.js +0 -0
  133. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/useConfirm-tMjvBFXR.js.map +0 -0
  134. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/useResource-C_rJCY8C.js +0 -0
  135. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/useResource-C_rJCY8C.js.map +0 -0
  136. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/useTable-CnZc5zhi.js +0 -0
  137. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/useTable-CnZc5zhi.js.map +0 -0
  138. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/useTable-Dg0XlRlq.css +0 -0
  139. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/useToast-DsZKx0IX.js +0 -0
  140. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/useToast-DsZKx0IX.js.map +0 -0
  141. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/utils-sbXoq7Ir.js +0 -0
  142. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/assets/utils-sbXoq7Ir.js.map +0 -0
  143. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/favicon.svg +0 -0
  144. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/icons.svg +0 -0
  145. {supython-0.1.5 → supython-0.1.7}/src/supython/admin/static/index.html +0 -0
  146. {supython-0.1.5 → supython-0.1.7}/src/supython/auth/__init__.py +0 -0
  147. {supython-0.1.5 → supython-0.1.7}/src/supython/auth/_email_job.py +0 -0
  148. {supython-0.1.5 → supython-0.1.7}/src/supython/auth/deps.py +0 -0
  149. {supython-0.1.5 → supython-0.1.7}/src/supython/auth/providers/__init__.py +0 -0
  150. {supython-0.1.5 → supython-0.1.7}/src/supython/auth/providers/github.py +0 -0
  151. {supython-0.1.5 → supython-0.1.7}/src/supython/auth/providers/google.py +0 -0
  152. {supython-0.1.5 → supython-0.1.7}/src/supython/auth/providers/oauth.py +0 -0
  153. {supython-0.1.5 → supython-0.1.7}/src/supython/auth/providers/registry.py +0 -0
  154. {supython-0.1.5 → supython-0.1.7}/src/supython/auth/ratelimit.py +0 -0
  155. {supython-0.1.5 → supython-0.1.7}/src/supython/auth/router.py +0 -0
  156. {supython-0.1.5 → supython-0.1.7}/src/supython/auth/schemas.py +0 -0
  157. {supython-0.1.5 → supython-0.1.7}/src/supython/auth/service.py +0 -0
  158. {supython-0.1.5 → supython-0.1.7}/src/supython/backups/__init__.py +0 -0
  159. {supython-0.1.5 → supython-0.1.7}/src/supython/backups/_backup_job.py +0 -0
  160. {supython-0.1.5 → supython-0.1.7}/src/supython/backups/schemas.py +0 -0
  161. {supython-0.1.5 → supython-0.1.7}/src/supython/backups/service.py +0 -0
  162. {supython-0.1.5 → supython-0.1.7}/src/supython/body_size.py +0 -0
  163. {supython-0.1.5 → supython-0.1.7}/src/supython/cli.py +0 -0
  164. {supython-0.1.5 → supython-0.1.7}/src/supython/client/__init__.py +0 -0
  165. {supython-0.1.5 → supython-0.1.7}/src/supython/client/_auth.py +0 -0
  166. {supython-0.1.5 → supython-0.1.7}/src/supython/client/_client.py +0 -0
  167. {supython-0.1.5 → supython-0.1.7}/src/supython/client/_config.py +0 -0
  168. {supython-0.1.5 → supython-0.1.7}/src/supython/client/_functions.py +0 -0
  169. {supython-0.1.5 → supython-0.1.7}/src/supython/client/_storage.py +0 -0
  170. {supython-0.1.5 → supython-0.1.7}/src/supython/client/py.typed +0 -0
  171. {supython-0.1.5 → supython-0.1.7}/src/supython/db.py +0 -0
  172. {supython-0.1.5 → supython-0.1.7}/src/supython/db_admin.py +0 -0
  173. {supython-0.1.5 → supython-0.1.7}/src/supython/extensions.py +0 -0
  174. {supython-0.1.5 → supython-0.1.7}/src/supython/functions/__init__.py +0 -0
  175. {supython-0.1.5 → supython-0.1.7}/src/supython/functions/loader.py +0 -0
  176. {supython-0.1.5 → supython-0.1.7}/src/supython/functions/router.py +0 -0
  177. {supython-0.1.5 → supython-0.1.7}/src/supython/functions/schemas.py +0 -0
  178. {supython-0.1.5 → supython-0.1.7}/src/supython/gen/__init__.py +0 -0
  179. {supython-0.1.5 → supython-0.1.7}/src/supython/gen/_introspect.py +0 -0
  180. {supython-0.1.5 → supython-0.1.7}/src/supython/gen/types_py.py +0 -0
  181. {supython-0.1.5 → supython-0.1.7}/src/supython/gen/types_ts.py +0 -0
  182. {supython-0.1.5 → supython-0.1.7}/src/supython/health.py +0 -0
  183. {supython-0.1.5 → supython-0.1.7}/src/supython/hooks.py +0 -0
  184. {supython-0.1.5 → supython-0.1.7}/src/supython/jobs/__init__.py +0 -0
  185. {supython-0.1.5 → supython-0.1.7}/src/supython/jobs/backends.py +0 -0
  186. {supython-0.1.5 → supython-0.1.7}/src/supython/jobs/context.py +0 -0
  187. {supython-0.1.5 → supython-0.1.7}/src/supython/jobs/cron.py +0 -0
  188. {supython-0.1.5 → supython-0.1.7}/src/supython/jobs/cron_inproc.py +0 -0
  189. {supython-0.1.5 → supython-0.1.7}/src/supython/jobs/decorators.py +0 -0
  190. {supython-0.1.5 → supython-0.1.7}/src/supython/jobs/registry.py +0 -0
  191. {supython-0.1.5 → supython-0.1.7}/src/supython/jobs/router.py +0 -0
  192. {supython-0.1.5 → supython-0.1.7}/src/supython/jobs/schemas.py +0 -0
  193. {supython-0.1.5 → supython-0.1.7}/src/supython/jobs/service.py +0 -0
  194. {supython-0.1.5 → supython-0.1.7}/src/supython/jobs/worker.py +0 -0
  195. {supython-0.1.5 → supython-0.1.7}/src/supython/jwks.py +0 -0
  196. {supython-0.1.5 → supython-0.1.7}/src/supython/keyset.py +0 -0
  197. {supython-0.1.5 → supython-0.1.7}/src/supython/logging_config.py +0 -0
  198. {supython-0.1.5 → supython-0.1.7}/src/supython/mail.py +0 -0
  199. {supython-0.1.5 → supython-0.1.7}/src/supython/mailer.py +0 -0
  200. {supython-0.1.5 → supython-0.1.7}/src/supython/migrate.py +0 -0
  201. {supython-0.1.5 → supython-0.1.7}/src/supython/migrations/0001_extensions_and_roles.sql +0 -0
  202. {supython-0.1.5 → supython-0.1.7}/src/supython/migrations/0002_auth_schema.sql +0 -0
  203. {supython-0.1.5 → supython-0.1.7}/src/supython/migrations/0003_demo_todos.sql +0 -0
  204. {supython-0.1.5 → supython-0.1.7}/src/supython/migrations/0004_auth_v0_2.sql +0 -0
  205. {supython-0.1.5 → supython-0.1.7}/src/supython/migrations/0005_storage_schema.sql +0 -0
  206. {supython-0.1.5 → supython-0.1.7}/src/supython/migrations/0006_realtime_schema.sql +0 -0
  207. {supython-0.1.5 → supython-0.1.7}/src/supython/migrations/0007_jobs_schema.sql +0 -0
  208. {supython-0.1.5 → supython-0.1.7}/src/supython/migrations/0008_jobs_last_error.sql +0 -0
  209. {supython-0.1.5 → supython-0.1.7}/src/supython/migrations/0009_auth_rate_limits.sql +0 -0
  210. {supython-0.1.5 → supython-0.1.7}/src/supython/migrations/0010_worker_heartbeat.sql +0 -0
  211. {supython-0.1.5 → supython-0.1.7}/src/supython/migrations/0011_admin_schema.sql +0 -0
  212. {supython-0.1.5 → supython-0.1.7}/src/supython/migrations/0012_auth_banned_until.sql +0 -0
  213. {supython-0.1.5 → supython-0.1.7}/src/supython/migrations/0013_email_templates.sql +0 -0
  214. {supython-0.1.5 → supython-0.1.7}/src/supython/migrations/0014_realtime_payload_warning.sql +0 -0
  215. {supython-0.1.5 → supython-0.1.7}/src/supython/migrations/0015_backups_schema.sql +0 -0
  216. {supython-0.1.5 → supython-0.1.7}/src/supython/passwords.py +0 -0
  217. {supython-0.1.5 → supython-0.1.7}/src/supython/realtime/__init__.py +0 -0
  218. {supython-0.1.5 → supython-0.1.7}/src/supython/realtime/broker.py +0 -0
  219. {supython-0.1.5 → supython-0.1.7}/src/supython/realtime/protocol.py +0 -0
  220. {supython-0.1.5 → supython-0.1.7}/src/supython/realtime/router.py +0 -0
  221. {supython-0.1.5 → supython-0.1.7}/src/supython/realtime/schemas.py +0 -0
  222. {supython-0.1.5 → supython-0.1.7}/src/supython/realtime/service.py +0 -0
  223. {supython-0.1.5 → supython-0.1.7}/src/supython/realtime/topics.py +0 -0
  224. {supython-0.1.5 → supython-0.1.7}/src/supython/realtime/websocket.py +0 -0
  225. {supython-0.1.5 → supython-0.1.7}/src/supython/scaffold/__init__.py +0 -0
  226. {supython-0.1.5 → supython-0.1.7}/src/supython/scaffold/init_project.py +0 -0
  227. {supython-0.1.5 → supython-0.1.7}/src/supython/scaffold/templates/Caddyfile.tmpl +0 -0
  228. {supython-0.1.5 → supython-0.1.7}/src/supython/scaffold/templates/README.md.tmpl +0 -0
  229. {supython-0.1.5 → supython-0.1.7}/src/supython/scaffold/templates/apps_hooks.py.tmpl +0 -0
  230. {supython-0.1.5 → supython-0.1.7}/src/supython/scaffold/templates/apps_jobs.py.tmpl +0 -0
  231. {supython-0.1.5 → supython-0.1.7}/src/supython/scaffold/templates/asgi.py.tmpl +0 -0
  232. {supython-0.1.5 → supython-0.1.7}/src/supython/scaffold/templates/docker-compose.prod.yml.tmpl +0 -0
  233. {supython-0.1.5 → supython-0.1.7}/src/supython/scaffold/templates/docker-compose.yml.tmpl +0 -0
  234. {supython-0.1.5 → supython-0.1.7}/src/supython/scaffold/templates/docker_postgres_Dockerfile.tmpl +0 -0
  235. {supython-0.1.5 → supython-0.1.7}/src/supython/scaffold/templates/docker_postgres_postgresql.conf.tmpl +0 -0
  236. {supython-0.1.5 → supython-0.1.7}/src/supython/scaffold/templates/env.example.tmpl +0 -0
  237. {supython-0.1.5 → supython-0.1.7}/src/supython/scaffold/templates/functions_README.md.tmpl +0 -0
  238. {supython-0.1.5 → supython-0.1.7}/src/supython/scaffold/templates/gitignore.tmpl +0 -0
  239. {supython-0.1.5 → supython-0.1.7}/src/supython/scaffold/templates/manage.py.tmpl +0 -0
  240. {supython-0.1.5 → supython-0.1.7}/src/supython/scaffold/templates/migrations/.gitkeep +0 -0
  241. {supython-0.1.5 → supython-0.1.7}/src/supython/scaffold/templates/package_init.py.tmpl +0 -0
  242. {supython-0.1.5 → supython-0.1.7}/src/supython/scaffold/templates/settings.py.tmpl +0 -0
  243. {supython-0.1.5 → supython-0.1.7}/src/supython/secretset.py +0 -0
  244. {supython-0.1.5 → supython-0.1.7}/src/supython/security_headers.py +0 -0
  245. {supython-0.1.5 → supython-0.1.7}/src/supython/settings.py +0 -0
  246. {supython-0.1.5 → supython-0.1.7}/src/supython/settings_module.py +0 -0
  247. {supython-0.1.5 → supython-0.1.7}/src/supython/storage/__init__.py +0 -0
  248. {supython-0.1.5 → supython-0.1.7}/src/supython/storage/backends.py +0 -0
  249. {supython-0.1.5 → supython-0.1.7}/src/supython/storage/router.py +0 -0
  250. {supython-0.1.5 → supython-0.1.7}/src/supython/storage/schemas.py +0 -0
  251. {supython-0.1.5 → supython-0.1.7}/src/supython/storage/service.py +0 -0
  252. {supython-0.1.5 → supython-0.1.7}/src/supython/storage/signing.py +0 -0
  253. {supython-0.1.5 → supython-0.1.7}/src/supython/tokens.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: supython
3
- Version: 0.1.5
3
+ Version: 0.1.7
4
4
  Summary: A lightweight Postgres-first BaaS framework for Python
5
5
  Project-URL: Homepage, https://github.com/Tkeby/supython
6
6
  Project-URL: Repository, https://github.com/Tkeby/supython
@@ -95,7 +95,7 @@ Shipped [v0.1.2]:
95
95
  **Jobs & cron**
96
96
  - **Job queue** — Postgres-backed (`SELECT FOR UPDATE SKIP LOCKED`), idempotent enqueue, retry with backoff
97
97
  - **Cron scheduling** — `pg_cron` (primary) or in-process `croniter` fallback
98
- - **Generic hooks** — `@app.on_signup` / `@app.on_login` lifecycle hooks; `@app.claims_provider` for custom JWT claims
98
+ - **Generic hooks** — `@app.on_signup` / `@app.on_login` lifecycle hooks; `@claims_provider` (from `supython.auth.claims`) for custom JWT claims
99
99
  - **`supython worker run`** — long-running worker with graceful SIGTERM drain
100
100
 
101
101
  **Operations & security**
@@ -418,17 +418,40 @@ SMTP_PASSWORD`.
418
418
  **OAuth** — add `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` (and/or GitHub
419
419
  equivalents) to `.env`. Providers without credentials are silently disabled.
420
420
 
421
+ **Logout semantics (stateless JWT)** — `/auth/v1/logout` revokes the
422
+ **refresh** token; the access token remains valid until its `exp` claim. This
423
+ is the standard stateless-JWT posture (same as Supabase Auth, Auth0, Cognito):
424
+ both supython and PostgREST verify access tokens from the JWKS with **no
425
+ per-request DB lookup**, so there is no place to consult a server-side
426
+ denylist without breaking that contract. The mitigation is a **short
427
+ `ACCESS_TOKEN_TTL`** plus refresh-token revocation:
428
+
429
+ - Clients must drop *both* tokens locally on logout — the access token must
430
+ not be reused after the user signs out.
431
+ - A stolen access token cannot be invalidated server-side mid-flight; it
432
+ stops being useful at `exp`. Pick a TTL that bounds your exposure.
433
+ - Default `ACCESS_TOKEN_TTL=3600` (1 hour) is fine for development. For
434
+ production, set it to **300–900 seconds** so logout / role changes
435
+ propagate in minutes rather than an hour. Refresh tokens are still
436
+ long-lived (`REFRESH_TOKEN_TTL=30d`) so users don't get prompted to log
437
+ in every few minutes — clients refresh transparently.
438
+
421
439
  ### Custom JWT claims [shipped v0.1.3]
422
440
 
423
- Register a `claims_provider` to inject application-specific claims into every
441
+ Register a claims provider to inject application-specific claims into every
424
442
  access token minted by the auth endpoints. Each provider is an async callable
425
443
  `(user, conn) -> dict` whose return value is merged into the token payload —
426
444
  on signup, password login, refresh, magic-link, OTP, and OAuth callbacks.
427
445
 
446
+ Import `register` directly from `supython.auth.claims` (typically aliased to
447
+ `claims_provider`). Don't reach for `supython.app.app` — extensions load
448
+ *during* `create_app()`, before `app` is bound, so importing it from a
449
+ user-side `EXTENSIONS` module is a circular import.
450
+
428
451
  ```python
429
- from supython.app import app
452
+ from supython.auth.claims import register as claims_provider
430
453
 
431
- @app.claims_provider
454
+ @claims_provider
432
455
  async def add_org(user, conn):
433
456
  org_id = await conn.fetchval(
434
457
  "select org_id from public.memberships where user_id = $1", user.id
@@ -472,7 +495,7 @@ async def me(user_id: Annotated[UUID, Depends(current_user_id)]) -> dict:
472
495
 
473
496
  @router.get("/whoami")
474
497
  async def whoami(claims: Annotated[dict, Depends(current_claims)]) -> dict:
475
- # Read whatever your `claims_provider` injected — e.g. org_id.
498
+ # Read whatever your claims provider injected — e.g. org_id.
476
499
  return {"user_id": claims["sub"], "org_id": claims.get("org_id")}
477
500
  ```
478
501
 
@@ -485,6 +508,8 @@ need any claim beyond the user UUID.
485
508
 
486
509
  | Variable | Default | Purpose |
487
510
  |---|---|---|
511
+ | `ACCESS_TOKEN_TTL` | `3600` | Access-token lifetime in seconds. Lower this (300–900) in production so logout / role changes propagate quickly — the access token is stateless and only stops working at `exp` |
512
+ | `REFRESH_TOKEN_TTL` | `2592000` | Refresh-token lifetime in seconds (30 d). Refresh tokens *are* revocable via `/auth/v1/logout` |
488
513
  | `DB_STATEMENT_TIMEOUT_MS` | `30000` | Per-connection query timeout for the asyncpg pool (`0` disables) |
489
514
  | `DB_POOL_MIN_SIZE` | `1` | Minimum asyncpg pool size |
490
515
  | `DB_POOL_MAX_SIZE` | `10` | Maximum asyncpg pool size |
@@ -37,7 +37,7 @@ Shipped [v0.1.2]:
37
37
  **Jobs & cron**
38
38
  - **Job queue** — Postgres-backed (`SELECT FOR UPDATE SKIP LOCKED`), idempotent enqueue, retry with backoff
39
39
  - **Cron scheduling** — `pg_cron` (primary) or in-process `croniter` fallback
40
- - **Generic hooks** — `@app.on_signup` / `@app.on_login` lifecycle hooks; `@app.claims_provider` for custom JWT claims
40
+ - **Generic hooks** — `@app.on_signup` / `@app.on_login` lifecycle hooks; `@claims_provider` (from `supython.auth.claims`) for custom JWT claims
41
41
  - **`supython worker run`** — long-running worker with graceful SIGTERM drain
42
42
 
43
43
  **Operations & security**
@@ -360,17 +360,40 @@ SMTP_PASSWORD`.
360
360
  **OAuth** — add `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` (and/or GitHub
361
361
  equivalents) to `.env`. Providers without credentials are silently disabled.
362
362
 
363
+ **Logout semantics (stateless JWT)** — `/auth/v1/logout` revokes the
364
+ **refresh** token; the access token remains valid until its `exp` claim. This
365
+ is the standard stateless-JWT posture (same as Supabase Auth, Auth0, Cognito):
366
+ both supython and PostgREST verify access tokens from the JWKS with **no
367
+ per-request DB lookup**, so there is no place to consult a server-side
368
+ denylist without breaking that contract. The mitigation is a **short
369
+ `ACCESS_TOKEN_TTL`** plus refresh-token revocation:
370
+
371
+ - Clients must drop *both* tokens locally on logout — the access token must
372
+ not be reused after the user signs out.
373
+ - A stolen access token cannot be invalidated server-side mid-flight; it
374
+ stops being useful at `exp`. Pick a TTL that bounds your exposure.
375
+ - Default `ACCESS_TOKEN_TTL=3600` (1 hour) is fine for development. For
376
+ production, set it to **300–900 seconds** so logout / role changes
377
+ propagate in minutes rather than an hour. Refresh tokens are still
378
+ long-lived (`REFRESH_TOKEN_TTL=30d`) so users don't get prompted to log
379
+ in every few minutes — clients refresh transparently.
380
+
363
381
  ### Custom JWT claims [shipped v0.1.3]
364
382
 
365
- Register a `claims_provider` to inject application-specific claims into every
383
+ Register a claims provider to inject application-specific claims into every
366
384
  access token minted by the auth endpoints. Each provider is an async callable
367
385
  `(user, conn) -> dict` whose return value is merged into the token payload —
368
386
  on signup, password login, refresh, magic-link, OTP, and OAuth callbacks.
369
387
 
388
+ Import `register` directly from `supython.auth.claims` (typically aliased to
389
+ `claims_provider`). Don't reach for `supython.app.app` — extensions load
390
+ *during* `create_app()`, before `app` is bound, so importing it from a
391
+ user-side `EXTENSIONS` module is a circular import.
392
+
370
393
  ```python
371
- from supython.app import app
394
+ from supython.auth.claims import register as claims_provider
372
395
 
373
- @app.claims_provider
396
+ @claims_provider
374
397
  async def add_org(user, conn):
375
398
  org_id = await conn.fetchval(
376
399
  "select org_id from public.memberships where user_id = $1", user.id
@@ -414,7 +437,7 @@ async def me(user_id: Annotated[UUID, Depends(current_user_id)]) -> dict:
414
437
 
415
438
  @router.get("/whoami")
416
439
  async def whoami(claims: Annotated[dict, Depends(current_claims)]) -> dict:
417
- # Read whatever your `claims_provider` injected — e.g. org_id.
440
+ # Read whatever your claims provider injected — e.g. org_id.
418
441
  return {"user_id": claims["sub"], "org_id": claims.get("org_id")}
419
442
  ```
420
443
 
@@ -427,6 +450,8 @@ need any claim beyond the user UUID.
427
450
 
428
451
  | Variable | Default | Purpose |
429
452
  |---|---|---|
453
+ | `ACCESS_TOKEN_TTL` | `3600` | Access-token lifetime in seconds. Lower this (300–900) in production so logout / role changes propagate quickly — the access token is stateless and only stops working at `exp` |
454
+ | `REFRESH_TOKEN_TTL` | `2592000` | Refresh-token lifetime in seconds (30 d). Refresh tokens *are* revocable via `/auth/v1/logout` |
430
455
  | `DB_STATEMENT_TIMEOUT_MS` | `30000` | Per-connection query timeout for the asyncpg pool (`0` disables) |
431
456
  | `DB_POOL_MIN_SIZE` | `1` | Minimum asyncpg pool size |
432
457
  | `DB_POOL_MAX_SIZE` | `10` | Maximum asyncpg pool size |
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "supython"
7
- version = "0.1.5"
7
+ version = "0.1.7"
8
8
  description = "A lightweight Postgres-first BaaS framework for Python"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -11,7 +11,6 @@ from fastapi.middleware.cors import CORSMiddleware
11
11
  from . import __version__, db, jwks
12
12
  from .admin import router as admin_api_router
13
13
  from .admin import spa as admin_spa
14
- from .auth import claims as auth_claims
15
14
  from .auth.router import router as auth_router
16
15
  from .extensions import load_extensions
17
16
  from .settings_module import UserSettings, load_user_settings
@@ -156,7 +155,6 @@ def create_app() -> FastAPI:
156
155
  app.on_signup = _make_hook_decorator("signup")
157
156
  app.on_login = _make_hook_decorator("login")
158
157
  app.on_logout = _make_hook_decorator("logout")
159
- app.claims_provider = auth_claims.register
160
158
 
161
159
  return app
162
160
 
@@ -1,9 +1,10 @@
1
1
  """Custom-claim providers for access-token issuance.
2
2
 
3
- Library users register an async callable via ``@app.claims_provider`` (or
4
- ``claims.register``) and the auth service invokes it inside ``_issue_pair``
5
- just before minting the JWT. Each provider returns a ``dict`` that is
6
- merged into the access token's payload.
3
+ Library users register an async callable via ``claims.register`` (typically
4
+ imported as ``from supython.auth.claims import register as claims_provider``)
5
+ and the auth service invokes it inside ``_issue_pair`` just before minting
6
+ the JWT. Each provider returns a ``dict`` that is merged into the access
7
+ token's payload.
7
8
 
8
9
  Contract (intentionally narrower than ``hooks.fire``):
9
10
 
@@ -11,6 +11,7 @@ rule that applies elsewhere.
11
11
  from __future__ import annotations
12
12
 
13
13
  from collections.abc import AsyncIterator, Awaitable, Callable
14
+ from contextlib import AbstractAsyncContextManager
14
15
  from dataclasses import dataclass, field
15
16
  from typing import TYPE_CHECKING, Any
16
17
  from uuid import UUID
@@ -18,6 +19,7 @@ from uuid import UUID
18
19
  import asyncpg
19
20
  import httpx
20
21
 
22
+ from .. import db as _db
21
23
  from ..mailer import EmailBackend, EmailMessage, get_mailer
22
24
  from ..settings import Settings, get_settings
23
25
  from ..storage import service as storage_service
@@ -73,9 +75,7 @@ class StorageClient:
73
75
  ``backend`` by hand.
74
76
  """
75
77
 
76
- def __init__(
77
- self, conn: asyncpg.Connection, backend: StorageBackend
78
- ) -> None:
78
+ def __init__(self, conn: asyncpg.Connection, backend: StorageBackend) -> None:
79
79
  self._conn = conn
80
80
  self._backend = backend
81
81
 
@@ -120,9 +120,7 @@ class StorageClient:
120
120
  )
121
121
 
122
122
  async def get_metadata(self, *, bucket: str, path: str) -> ObjectResponse:
123
- return await storage_service.get_object_metadata(
124
- self._conn, bucket, path
125
- )
123
+ return await storage_service.get_object_metadata(self._conn, bucket, path)
126
124
 
127
125
  async def sign(
128
126
  self, *, bucket: str, path: str, expires_in: int | None = None
@@ -234,6 +232,30 @@ class Ctx:
234
232
  request: Request
235
233
  settings: Settings
236
234
 
235
+ def service_db(
236
+ self,
237
+ *,
238
+ with_user_claims: bool = True,
239
+ ) -> AbstractAsyncContextManager[asyncpg.Connection]:
240
+ """Yield a ``service_role`` connection for housekeeping inside a handler.
241
+
242
+ Convenience wrapper around :func:`supython.db.as_service_role` so user
243
+ code can write::
244
+
245
+ async with ctx.service_db() as conn:
246
+ await conn.execute("insert into audit.events ...")
247
+
248
+ instead of importing ``supython.db``. ``service_role`` bypasses RLS;
249
+ when the caller is authenticated the user's JWT claims are forwarded
250
+ to the session so helpers like ``auth.uid()`` still return the
251
+ caller's id inside the block. Pass ``with_user_claims=False`` to
252
+ suppress that and run truly impersonal admin work.
253
+ """
254
+ claims = (
255
+ self.user.claims if (with_user_claims and self.user is not None) else None
256
+ )
257
+ return _db.as_service_role(claims=claims)
258
+
237
259
 
238
260
  def build_ctx(
239
261
  *,
File without changes
File without changes
File without changes
File without changes