pyweb-stack 0.6.0__tar.gz → 0.6.2__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.
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/CHANGELOG.md +112 -0
- {pyweb_stack-0.6.0/pyweb_stack.egg-info → pyweb_stack-0.6.2}/PKG-INFO +15 -4
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/README.md +14 -3
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/THREAT_MODEL.md +15 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/01-introduction.md +4 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/02-quickstart.md +13 -1
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/14-cli.md +46 -7
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/16-limitations-roadmap.md +12 -4
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/17-ai-assistants.md +22 -1
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/27-upgrading.md +1 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/29-performance.md +11 -1
- pyweb_stack-0.6.2/docs/35-dev-loop.md +151 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyproject.toml +2 -2
- pyweb_stack-0.6.2/pyweb/_templates.py +18 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/app_loader.py +53 -9
- pyweb_stack-0.6.2/pyweb/assist.py +394 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/bench.py +68 -1
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/cli/__init__.py +354 -45
- pyweb_stack-0.6.2/pyweb/compiler/diskcache.py +72 -0
- pyweb_stack-0.6.2/pyweb/compiler/errors.py +223 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/compiler/lower.py +12 -3
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/compiler/parser.py +56 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/compiler/pipeline.py +64 -2
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/compiler/pyjs.py +17 -3
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/devlink.py +37 -3
- pyweb_stack-0.6.2/pyweb/devopen.py +92 -0
- pyweb_stack-0.6.2/pyweb/doctor.py +303 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/hosting.py +4 -3
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/lsp_ui.py +19 -2
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/mcp.py +92 -49
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/mcp_tools.py +22 -0
- pyweb_stack-0.6.2/pyweb/qr.py +273 -0
- pyweb_stack-0.6.2/pyweb/runtime/browser/dev/assist.js +156 -0
- pyweb_stack-0.6.2/pyweb/runtime/browser/dev/inspect.js +138 -0
- pyweb_stack-0.6.2/pyweb/runtime/browser/dev/reload.js +180 -0
- pyweb_stack-0.6.2/pyweb/runtime/browser/dev/timeline.js +144 -0
- pyweb_stack-0.6.2/pyweb/runtime/browser/dev/welcome.js +46 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/runtime.js +6 -4
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/server/__init__.py +4 -2
- pyweb_stack-0.6.2/pyweb/share.py +172 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/telemetry/devtools.py +4 -1
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/extending.py +7 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/upgrade.py +12 -1
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2/pyweb_stack.egg-info}/PKG-INFO +15 -4
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb_stack.egg-info/SOURCES.txt +22 -0
- pyweb_stack-0.6.2/tests/test_assist.py +243 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_auth.py +2 -1
- pyweb_stack-0.6.2/tests/test_cli_test.py +44 -0
- pyweb_stack-0.6.2/tests/test_compile_cache.py +149 -0
- pyweb_stack-0.6.2/tests/test_dev_reload.py +55 -0
- pyweb_stack-0.6.2/tests/test_devopen.py +87 -0
- pyweb_stack-0.6.2/tests/test_doctor.py +128 -0
- pyweb_stack-0.6.2/tests/test_error_messages.py +164 -0
- pyweb_stack-0.6.2/tests/test_first_run.py +119 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_forms_v5.py +2 -1
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_mcp.py +3 -1
- pyweb_stack-0.6.2/tests/test_qr.py +103 -0
- pyweb_stack-0.6.2/tests/test_share.py +153 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_trusted_types.py +8 -0
- pyweb_stack-0.6.0/pyweb/_templates.py +0 -3
- pyweb_stack-0.6.0/pyweb/compiler/errors.py +0 -29
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/LICENSE +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/MANIFEST.in +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/03-tutorial.md +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/04-pyweb-files.md +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/05-reactivity.md +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/06-server-functions.md +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/07-browser-python.md +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/08-pages-routing-assets.md +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/09-data.md +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/10-auth.md +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/11-testing.md +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/12-deployment.md +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/13-security.md +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/15-toolkit.md +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/18-npm-packages.md +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/19-layouts-navigation.md +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/20-ai-apps.md +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/21-live-data.md +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/22-recipe-web3.md +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/23-forms.md +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/24-jobs.md +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/25-scaling.md +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/26-observability.md +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/28-saas-tutorial.md +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/30-teams.md +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/31-pwa-push.md +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/32-desktop.md +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/33-webhooks-files.md +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/34-ui-and-motion.md +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/__init__.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/_speedups.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/a11y.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ai/guide.md +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/app.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/asgi.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/auth.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/authkit/__init__.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/authkit/admin.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/authkit/html.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/authkit/models.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/authkit/oauth.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/authkit/orgpages.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/authkit/orgs.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/authkit/pages.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/authkit/passwords.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/authkit/privacy.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/authkit/teams.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/authkit/throttle.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/authkit/tokens.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/authkit/webauthn.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/browser.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/build.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/cache.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/cli/__main__.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/compiler/__init__.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/compiler/ast.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/compiler/codegen/__init__.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/compiler/codegen/ir.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/compiler/rpc.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/config.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/context.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/csp_report.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/css.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/db/__init__.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/db/dialect.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/db/migrate.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/db/rls.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/db/schema.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/db/seeds.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/decorators.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/deploy/__init__.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/deploy/legacy.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/deploy/plan.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/deploy/targets.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/deprecation.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/desktop/__init__.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/desktop/gate.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/desktop/package.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/desktop/shell.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/dts.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/fieldcrypt.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/filegc.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/forms.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/http.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/jobs/__init__.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/jobs/builtin.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/jobs/core.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/jobs/db.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/jobs/legacy.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/jobs/memory.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/jobs/redis.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/jobs/schedule.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/jobs/worker.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/keys.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/livedata.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/livetable.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/lsp.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/lsp_data.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/lsp_teams.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/mail.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/markdown.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/mcp_http.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/models/__init__.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/models/fields.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/models/query.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/models/relations.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/motion.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/net/__init__.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/net/http.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/net/live.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/net/server.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/net/ws.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/observability.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/openapi.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/packages.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/platform.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/plugins.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/profile.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/push.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/pwa.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/py.typed +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/realtime.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/rooms.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/rpc.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/rules.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/auth.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/desktop.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/forms.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/live.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/markdown.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/motion-api.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/motion-count.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/motion-drag.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/motion-layout.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/motion-math.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/motion.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/pwa.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/sw.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/accordion.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/calendar.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/carousel.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/checkbox.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/collapsible.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/combobox.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/command.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/context-menu.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/core.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/dialog.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/hover-card.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/index.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/listbox.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/menu.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/menubar.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/navigation-menu.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/otp.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/popover.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/radio-group.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/resizable.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/select.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/sidebar.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/slider.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/tabs.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/toaster.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/toggle-group.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/toggle.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/tooltip.js +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/server/argcheck.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/sbom.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/secret_scan.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/security.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/serve.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ssr.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ssr_codegen.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/storage.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/sync.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/telemetry/__init__.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/telemetry/instruments.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/telemetry/logs.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/telemetry/metrics.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/telemetry/tracing.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/templates/ai-chat.pyweb +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/templates/app.css +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/templates/auth.pyweb +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/templates/blog.pyweb +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/templates/chat.pyweb +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/templates/counter.pyweb +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/templates/desktop/app.pyweb +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/templates/desktop/test_app.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/templates/saas/app.pyweb +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/templates/saas/seeds.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/templates/saas/test_app.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/templates/todo.pyweb +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/tenancy.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/testing.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/__init__.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/cli.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/button.pyweb +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/card.pyweb +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/carousel.pyweb +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/chart.pyweb +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/command.pyweb +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/controls.pyweb +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/data.pyweb +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/date.pyweb +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/dialog.pyweb +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/disclosure.pyweb +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/display.pyweb +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/layout.pyweb +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/menu.pyweb +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/overlay.pyweb +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/style.pyweb +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/serve.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/source_edit.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/static/ui.css +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/theme.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/uploads.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/webhooks.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb_stack.egg-info/dependency_links.txt +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb_stack.egg-info/entry_points.txt +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb_stack.egg-info/requires.txt +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb_stack.egg-info/top_level.txt +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/setup.cfg +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/setup.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_account_privacy.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_api_tokens.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_auth_contract.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_auth_security.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_auth_sessions.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_auth_v1.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_authkit.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_authkit_units.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_backplane.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_browser_build.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_budget.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_cli_deploy.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_codegen.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_compiler.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_cron.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_customise.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_data_layer.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_db_production.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_deploy_upload_render.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_deploy_v5.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_desktop.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_docs.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_dts.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_dx_v5.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_e2e.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_encrypted_fields.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_examples.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_filegc.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_forms_security_obs.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_fuzz_requests.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_http_fetch.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_jobs_app.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_jobs_cache_realtime.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_jobs_v5.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_keys_sessions.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_live_patches.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_livedata.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_lsp.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_lsp_teams.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_markdown.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_mcp_teams.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_mcp_v6.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_migrations_property.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_migrations_v5.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_models_db.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_motion.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_multifile.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_multipage.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_net.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_observability.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_openapi.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_org_pages.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_packages.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_parser.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_parser_v1.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_plugins_platform_bench.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_production_gaps.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_profile.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_push.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_pwa.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_pyjs_semantics.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_rate_per_function.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_reactivity.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_realtime_transport.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_reference_apps.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_request_hardening.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_rpc_placement.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_rpc_production.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_runtime_signals.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_sbom.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_secret_scan.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_server_db.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_speedups.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_ssr_codegen.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_static_hashing.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_static_serving.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_streaming.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_sync_live.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_systems.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_telemetry.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_tenancy.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_testing_orgs.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_threat_model.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_ui_kit.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_webhooks.py +0 -0
- {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_website.py +0 -0
|
@@ -6,6 +6,118 @@ project uses [semantic versioning](https://semver.org).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.6.2]
|
|
10
|
+
|
|
11
|
+
The dev loop. Saves update the open page in place with every page and
|
|
12
|
+
component keeping its state, any element opens its own line in your
|
|
13
|
+
editor, error pages fix themselves with AI (your assistant's model through
|
|
14
|
+
MCP, or your own key), a timeline steps back through every change, and
|
|
15
|
+
`pyweb dev --share` gives someone a link to try what you're building. All
|
|
16
|
+
of it lives in `pyweb dev`: production output is unchanged and there is
|
|
17
|
+
nothing to change in your apps. See [The dev loop](docs/35-dev-loop.md).
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
- **Hot reload without a page load.** A save swaps the page in place
|
|
21
|
+
through client navigation: no reload, no flash. Page variables,
|
|
22
|
+
component variables (each instance keeps its own), form fields, scroll,
|
|
23
|
+
focus and the selection stay. A stylesheet-only save swaps just that
|
|
24
|
+
stylesheet. When the page changed too much to swap, it reloads with the
|
|
25
|
+
same state, also after a compile error is fixed.
|
|
26
|
+
- **Click to source.** Hold Alt to see where any element comes from;
|
|
27
|
+
Alt-click opens that line in your editor (`PYWEB_EDITOR`, else VS Code,
|
|
28
|
+
Cursor, Windsurf, Zed or Sublime Text, else a `vscode://` link) and
|
|
29
|
+
shows the **inspector**: the components around it with their live
|
|
30
|
+
variables, which you can edit.
|
|
31
|
+
- **Fix with AI and Edit with AI.** Compile error pages and dev 500 pages
|
|
32
|
+
have Fix with AI; Alt+Shift-click any element to ask for a change. The
|
|
33
|
+
answer is a compiled diff of one app file: Apply writes it (refused if
|
|
34
|
+
the file changed since) and Undo puts it back (`.pyweb/history/`). It is
|
|
35
|
+
answered by the assistant connected through `pyweb mcp` when its app
|
|
36
|
+
supports MCP sampling, else `ANTHROPIC_API_KEY` or
|
|
37
|
+
`OPENAI_API_KEY`/`OPENAI_BASE_URL`, else the page offers the prompt to
|
|
38
|
+
copy. Credentials in what's sent are replaced by placeholders and put
|
|
39
|
+
back in the answer.
|
|
40
|
+
- **Time-travel timeline.** The toolbar's Timeline tab records every change
|
|
41
|
+
to the page's variables with its cause (a click, typing, a server call);
|
|
42
|
+
a slider steps back through them with the page paused, and Resume
|
|
43
|
+
returns to now.
|
|
44
|
+
- **`pyweb dev --share`**: a temporary public link (cloudflared, else
|
|
45
|
+
localhost.run) with a QR code. The link's token sets a cookie that every
|
|
46
|
+
request through the tunnel needs; guests get the app and hot reload, not
|
|
47
|
+
your tools.
|
|
48
|
+
- **A better first five minutes.** `pyweb new` with no name asks for the
|
|
49
|
+
name, a starter and a colour preset (`--theme` without asking); `pyweb
|
|
50
|
+
dev` opens the browser, prints the network URL with a QR code for a phone
|
|
51
|
+
with `--host 0.0.0.0`, and shows a one-time Welcome panel with what to
|
|
52
|
+
try and how to connect your assistant.
|
|
53
|
+
- **A faster first start.** Parse results and compiled code are cached on
|
|
54
|
+
disk (`~/.cache/pyweb`; `PYWEB_CACHE=0` turns it off): loading the saas
|
|
55
|
+
example in a fresh process went from about 340 to 210 ms.
|
|
56
|
+
`pyweb.bench --system` reports `cold_dev_ms`.
|
|
57
|
+
- MCP: the `pyweb_assist_requests` tool and the `fix_errors` prompt;
|
|
58
|
+
`pyweb mcp` answers the page's AI requests through sampling.
|
|
59
|
+
|
|
60
|
+
### Changed
|
|
61
|
+
- `pyweb dev`'s toolbar and its `/__pyweb/dev/` endpoints answer only the
|
|
62
|
+
person running it: a request from this machine to a loopback address.
|
|
63
|
+
Visitors from the network (`--host 0.0.0.0`) or a share link get hot
|
|
64
|
+
reload only.
|
|
65
|
+
- The runtime is 25 bytes bigger (gzip) for the dev hooks; nothing runs
|
|
66
|
+
in production.
|
|
67
|
+
|
|
68
|
+
## [0.6.1]
|
|
69
|
+
|
|
70
|
+
Better error messages, `pyweb doctor`, a `pyweb dev` that keeps your place
|
|
71
|
+
when it reloads, much faster reloads and tests, and fixes found by
|
|
72
|
+
installing 0.6.0 from PyPI and putting every template through every
|
|
73
|
+
command. Nothing to change in your apps.
|
|
74
|
+
|
|
75
|
+
### Added
|
|
76
|
+
- **Better error messages.** Compile errors show the line with a caret under
|
|
77
|
+
the problem, suggest the name you meant (a prop, component, variable,
|
|
78
|
+
server function argument, kit variant or motion preset: "did you mean
|
|
79
|
+
'name'?"), and link the docs page that explains them. The CLI, the
|
|
80
|
+
`pyweb dev` overlay and the MCP tools (`frame`, `docs` fields) show the
|
|
81
|
+
same. When page code raises in `pyweb dev`, the error page starts with the
|
|
82
|
+
frames in your own files and their source lines.
|
|
83
|
+
- **`pyweb dev` keeps your place when it reloads.** After a save, the page
|
|
84
|
+
comes back with its variables (a counter's count, a bound input's text),
|
|
85
|
+
unbound form fields, scroll position and focus as they were. A variable
|
|
86
|
+
whose type changed, or that was renamed, starts over; add `?fresh` to the
|
|
87
|
+
URL to start everything over. Production builds only grow by the names
|
|
88
|
+
of page variables.
|
|
89
|
+
- **`pyweb doctor`** checks the project and the machine in one go: Python,
|
|
90
|
+
whether the app compiles, optional packages the app needs, the database
|
|
91
|
+
and pending migrations, Redis, secrets written in the source, changes
|
|
92
|
+
`pyweb upgrade` wants, a stale dev server link, tests, the port and the
|
|
93
|
+
editor extension, each with a fix (`--production` adds the production
|
|
94
|
+
settings, `--json` for CI). Assistants get it as the `pyweb_doctor` tool.
|
|
95
|
+
- **Faster reloads and tests.** The UI kit is compiled once per process and
|
|
96
|
+
each file's Python code is reused until it changes: on the saas example a
|
|
97
|
+
`pyweb dev` reload after a save went from about 255 to 60 ms, a
|
|
98
|
+
`TestClient` from about 255 to 55 ms, and compiling from about 240 to
|
|
99
|
+
60 ms. The dev server notices a save within 0.1 s (was 0.4 s) and the
|
|
100
|
+
page asks for the new version every 0.25 s (was 0.6 s).
|
|
101
|
+
`python -m pyweb.bench --system` reports `reload_ms` and `test_client_ms`,
|
|
102
|
+
and CI's benchmark gate watches them.
|
|
103
|
+
- `pyweb check` warns about kit props and motion values that won't work
|
|
104
|
+
(`<Button variant="outlin">`), as the editor already did.
|
|
105
|
+
|
|
106
|
+
### Fixed
|
|
107
|
+
- `pyweb check` printed the file and line twice for compile errors.
|
|
108
|
+
- Components drawn as a kit button (`DialogClose`) were flagged by the
|
|
109
|
+
editor for `variant="default"`, which they support.
|
|
110
|
+
- `pyweb test` with no path ran `pytest tests/`, which new apps don't have
|
|
111
|
+
(their test is `test_app.py` next to `app.pyweb`), so it failed in every
|
|
112
|
+
new project. It now runs the current folder, and accepts the app's
|
|
113
|
+
`.pyweb` file as well as a test file or folder.
|
|
114
|
+
- The `pyweb_test` MCP tool given the app's `.pyweb` file (as every other
|
|
115
|
+
tool takes) found no tests; it now tests that file's folder.
|
|
116
|
+
- `pyweb upgrade` says to apply pending migrations before creating the
|
|
117
|
+
`auth_sessions` one (on a fresh checkout `pyweb db diff` refused to run),
|
|
118
|
+
and notes that 0.6's `pyweb check` reports accessibility problems, which
|
|
119
|
+
`--strict` treats as failures.
|
|
120
|
+
|
|
9
121
|
## [0.6.0]
|
|
10
122
|
|
|
11
123
|
Teams, installable and desktop apps, a UI kit and motion, and security by
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyweb-stack
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.2
|
|
4
4
|
Summary: Full-stack web apps in one Python file: server-rendered pages, reactive browser UI, typed RPC.
|
|
5
5
|
Author-email: MaanavKrishna <67054795+MaanavKrishna@users.noreply.github.com>
|
|
6
6
|
Maintainer-email: MaanavKrishna <67054795+MaanavKrishna@users.noreply.github.com>
|
|
@@ -400,6 +400,17 @@ develop a toolbar on every page shows each request's queries and flags
|
|
|
400
400
|
N+1 loops. [Scaling & deploying →](docs/25-scaling.md) ·
|
|
401
401
|
[Logs, metrics & tracing →](docs/26-observability.md)
|
|
402
402
|
|
|
403
|
+
### A dev loop that keeps up
|
|
404
|
+
|
|
405
|
+
Save, and the open page changes in place: no reload, and every page and
|
|
406
|
+
component keeps its state. Hold Alt and click any element to open its
|
|
407
|
+
line in your editor; Alt+Shift-click to change it with AI, and error
|
|
408
|
+
pages have **Fix with AI** (your assistant's model through MCP, or your
|
|
409
|
+
own API key), with a diff to apply and Undo. The toolbar's timeline
|
|
410
|
+
steps back through every change and what caused it, and
|
|
411
|
+
`pyweb dev --share` gives someone a link to try what you're building.
|
|
412
|
+
[The dev loop →](docs/35-dev-loop.md)
|
|
413
|
+
|
|
403
414
|
### Small, fast and boring to run
|
|
404
415
|
|
|
405
416
|
- **Every page is server-rendered**: complete HTML on first paint, then
|
|
@@ -442,7 +453,7 @@ it runs the real PyWeb, server functions included, in your browser.
|
|
|
442
453
|
pip install pyweb-stack
|
|
443
454
|
pyweb new myapp --template saas # saas | desktop | blank | counter | todo | blog | auth | chat | ai-chat
|
|
444
455
|
cd myapp
|
|
445
|
-
pyweb dev app.pyweb #
|
|
456
|
+
pyweb dev app.pyweb # saves update the open page in place, state kept
|
|
446
457
|
```
|
|
447
458
|
|
|
448
459
|
Then:
|
|
@@ -478,7 +489,7 @@ The [architecture overview](ARCHITECTURE.md) goes through each stage.
|
|
|
478
489
|
|
|
479
490
|
## Build it with AI
|
|
480
491
|
|
|
481
|
-
PyWeb ships an MCP server with
|
|
492
|
+
PyWeb ships an MCP server with 31 tools, so AI assistants can do what
|
|
482
493
|
you'd do: scaffold an app, search the docs, check each edit (errors come
|
|
483
494
|
back as line numbers with fix hints), build with the UI kit and a theme,
|
|
484
495
|
render pages and call server functions as any signed-in member, look at
|
|
@@ -566,7 +577,7 @@ Upgrade with `pip install -U pyweb-stack`.
|
|
|
566
577
|
|
|
567
578
|
| Version | Highlights |
|
|
568
579
|
|---|---|
|
|
569
|
-
| 0.6 | Teams with roles, invitations and tenant-scoped Models (Postgres row-level security), API tokens and OpenAPI, webhooks, installable apps with Web Push, desktop windows and installers, a UI kit with themes and motion, Trusted Types, encrypted fields and a threat model, about 2.5× faster serving, Python 3.15 and free-threaded builds, a much richer MCP server |
|
|
580
|
+
| 0.6 | Teams with roles, invitations and tenant-scoped Models (Postgres row-level security), API tokens and OpenAPI, webhooks, installable apps with Web Push, desktop windows and installers, a UI kit with themes and motion, Trusted Types, encrypted fields and a threat model, about 2.5× faster serving, Python 3.15 and free-threaded builds, a much richer MCP server; 0.6.1: error messages with code frames and suggestions, `pyweb doctor`, dev reloads that keep page state, 4× faster reloads and tests; 0.6.2: the dev loop (hot reload in place with component state, Alt-click to source, Fix/Edit with AI, a time-travel timeline, `pyweb dev --share`, a guided `pyweb new`) |
|
|
570
581
|
| 0.5 | Models with migrations, forms, auth kit with passkeys, OAuth and an admin, row-level live updates over WebSockets on PyWeb's own server, durable jobs and schedules, `pyweb deploy` for docker, compose, k8s, fly, render and railway, logs, metrics, tracing and a dev toolbar, data-aware editor and MCP tools, the `saas` template, `pyweb upgrade` |
|
|
571
582
|
| 0.4 | npm packages without Node, layouts and client-side navigation, streaming server functions and `<Markdown>` for AI apps, live queries, page head tags, `.pyweb` error pages; 0.4.1: richer MCP tools; 0.4.2: VS Code run, new-app and MCP commands; 0.4.3: fixes, security hardening, gzip and caching; 0.4.4: key rotation, session revocation, typed arguments, Redis-shared limits, `check --production` |
|
|
572
583
|
| 0.3 | Hydration, live updates (SSE), multi-file apps, language server + VS Code extension, browser playground, faster rendering, screenshot/test MCP tools |
|
|
@@ -326,6 +326,17 @@ develop a toolbar on every page shows each request's queries and flags
|
|
|
326
326
|
N+1 loops. [Scaling & deploying →](docs/25-scaling.md) ·
|
|
327
327
|
[Logs, metrics & tracing →](docs/26-observability.md)
|
|
328
328
|
|
|
329
|
+
### A dev loop that keeps up
|
|
330
|
+
|
|
331
|
+
Save, and the open page changes in place: no reload, and every page and
|
|
332
|
+
component keeps its state. Hold Alt and click any element to open its
|
|
333
|
+
line in your editor; Alt+Shift-click to change it with AI, and error
|
|
334
|
+
pages have **Fix with AI** (your assistant's model through MCP, or your
|
|
335
|
+
own API key), with a diff to apply and Undo. The toolbar's timeline
|
|
336
|
+
steps back through every change and what caused it, and
|
|
337
|
+
`pyweb dev --share` gives someone a link to try what you're building.
|
|
338
|
+
[The dev loop →](docs/35-dev-loop.md)
|
|
339
|
+
|
|
329
340
|
### Small, fast and boring to run
|
|
330
341
|
|
|
331
342
|
- **Every page is server-rendered**: complete HTML on first paint, then
|
|
@@ -368,7 +379,7 @@ it runs the real PyWeb, server functions included, in your browser.
|
|
|
368
379
|
pip install pyweb-stack
|
|
369
380
|
pyweb new myapp --template saas # saas | desktop | blank | counter | todo | blog | auth | chat | ai-chat
|
|
370
381
|
cd myapp
|
|
371
|
-
pyweb dev app.pyweb #
|
|
382
|
+
pyweb dev app.pyweb # saves update the open page in place, state kept
|
|
372
383
|
```
|
|
373
384
|
|
|
374
385
|
Then:
|
|
@@ -404,7 +415,7 @@ The [architecture overview](ARCHITECTURE.md) goes through each stage.
|
|
|
404
415
|
|
|
405
416
|
## Build it with AI
|
|
406
417
|
|
|
407
|
-
PyWeb ships an MCP server with
|
|
418
|
+
PyWeb ships an MCP server with 31 tools, so AI assistants can do what
|
|
408
419
|
you'd do: scaffold an app, search the docs, check each edit (errors come
|
|
409
420
|
back as line numbers with fix hints), build with the UI kit and a theme,
|
|
410
421
|
render pages and call server functions as any signed-in member, look at
|
|
@@ -492,7 +503,7 @@ Upgrade with `pip install -U pyweb-stack`.
|
|
|
492
503
|
|
|
493
504
|
| Version | Highlights |
|
|
494
505
|
|---|---|
|
|
495
|
-
| 0.6 | Teams with roles, invitations and tenant-scoped Models (Postgres row-level security), API tokens and OpenAPI, webhooks, installable apps with Web Push, desktop windows and installers, a UI kit with themes and motion, Trusted Types, encrypted fields and a threat model, about 2.5× faster serving, Python 3.15 and free-threaded builds, a much richer MCP server |
|
|
506
|
+
| 0.6 | Teams with roles, invitations and tenant-scoped Models (Postgres row-level security), API tokens and OpenAPI, webhooks, installable apps with Web Push, desktop windows and installers, a UI kit with themes and motion, Trusted Types, encrypted fields and a threat model, about 2.5× faster serving, Python 3.15 and free-threaded builds, a much richer MCP server; 0.6.1: error messages with code frames and suggestions, `pyweb doctor`, dev reloads that keep page state, 4× faster reloads and tests; 0.6.2: the dev loop (hot reload in place with component state, Alt-click to source, Fix/Edit with AI, a time-travel timeline, `pyweb dev --share`, a guided `pyweb new`) |
|
|
496
507
|
| 0.5 | Models with migrations, forms, auth kit with passkeys, OAuth and an admin, row-level live updates over WebSockets on PyWeb's own server, durable jobs and schedules, `pyweb deploy` for docker, compose, k8s, fly, render and railway, logs, metrics, tracing and a dev toolbar, data-aware editor and MCP tools, the `saas` template, `pyweb upgrade` |
|
|
497
508
|
| 0.4 | npm packages without Node, layouts and client-side navigation, streaming server functions and `<Markdown>` for AI apps, live queries, page head tags, `.pyweb` error pages; 0.4.1: richer MCP tools; 0.4.2: VS Code run, new-app and MCP commands; 0.4.3: fixes, security hardening, gzip and caching; 0.4.4: key rotation, session revocation, typed arguments, Redis-shared limits, `check --production` |
|
|
498
509
|
| 0.3 | Hydration, live updates (SSE), multi-file apps, language server + VS Code extension, browser playground, faster rendering, screenshot/test MCP tools |
|
|
@@ -177,6 +177,21 @@ websites in the user's browser.
|
|
|
177
177
|
| T | An assistant's "read-only" SQL changing data | One statement, write keywords refused (even in a CTE), a read-only transaction that is rolled back; secrets redacted | `test_dx_v5.py::test_mcp_data_tools` |
|
|
178
178
|
| T | Malformed tool arguments reaching app code | Arguments are checked against each tool's schema before it runs | `test_mcp_v6.py::test_arguments_are_checked_before_the_tool_runs` |
|
|
179
179
|
|
|
180
|
+
## 7d. The dev loop: sharing, AI help, open in editor
|
|
181
|
+
|
|
182
|
+
`pyweb dev` only. Its tools change files, open programs and show request data, so they are for the
|
|
183
|
+
person running it, on that machine: a request must come from a loopback address and name a loopback
|
|
184
|
+
`Host` (a tunnel's or the LAN's requests don't), and writes must be same-origin.
|
|
185
|
+
|
|
186
|
+
| | Threat | Mitigation | Proof |
|
|
187
|
+
|---|---|---|---|
|
|
188
|
+
| S | Someone who learns the `--share` address (or guesses the tunnel name) using the app | Every request through the tunnel needs a cookie (`HttpOnly`, `Secure`, `SameSite=Lax`) set by the printed link's random token; forged cookies are refused | `test_share.py::test_the_link_sets_a_cookie_and_nothing_else_gets_in`, `test_share.py::test_pyweb_dev_share_end_to_end` |
|
|
189
|
+
| E/I | A share-link guest (or someone on the LAN) using the developer's tools: the toolbar's SQL and requests, the agent endpoints, AI fixes, opening files, saving the theme | Guests get the app and hot reload only; every `/__pyweb/dev/` endpoint but change polling answers 403 to them, and their pages carry no toolbar or tool scripts | `test_share.py::test_guests_get_the_app_and_hot_reload_only`, `test_share.py::test_you_still_get_everything_and_the_lan_gets_hot_reload`, `test_share.py::test_a_compile_error_page_for_guests_has_no_tools` |
|
|
190
|
+
| T | A web page making "Fix with AI" or "Edit with AI" write to the app | Same-origin, loopback-only POSTs; the answer is compiled first, applied only on Apply, only to `.pyweb` files in the app, refused if the file changed since; the old version is kept for Undo | `test_assist.py::test_endpoints_refuse_other_sites_and_other_machines`, `test_assist.py::test_a_change_that_does_not_compile_is_refused`, `test_assist.py::test_apply_refuses_when_the_file_changed_since`, `test_assist.py::test_only_app_files_are_targets` |
|
|
191
|
+
| I | Credentials in the app's source sent to a model | Known key formats and random-looking secret values are replaced by placeholders before sending and put back in the answer | `test_assist.py::test_secrets_are_replaced_before_sending_and_put_back`, `test_assist.py::test_the_connected_assistant_answers_through_mcp_sampling` |
|
|
192
|
+
| E | Alt-click "open in editor" used to open arbitrary files or run commands | Only `.pyweb` files inside the app folder or the UI kit; the editor gets an argument list, never a shell; same-origin and loopback only | `test_devopen.py::test_only_app_and_kit_files_resolve`, `e2e/test_dev_inspect_browser.py::test_open_refuses_cross_site_and_outside_files` |
|
|
193
|
+
| I | Dev-only markers or scripts in production pages | `data-pw-src` markers come from dev compiles only; the dev scripts are added by the dev server only | `test_devopen.py::test_other_builds_have_no_marks`, `test_trusted_types.py::test_dev_scripts_never_ship_in_built_pages` |
|
|
194
|
+
|
|
180
195
|
## 8. The release
|
|
181
196
|
|
|
182
197
|
| | Threat | Mitigation | Proof |
|
|
@@ -43,6 +43,10 @@ Around that core, PyWeb has what a product needs, in the same file:
|
|
|
43
43
|
([Installable apps](31-pwa-push.md), [Desktop apps](32-desktop.md))
|
|
44
44
|
- **Webhooks and files**: signed webhooks in and out, and unused uploads
|
|
45
45
|
cleaned up. ([Webhooks & files](33-webhooks-files.md))
|
|
46
|
+
- **A dev loop that keeps up**: saves update the open page in place with
|
|
47
|
+
its state kept; Alt-click opens any element's source; Fix with AI and
|
|
48
|
+
Edit with AI; a time-travel timeline; `pyweb dev --share`.
|
|
49
|
+
([The dev loop](35-dev-loop.md))
|
|
46
50
|
- **Shipping**: `pyweb deploy` writes Docker, Compose, Kubernetes, Fly,
|
|
47
51
|
Render or Railway files; logs, metrics and traces come built in.
|
|
48
52
|
([Scaling & deploying](25-scaling.md))
|
|
@@ -20,9 +20,14 @@ pip install "pyweb-stack[all]" # optional: Postgres, MySQL, Redis, argon2, O
|
|
|
20
20
|
```bash
|
|
21
21
|
pyweb new hello
|
|
22
22
|
cd hello
|
|
23
|
-
pyweb dev app.pyweb # http://localhost:8000
|
|
23
|
+
pyweb dev app.pyweb # opens http://localhost:8000; saves update the page in place
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
+
(`pyweb new` with no name asks for one, a starter and colours.) Save a
|
|
27
|
+
change and the open page updates without losing its state; hold Alt and
|
|
28
|
+
click anything to open its line in your editor. [The dev loop](35-dev-loop.md)
|
|
29
|
+
has the rest: Fix with AI, time travel and sharing with `--share`.
|
|
30
|
+
|
|
26
31
|
`pyweb new` writes `app.pyweb`, a starter test (`test_app.py`) and
|
|
27
32
|
`AGENTS.md`/`CLAUDE.md` (instructions for AI coding agents). Add
|
|
28
33
|
`--template saas` for a small product with teams, accounts, a database,
|
|
@@ -88,6 +93,12 @@ pyweb serve dist # production server with /healthz
|
|
|
88
93
|
`dist/` contains your app source, static assets and a `Dockerfile`; see
|
|
89
94
|
[Deployment](12-deployment.md).
|
|
90
95
|
|
|
96
|
+
If something doesn't work and the error isn't clear, `pyweb doctor`
|
|
97
|
+
checks the project and your machine (Python, the app, optional packages,
|
|
98
|
+
the database and migrations, the port, your editor) and prints a fix for
|
|
99
|
+
each problem; `pyweb doctor --production` also checks the production
|
|
100
|
+
settings.
|
|
101
|
+
|
|
91
102
|
## Next
|
|
92
103
|
|
|
93
104
|
The [tutorial](03-tutorial.md) builds a notes app with a database,
|
|
@@ -101,6 +112,7 @@ ships it. Then, depending on what you're building:
|
|
|
101
112
|
- work that runs later or on a schedule: [Background jobs](24-jobs.md);
|
|
102
113
|
- teams that share data: [Teams & organizations](30-teams.md);
|
|
103
114
|
- components, a theme and animation: [UI kit & motion](34-ui-and-motion.md);
|
|
115
|
+
- everything `pyweb dev` does for you: [The dev loop](35-dev-loop.md);
|
|
104
116
|
- an app people install, or a desktop app: [Installable apps & push](31-pwa-push.md),
|
|
105
117
|
[Desktop apps](32-desktop.md);
|
|
106
118
|
- several pages with a shared header: [Layouts & navigation](19-layouts-navigation.md);
|
|
@@ -1,17 +1,30 @@
|
|
|
1
1
|
# Command line
|
|
2
2
|
|
|
3
3
|
```text
|
|
4
|
-
pyweb new NAME [--template T]
|
|
4
|
+
pyweb new [NAME] [--template T] [--theme PRESET]
|
|
5
|
+
create NAME/ with app.pyweb, test_app.py, AGENTS.md, CLAUDE.md, static/;
|
|
5
6
|
T = blank | counter (default) | todo | blog | saas | auth | chat | ai-chat | desktop
|
|
6
|
-
(apps with a database also get migrations/0001_initial.py and a README)
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
(apps with a database also get migrations/0001_initial.py and a README);
|
|
8
|
+
PRESET = indigo | zinc | slate | rose | ocean | violet | emerald | amber
|
|
9
|
+
(written into App(theme=...)); with no NAME, in a terminal, it asks
|
|
10
|
+
pyweb dev FILE [--port 8000] [--host 127.0.0.1] [--no-reload] [--no-open] [--share]
|
|
11
|
+
development server (see The dev loop): saves update the open page
|
|
12
|
+
in place, keeping page and component state (?fresh starts over);
|
|
13
|
+
Alt-click opens an element's line in your editor, Alt+Shift-click
|
|
14
|
+
changes it with AI, error pages have Fix with AI; the dev toolbar
|
|
15
|
+
(requests, SQL, jobs, emails, theme, motion, a time-travel timeline);
|
|
16
|
+
background jobs in the same process; opens the browser (not in CI,
|
|
17
|
+
over SSH or with --no-open); --host 0.0.0.0 prints the network URL
|
|
18
|
+
with a QR code; --share prints a temporary public link; writes
|
|
11
19
|
.pyweb/dev.json so `pyweb mcp` can see its errors and logs
|
|
12
20
|
pyweb check FILE [--production] [--strict]
|
|
13
21
|
compile, security and accessibility checks; --production also checks
|
|
14
22
|
the environment; --strict fails on warnings too
|
|
23
|
+
pyweb doctor [FILE] [--production] [--json] [--port 8000]
|
|
24
|
+
is the project ready? Python, the app compiles, optional packages,
|
|
25
|
+
database and migrations, Redis, secrets in the source, upgrade
|
|
26
|
+
changes, a stale dev server link, tests, the port, the editor; a fix
|
|
27
|
+
for each problem (exit 1 on any failure; --json for CI)
|
|
15
28
|
pyweb upgrade [FILE] [--fix] what to change for this PyWeb version (file and line); --fix applies
|
|
16
29
|
the safe rewrites
|
|
17
30
|
pyweb inspect FILE [--security] where every name runs and why; RPC table; findings
|
|
@@ -66,13 +79,39 @@ pyweb dts FILE.d.ts Python dataclasses from TypeScript declarat
|
|
|
66
79
|
pyweb mcp MCP server over stdio for AI assistants (see AI assistants & MCP)
|
|
67
80
|
pyweb mcp --http [--port 8765] [--token T] the same over Streamable HTTP (127.0.0.1 only without a token)
|
|
68
81
|
pyweb lsp language server over stdio for editors (see below)
|
|
69
|
-
pyweb test [PATH] run pytest
|
|
82
|
+
pyweb test [PATH] run pytest on PATH (a test file, a folder or app.pyweb's folder;
|
|
83
|
+
default: the current folder, where new apps keep test_app.py)
|
|
70
84
|
pyweb fmt [PATH] / pyweb lint [PATH] run ruff format / ruff check (if installed)
|
|
71
85
|
pyweb --version
|
|
72
86
|
```
|
|
73
87
|
|
|
74
88
|
`python -m pyweb.cli ...` is equivalent to `pyweb ...`.
|
|
75
89
|
|
|
90
|
+
## Error messages
|
|
91
|
+
|
|
92
|
+
A compile error names the file and line, shows the line with a caret under
|
|
93
|
+
the problem, suggests the name you probably meant, and links the docs page
|
|
94
|
+
that explains it:
|
|
95
|
+
|
|
96
|
+
```text
|
|
97
|
+
error: app.pyweb:17: <Greeting> has no prop 'nme'; did you mean 'name'?
|
|
98
|
+
|
|
99
|
+
16 | <h1>{count}</h1>
|
|
100
|
+
> 17 | <Greeting nme="x" />
|
|
101
|
+
| ^
|
|
102
|
+
18 | </main>
|
|
103
|
+
|
|
104
|
+
hint: Use one of the component's parameter names as the attribute.
|
|
105
|
+
docs: https://maanavkrishna.github.io/PyWeb/language.html
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
The first line keeps the `file:line: message` shape, so editors and CI
|
|
109
|
+
logs can jump to it. `pyweb check` also warns about kit props and motion
|
|
110
|
+
values that won't work (`<Button variant="outlin">`). The `pyweb dev`
|
|
111
|
+
overlay shows the same, and when page code raises, its error page starts
|
|
112
|
+
with the frames in your own files and their source lines, before the full
|
|
113
|
+
traceback.
|
|
114
|
+
|
|
76
115
|
## Exit codes
|
|
77
116
|
|
|
78
117
|
`check` and `build` exit `1` on compile or security errors and `2` on
|
|
@@ -11,8 +11,9 @@ can decide up front whether they matter for your app.
|
|
|
11
11
|
- **npm packages must ship ES modules.** CommonJS-only packages and
|
|
12
12
|
packages built on Node.js modules can't run in the browser; see
|
|
13
13
|
[npm packages](18-npm-packages.md).
|
|
14
|
-
- **
|
|
15
|
-
|
|
14
|
+
- **Time travel moves the page's state only.** The dev timeline puts the
|
|
15
|
+
page's and components' variables back; data on the server isn't
|
|
16
|
+
rolled back.
|
|
16
17
|
- **SQLite is for one machine.** Several processes on one host share it
|
|
17
18
|
fine, but more than one server needs Postgres or MySQL;
|
|
18
19
|
`pyweb check --production` and `pyweb deploy` say so.
|
|
@@ -33,7 +34,13 @@ can decide up front whether they matter for your app.
|
|
|
33
34
|
with Web Push, desktop windows and installers, a UI kit with themes and
|
|
34
35
|
motion, Trusted Types, encrypted fields and a threat model, about 2.5×
|
|
35
36
|
faster serving, Python 3.15 and free-threaded builds, and a much richer
|
|
36
|
-
MCP server.
|
|
37
|
+
MCP server. 0.6.1 added error messages with code frames and
|
|
38
|
+
suggestions, `pyweb doctor`, dev reloads that keep page state, and 4×
|
|
39
|
+
faster reloads and tests. 0.6.2 made the [dev loop](35-dev-loop.md):
|
|
40
|
+
saves update the page in place with component state kept, Alt-click
|
|
41
|
+
opens any element's source, Fix with AI and Edit with AI, a
|
|
42
|
+
time-travel timeline, `pyweb dev --share`, a faster first start and a
|
|
43
|
+
guided `pyweb new`.
|
|
37
44
|
- **0.5**: production apps. Models with relations and migrations, forms
|
|
38
45
|
checked in the browser and on the server, an auth kit (passwords,
|
|
39
46
|
passkeys, emailed links, OAuth, two-step sign-in, an admin), row-level
|
|
@@ -64,7 +71,8 @@ Planned, roughly in order. Nothing here is promised for a date.
|
|
|
64
71
|
1. **1.0**: the API, RPC protocol and CLI frozen under semantic versioning,
|
|
65
72
|
after 0.6 has been used in production for a while.
|
|
66
73
|
2. **File uploads from the playground and the admin.**
|
|
67
|
-
3. **
|
|
74
|
+
3. **Fix with AI in the editor**, from the same proposals the dev page
|
|
75
|
+
shows (diff, apply, undo), through the VS Code extension.
|
|
68
76
|
|
|
69
77
|
Ideas, bug reports and pull requests are welcome; see
|
|
70
78
|
[CONTRIBUTING.md](https://github.com/MaanavKrishna/PyWeb/blob/main/CONTRIBUTING.md).
|
|
@@ -70,7 +70,7 @@ tool runs. Slow tools (tests, screenshots, profiling) report progress.
|
|
|
70
70
|
| `pyweb_guide` | The rules for writing `.pyweb` apps (or one section): what runs where, state, markup, components, server functions, the browser Python subset, and every common error with its fix. |
|
|
71
71
|
| `pyweb_docs` | Searches the documentation (every page, the guide and the threat model) and returns the matching sections, or one whole page. For any "how do I..." question. |
|
|
72
72
|
| `pyweb_new_app` | Creates an app from a template (`blank`, `counter`, `todo`, `blog`, `saas`, `auth`, `chat`, `ai-chat`, `desktop`) with `AGENTS.md`, `CLAUDE.md`, tests and a stylesheet; apps with a database also get their first migration. `saas` (teams, accounts, tenant Models, forms, live pages, jobs, webhooks, admin) is the best start for a product; `desktop` is a notes app for `pyweb desktop`. |
|
|
73
|
-
| `pyweb_check` | Compiles the app and runs the security and accessibility checks. Returns `ok`, errors with `line`, `message
|
|
73
|
+
| `pyweb_check` | Compiles the app and runs the security and accessibility checks. Returns `ok`, errors with `line`, `message`, a fix `hint`, a code `frame` and a `docs` link, plus pages (with their layouts, live-data variables and npm packages), signals, what's sent to the browser, JS size and the server functions. |
|
|
74
74
|
| `pyweb_explain` | What your editor shows for a line: for each name, where it runs and why (or its signature or npm type), the problems on that line and, with `complete`, the completions at a column. |
|
|
75
75
|
| `pyweb_inspect` | For every name: does it run in the browser or on the server, and why. |
|
|
76
76
|
| `pyweb_compiled` | The JavaScript generated for a page, and its server-rendered HTML. |
|
|
@@ -106,7 +106,9 @@ tool runs. Slow tools (tests, screenshots, profiling) report progress.
|
|
|
106
106
|
| Tool | What it does |
|
|
107
107
|
|---|---|
|
|
108
108
|
| `pyweb_dev` | Whether `pyweb dev` is running for this app: its URL, whether the app compiles right now (with the error and traceback), its pages and recent 500 errors. |
|
|
109
|
+
| `pyweb_doctor` | Project health, as `pyweb doctor`: each check with `status` (ok, warn, fail), `detail` and a `fix`; `production=true` adds the production settings. |
|
|
109
110
|
| `pyweb_logs` | The dev server's log lines (warnings, errors with tracebacks, slow queries, job failures); `since` returns only newer ones. |
|
|
111
|
+
| `pyweb_assist_requests` | What the developer asked for from the page (Fix with AI on an error page, Alt+Shift-click → Edit with AI) while no AI was set up to answer: the file, the error or the element's line, and the instruction. |
|
|
110
112
|
|
|
111
113
|
When `pyweb dev` starts, it writes `.pyweb/dev.json` next to the app: its
|
|
112
114
|
address and a random token, readable only by you (the folder has its own
|
|
@@ -148,6 +150,7 @@ Prompts are step-by-step workflows that name the tools to use:
|
|
|
148
150
|
| `design_pass` | Kit components, a theme and motion, reviewed in light, dark and on a phone. |
|
|
149
151
|
| `fix_failing_test` | Reproduce, find the cause in the app, fix, re-run. |
|
|
150
152
|
| `debug_page` | Errors, logs, requests and a profile for one page. |
|
|
153
|
+
| `fix_errors` | Check, fix and test in a loop until the app compiles cleanly and the tests pass; first does what was asked from the page. |
|
|
151
154
|
|
|
152
155
|
### What a session looks like
|
|
153
156
|
|
|
@@ -171,6 +174,24 @@ Prompts are step-by-step workflows that name the tools to use:
|
|
|
171
174
|
click around, the assistant reads the error with `pyweb_dev` and
|
|
172
175
|
`pyweb_logs` and fixes it.
|
|
173
176
|
|
|
177
|
+
### Fix with AI from the page (sampling)
|
|
178
|
+
|
|
179
|
+
`pyweb dev` puts a **Fix with AI** button on error pages, and
|
|
180
|
+
Alt+Shift-click asks for a change to any element (see
|
|
181
|
+
[The dev loop](35-dev-loop.md#fix-with-ai-and-edit-with-ai)). When your
|
|
182
|
+
assistant's app supports MCP **sampling** (the client lets a server ask
|
|
183
|
+
its model a question, after you approve), `pyweb mcp` answers those
|
|
184
|
+
requests with your assistant's own model: it notices the client offers
|
|
185
|
+
sampling when it connects, finds the running `pyweb dev` through
|
|
186
|
+
`.pyweb/dev.json`, and hands each request over. The page shows the
|
|
187
|
+
answer as a diff to apply or discard. This works over stdio (`pyweb
|
|
188
|
+
mcp`); set `PYWEB_APP` when the app file isn't `app.pyweb` in the folder
|
|
189
|
+
the assistant starts in.
|
|
190
|
+
|
|
191
|
+
Assistants without sampling see the same requests with
|
|
192
|
+
`pyweb_assist_requests` and can do them with their own file tools; the
|
|
193
|
+
`fix_errors` prompt starts there.
|
|
194
|
+
|
|
174
195
|
`pyweb_render`, `pyweb_call`, `pyweb_screenshot`, `pyweb_review`,
|
|
175
196
|
`pyweb_profile`, `pyweb_webhook_send`, `pyweb_jobs` and `pyweb_test` run
|
|
176
197
|
your app's code, as `pyweb dev` or `pytest` would; `pyweb_packages`
|
|
@@ -107,12 +107,22 @@ you use it in a browser.
|
|
|
107
107
|
Profile against a copy of your real data. A page that's fast with ten
|
|
108
108
|
rows can be slow with ten thousand.
|
|
109
109
|
|
|
110
|
+
## Fast reloads and tests
|
|
111
|
+
|
|
112
|
+
The UI kit is compiled once per process, and each `.pyweb` file's Python
|
|
113
|
+
code is reused until the file changes. On the saas example that took a
|
|
114
|
+
reload in `pyweb dev` from about 255 to 60 ms and creating a
|
|
115
|
+
`TestClient` from about 255 to 55 ms; the dev server also notices a save
|
|
116
|
+
within a tenth of a second. Compiled output is byte-for-byte what a fresh
|
|
117
|
+
compile gives, and a test checks that.
|
|
118
|
+
|
|
110
119
|
## Benchmarks in CI
|
|
111
120
|
|
|
112
121
|
`python -m pyweb.bench` reports compile time, shipped JavaScript and
|
|
113
122
|
render time per page. `--system` measures the whole stack: requests per
|
|
114
123
|
second over real sockets, a signed-in page with a database, start-up
|
|
115
|
-
time,
|
|
124
|
+
time, live query hashing, and how long loading an app again takes (what
|
|
125
|
+
`pyweb dev` does after a save, and what each `TestClient` does).
|
|
116
126
|
|
|
117
127
|
PyWeb's CI runs `--compare` on every push and pull request. It checks out
|
|
118
128
|
the commit before the change next to the new one and runs both five
|