Overview of #535: PyView: Real-time Python Web Apps
Michael Kennedy interviews Larry Ogrenek about PyView — a Python implementation inspired by Phoenix LiveView that brings server-driven, real-time web UI to Python developers. The episode explains PyView’s mental model (server-side state + HTML rendering + WebSocket diffs), how it reuses the Phoenix LiveView front-end client, example apps and integrations, architecture/deployment considerations, and the short-term roadmap and contribution needs.
Key takeaways
- PyView lets you write application logic in Python, render ordinary HTML templates, and get SPA-level interactivity by sending minimal diffs over WebSockets.
- The project uses the Phoenix LiveView front-end client JS and implements the backend in Python (inspired by LiveView, not a direct port).
- It favors keeping web primitives (HTML/CSS) visible, enabling simpler debugging and direct control over the browser DOM.
- PyView runs as an ASGI app (Starlette) so it deploys where typical Python ASGI apps run (uvicorn + Docker, etc.), but multi-node presence/pubsub requires extra work (Redis or similar).
- The project is early (0.x), typed, open to contributions, and has a cookiecutter starter that uses Poetry and just for developer ergonomics.
What PyView is and how it works
- Mental model: server holds the authoritative state; user interactions (clicks, keys, forms) are sent as events to the server; server updates state, re-renders the view, diffs old vs. new render tree, and sends minimal patches to the client via WebSocket.
- Front-end: uses Phoenix LiveView client JS (so many phx-* attributes and hooks directly apply).
- Templating: PyView needs a template → render-tree representation (statics + dynamics). Early versions used a simple IBIS-like templating engine; PyView aims to adopt Python 3.14 T-strings / tdom for cleaner templating and component patterns.
- API surface:
- LiveView classes with mount, handle_params, render, and event handlers.
- Context/state commonly typed using dataclasses or pydantic models.
- Event handling can be centralized (handle_event) or per-event using an @event decorator.
- Hooks expose JS integration points for bidirectional custom JS (maps, editors, drag/drop).
- Diffing: server always re-renders but sends only the diff; client applies patches to DOM. Templates are instrumented with identifiers to support fine-grained diffs.
Comparison: Phoenix LiveView, HTMX, and PyView
- Phoenix LiveView: PyView is inspired by it and reuses its client JS. LiveView’s Elixir server is the original, battle-tested implementation; PyView brings that paradigm to Python.
- HTMX: Similar idea (server-driven HTML fragments), but HTMX is more fragment-based and request/response oriented. PyView provides a more structured, stateful model with WebSockets and automatic diffs (less manual wiring than HTMX).
- Trade-offs:
- PyView gives more integration/convenience (less glue code, automatic diffing, presence, server push).
- HTMX offers more explicit control over which fragments are replaced (simpler model, sometimes more flexible).
- PyView adds opinionated lifecycle (mount, render, handle_event) and aims for easier multi-user real-time features.
Developer experience & notable examples
- Starter: cookiecutter project (Poetry + just). Run poetry install, then just to start; examples at pyview.rocks show live interactions and WebSocket messages.
- Examples highlighted:
- Volume control (keyboard bindings, transitions) — demonstrates event mapping (phx-click, phx-key) and accessibility-friendly behavior.
- Counter examples (old-style handler vs. @event-decorator approach, and T-strings usage).
- Maps (Leaflet integration) — shows JS hooks and bi-directional events (select item in map ↔ list highlight).
- Drag & drop / collaborative examples, CodeMirror editor integration, graphs via JS charting libs (Altair backend + JS front-end).
- Styling: many examples use Tailwind for polished visuals.
- File uploads: PyView supports file uploads (including multipart S3 upload variants), building on concepts pioneered in LiveView.
Architecture & deployment considerations
- Runtime: PyView is an ASGI app built on Starlette — deploy like any ASGI app (uvicorn, Docker, k8s, etc.).
- State & sessions:
- Each LiveView instance maintains in-memory state for connected clients (so session affinity / sticky sessions are required for single-machine deployments).
- Multi-node scenarios need external PubSub/persistent routing (Redis, other brokers) — currently a work-in-progress; single-machine use-cases work well now.
- Scaling and multi-node features:
- Presence and PubSub are straightforward if you add Redis (or similar) for cross-process/pubsub coordination.
- Potential future options: specialized WebSocket brokers (API Gateway), distributed storage of view state, or serverless models (experimental).
- Observability: examples show live WebSocket messages in browser devtools — useful for debugging.
LLMs and tooling
- LLMs can assist writing PyView code; prompts like “PyView is Phoenix LiveView but in Python” work well to orient models.
- Practical tips:
- Provide the cookiecutter / project structure + just/Poetry instructions to avoid environment confusion.
- LLMs sometimes confuse templating differences (Jinja filters vs whatever templating engine is used) and project commands (poetry vs python vs just).
- Building a Claude/ChatGPT skill or a short spec/llms.txt that explains PyView idioms would make LLM usage more reliable (recommended by Larry).
- Larry already uses LLMs for app code and finds simple, targeted prompts effective.
Roadmap, contributions & project status
- Current status: early-stage (0.x); being used in production for a few internal apps at Larry’s company but still evolving.
- Short-term priorities:
- Improve documentation (task-based docs and examples).
- Expand examples (larger demos like an audio player, AI chat, charts).
- Improve templating (T-strings integration, better CSS handling in T-strings).
- Better form support (validation, nested forms, PyDantic/pydantic integration).
- Multi-node pubsub & presence: planned; using Redis or similar is the likely approach for a robust production multi-instance setup.
- Contributions wanted:
- Try it, build apps, and give feedback (usability, rough edges).
- Examples and docs are particularly useful as contributions.
- Feature PRs welcome, but reporting real-world usage & issues is most valuable.
Actionable next steps / resources
- Try a live demo: visit pyview.rocks (live examples).
- Starter template: use the PyView cookiecutter (Poetry + just). Steps: clone cookiecutter, poetry install, just run (open localhost:8000).
- Inspect WebSockets: open browser devtools → Network → WebSocket to watch events/diffs.
- If you want to help:
- Open issues with reproducible examples and UX feedback.
- Contribute docs, examples, or small features (templating, form handling, JS hooks).
- Keywords to search/github: PyView, Phoenix LiveView, Starlette, ASGI, T-strings, pyview.rocks.
Notable quote
- Michael Kennedy: “Building on the web is like working with the perfect clay. It's malleable and can become almost anything.”
- Larry Ogrenek: “PyView is Phoenix LiveView, but in Python — reuse the good client side ideas, and make the backend Pythonic, typed, and easy to use.”
If you want a concise checklist to get started:
- Clone the cookiecutter example → poetry install → just start.
- Open pyview.rocks to see how client events ↔ server updates work in real time.
- Try a simple app (counter → volume → map) and experiment with a JS hook (Leaflet or CodeMirror).
- Report feedback or submit examples to the project repo/discussions.
