Repository navigation
feat(infra): demo.pywire.dev/realtime Worker and routes - #20
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NUEPGc2SgMUHxx4Z28HS8v
Terraform plan — 📝 changescloudflare_dns_record.vscode_verification: Refreshing state... [id=8ac56f7d47b8d2401df848706ad88cdd]
cloudflare_dns_record.docs_cname: Refreshing state... [id=e562a5382eacb08985eaba0d4907fb2c]
cloudflare_email_routing_address.destinations["[email]"]: Refreshing state... [id=ba2224a5004345f19ad66c5a71343976]
cloudflare_workers_script.demo["form-builder"]: Refreshing state... [id=pywire-demo-form-builder]
cloudflare_workers_script.demo["site"]: Refreshing state... [id=pywire-demo]
cloudflare_email_routing_address.destinations["[email]"]: Refreshing state... [id=b465118aef02490e9f584146ce54f65b]
cloudflare_ruleset.allow_llm_crawlers: Refreshing state... [id=375241922de4405a8b77b812e6e25730]
cloudflare_pages_project.landing: Refreshing state... [id=pywire-landing]
cloudflare_pages_project.docs: Refreshing state... [id=pywire-docs]
cloudflare_email_routing_settings.main: Refreshing state... [id=9f1c5e8c997d29163e81a24f7b26dc35]
cloudflare_workers_script.demo["edge-stateless"]: Refreshing state... [id=pywire-demo-edge-stateless]
cloudflare_r2_bucket.cdn: Refreshing state... [id=pywire-cdn]
cloudflare_dns_record.demo: Refreshing state... [id=b0bddc628bb491021da19902143848d8]
cloudflare_email_routing_rule.individual_aliases["hello"]: Refreshing state... [id=1ff2a9d2add740089d4c7952455e4b56]
cloudflare_email_routing_rule.individual_aliases["reece"]: Refreshing state... [id=d14078e65aea4106adf662dc46d54710]
cloudflare_email_routing_rule.maintainers_group: Refreshing state... [id=2f20558a55f04e10959ead934f397730]
cloudflare_pages_domain.docs: Refreshing state... [id=docs.pywire.dev]
cloudflare_pages_domain.landing: Refreshing state... [id=pywire.dev]
cloudflare_dns_record.nightly: Refreshing state... [id=6a2d6b6878cc8452e1e29dd1f30c6dd1]
cloudflare_workers_script.router: Refreshing state... [id=pywire-router]
cloudflare_workers_route.demo["edge-stateless/*"]: Refreshing state... [id=939cf05574124030b942e2d20552c9d6]
cloudflare_workers_route.demo["edge-stateless"]: Refreshing state... [id=d2289e6c48be4e6aa371334d032b3785]
cloudflare_workers_route.demo["form-builder/*"]: Refreshing state... [id=06e617e3d0d74001a39f898c01f399a5]
cloudflare_workers_route.demo["form-builder"]: Refreshing state... [id=a02f4f0d3af44aeabb62cffdd9662efe]
cloudflare_workers_route.demo["site"]: Refreshing state... [id=8ce59be56755407a9a9d269861fd2b53]
cloudflare_workers_route.nightly: Refreshing state... [id=874d0be239a04de79226d64cd941e9bf]
cloudflare_workers_route.catch_all: Refreshing state... [id=a70946d772474786ada02b87b9fd05cf]
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# cloudflare_workers_route.demo["realtime"] will be created
+ resource "cloudflare_workers_route" "demo" {
+ id = (known after apply)
+ pattern = "demo.pywire.dev/realtime"
+ script = "pywire-demo-realtime"
+ zone_id = "9f1c5e8c997d29163e81a24f7b26dc35"
}
# cloudflare_workers_route.demo["realtime/*"] will be created
+ resource "cloudflare_workers_route" "demo" {
+ id = (known after apply)
+ pattern = "demo.pywire.dev/realtime/*"
+ script = "pywire-demo-realtime"
+ zone_id = "9f1c5e8c997d29163e81a24f7b26dc35"
}
# cloudflare_workers_script.demo["realtime"] will be created
+ resource "cloudflare_workers_script" "demo" {
+ account_id = "abd8226d8d910afcfa1d370097e6336a"
+ bindings = (known after apply)
+ compatibility_date = "2026-09-01"
+ compatibility_flags = (known after apply)
+ content = <<-EOT
export default {
fetch() {
return new Response("This demo hasn't been deployed yet.", { status: 503 });
},
};
EOT
+ created_on = (known after apply)
+ etag = (known after apply)
+ handlers = (known after apply)
+ has_assets = (known after apply)
+ has_modules = (known after apply)
+ id = (known after apply)
+ last_deployed_from = (known after apply)
+ logpush = false
+ main_module = "placeholder.js"
+ migration_tag = (known after apply)
+ modified_on = (known after apply)
+ named_handlers = (known after apply)
+ placement = (known after apply)
+ script_name = "pywire-demo-realtime"
+ startup_time_ms = (known after apply)
+ tail_consumers = (known after apply)
+ usage_model = "standard"
}
Plan: 3 to add, 0 to change, 0 to destroy.
Releasing state lock. This may take a few moments... |
reecelikesramen
added a commit
to pywire/pywire
that referenced
this pull request
Sep 30, 2026
…n a src/ Worker (#405) Before: `pywire build --platform cloudflare` wrote the Worker's modules to the project root. Wrangler uploads every `.py` under `main`'s folder, so that included tests and pywrangler's `.venv-workers`. The build also left `entry.py` to `pywire deploy`. The realtime example wasn't on demo.pywire.dev. After: the Durable Object target uses the same layout as the edge target (#400). For a `src.main:app` app, `entry.py`, `pywire_do.py`, `_routes.py` and `_pywire_build/` all go in `src/`, and `wrangler.toml` gets `main = "src/entry.py"`. An existing `wrangler.toml` is kept. If it lacks `main`, the `PYWIRE_APP` binding, or the `PyWireAppDO` migration, the build warns and names the missing piece, as the shared-DO thread asked. demo.pywire.dev/realtime runs the realtime example on one global app object (`PYWIRE_PLACEMENT = "global"`), so every visitor shares the poll, presence and chat. How: - `deploy.edge_worker_layout` is now `worker_layout`, used by both targets in `build` and `deploy`. `wrangler.toml.j2` takes `main`. - `examples/realtime` gets a committed `wrangler.toml` (DO binding, one `v2` migration, base path `/realtime`), and `pywire[cli]` moves to its dev group. - The Deploy Examples matrix now carries a platform, with realtime on `cloudflare`. The landing page gets a Realtime card, and the README gets its secret command. Order: 1. Merge pywire/pywire.dev#20 and run Infra apply. That creates the placeholder Worker and routes. 2. `npx wrangler secret put PYWIRE_SECRET_KEY --name pywire-demo-realtime`. 3. Merge this. Tests: two new CLI tests (the DO target's src/ layout, and the warning for an old `wrangler.toml`), 104 CLI tests passing, ruff and ty clean, and `examples/scripts/check` green. I also built realtime with this CLI and ran it in local workerd (`pywrangler dev`). In Chromium, a vote in one tab showed up in the other, presence showed both tabs, and the clock ticked. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- _Generated by [Claude Code](https://claude.ai/code/session_01NUEPGc2SgMUHxx4Z28HS8v)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Before: demo.pywire.dev has Workers and routes for the landing page, edge-stateless and form-builder.
After: it also has
pywire-demo-realtime, as a 503 placeholder until pywire/pywire's Deploy Examples workflow uploads the code, plus routes fordemo.pywire.dev/realtimeand/realtime/*.How: adds
realtimetolocal.demo_examples. The Worker's Durable Object binding and migration come fromexamples/realtime/wrangler.tomlon its first deploy. Apply this before merging the pywire/pywire PR that adds the realtime deploy.🤖 Generated with Claude Code
Generated by Claude Code