Skip to main content

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/, with document (pure SSR) and hybrid (SSR + hydration) modes plus standalone mount(...) SPAs
  • Browser code is compiled PythonComponent and Module classes are real Python that SPRAG compiles to Ragot ESM JavaScript at build time
  • Cross-runtime statestore(...) 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 build produces a deployable artifact; sprag build static produces a pre-rendered static site; sprag pack optimizes 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/sprag_project_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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

spragkit-0.1.24.tar.gz (309.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

spragkit-0.1.24-py3-none-any.whl (397.1 kB view details)

Uploaded Python 3

File details

Details for the file spragkit-0.1.24.tar.gz.

File metadata

  • Download URL: spragkit-0.1.24.tar.gz
  • Upload date:
  • Size: 309.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for spragkit-0.1.24.tar.gz
Algorithm Hash digest
SHA256 65dcaced43f554ce278aae40fd8ed522eedd807419fb59f836bfa0b2b2ddda1d
MD5 2d828a033deb76a558d41b6c217876c8
BLAKE2b-256 b5ac1d7de4990323f169e1b0e198dd53e3b086b1d3d0e085ff60cccbccef0eb3

See more details on using hashes here.

File details

Details for the file spragkit-0.1.24-py3-none-any.whl.

File metadata

  • Download URL: spragkit-0.1.24-py3-none-any.whl
  • Upload date:
  • Size: 397.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for spragkit-0.1.24-py3-none-any.whl
Algorithm Hash digest
SHA256 184cd56ea814db86bd9450a9bdbcf764b72c686e3d88a553e0d60966c1a2f4e2
MD5 44d1d2f39daa6ec0dfd6c5f49ffce5e0
BLAKE2b-256 d259ff6b64339bd88def89bc90a12e2d1356048a92f715410c3e559e59dcfaf6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page