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.
- supython-0.1.0/.gitignore +44 -0
- supython-0.1.0/CHANGELOG.md +204 -0
- supython-0.1.0/LICENSE +21 -0
- supython-0.1.0/PKG-INFO +756 -0
- supython-0.1.0/README.md +698 -0
- supython-0.1.0/SECURITY.md +41 -0
- supython-0.1.0/pyproject.toml +118 -0
- supython-0.1.0/src/supython/__init__.py +24 -0
- supython-0.1.0/src/supython/admin/__init__.py +3 -0
- supython-0.1.0/src/supython/admin/api/__init__.py +24 -0
- supython-0.1.0/src/supython/admin/api/auth.py +118 -0
- supython-0.1.0/src/supython/admin/api/auth_templates.py +67 -0
- supython-0.1.0/src/supython/admin/api/auth_users.py +225 -0
- supython-0.1.0/src/supython/admin/api/db.py +174 -0
- supython-0.1.0/src/supython/admin/api/functions.py +92 -0
- supython-0.1.0/src/supython/admin/api/jobs.py +192 -0
- supython-0.1.0/src/supython/admin/api/ops.py +224 -0
- supython-0.1.0/src/supython/admin/api/realtime.py +281 -0
- supython-0.1.0/src/supython/admin/api/service_auth.py +49 -0
- supython-0.1.0/src/supython/admin/api/service_auth_templates.py +83 -0
- supython-0.1.0/src/supython/admin/api/service_auth_users.py +346 -0
- supython-0.1.0/src/supython/admin/api/service_db.py +214 -0
- supython-0.1.0/src/supython/admin/api/service_functions.py +287 -0
- supython-0.1.0/src/supython/admin/api/service_jobs.py +282 -0
- supython-0.1.0/src/supython/admin/api/service_ops.py +213 -0
- supython-0.1.0/src/supython/admin/api/service_realtime.py +30 -0
- supython-0.1.0/src/supython/admin/api/service_storage.py +220 -0
- supython-0.1.0/src/supython/admin/api/storage.py +117 -0
- supython-0.1.0/src/supython/admin/api/system.py +37 -0
- supython-0.1.0/src/supython/admin/audit.py +29 -0
- supython-0.1.0/src/supython/admin/deps.py +22 -0
- supython-0.1.0/src/supython/admin/errors.py +16 -0
- supython-0.1.0/src/supython/admin/schemas.py +310 -0
- supython-0.1.0/src/supython/admin/session.py +52 -0
- supython-0.1.0/src/supython/admin/spa.py +38 -0
- supython-0.1.0/src/supython/admin/static/assets/Alert-dluGVkos.js +49 -0
- supython-0.1.0/src/supython/admin/static/assets/Alert-dluGVkos.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/Audit-Njung3HI.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/Audit-Njung3HI.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/Backups-DzPlFgrm.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/Backups-DzPlFgrm.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/Buckets-ByacGkU1.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/Buckets-ByacGkU1.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/Channels-BoIuTtam.js +353 -0
- supython-0.1.0/src/supython/admin/static/assets/Channels-BoIuTtam.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/ChevronRight-CtQH1EQ1.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/ChevronRight-CtQH1EQ1.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/CodeViewer-Bqy7-wvH.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/CodeViewer-Bqy7-wvH.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/Crons-B67vc39F.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/Crons-B67vc39F.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/DashboardView-CUTFVL6k.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/DashboardView-CUTFVL6k.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/DataTable-COAAWEft.js +747 -0
- supython-0.1.0/src/supython/admin/static/assets/DataTable-COAAWEft.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/DescriptionsItem-P8JUDaBs.js +75 -0
- supython-0.1.0/src/supython/admin/static/assets/DescriptionsItem-P8JUDaBs.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/DrawerContent-TpYTFgF1.js +139 -0
- supython-0.1.0/src/supython/admin/static/assets/DrawerContent-TpYTFgF1.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/Empty-cr2r7e2u.js +25 -0
- supython-0.1.0/src/supython/admin/static/assets/Empty-cr2r7e2u.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/EmptyState-DeDck-OL.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/EmptyState-DeDck-OL.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/Grid-hFkp9F4P.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/Grid-hFkp9F4P.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/Input-DppYTq9C.js +259 -0
- supython-0.1.0/src/supython/admin/static/assets/Input-DppYTq9C.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/Invoke-DW3Nveeh.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/Invoke-DW3Nveeh.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/JsonField-DibyJgun.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/JsonField-DibyJgun.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/LoginView-BjLyE3Ds.css +1 -0
- supython-0.1.0/src/supython/admin/static/assets/LoginView-CoOjECT_.js +111 -0
- supython-0.1.0/src/supython/admin/static/assets/LoginView-CoOjECT_.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/Logs-D9WYrnIT.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/Logs-D9WYrnIT.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/Logs-DS1XPa0h.css +1 -0
- supython-0.1.0/src/supython/admin/static/assets/Migrations-DOSC2ddQ.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/Migrations-DOSC2ddQ.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/ObjectBrowser-_5w8vOX8.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/ObjectBrowser-_5w8vOX8.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/Queue-CywZs6vI.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/Queue-CywZs6vI.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/RefreshTokens-Ccjr53jg.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/RefreshTokens-Ccjr53jg.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/RlsEditor-BSlH9vSc.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/RlsEditor-BSlH9vSc.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/Routes-BiLXE49D.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/Routes-BiLXE49D.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/Routes-C-ianIGD.css +1 -0
- supython-0.1.0/src/supython/admin/static/assets/SchemaBrowser-DKy2_KQi.css +1 -0
- supython-0.1.0/src/supython/admin/static/assets/SchemaBrowser-XFvFbtDB.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/SchemaBrowser-XFvFbtDB.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/Select-DIzZyRZb.js +434 -0
- supython-0.1.0/src/supython/admin/static/assets/Select-DIzZyRZb.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/Space-n5-XcguU.js +400 -0
- supython-0.1.0/src/supython/admin/static/assets/Space-n5-XcguU.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/SqlEditor-b8pTsILY.js +3 -0
- supython-0.1.0/src/supython/admin/static/assets/SqlEditor-b8pTsILY.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/SqlWorkspace-BUS7IntH.js +104 -0
- supython-0.1.0/src/supython/admin/static/assets/SqlWorkspace-BUS7IntH.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/TableData-CQIagLKn.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/TableData-CQIagLKn.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/Tag-D1fOKpTH.js +72 -0
- supython-0.1.0/src/supython/admin/static/assets/Tag-D1fOKpTH.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/Templates-BS-ugkdq.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/Templates-BS-ugkdq.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/Thing-CEAniuMg.js +107 -0
- supython-0.1.0/src/supython/admin/static/assets/Thing-CEAniuMg.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/Users-wzwajhlh.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/Users-wzwajhlh.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/_plugin-vue_export-helper-DGA9ry_j.js +1 -0
- supython-0.1.0/src/supython/admin/static/assets/dist-VXIJLCYq.js +13 -0
- supython-0.1.0/src/supython/admin/static/assets/dist-VXIJLCYq.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/format-length-CGCY1rMh.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/format-length-CGCY1rMh.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/get-Ca6unauB.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/get-Ca6unauB.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/index-CeE6v959.js +951 -0
- supython-0.1.0/src/supython/admin/static/assets/index-CeE6v959.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/pinia-COXwfrOX.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/pinia-COXwfrOX.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/resources-Bt6thQCD.js +44 -0
- supython-0.1.0/src/supython/admin/static/assets/resources-Bt6thQCD.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/use-locale-mtgM0a3a.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/use-locale-mtgM0a3a.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/use-merged-state-BvhkaHNX.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/use-merged-state-BvhkaHNX.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/useConfirm-tMjvBFXR.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/useConfirm-tMjvBFXR.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/useResource-C_rJCY8C.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/useResource-C_rJCY8C.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/useTable-CnZc5zhi.js +363 -0
- supython-0.1.0/src/supython/admin/static/assets/useTable-CnZc5zhi.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/useTable-Dg0XlRlq.css +1 -0
- supython-0.1.0/src/supython/admin/static/assets/useToast-DsZKx0IX.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/useToast-DsZKx0IX.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/assets/utils-sbXoq7Ir.js +2 -0
- supython-0.1.0/src/supython/admin/static/assets/utils-sbXoq7Ir.js.map +1 -0
- supython-0.1.0/src/supython/admin/static/favicon.svg +1 -0
- supython-0.1.0/src/supython/admin/static/icons.svg +24 -0
- supython-0.1.0/src/supython/admin/static/index.html +24 -0
- supython-0.1.0/src/supython/app.py +162 -0
- supython-0.1.0/src/supython/auth/__init__.py +3 -0
- supython-0.1.0/src/supython/auth/_email_job.py +11 -0
- supython-0.1.0/src/supython/auth/providers/__init__.py +34 -0
- supython-0.1.0/src/supython/auth/providers/github.py +22 -0
- supython-0.1.0/src/supython/auth/providers/google.py +19 -0
- supython-0.1.0/src/supython/auth/providers/oauth.py +56 -0
- supython-0.1.0/src/supython/auth/providers/registry.py +16 -0
- supython-0.1.0/src/supython/auth/ratelimit.py +39 -0
- supython-0.1.0/src/supython/auth/router.py +282 -0
- supython-0.1.0/src/supython/auth/schemas.py +79 -0
- supython-0.1.0/src/supython/auth/service.py +587 -0
- supython-0.1.0/src/supython/backups/__init__.py +24 -0
- supython-0.1.0/src/supython/backups/_backup_job.py +170 -0
- supython-0.1.0/src/supython/backups/schemas.py +18 -0
- supython-0.1.0/src/supython/backups/service.py +217 -0
- supython-0.1.0/src/supython/body_size.py +184 -0
- supython-0.1.0/src/supython/cli.py +1663 -0
- supython-0.1.0/src/supython/client/__init__.py +67 -0
- supython-0.1.0/src/supython/client/_auth.py +249 -0
- supython-0.1.0/src/supython/client/_client.py +145 -0
- supython-0.1.0/src/supython/client/_config.py +92 -0
- supython-0.1.0/src/supython/client/_functions.py +69 -0
- supython-0.1.0/src/supython/client/_storage.py +255 -0
- supython-0.1.0/src/supython/client/py.typed +0 -0
- supython-0.1.0/src/supython/db.py +151 -0
- supython-0.1.0/src/supython/db_admin.py +8 -0
- supython-0.1.0/src/supython/extensions.py +36 -0
- supython-0.1.0/src/supython/functions/__init__.py +19 -0
- supython-0.1.0/src/supython/functions/context.py +262 -0
- supython-0.1.0/src/supython/functions/loader.py +307 -0
- supython-0.1.0/src/supython/functions/router.py +228 -0
- supython-0.1.0/src/supython/functions/schemas.py +50 -0
- supython-0.1.0/src/supython/gen/__init__.py +5 -0
- supython-0.1.0/src/supython/gen/_introspect.py +137 -0
- supython-0.1.0/src/supython/gen/types_py.py +270 -0
- supython-0.1.0/src/supython/gen/types_ts.py +365 -0
- supython-0.1.0/src/supython/health.py +229 -0
- supython-0.1.0/src/supython/hooks.py +117 -0
- supython-0.1.0/src/supython/jobs/__init__.py +31 -0
- supython-0.1.0/src/supython/jobs/backends.py +97 -0
- supython-0.1.0/src/supython/jobs/context.py +58 -0
- supython-0.1.0/src/supython/jobs/cron.py +152 -0
- supython-0.1.0/src/supython/jobs/cron_inproc.py +119 -0
- supython-0.1.0/src/supython/jobs/decorators.py +76 -0
- supython-0.1.0/src/supython/jobs/registry.py +79 -0
- supython-0.1.0/src/supython/jobs/router.py +136 -0
- supython-0.1.0/src/supython/jobs/schemas.py +92 -0
- supython-0.1.0/src/supython/jobs/service.py +311 -0
- supython-0.1.0/src/supython/jobs/worker.py +219 -0
- supython-0.1.0/src/supython/jwks.py +257 -0
- supython-0.1.0/src/supython/keyset.py +279 -0
- supython-0.1.0/src/supython/logging_config.py +291 -0
- supython-0.1.0/src/supython/mail.py +33 -0
- supython-0.1.0/src/supython/mailer.py +65 -0
- supython-0.1.0/src/supython/migrate.py +81 -0
- supython-0.1.0/src/supython/migrations/0001_extensions_and_roles.sql +46 -0
- supython-0.1.0/src/supython/migrations/0002_auth_schema.sql +66 -0
- supython-0.1.0/src/supython/migrations/0003_demo_todos.sql +42 -0
- supython-0.1.0/src/supython/migrations/0004_auth_v0_2.sql +47 -0
- supython-0.1.0/src/supython/migrations/0005_storage_schema.sql +117 -0
- supython-0.1.0/src/supython/migrations/0006_realtime_schema.sql +206 -0
- supython-0.1.0/src/supython/migrations/0007_jobs_schema.sql +254 -0
- supython-0.1.0/src/supython/migrations/0008_jobs_last_error.sql +56 -0
- supython-0.1.0/src/supython/migrations/0009_auth_rate_limits.sql +33 -0
- supython-0.1.0/src/supython/migrations/0010_worker_heartbeat.sql +14 -0
- supython-0.1.0/src/supython/migrations/0011_admin_schema.sql +45 -0
- supython-0.1.0/src/supython/migrations/0012_auth_banned_until.sql +10 -0
- supython-0.1.0/src/supython/migrations/0013_email_templates.sql +19 -0
- supython-0.1.0/src/supython/migrations/0014_realtime_payload_warning.sql +96 -0
- supython-0.1.0/src/supython/migrations/0015_backups_schema.sql +14 -0
- supython-0.1.0/src/supython/passwords.py +15 -0
- supython-0.1.0/src/supython/realtime/__init__.py +6 -0
- supython-0.1.0/src/supython/realtime/broker.py +814 -0
- supython-0.1.0/src/supython/realtime/protocol.py +234 -0
- supython-0.1.0/src/supython/realtime/router.py +184 -0
- supython-0.1.0/src/supython/realtime/schemas.py +207 -0
- supython-0.1.0/src/supython/realtime/service.py +261 -0
- supython-0.1.0/src/supython/realtime/topics.py +175 -0
- supython-0.1.0/src/supython/realtime/websocket.py +586 -0
- supython-0.1.0/src/supython/scaffold/__init__.py +5 -0
- supython-0.1.0/src/supython/scaffold/init_project.py +144 -0
- supython-0.1.0/src/supython/scaffold/templates/Caddyfile.tmpl +4 -0
- supython-0.1.0/src/supython/scaffold/templates/README.md.tmpl +22 -0
- supython-0.1.0/src/supython/scaffold/templates/apps_hooks.py.tmpl +11 -0
- supython-0.1.0/src/supython/scaffold/templates/apps_jobs.py.tmpl +8 -0
- supython-0.1.0/src/supython/scaffold/templates/asgi.py.tmpl +14 -0
- supython-0.1.0/src/supython/scaffold/templates/docker-compose.prod.yml.tmpl +84 -0
- supython-0.1.0/src/supython/scaffold/templates/docker-compose.yml.tmpl +45 -0
- supython-0.1.0/src/supython/scaffold/templates/docker_postgres_Dockerfile.tmpl +9 -0
- supython-0.1.0/src/supython/scaffold/templates/docker_postgres_postgresql.conf.tmpl +3 -0
- supython-0.1.0/src/supython/scaffold/templates/env.example.tmpl +168 -0
- supython-0.1.0/src/supython/scaffold/templates/functions_README.md.tmpl +21 -0
- supython-0.1.0/src/supython/scaffold/templates/gitignore.tmpl +14 -0
- supython-0.1.0/src/supython/scaffold/templates/manage.py.tmpl +11 -0
- supython-0.1.0/src/supython/scaffold/templates/migrations/.gitkeep +0 -0
- supython-0.1.0/src/supython/scaffold/templates/package_init.py.tmpl +1 -0
- supython-0.1.0/src/supython/scaffold/templates/settings.py.tmpl +31 -0
- supython-0.1.0/src/supython/secretset.py +347 -0
- supython-0.1.0/src/supython/security_headers.py +78 -0
- supython-0.1.0/src/supython/settings.py +244 -0
- supython-0.1.0/src/supython/settings_module.py +117 -0
- supython-0.1.0/src/supython/storage/__init__.py +5 -0
- supython-0.1.0/src/supython/storage/backends.py +392 -0
- supython-0.1.0/src/supython/storage/router.py +341 -0
- supython-0.1.0/src/supython/storage/schemas.py +50 -0
- supython-0.1.0/src/supython/storage/service.py +445 -0
- supython-0.1.0/src/supython/storage/signing.py +119 -0
- 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.
|