Python-first application framework over SPECTER and RAGOT
Project description
SPRAG
One Python language, two runtimes.
Write your entire web app in Python — server logic, UI components, browser behavior, state, realtime — and SPRAG compiles, ships, and runs it as a single coherent application. No JavaScript to write. No frontend build chain to maintain. No "API layer" between your server and your UI.
pip install spragkit
sprag new myapp && cd myapp && sprag dev
Status: pre-alpha. The framework is real and working. The API surface is not pinned yet.
Documentation
→ bleedingxiko.github.io/SPRAG
The docs site is a SPRAG app built with the docs template — dogfooding the framework. Start with Installation, then First App.
60-Second Example
A hybrid route: server-rendered HTML, browser hydration, typed action.
# app/routes/counter/server.py
from sprag import Controller, Field, Schema, action
class CounterController(Controller):
route = "/counter"
def load(self):
return {"count": 0}
@action(schema=Schema("increment", {"count": Field(int, required=True)}))
def increment(self, count):
return {"count": count + 1}
# app/routes/counter/components.py
from sprag import Component, ui
class CounterCard(Component):
def render(self, props=None):
return ui.div(
ui.div(str(self.state["count"]), class_="counter-display"),
ui.button("Increment", type="button", data_role="increment"),
class_="counter-card",
)
# app/routes/counter/modules.py
from sprag import Module
class CounterModule(Module):
def __init__(self, screen=None, state=None):
super().__init__(screen=screen, state=state or {"count": 0})
def on_start(self):
self.delegate(self.element, "click", "[data-role='increment']", self.on_click)
def on_click(self, event):
event.prevent_default()
self.call_action("increment", {"count": self.state["count"]}).then(self.on_result)
def on_result(self, result):
self.set_state(result.value)
The Module is Python. SPRAG compiles it to JavaScript at build time, ships it with the route, wires the action bridge, and hydrates the component in place. No handoff. No separate frontend.
What It Is
- File-discovered routes under
app/routes/, withdocument(pure SSR) andhybrid(SSR + hydration) modes plus standalonemount(...)SPAs - Browser code is compiled Python —
ComponentandModuleclasses are real Python that SPRAG compiles to Ragot ESM JavaScript at build time - Cross-runtime state —
store(...)works identically on server and browser - Typed actions — server mutations go through schema-validated dispatch
- Realtime built in — SSE, websockets, queues, watchers as framework primitives
sprag buildproduces a deployable artifact;sprag build staticproduces a pre-rendered static site;sprag packoptimizes for production
CLI
sprag new myapp [--template default|bare|docs|labs]
sprag dev [--port 8000]
sprag build # full app (server + client)
sprag build static # pre-rendered static site
sprag pack # minify, bytecode-compile, optimize images
sprag types # generate .sprag/types.pyi from the build manifest
sprag add route|mount|content <name>
sprag routes # list all surfaces
sprag inspect /path # show compiled output for a route
sprag doctor # structural health check
See the CLI reference for the full surface.
Templates
| Template | What you get |
|---|---|
default |
Counter demo + about page — minimal hybrid app |
bare |
Skeleton with one route, no demos |
docs |
Markdown-backed docs/blog site (the docs site itself) |
labs |
Every framework primitive exercised in a real app — counter, virtual scroll, queues, watchers, sockets, uploads, auth, forms, animation, mounts |
Under the Hood
SPRAG sits on two runtimes:
- Specter on the server — controllers, services, queues, watchers, operations, lifecycle
- Ragot in the browser — components, modules, DOM ownership, stores, hydration
SPRAG makes them feel like one framework: set_state, subscribe, timeout, adopt follow the same model on both sides.
License
Apache-2.0. See LICENSE and CONTRIBUTING.md.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file spragkit-0.1.16.tar.gz.
File metadata
- Download URL: spragkit-0.1.16.tar.gz
- Upload date:
- Size: 297.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b3270c891dc5628e87ab9fca84110bd9544636b29547876e22519cbb1add21f8
|
|
| MD5 |
a15d220a692209d1a4d1f9645104f088
|
|
| BLAKE2b-256 |
9be9b2077ee2d98284de29481599df4658ada550504b074cc5bdda2821cd40a9
|
File details
Details for the file spragkit-0.1.16-py3-none-any.whl.
File metadata
- Download URL: spragkit-0.1.16-py3-none-any.whl
- Upload date:
- Size: 383.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cd2e7958a5d48a055bbdbadf3f1a1ee4a70244c47fc1580b59616e8e95a8925d
|
|
| MD5 |
c5a0889057381dc7e56448d5c12b653c
|
|
| BLAKE2b-256 |
0d17766f7133f6e755f1d604d7fd00b432b94fd339549f6a31b93e1b9b619a4f
|