supython 0.1.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 (251) hide show
  1. supython-0.1.0/.gitignore +44 -0
  2. supython-0.1.0/CHANGELOG.md +204 -0
  3. supython-0.1.0/LICENSE +21 -0
  4. supython-0.1.0/PKG-INFO +756 -0
  5. supython-0.1.0/README.md +698 -0
  6. supython-0.1.0/SECURITY.md +41 -0
  7. supython-0.1.0/pyproject.toml +118 -0
  8. supython-0.1.0/src/supython/__init__.py +24 -0
  9. supython-0.1.0/src/supython/admin/__init__.py +3 -0
  10. supython-0.1.0/src/supython/admin/api/__init__.py +24 -0
  11. supython-0.1.0/src/supython/admin/api/auth.py +118 -0
  12. supython-0.1.0/src/supython/admin/api/auth_templates.py +67 -0
  13. supython-0.1.0/src/supython/admin/api/auth_users.py +225 -0
  14. supython-0.1.0/src/supython/admin/api/db.py +174 -0
  15. supython-0.1.0/src/supython/admin/api/functions.py +92 -0
  16. supython-0.1.0/src/supython/admin/api/jobs.py +192 -0
  17. supython-0.1.0/src/supython/admin/api/ops.py +224 -0
  18. supython-0.1.0/src/supython/admin/api/realtime.py +281 -0
  19. supython-0.1.0/src/supython/admin/api/service_auth.py +49 -0
  20. supython-0.1.0/src/supython/admin/api/service_auth_templates.py +83 -0
  21. supython-0.1.0/src/supython/admin/api/service_auth_users.py +346 -0
  22. supython-0.1.0/src/supython/admin/api/service_db.py +214 -0
  23. supython-0.1.0/src/supython/admin/api/service_functions.py +287 -0
  24. supython-0.1.0/src/supython/admin/api/service_jobs.py +282 -0
  25. supython-0.1.0/src/supython/admin/api/service_ops.py +213 -0
  26. supython-0.1.0/src/supython/admin/api/service_realtime.py +30 -0
  27. supython-0.1.0/src/supython/admin/api/service_storage.py +220 -0
  28. supython-0.1.0/src/supython/admin/api/storage.py +117 -0
  29. supython-0.1.0/src/supython/admin/api/system.py +37 -0
  30. supython-0.1.0/src/supython/admin/audit.py +29 -0
  31. supython-0.1.0/src/supython/admin/deps.py +22 -0
  32. supython-0.1.0/src/supython/admin/errors.py +16 -0
  33. supython-0.1.0/src/supython/admin/schemas.py +310 -0
  34. supython-0.1.0/src/supython/admin/session.py +52 -0
  35. supython-0.1.0/src/supython/admin/spa.py +38 -0
  36. supython-0.1.0/src/supython/admin/static/assets/Alert-dluGVkos.js +49 -0
  37. supython-0.1.0/src/supython/admin/static/assets/Alert-dluGVkos.js.map +1 -0
  38. supython-0.1.0/src/supython/admin/static/assets/Audit-Njung3HI.js +2 -0
  39. supython-0.1.0/src/supython/admin/static/assets/Audit-Njung3HI.js.map +1 -0
  40. supython-0.1.0/src/supython/admin/static/assets/Backups-DzPlFgrm.js +2 -0
  41. supython-0.1.0/src/supython/admin/static/assets/Backups-DzPlFgrm.js.map +1 -0
  42. supython-0.1.0/src/supython/admin/static/assets/Buckets-ByacGkU1.js +2 -0
  43. supython-0.1.0/src/supython/admin/static/assets/Buckets-ByacGkU1.js.map +1 -0
  44. supython-0.1.0/src/supython/admin/static/assets/Channels-BoIuTtam.js +353 -0
  45. supython-0.1.0/src/supython/admin/static/assets/Channels-BoIuTtam.js.map +1 -0
  46. supython-0.1.0/src/supython/admin/static/assets/ChevronRight-CtQH1EQ1.js +2 -0
  47. supython-0.1.0/src/supython/admin/static/assets/ChevronRight-CtQH1EQ1.js.map +1 -0
  48. supython-0.1.0/src/supython/admin/static/assets/CodeViewer-Bqy7-wvH.js +2 -0
  49. supython-0.1.0/src/supython/admin/static/assets/CodeViewer-Bqy7-wvH.js.map +1 -0
  50. supython-0.1.0/src/supython/admin/static/assets/Crons-B67vc39F.js +2 -0
  51. supython-0.1.0/src/supython/admin/static/assets/Crons-B67vc39F.js.map +1 -0
  52. supython-0.1.0/src/supython/admin/static/assets/DashboardView-CUTFVL6k.js +2 -0
  53. supython-0.1.0/src/supython/admin/static/assets/DashboardView-CUTFVL6k.js.map +1 -0
  54. supython-0.1.0/src/supython/admin/static/assets/DataTable-COAAWEft.js +747 -0
  55. supython-0.1.0/src/supython/admin/static/assets/DataTable-COAAWEft.js.map +1 -0
  56. supython-0.1.0/src/supython/admin/static/assets/DescriptionsItem-P8JUDaBs.js +75 -0
  57. supython-0.1.0/src/supython/admin/static/assets/DescriptionsItem-P8JUDaBs.js.map +1 -0
  58. supython-0.1.0/src/supython/admin/static/assets/DrawerContent-TpYTFgF1.js +139 -0
  59. supython-0.1.0/src/supython/admin/static/assets/DrawerContent-TpYTFgF1.js.map +1 -0
  60. supython-0.1.0/src/supython/admin/static/assets/Empty-cr2r7e2u.js +25 -0
  61. supython-0.1.0/src/supython/admin/static/assets/Empty-cr2r7e2u.js.map +1 -0
  62. supython-0.1.0/src/supython/admin/static/assets/EmptyState-DeDck-OL.js +2 -0
  63. supython-0.1.0/src/supython/admin/static/assets/EmptyState-DeDck-OL.js.map +1 -0
  64. supython-0.1.0/src/supython/admin/static/assets/Grid-hFkp9F4P.js +2 -0
  65. supython-0.1.0/src/supython/admin/static/assets/Grid-hFkp9F4P.js.map +1 -0
  66. supython-0.1.0/src/supython/admin/static/assets/Input-DppYTq9C.js +259 -0
  67. supython-0.1.0/src/supython/admin/static/assets/Input-DppYTq9C.js.map +1 -0
  68. supython-0.1.0/src/supython/admin/static/assets/Invoke-DW3Nveeh.js +2 -0
  69. supython-0.1.0/src/supython/admin/static/assets/Invoke-DW3Nveeh.js.map +1 -0
  70. supython-0.1.0/src/supython/admin/static/assets/JsonField-DibyJgun.js +2 -0
  71. supython-0.1.0/src/supython/admin/static/assets/JsonField-DibyJgun.js.map +1 -0
  72. supython-0.1.0/src/supython/admin/static/assets/LoginView-BjLyE3Ds.css +1 -0
  73. supython-0.1.0/src/supython/admin/static/assets/LoginView-CoOjECT_.js +111 -0
  74. supython-0.1.0/src/supython/admin/static/assets/LoginView-CoOjECT_.js.map +1 -0
  75. supython-0.1.0/src/supython/admin/static/assets/Logs-D9WYrnIT.js +2 -0
  76. supython-0.1.0/src/supython/admin/static/assets/Logs-D9WYrnIT.js.map +1 -0
  77. supython-0.1.0/src/supython/admin/static/assets/Logs-DS1XPa0h.css +1 -0
  78. supython-0.1.0/src/supython/admin/static/assets/Migrations-DOSC2ddQ.js +2 -0
  79. supython-0.1.0/src/supython/admin/static/assets/Migrations-DOSC2ddQ.js.map +1 -0
  80. supython-0.1.0/src/supython/admin/static/assets/ObjectBrowser-_5w8vOX8.js +2 -0
  81. supython-0.1.0/src/supython/admin/static/assets/ObjectBrowser-_5w8vOX8.js.map +1 -0
  82. supython-0.1.0/src/supython/admin/static/assets/Queue-CywZs6vI.js +2 -0
  83. supython-0.1.0/src/supython/admin/static/assets/Queue-CywZs6vI.js.map +1 -0
  84. supython-0.1.0/src/supython/admin/static/assets/RefreshTokens-Ccjr53jg.js +2 -0
  85. supython-0.1.0/src/supython/admin/static/assets/RefreshTokens-Ccjr53jg.js.map +1 -0
  86. supython-0.1.0/src/supython/admin/static/assets/RlsEditor-BSlH9vSc.js +2 -0
  87. supython-0.1.0/src/supython/admin/static/assets/RlsEditor-BSlH9vSc.js.map +1 -0
  88. supython-0.1.0/src/supython/admin/static/assets/Routes-BiLXE49D.js +2 -0
  89. supython-0.1.0/src/supython/admin/static/assets/Routes-BiLXE49D.js.map +1 -0
  90. supython-0.1.0/src/supython/admin/static/assets/Routes-C-ianIGD.css +1 -0
  91. supython-0.1.0/src/supython/admin/static/assets/SchemaBrowser-DKy2_KQi.css +1 -0
  92. supython-0.1.0/src/supython/admin/static/assets/SchemaBrowser-XFvFbtDB.js +2 -0
  93. supython-0.1.0/src/supython/admin/static/assets/SchemaBrowser-XFvFbtDB.js.map +1 -0
  94. supython-0.1.0/src/supython/admin/static/assets/Select-DIzZyRZb.js +434 -0
  95. supython-0.1.0/src/supython/admin/static/assets/Select-DIzZyRZb.js.map +1 -0
  96. supython-0.1.0/src/supython/admin/static/assets/Space-n5-XcguU.js +400 -0
  97. supython-0.1.0/src/supython/admin/static/assets/Space-n5-XcguU.js.map +1 -0
  98. supython-0.1.0/src/supython/admin/static/assets/SqlEditor-b8pTsILY.js +3 -0
  99. supython-0.1.0/src/supython/admin/static/assets/SqlEditor-b8pTsILY.js.map +1 -0
  100. supython-0.1.0/src/supython/admin/static/assets/SqlWorkspace-BUS7IntH.js +104 -0
  101. supython-0.1.0/src/supython/admin/static/assets/SqlWorkspace-BUS7IntH.js.map +1 -0
  102. supython-0.1.0/src/supython/admin/static/assets/TableData-CQIagLKn.js +2 -0
  103. supython-0.1.0/src/supython/admin/static/assets/TableData-CQIagLKn.js.map +1 -0
  104. supython-0.1.0/src/supython/admin/static/assets/Tag-D1fOKpTH.js +72 -0
  105. supython-0.1.0/src/supython/admin/static/assets/Tag-D1fOKpTH.js.map +1 -0
  106. supython-0.1.0/src/supython/admin/static/assets/Templates-BS-ugkdq.js +2 -0
  107. supython-0.1.0/src/supython/admin/static/assets/Templates-BS-ugkdq.js.map +1 -0
  108. supython-0.1.0/src/supython/admin/static/assets/Thing-CEAniuMg.js +107 -0
  109. supython-0.1.0/src/supython/admin/static/assets/Thing-CEAniuMg.js.map +1 -0
  110. supython-0.1.0/src/supython/admin/static/assets/Users-wzwajhlh.js +2 -0
  111. supython-0.1.0/src/supython/admin/static/assets/Users-wzwajhlh.js.map +1 -0
  112. supython-0.1.0/src/supython/admin/static/assets/_plugin-vue_export-helper-DGA9ry_j.js +1 -0
  113. supython-0.1.0/src/supython/admin/static/assets/dist-VXIJLCYq.js +13 -0
  114. supython-0.1.0/src/supython/admin/static/assets/dist-VXIJLCYq.js.map +1 -0
  115. supython-0.1.0/src/supython/admin/static/assets/format-length-CGCY1rMh.js +2 -0
  116. supython-0.1.0/src/supython/admin/static/assets/format-length-CGCY1rMh.js.map +1 -0
  117. supython-0.1.0/src/supython/admin/static/assets/get-Ca6unauB.js +2 -0
  118. supython-0.1.0/src/supython/admin/static/assets/get-Ca6unauB.js.map +1 -0
  119. supython-0.1.0/src/supython/admin/static/assets/index-CeE6v959.js +951 -0
  120. supython-0.1.0/src/supython/admin/static/assets/index-CeE6v959.js.map +1 -0
  121. supython-0.1.0/src/supython/admin/static/assets/pinia-COXwfrOX.js +2 -0
  122. supython-0.1.0/src/supython/admin/static/assets/pinia-COXwfrOX.js.map +1 -0
  123. supython-0.1.0/src/supython/admin/static/assets/resources-Bt6thQCD.js +44 -0
  124. supython-0.1.0/src/supython/admin/static/assets/resources-Bt6thQCD.js.map +1 -0
  125. supython-0.1.0/src/supython/admin/static/assets/use-locale-mtgM0a3a.js +2 -0
  126. supython-0.1.0/src/supython/admin/static/assets/use-locale-mtgM0a3a.js.map +1 -0
  127. supython-0.1.0/src/supython/admin/static/assets/use-merged-state-BvhkaHNX.js +2 -0
  128. supython-0.1.0/src/supython/admin/static/assets/use-merged-state-BvhkaHNX.js.map +1 -0
  129. supython-0.1.0/src/supython/admin/static/assets/useConfirm-tMjvBFXR.js +2 -0
  130. supython-0.1.0/src/supython/admin/static/assets/useConfirm-tMjvBFXR.js.map +1 -0
  131. supython-0.1.0/src/supython/admin/static/assets/useResource-C_rJCY8C.js +2 -0
  132. supython-0.1.0/src/supython/admin/static/assets/useResource-C_rJCY8C.js.map +1 -0
  133. supython-0.1.0/src/supython/admin/static/assets/useTable-CnZc5zhi.js +363 -0
  134. supython-0.1.0/src/supython/admin/static/assets/useTable-CnZc5zhi.js.map +1 -0
  135. supython-0.1.0/src/supython/admin/static/assets/useTable-Dg0XlRlq.css +1 -0
  136. supython-0.1.0/src/supython/admin/static/assets/useToast-DsZKx0IX.js +2 -0
  137. supython-0.1.0/src/supython/admin/static/assets/useToast-DsZKx0IX.js.map +1 -0
  138. supython-0.1.0/src/supython/admin/static/assets/utils-sbXoq7Ir.js +2 -0
  139. supython-0.1.0/src/supython/admin/static/assets/utils-sbXoq7Ir.js.map +1 -0
  140. supython-0.1.0/src/supython/admin/static/favicon.svg +1 -0
  141. supython-0.1.0/src/supython/admin/static/icons.svg +24 -0
  142. supython-0.1.0/src/supython/admin/static/index.html +24 -0
  143. supython-0.1.0/src/supython/app.py +162 -0
  144. supython-0.1.0/src/supython/auth/__init__.py +3 -0
  145. supython-0.1.0/src/supython/auth/_email_job.py +11 -0
  146. supython-0.1.0/src/supython/auth/providers/__init__.py +34 -0
  147. supython-0.1.0/src/supython/auth/providers/github.py +22 -0
  148. supython-0.1.0/src/supython/auth/providers/google.py +19 -0
  149. supython-0.1.0/src/supython/auth/providers/oauth.py +56 -0
  150. supython-0.1.0/src/supython/auth/providers/registry.py +16 -0
  151. supython-0.1.0/src/supython/auth/ratelimit.py +39 -0
  152. supython-0.1.0/src/supython/auth/router.py +282 -0
  153. supython-0.1.0/src/supython/auth/schemas.py +79 -0
  154. supython-0.1.0/src/supython/auth/service.py +587 -0
  155. supython-0.1.0/src/supython/backups/__init__.py +24 -0
  156. supython-0.1.0/src/supython/backups/_backup_job.py +170 -0
  157. supython-0.1.0/src/supython/backups/schemas.py +18 -0
  158. supython-0.1.0/src/supython/backups/service.py +217 -0
  159. supython-0.1.0/src/supython/body_size.py +184 -0
  160. supython-0.1.0/src/supython/cli.py +1663 -0
  161. supython-0.1.0/src/supython/client/__init__.py +67 -0
  162. supython-0.1.0/src/supython/client/_auth.py +249 -0
  163. supython-0.1.0/src/supython/client/_client.py +145 -0
  164. supython-0.1.0/src/supython/client/_config.py +92 -0
  165. supython-0.1.0/src/supython/client/_functions.py +69 -0
  166. supython-0.1.0/src/supython/client/_storage.py +255 -0
  167. supython-0.1.0/src/supython/client/py.typed +0 -0
  168. supython-0.1.0/src/supython/db.py +151 -0
  169. supython-0.1.0/src/supython/db_admin.py +8 -0
  170. supython-0.1.0/src/supython/extensions.py +36 -0
  171. supython-0.1.0/src/supython/functions/__init__.py +19 -0
  172. supython-0.1.0/src/supython/functions/context.py +262 -0
  173. supython-0.1.0/src/supython/functions/loader.py +307 -0
  174. supython-0.1.0/src/supython/functions/router.py +228 -0
  175. supython-0.1.0/src/supython/functions/schemas.py +50 -0
  176. supython-0.1.0/src/supython/gen/__init__.py +5 -0
  177. supython-0.1.0/src/supython/gen/_introspect.py +137 -0
  178. supython-0.1.0/src/supython/gen/types_py.py +270 -0
  179. supython-0.1.0/src/supython/gen/types_ts.py +365 -0
  180. supython-0.1.0/src/supython/health.py +229 -0
  181. supython-0.1.0/src/supython/hooks.py +117 -0
  182. supython-0.1.0/src/supython/jobs/__init__.py +31 -0
  183. supython-0.1.0/src/supython/jobs/backends.py +97 -0
  184. supython-0.1.0/src/supython/jobs/context.py +58 -0
  185. supython-0.1.0/src/supython/jobs/cron.py +152 -0
  186. supython-0.1.0/src/supython/jobs/cron_inproc.py +119 -0
  187. supython-0.1.0/src/supython/jobs/decorators.py +76 -0
  188. supython-0.1.0/src/supython/jobs/registry.py +79 -0
  189. supython-0.1.0/src/supython/jobs/router.py +136 -0
  190. supython-0.1.0/src/supython/jobs/schemas.py +92 -0
  191. supython-0.1.0/src/supython/jobs/service.py +311 -0
  192. supython-0.1.0/src/supython/jobs/worker.py +219 -0
  193. supython-0.1.0/src/supython/jwks.py +257 -0
  194. supython-0.1.0/src/supython/keyset.py +279 -0
  195. supython-0.1.0/src/supython/logging_config.py +291 -0
  196. supython-0.1.0/src/supython/mail.py +33 -0
  197. supython-0.1.0/src/supython/mailer.py +65 -0
  198. supython-0.1.0/src/supython/migrate.py +81 -0
  199. supython-0.1.0/src/supython/migrations/0001_extensions_and_roles.sql +46 -0
  200. supython-0.1.0/src/supython/migrations/0002_auth_schema.sql +66 -0
  201. supython-0.1.0/src/supython/migrations/0003_demo_todos.sql +42 -0
  202. supython-0.1.0/src/supython/migrations/0004_auth_v0_2.sql +47 -0
  203. supython-0.1.0/src/supython/migrations/0005_storage_schema.sql +117 -0
  204. supython-0.1.0/src/supython/migrations/0006_realtime_schema.sql +206 -0
  205. supython-0.1.0/src/supython/migrations/0007_jobs_schema.sql +254 -0
  206. supython-0.1.0/src/supython/migrations/0008_jobs_last_error.sql +56 -0
  207. supython-0.1.0/src/supython/migrations/0009_auth_rate_limits.sql +33 -0
  208. supython-0.1.0/src/supython/migrations/0010_worker_heartbeat.sql +14 -0
  209. supython-0.1.0/src/supython/migrations/0011_admin_schema.sql +45 -0
  210. supython-0.1.0/src/supython/migrations/0012_auth_banned_until.sql +10 -0
  211. supython-0.1.0/src/supython/migrations/0013_email_templates.sql +19 -0
  212. supython-0.1.0/src/supython/migrations/0014_realtime_payload_warning.sql +96 -0
  213. supython-0.1.0/src/supython/migrations/0015_backups_schema.sql +14 -0
  214. supython-0.1.0/src/supython/passwords.py +15 -0
  215. supython-0.1.0/src/supython/realtime/__init__.py +6 -0
  216. supython-0.1.0/src/supython/realtime/broker.py +814 -0
  217. supython-0.1.0/src/supython/realtime/protocol.py +234 -0
  218. supython-0.1.0/src/supython/realtime/router.py +184 -0
  219. supython-0.1.0/src/supython/realtime/schemas.py +207 -0
  220. supython-0.1.0/src/supython/realtime/service.py +261 -0
  221. supython-0.1.0/src/supython/realtime/topics.py +175 -0
  222. supython-0.1.0/src/supython/realtime/websocket.py +586 -0
  223. supython-0.1.0/src/supython/scaffold/__init__.py +5 -0
  224. supython-0.1.0/src/supython/scaffold/init_project.py +144 -0
  225. supython-0.1.0/src/supython/scaffold/templates/Caddyfile.tmpl +4 -0
  226. supython-0.1.0/src/supython/scaffold/templates/README.md.tmpl +22 -0
  227. supython-0.1.0/src/supython/scaffold/templates/apps_hooks.py.tmpl +11 -0
  228. supython-0.1.0/src/supython/scaffold/templates/apps_jobs.py.tmpl +8 -0
  229. supython-0.1.0/src/supython/scaffold/templates/asgi.py.tmpl +14 -0
  230. supython-0.1.0/src/supython/scaffold/templates/docker-compose.prod.yml.tmpl +84 -0
  231. supython-0.1.0/src/supython/scaffold/templates/docker-compose.yml.tmpl +45 -0
  232. supython-0.1.0/src/supython/scaffold/templates/docker_postgres_Dockerfile.tmpl +9 -0
  233. supython-0.1.0/src/supython/scaffold/templates/docker_postgres_postgresql.conf.tmpl +3 -0
  234. supython-0.1.0/src/supython/scaffold/templates/env.example.tmpl +168 -0
  235. supython-0.1.0/src/supython/scaffold/templates/functions_README.md.tmpl +21 -0
  236. supython-0.1.0/src/supython/scaffold/templates/gitignore.tmpl +14 -0
  237. supython-0.1.0/src/supython/scaffold/templates/manage.py.tmpl +11 -0
  238. supython-0.1.0/src/supython/scaffold/templates/migrations/.gitkeep +0 -0
  239. supython-0.1.0/src/supython/scaffold/templates/package_init.py.tmpl +1 -0
  240. supython-0.1.0/src/supython/scaffold/templates/settings.py.tmpl +31 -0
  241. supython-0.1.0/src/supython/secretset.py +347 -0
  242. supython-0.1.0/src/supython/security_headers.py +78 -0
  243. supython-0.1.0/src/supython/settings.py +244 -0
  244. supython-0.1.0/src/supython/settings_module.py +117 -0
  245. supython-0.1.0/src/supython/storage/__init__.py +5 -0
  246. supython-0.1.0/src/supython/storage/backends.py +392 -0
  247. supython-0.1.0/src/supython/storage/router.py +341 -0
  248. supython-0.1.0/src/supython/storage/schemas.py +50 -0
  249. supython-0.1.0/src/supython/storage/service.py +445 -0
  250. supython-0.1.0/src/supython/storage/signing.py +119 -0
  251. supython-0.1.0/src/supython/tokens.py +85 -0
@@ -0,0 +1,44 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ build/
5
+ dist/
6
+ .venv/
7
+ venv/
8
+ .env
9
+ .pytest_cache/
10
+ .ruff_cache/
11
+ .coverage
12
+ htmlcov/
13
+ *.sqlite3
14
+ .DS_Store
15
+ .cursor
16
+ .cursor/
17
+ .cursor/rules/
18
+
19
+ .kilo
20
+ .kilo/
21
+ .kilo/killo.jsonc
22
+
23
+ # dev-app/ is the dogfooded scaffolded project living inside the lib repo.
24
+ # Its checked-in shape (compose files, functions, storage fixtures) mirrors
25
+ # what `supython init` would produce; runtime state stays untracked.
26
+ dev-app/.env
27
+ dev-app/.supython/
28
+ dev-app/backups/
29
+ dev-app/__pycache__/
30
+ dev-app/functions/__pycache__/
31
+ dev-app/.tmp/
32
+
33
+ .references/
34
+ .claude/
35
+
36
+ ts-sdk/node_modules/
37
+ ts-sdk/dist/
38
+ ts-sdk/.turbo/
39
+ ts-sdk/.vitest-results/
40
+ ts-sdk/*.log
41
+
42
+ .tmp/
43
+
44
+ admin-ui/node_modules/
@@ -0,0 +1,204 @@
1
+ # Changelog
2
+
3
+ All notable changes to supython are recorded here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the
5
+ project uses **ZeroVer** (`0.x.y`) — see `docs/PROJECT.md` §14.0 for
6
+ what counts as a breaking change. There is no scheduled `1.0.0`; treat
7
+ every `MINOR` as a potential breaking release.
8
+
9
+ Categories used per release:
10
+
11
+ - **Breaking** — frozen-surface change as defined in §14.0; bumps `MINOR`.
12
+ - **Added** — new capability (no breakage); bumps `MINOR` or `PATCH`.
13
+ - **Changed** — backwards-compatible behaviour change.
14
+ - **Deprecated** — still works, scheduled for removal.
15
+ - **Removed** — gone.
16
+ - **Fixed** — bug fix.
17
+ - **Security** — vulnerability fix or hardening.
18
+
19
+ Each entry links the relevant `PROJECT.md` section and decision-log row
20
+ (`§19 YYYY-MM-DD`) where one exists.
21
+
22
+ ## [Unreleased]
23
+
24
+ ### Breaking
25
+ ### Added
26
+ ### Changed
27
+ ### Deprecated
28
+ ### Removed
29
+ ### Fixed
30
+ ### Security
31
+
32
+ ---
33
+
34
+ ## [0.1.0] — 2026-05-08
35
+
36
+ The first public release. Everything currently on `main` collapses
37
+ into this single ZeroVer entry — auth, storage, functions, realtime,
38
+ jobs, the admin control plane, and the security/ops baseline that
39
+ shipped over seven internal development phases (originally labelled
40
+ v0.1–v0.7 plus a v1.1.x admin track; see §19 decision log
41
+ 2026-05-08 for the renumbering rationale).
42
+
43
+ ### Added
44
+
45
+ **Auth (§9.2, §8)**
46
+
47
+ - Email/password signup, login, refresh-token rotation with reuse
48
+ detection (recursive descendant revoke + `auth.audit_log` row).
49
+ - OAuth (Google + GitHub) via `authlib` with PKCE
50
+ (`code_challenge_method="S256"`).
51
+ - Password reset, magic link, and email OTP flows.
52
+ - Pluggable email backend (`ConsoleBackend` + `SmtpBackend` via
53
+ `aiosmtplib`); SMTP failures retry via `jobs.jobs`.
54
+ - Per-IP fixed-window rate limiting on `/auth/v1/{token,signup,
55
+ recover,otp,magiclink}` backed by `auth.rate_limit_buckets` plus
56
+ conditional `pg_cron` pruning.
57
+ - Audit log on every security-relevant event (refresh reuse,
58
+ password change, OAuth link, etc.).
59
+ - `AUTHENTICATOR_PASSWORD` env-var hardens the PostgREST login role.
60
+
61
+ **JWT (§8)**
62
+
63
+ - RS256 default, ES256 optional. **HS256 removed entirely** — no
64
+ `JWT_SECRET`, no shared-secret fallback.
65
+ - Public key published as JWKS for PostgREST; `supython keygen
66
+ init/rotate/activate/prune` runs zero-downtime key rotation;
67
+ PostgREST hot-reloads via `SIGUSR2`.
68
+
69
+ **Storage (§9.5)**
70
+
71
+ - `LocalBackend` and `S3Backend` (optional `[s3]` extra) behind a
72
+ `StorageBackend` protocol.
73
+ - `storage.buckets` / `storage.objects` schema with RLS; one
74
+ physical S3 bucket via key prefixes for all logical buckets.
75
+ - HMAC-signed URLs keyed off a separate
76
+ `STORAGE_SIGNED_URL_SECRET`; multipart upload, range download.
77
+
78
+ **Functions (§9.6)**
79
+
80
+ - Filesystem convention `functions/<name>.py` with hot reload in dev
81
+ (mtime-on-dispatch, no watcher thread).
82
+ - `ctx` carries a role-scoped `asyncpg.Connection`, the caller's
83
+ user, a storage helper, a PostgREST `httpx` client, and the mailer.
84
+
85
+ **Realtime (§9.4)**
86
+
87
+ - `LISTEN/NOTIFY`-sourced channels with RLS-aware filtering.
88
+ - Phoenix Channels 5-tuple wire format (`vsn=1.0.0`) — unmodified
89
+ Supabase SDKs (`@supabase/realtime-js`, `supabase-py`, etc.)
90
+ connect.
91
+ - `postgres_changes`, `broadcast`, `presence` event types; generic
92
+ `realtime.enable(regclass, owner_column)` SQL helper installs the
93
+ trigger and registers the table.
94
+ - Oversize-payload (>~7900 bytes) warn-and-skip path so user writes
95
+ still commit when NOTIFY would exceed the 8000-byte cap.
96
+
97
+ **Jobs & cron (§9.7)**
98
+
99
+ - `jobs.jobs` Postgres queue with `SELECT FOR UPDATE SKIP LOCKED`;
100
+ 4-policy RLS; `SECURITY DEFINER` `jobs.enqueue` / `jobs.claim_next`
101
+ granted to `service_role` only.
102
+ - `@job` decorator with idempotency keys; exponential / linear /
103
+ constant backoff; per-definition `role` / `claims_from` so
104
+ user-scoped jobs run under `db.as_role()`.
105
+ - `@cron(...)` decorator backed by `pg_cron` with `sync_pg_cron()`
106
+ at startup; `InProcScheduler` fallback behind the `cron-inproc`
107
+ extra.
108
+ - Generic hook system (`hooks.on` / `hooks.fire`); signup → welcome
109
+ email wired through it.
110
+ - `last_error` column on `jobs.jobs` populated on retry/final
111
+ failure and surfaced via `JobResponse`.
112
+ - CLI: `supython worker run` (with SIGINT/SIGTERM drain),
113
+ `supython jobs {list,show,cancel,retry,enqueue}`,
114
+ `supython cron {list,sync}`.
115
+ - HTTP: `POST /jobs/v1/enqueue`, `GET /jobs/v1/jobs`,
116
+ `POST /jobs/v1/jobs/{id}/{cancel,retry}` (retry gates on
117
+ `failed`/`cancelled`; 409 otherwise).
118
+
119
+ **Admin control plane (§9.8)**
120
+
121
+ - Vue 3 + Vite SPA at `/admin`, pre-built static bundle inside the
122
+ wheel — **no Node at `pip install`**.
123
+ - Dedicated admin session (cookie: `HttpOnly` + `Secure` +
124
+ `SameSite=Strict` + `Path=/admin`), separate from end-user JWTs.
125
+ - `supython admin create-user` to bootstrap the first admin.
126
+ - Database surface: schema browser, table data view with role
127
+ switcher, SQL workspace (read-only default + opt-in write toggle
128
+ with confirm), RLS policy editor + dry-run, migrations panel.
129
+ - Auth surface: user search, ban/unban/force-logout, refresh-token
130
+ inspector, audit log, email-template editor.
131
+ - Storage / functions / realtime / jobs operator screens; backups
132
+ list / start / download; live log tail via SSE with level and
133
+ request-id filters.
134
+ - Every mutating handler dual-writes to `auth.audit_log` and
135
+ `admin.admin_audit`.
136
+
137
+ **Operations & security baseline (§11.1)**
138
+
139
+ - Structured JSON logging with `request_id` propagation; request
140
+ logging middleware redacts `Authorization` headers and includes
141
+ request body + traceback on 5xx.
142
+ - `/livez` (process alive), `/readyz` (per-dependency timeouts on
143
+ DB, PostgREST, broker, worker heartbeat, pg_cron health) returning
144
+ 503 + JSON failure detail, deep `/health`.
145
+ - Security headers middleware: HSTS, CSP, `X-Content-Type-Options:
146
+ nosniff`, `X-Frame-Options: DENY`, `Referrer-Policy`.
147
+ - Input size guards on every write route (max body bytes, max email
148
+ length, max password length).
149
+ - `db.as_role(role, claims)` and `db.as_service_role(claims=...)`
150
+ primitives; RLS-symmetric with PostgREST.
151
+ - `db_statement_timeout_ms` per-connection asyncpg
152
+ `statement_timeout`; `db_pool_min_size` / `db_pool_max_size`
153
+ settings replace the hardcoded pool sizing.
154
+ - Symmetric secret rotation: `supython secret
155
+ {status,rotate,activate,prune}` for `STORAGE_SIGNED_URL_SECRET`
156
+ and `OAUTH_STATE_SECRET`.
157
+ - Postgres password rotation: `supython password rotate <role>`.
158
+ - `supython doctor` checks: Postgres version + reachability; roles;
159
+ required + recommended extensions; JWT signing material; PostgREST
160
+ reachability; `wal_level`; role attribute sanity (LOGIN /
161
+ BYPASSRLS); grant sanity; framework schema ownership; migration
162
+ drift against `supython.migrations`; symmetric secret validity.
163
+ Exits non-zero when blockers are present.
164
+
165
+ **Tooling**
166
+
167
+ - `supython init`, `supython up`/`down`/`reset`, `supython dev`,
168
+ `supython migrate`, `supython doctor`, `supython gen types --lang
169
+ py`.
170
+ - `supython realtime enable <table>`.
171
+ - `supython test up`/`run`/`down`/`reset` for the dedicated test
172
+ Postgres on port 54323; `pytest tests/unit` runs without Docker.
173
+ - Multi-arch Docker image (`linux/amd64`, `linux/arm64`) on
174
+ `python:3.11-slim`: non-root `supython` user, `tini` PID 1,
175
+ `/livez` HEALTHCHECK; `.github/workflows/docker.yml` builds both
176
+ arches and publishes the multi-arch manifest to GHCR on `v*` tags.
177
+
178
+ ### Security
179
+
180
+ - All comparisons of password hashes / token hashes / signed-URL
181
+ signatures verified to be timing-safe (argon2 C-level `verify()`,
182
+ `hmac.compare_digest` via `itsdangerous`, RSA/ECDSA JWT
183
+ verification).
184
+ - CORS closed by default: `CORS_ORIGINS` is required for any browser
185
+ client; previously `["*"]`.
186
+ - `service_role` is never exposed to the browser. Admin handlers run
187
+ via `db.as_service_role()`; `service_role` JWTs in localStorage are
188
+ explicitly rejected as a deployment pattern.
189
+
190
+ ### Notes
191
+
192
+ - This is the *first* tagged public release. The previous
193
+ `v0.5.0a` git tag was deleted as part of this versioning reset
194
+ (§19 decision log 2026-05-08).
195
+ - The admin SPA's per-phase plan continues under
196
+ `docs/admin-ui/admin-surface-plan.md`. Remaining DoD items
197
+ (Vitest coverage gates, the optional visual-designer phase, the
198
+ static-asset gzip-budget tripwire) are tracked there and land as
199
+ 0.1.x patches.
200
+
201
+ ---
202
+
203
+ [Unreleased]: https://github.com/Tkeby/supython/compare/v0.1.0...HEAD
204
+ [0.1.0]: https://github.com/Tkeby/supython/releases/tag/v0.1.0
supython-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 supython contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.