supython 0.1.6__tar.gz → 0.1.8__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.6 → supython-0.1.8}/PKG-INFO +21 -1
  2. {supython-0.1.6 → supython-0.1.8}/README.md +20 -0
  3. {supython-0.1.6 → supython-0.1.8}/pyproject.toml +1 -1
  4. {supython-0.1.6 → supython-0.1.8}/src/supython/cli.py +22 -2
  5. {supython-0.1.6 → supython-0.1.8}/src/supython/functions/context.py +28 -6
  6. {supython-0.1.6 → supython-0.1.8}/.gitignore +0 -0
  7. {supython-0.1.6 → supython-0.1.8}/CHANGELOG.md +0 -0
  8. {supython-0.1.6 → supython-0.1.8}/LICENSE +0 -0
  9. {supython-0.1.6 → supython-0.1.8}/SECURITY.md +0 -0
  10. {supython-0.1.6 → supython-0.1.8}/src/supython/__init__.py +0 -0
  11. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/__init__.py +0 -0
  12. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/api/__init__.py +0 -0
  13. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/api/auth.py +0 -0
  14. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/api/auth_templates.py +0 -0
  15. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/api/auth_users.py +0 -0
  16. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/api/db.py +0 -0
  17. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/api/functions.py +0 -0
  18. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/api/jobs.py +0 -0
  19. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/api/ops.py +0 -0
  20. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/api/realtime.py +0 -0
  21. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/api/service_auth.py +0 -0
  22. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/api/service_auth_templates.py +0 -0
  23. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/api/service_auth_users.py +0 -0
  24. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/api/service_db.py +0 -0
  25. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/api/service_functions.py +0 -0
  26. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/api/service_jobs.py +0 -0
  27. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/api/service_ops.py +0 -0
  28. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/api/service_realtime.py +0 -0
  29. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/api/service_storage.py +0 -0
  30. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/api/storage.py +0 -0
  31. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/api/system.py +0 -0
  32. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/audit.py +0 -0
  33. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/deps.py +0 -0
  34. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/errors.py +0 -0
  35. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/schemas.py +0 -0
  36. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/session.py +0 -0
  37. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/spa.py +0 -0
  38. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Alert-dluGVkos.js +0 -0
  39. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Alert-dluGVkos.js.map +0 -0
  40. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Audit-Njung3HI.js +0 -0
  41. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Audit-Njung3HI.js.map +0 -0
  42. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Backups-DzPlFgrm.js +0 -0
  43. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Backups-DzPlFgrm.js.map +0 -0
  44. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Buckets-ByacGkU1.js +0 -0
  45. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Buckets-ByacGkU1.js.map +0 -0
  46. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Channels-BoIuTtam.js +0 -0
  47. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Channels-BoIuTtam.js.map +0 -0
  48. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/ChevronRight-CtQH1EQ1.js +0 -0
  49. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/ChevronRight-CtQH1EQ1.js.map +0 -0
  50. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/CodeViewer-Bqy7-wvH.js +0 -0
  51. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/CodeViewer-Bqy7-wvH.js.map +0 -0
  52. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Crons-B67vc39F.js +0 -0
  53. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Crons-B67vc39F.js.map +0 -0
  54. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/DashboardView-CUTFVL6k.js +0 -0
  55. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/DashboardView-CUTFVL6k.js.map +0 -0
  56. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/DataTable-COAAWEft.js +0 -0
  57. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/DataTable-COAAWEft.js.map +0 -0
  58. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/DescriptionsItem-P8JUDaBs.js +0 -0
  59. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/DescriptionsItem-P8JUDaBs.js.map +0 -0
  60. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/DrawerContent-TpYTFgF1.js +0 -0
  61. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/DrawerContent-TpYTFgF1.js.map +0 -0
  62. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Empty-cr2r7e2u.js +0 -0
  63. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Empty-cr2r7e2u.js.map +0 -0
  64. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/EmptyState-DeDck-OL.js +0 -0
  65. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/EmptyState-DeDck-OL.js.map +0 -0
  66. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Grid-hFkp9F4P.js +0 -0
  67. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Grid-hFkp9F4P.js.map +0 -0
  68. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Input-DppYTq9C.js +0 -0
  69. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Input-DppYTq9C.js.map +0 -0
  70. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Invoke-DW3Nveeh.js +0 -0
  71. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Invoke-DW3Nveeh.js.map +0 -0
  72. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/JsonField-DibyJgun.js +0 -0
  73. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/JsonField-DibyJgun.js.map +0 -0
  74. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/LoginView-BjLyE3Ds.css +0 -0
  75. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/LoginView-CoOjECT_.js +0 -0
  76. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/LoginView-CoOjECT_.js.map +0 -0
  77. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Logs-D9WYrnIT.js +0 -0
  78. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Logs-D9WYrnIT.js.map +0 -0
  79. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Logs-DS1XPa0h.css +0 -0
  80. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Migrations-DOSC2ddQ.js +0 -0
  81. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Migrations-DOSC2ddQ.js.map +0 -0
  82. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/ObjectBrowser-_5w8vOX8.js +0 -0
  83. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/ObjectBrowser-_5w8vOX8.js.map +0 -0
  84. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Queue-CywZs6vI.js +0 -0
  85. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Queue-CywZs6vI.js.map +0 -0
  86. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/RefreshTokens-Ccjr53jg.js +0 -0
  87. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/RefreshTokens-Ccjr53jg.js.map +0 -0
  88. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/RlsEditor-BSlH9vSc.js +0 -0
  89. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/RlsEditor-BSlH9vSc.js.map +0 -0
  90. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Routes-BiLXE49D.js +0 -0
  91. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Routes-BiLXE49D.js.map +0 -0
  92. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Routes-C-ianIGD.css +0 -0
  93. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/SchemaBrowser-DKy2_KQi.css +0 -0
  94. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/SchemaBrowser-XFvFbtDB.js +0 -0
  95. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/SchemaBrowser-XFvFbtDB.js.map +0 -0
  96. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Select-DIzZyRZb.js +0 -0
  97. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Select-DIzZyRZb.js.map +0 -0
  98. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Space-n5-XcguU.js +0 -0
  99. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Space-n5-XcguU.js.map +0 -0
  100. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/SqlEditor-b8pTsILY.js +0 -0
  101. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/SqlEditor-b8pTsILY.js.map +0 -0
  102. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/SqlWorkspace-BUS7IntH.js +0 -0
  103. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/SqlWorkspace-BUS7IntH.js.map +0 -0
  104. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/TableData-CQIagLKn.js +0 -0
  105. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/TableData-CQIagLKn.js.map +0 -0
  106. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Tag-D1fOKpTH.js +0 -0
  107. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Tag-D1fOKpTH.js.map +0 -0
  108. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Templates-BS-ugkdq.js +0 -0
  109. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Templates-BS-ugkdq.js.map +0 -0
  110. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Thing-CEAniuMg.js +0 -0
  111. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Thing-CEAniuMg.js.map +0 -0
  112. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Users-wzwajhlh.js +0 -0
  113. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/Users-wzwajhlh.js.map +0 -0
  114. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/_plugin-vue_export-helper-DGA9ry_j.js +0 -0
  115. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/dist-VXIJLCYq.js +0 -0
  116. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/dist-VXIJLCYq.js.map +0 -0
  117. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/format-length-CGCY1rMh.js +0 -0
  118. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/format-length-CGCY1rMh.js.map +0 -0
  119. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/get-Ca6unauB.js +0 -0
  120. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/get-Ca6unauB.js.map +0 -0
  121. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/index-CeE6v959.js +0 -0
  122. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/index-CeE6v959.js.map +0 -0
  123. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/pinia-COXwfrOX.js +0 -0
  124. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/pinia-COXwfrOX.js.map +0 -0
  125. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/resources-Bt6thQCD.js +0 -0
  126. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/resources-Bt6thQCD.js.map +0 -0
  127. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/use-locale-mtgM0a3a.js +0 -0
  128. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/use-locale-mtgM0a3a.js.map +0 -0
  129. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/use-merged-state-BvhkaHNX.js +0 -0
  130. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/use-merged-state-BvhkaHNX.js.map +0 -0
  131. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/useConfirm-tMjvBFXR.js +0 -0
  132. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/useConfirm-tMjvBFXR.js.map +0 -0
  133. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/useResource-C_rJCY8C.js +0 -0
  134. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/useResource-C_rJCY8C.js.map +0 -0
  135. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/useTable-CnZc5zhi.js +0 -0
  136. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/useTable-CnZc5zhi.js.map +0 -0
  137. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/useTable-Dg0XlRlq.css +0 -0
  138. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/useToast-DsZKx0IX.js +0 -0
  139. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/useToast-DsZKx0IX.js.map +0 -0
  140. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/utils-sbXoq7Ir.js +0 -0
  141. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/assets/utils-sbXoq7Ir.js.map +0 -0
  142. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/favicon.svg +0 -0
  143. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/icons.svg +0 -0
  144. {supython-0.1.6 → supython-0.1.8}/src/supython/admin/static/index.html +0 -0
  145. {supython-0.1.6 → supython-0.1.8}/src/supython/app.py +0 -0
  146. {supython-0.1.6 → supython-0.1.8}/src/supython/auth/__init__.py +0 -0
  147. {supython-0.1.6 → supython-0.1.8}/src/supython/auth/_email_job.py +0 -0
  148. {supython-0.1.6 → supython-0.1.8}/src/supython/auth/claims.py +0 -0
  149. {supython-0.1.6 → supython-0.1.8}/src/supython/auth/deps.py +0 -0
  150. {supython-0.1.6 → supython-0.1.8}/src/supython/auth/providers/__init__.py +0 -0
  151. {supython-0.1.6 → supython-0.1.8}/src/supython/auth/providers/github.py +0 -0
  152. {supython-0.1.6 → supython-0.1.8}/src/supython/auth/providers/google.py +0 -0
  153. {supython-0.1.6 → supython-0.1.8}/src/supython/auth/providers/oauth.py +0 -0
  154. {supython-0.1.6 → supython-0.1.8}/src/supython/auth/providers/registry.py +0 -0
  155. {supython-0.1.6 → supython-0.1.8}/src/supython/auth/ratelimit.py +0 -0
  156. {supython-0.1.6 → supython-0.1.8}/src/supython/auth/router.py +0 -0
  157. {supython-0.1.6 → supython-0.1.8}/src/supython/auth/schemas.py +0 -0
  158. {supython-0.1.6 → supython-0.1.8}/src/supython/auth/service.py +0 -0
  159. {supython-0.1.6 → supython-0.1.8}/src/supython/backups/__init__.py +0 -0
  160. {supython-0.1.6 → supython-0.1.8}/src/supython/backups/_backup_job.py +0 -0
  161. {supython-0.1.6 → supython-0.1.8}/src/supython/backups/schemas.py +0 -0
  162. {supython-0.1.6 → supython-0.1.8}/src/supython/backups/service.py +0 -0
  163. {supython-0.1.6 → supython-0.1.8}/src/supython/body_size.py +0 -0
  164. {supython-0.1.6 → supython-0.1.8}/src/supython/client/__init__.py +0 -0
  165. {supython-0.1.6 → supython-0.1.8}/src/supython/client/_auth.py +0 -0
  166. {supython-0.1.6 → supython-0.1.8}/src/supython/client/_client.py +0 -0
  167. {supython-0.1.6 → supython-0.1.8}/src/supython/client/_config.py +0 -0
  168. {supython-0.1.6 → supython-0.1.8}/src/supython/client/_functions.py +0 -0
  169. {supython-0.1.6 → supython-0.1.8}/src/supython/client/_storage.py +0 -0
  170. {supython-0.1.6 → supython-0.1.8}/src/supython/client/py.typed +0 -0
  171. {supython-0.1.6 → supython-0.1.8}/src/supython/db.py +0 -0
  172. {supython-0.1.6 → supython-0.1.8}/src/supython/db_admin.py +0 -0
  173. {supython-0.1.6 → supython-0.1.8}/src/supython/extensions.py +0 -0
  174. {supython-0.1.6 → supython-0.1.8}/src/supython/functions/__init__.py +0 -0
  175. {supython-0.1.6 → supython-0.1.8}/src/supython/functions/loader.py +0 -0
  176. {supython-0.1.6 → supython-0.1.8}/src/supython/functions/router.py +0 -0
  177. {supython-0.1.6 → supython-0.1.8}/src/supython/functions/schemas.py +0 -0
  178. {supython-0.1.6 → supython-0.1.8}/src/supython/gen/__init__.py +0 -0
  179. {supython-0.1.6 → supython-0.1.8}/src/supython/gen/_introspect.py +0 -0
  180. {supython-0.1.6 → supython-0.1.8}/src/supython/gen/types_py.py +0 -0
  181. {supython-0.1.6 → supython-0.1.8}/src/supython/gen/types_ts.py +0 -0
  182. {supython-0.1.6 → supython-0.1.8}/src/supython/health.py +0 -0
  183. {supython-0.1.6 → supython-0.1.8}/src/supython/hooks.py +0 -0
  184. {supython-0.1.6 → supython-0.1.8}/src/supython/jobs/__init__.py +0 -0
  185. {supython-0.1.6 → supython-0.1.8}/src/supython/jobs/backends.py +0 -0
  186. {supython-0.1.6 → supython-0.1.8}/src/supython/jobs/context.py +0 -0
  187. {supython-0.1.6 → supython-0.1.8}/src/supython/jobs/cron.py +0 -0
  188. {supython-0.1.6 → supython-0.1.8}/src/supython/jobs/cron_inproc.py +0 -0
  189. {supython-0.1.6 → supython-0.1.8}/src/supython/jobs/decorators.py +0 -0
  190. {supython-0.1.6 → supython-0.1.8}/src/supython/jobs/registry.py +0 -0
  191. {supython-0.1.6 → supython-0.1.8}/src/supython/jobs/router.py +0 -0
  192. {supython-0.1.6 → supython-0.1.8}/src/supython/jobs/schemas.py +0 -0
  193. {supython-0.1.6 → supython-0.1.8}/src/supython/jobs/service.py +0 -0
  194. {supython-0.1.6 → supython-0.1.8}/src/supython/jobs/worker.py +0 -0
  195. {supython-0.1.6 → supython-0.1.8}/src/supython/jwks.py +0 -0
  196. {supython-0.1.6 → supython-0.1.8}/src/supython/keyset.py +0 -0
  197. {supython-0.1.6 → supython-0.1.8}/src/supython/logging_config.py +0 -0
  198. {supython-0.1.6 → supython-0.1.8}/src/supython/mail.py +0 -0
  199. {supython-0.1.6 → supython-0.1.8}/src/supython/mailer.py +0 -0
  200. {supython-0.1.6 → supython-0.1.8}/src/supython/migrate.py +0 -0
  201. {supython-0.1.6 → supython-0.1.8}/src/supython/migrations/0001_extensions_and_roles.sql +0 -0
  202. {supython-0.1.6 → supython-0.1.8}/src/supython/migrations/0002_auth_schema.sql +0 -0
  203. {supython-0.1.6 → supython-0.1.8}/src/supython/migrations/0003_demo_todos.sql +0 -0
  204. {supython-0.1.6 → supython-0.1.8}/src/supython/migrations/0004_auth_v0_2.sql +0 -0
  205. {supython-0.1.6 → supython-0.1.8}/src/supython/migrations/0005_storage_schema.sql +0 -0
  206. {supython-0.1.6 → supython-0.1.8}/src/supython/migrations/0006_realtime_schema.sql +0 -0
  207. {supython-0.1.6 → supython-0.1.8}/src/supython/migrations/0007_jobs_schema.sql +0 -0
  208. {supython-0.1.6 → supython-0.1.8}/src/supython/migrations/0008_jobs_last_error.sql +0 -0
  209. {supython-0.1.6 → supython-0.1.8}/src/supython/migrations/0009_auth_rate_limits.sql +0 -0
  210. {supython-0.1.6 → supython-0.1.8}/src/supython/migrations/0010_worker_heartbeat.sql +0 -0
  211. {supython-0.1.6 → supython-0.1.8}/src/supython/migrations/0011_admin_schema.sql +0 -0
  212. {supython-0.1.6 → supython-0.1.8}/src/supython/migrations/0012_auth_banned_until.sql +0 -0
  213. {supython-0.1.6 → supython-0.1.8}/src/supython/migrations/0013_email_templates.sql +0 -0
  214. {supython-0.1.6 → supython-0.1.8}/src/supython/migrations/0014_realtime_payload_warning.sql +0 -0
  215. {supython-0.1.6 → supython-0.1.8}/src/supython/migrations/0015_backups_schema.sql +0 -0
  216. {supython-0.1.6 → supython-0.1.8}/src/supython/passwords.py +0 -0
  217. {supython-0.1.6 → supython-0.1.8}/src/supython/realtime/__init__.py +0 -0
  218. {supython-0.1.6 → supython-0.1.8}/src/supython/realtime/broker.py +0 -0
  219. {supython-0.1.6 → supython-0.1.8}/src/supython/realtime/protocol.py +0 -0
  220. {supython-0.1.6 → supython-0.1.8}/src/supython/realtime/router.py +0 -0
  221. {supython-0.1.6 → supython-0.1.8}/src/supython/realtime/schemas.py +0 -0
  222. {supython-0.1.6 → supython-0.1.8}/src/supython/realtime/service.py +0 -0
  223. {supython-0.1.6 → supython-0.1.8}/src/supython/realtime/topics.py +0 -0
  224. {supython-0.1.6 → supython-0.1.8}/src/supython/realtime/websocket.py +0 -0
  225. {supython-0.1.6 → supython-0.1.8}/src/supython/scaffold/__init__.py +0 -0
  226. {supython-0.1.6 → supython-0.1.8}/src/supython/scaffold/init_project.py +0 -0
  227. {supython-0.1.6 → supython-0.1.8}/src/supython/scaffold/templates/Caddyfile.tmpl +0 -0
  228. {supython-0.1.6 → supython-0.1.8}/src/supython/scaffold/templates/README.md.tmpl +0 -0
  229. {supython-0.1.6 → supython-0.1.8}/src/supython/scaffold/templates/apps_hooks.py.tmpl +0 -0
  230. {supython-0.1.6 → supython-0.1.8}/src/supython/scaffold/templates/apps_jobs.py.tmpl +0 -0
  231. {supython-0.1.6 → supython-0.1.8}/src/supython/scaffold/templates/asgi.py.tmpl +0 -0
  232. {supython-0.1.6 → supython-0.1.8}/src/supython/scaffold/templates/docker-compose.prod.yml.tmpl +0 -0
  233. {supython-0.1.6 → supython-0.1.8}/src/supython/scaffold/templates/docker-compose.yml.tmpl +0 -0
  234. {supython-0.1.6 → supython-0.1.8}/src/supython/scaffold/templates/docker_postgres_Dockerfile.tmpl +0 -0
  235. {supython-0.1.6 → supython-0.1.8}/src/supython/scaffold/templates/docker_postgres_postgresql.conf.tmpl +0 -0
  236. {supython-0.1.6 → supython-0.1.8}/src/supython/scaffold/templates/env.example.tmpl +0 -0
  237. {supython-0.1.6 → supython-0.1.8}/src/supython/scaffold/templates/functions_README.md.tmpl +0 -0
  238. {supython-0.1.6 → supython-0.1.8}/src/supython/scaffold/templates/gitignore.tmpl +0 -0
  239. {supython-0.1.6 → supython-0.1.8}/src/supython/scaffold/templates/manage.py.tmpl +0 -0
  240. {supython-0.1.6 → supython-0.1.8}/src/supython/scaffold/templates/migrations/.gitkeep +0 -0
  241. {supython-0.1.6 → supython-0.1.8}/src/supython/scaffold/templates/package_init.py.tmpl +0 -0
  242. {supython-0.1.6 → supython-0.1.8}/src/supython/scaffold/templates/settings.py.tmpl +0 -0
  243. {supython-0.1.6 → supython-0.1.8}/src/supython/secretset.py +0 -0
  244. {supython-0.1.6 → supython-0.1.8}/src/supython/security_headers.py +0 -0
  245. {supython-0.1.6 → supython-0.1.8}/src/supython/settings.py +0 -0
  246. {supython-0.1.6 → supython-0.1.8}/src/supython/settings_module.py +0 -0
  247. {supython-0.1.6 → supython-0.1.8}/src/supython/storage/__init__.py +0 -0
  248. {supython-0.1.6 → supython-0.1.8}/src/supython/storage/backends.py +0 -0
  249. {supython-0.1.6 → supython-0.1.8}/src/supython/storage/router.py +0 -0
  250. {supython-0.1.6 → supython-0.1.8}/src/supython/storage/schemas.py +0 -0
  251. {supython-0.1.6 → supython-0.1.8}/src/supython/storage/service.py +0 -0
  252. {supython-0.1.6 → supython-0.1.8}/src/supython/storage/signing.py +0 -0
  253. {supython-0.1.6 → supython-0.1.8}/src/supython/tokens.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: supython
3
- Version: 0.1.6
3
+ Version: 0.1.8
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
@@ -418,6 +418,24 @@ 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
441
  Register a claims provider to inject application-specific claims into every
@@ -490,6 +508,8 @@ need any claim beyond the user UUID.
490
508
 
491
509
  | Variable | Default | Purpose |
492
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` |
493
513
  | `DB_STATEMENT_TIMEOUT_MS` | `30000` | Per-connection query timeout for the asyncpg pool (`0` disables) |
494
514
  | `DB_POOL_MIN_SIZE` | `1` | Minimum asyncpg pool size |
495
515
  | `DB_POOL_MAX_SIZE` | `10` | Maximum asyncpg pool size |
@@ -360,6 +360,24 @@ 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
383
  Register a claims provider to inject application-specific claims into every
@@ -432,6 +450,8 @@ need any claim beyond the user UUID.
432
450
 
433
451
  | Variable | Default | Purpose |
434
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` |
435
455
  | `DB_STATEMENT_TIMEOUT_MS` | `30000` | Per-connection query timeout for the asyncpg pool (`0` disables) |
436
456
  | `DB_POOL_MIN_SIZE` | `1` | Minimum asyncpg pool size |
437
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.6"
7
+ version = "0.1.8"
8
8
  description = "A lightweight Postgres-first BaaS framework for Python"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -1355,14 +1355,22 @@ def up(
1355
1355
  timeout: int = typer.Option(30, help="Seconds to wait for Postgres."),
1356
1356
  prod: bool = typer.Option(False, "--prod", help="Use docker-compose.prod.yml."),
1357
1357
  worker: bool = typer.Option(False, "--worker", help="Also start the worker (prod only)."),
1358
+ profile: list[str] = typer.Option(
1359
+ [],
1360
+ "--profile",
1361
+ help="Compose profile(s) to enable. Repeatable; user-defined extension services gated by a profile come up via a final sweep.",
1362
+ ),
1358
1363
  ) -> None:
1359
1364
  """Start Postgres + PostgREST and apply migrations.
1360
1365
 
1361
1366
  Brings the DB up first, runs migrations (which create the roles
1362
1367
  PostgREST needs), rotates the authenticator password, then starts PostgREST.
1368
+ Any user-added services gated behind a compose profile come up after the
1369
+ core services when `--profile <name>` is passed.
1363
1370
  """
1364
1371
  compose_file = _resolve_compose_file(prod)
1365
1372
  is_prod = compose_file == "docker-compose.prod.yml"
1373
+ user_profiles = tuple(profile)
1366
1374
  configure_logging("INFO", json_format=False)
1367
1375
  _compose_with(compose_file, "up", "-d", "db")
1368
1376
  typer.echo("waiting for Postgres ...")
@@ -1379,6 +1387,8 @@ def up(
1379
1387
  _compose_with(compose_file, "up", "-d", "postgrest", "supython")
1380
1388
  if worker:
1381
1389
  _compose_with(compose_file, "--profile", "worker", "up", "-d", "worker")
1390
+ if user_profiles:
1391
+ _compose_with(compose_file, "up", "-d", profiles=user_profiles)
1382
1392
  typer.echo("")
1383
1393
  typer.echo("ready.")
1384
1394
  typer.echo(" postgres localhost:54322 (bind 127.0.0.1 only)")
@@ -1386,12 +1396,18 @@ def up(
1386
1396
  typer.echo(" supython http://localhost:8000")
1387
1397
  if worker:
1388
1398
  typer.echo(" worker running (profile=worker)")
1399
+ for p in user_profiles:
1400
+ typer.echo(f" profile {p} # user-defined services")
1389
1401
  else:
1390
1402
  _compose_with(compose_file, "up", "-d", "postgrest")
1403
+ if user_profiles:
1404
+ _compose_with(compose_file, "up", "-d", profiles=user_profiles)
1391
1405
  typer.echo("")
1392
1406
  typer.echo("ready.")
1393
1407
  typer.echo(" postgres localhost:54322 (user/db: supython)")
1394
1408
  typer.echo(f" postgrest {s.postgrest_url}")
1409
+ for p in user_profiles:
1410
+ typer.echo(f" profile {p} # user-defined services")
1395
1411
  typer.echo(" next supython dev # start the auth/API service")
1396
1412
 
1397
1413
 
@@ -1610,11 +1626,15 @@ def _compose(*args: str) -> None:
1610
1626
  _compose_with(None, *args)
1611
1627
 
1612
1628
 
1613
- def _compose_with(file: str | None, *args: str) -> None:
1614
- """Run `docker compose [-f <file>] <args...>`, surfacing common errors."""
1629
+ def _compose_with(
1630
+ file: str | None, *args: str, profiles: tuple[str, ...] = ()
1631
+ ) -> None:
1632
+ """Run `docker compose [-f <file>] [--profile <p>]... <args...>`, surfacing common errors."""
1615
1633
  cmd = ["docker", "compose"]
1616
1634
  if file:
1617
1635
  cmd += ["-f", file]
1636
+ for p in profiles:
1637
+ cmd += ["--profile", p]
1618
1638
  cmd += list(args)
1619
1639
  try:
1620
1640
  subprocess.run(cmd, check=True)
@@ -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
File without changes