Workpeg function runtime and SDK
Project description
Workpeg SDK
Python SDK and CLI for building, packaging, publishing, and distributing Workpeg Pegs.
Workpeg is a platform for developing portable applications called Pegs. Pegs can be built, packaged, distributed through the PegStore, and integrated into the broader Workpeg ecosystem.
The SDK covers:
- Functions — serverless backend logic, Docker packaging, registry publishing
- CDN — static asset uploads for Peg branding and distribution
- UI Compiler — compile Python UI apps directly to browser JavaScript
Installation
pip install workpeg
Install locally from source:
pip install -e .
Verify:
workpeg --version
CLI
Workpeg uses a namespace-oriented CLI.
workpeg function ...
workpeg cdn ...
workpeg ui ...
| Namespace | Purpose |
|---|---|
function |
Create, build, run, and publish Workpeg Functions |
cdn |
Upload public Peg assets to the CDN |
ui |
Scaffold, compile, and serve Python Peg UI apps |
workpeg --help
workpeg function --help
workpeg cdn --help
workpeg ui --help
Functions
Functions are the backend logic of a Peg. They are packaged as Docker images and published to the Workpeg Registry.
Create a project:
workpeg function new hello
hello/
├── app/
│ ├── __init__.py
│ └── main.py
├── Dockerfile
├── requirements.txt
└── README.md
Write a function:
def main(context, payload):
return {
"message": "Hello from Workpeg",
"payload": payload,
}
Run locally (no Docker):
echo '{"context": {}, "payload": {"name": "world"}}' \
| workpeg function runtime
Run with Docker:
workpeg function build
workpeg function run --with docker
Publish:
export WORKPEG_PK=<your-token>
workpeg function submit hello:1.0.0
Full reference: docs/functions.md
CDN
Upload static assets — logos, screenshots, banners — to the Peg CDN.
export WORKPEG_PK=<your-token>
# Single file
workpeg cdn submit logo.svg
# Directory
workpeg cdn submit ./assets
# With explicit CDN path
workpeg cdn submit ./assets --path brand
# Replace existing
workpeg cdn submit ./assets --overwrite
Full reference: docs/cdn.md
UI Compiler
Write Peg UI apps in Python. The SDK compiles them to vanilla JavaScript — no React, no Vue, no Python in the browser.
Python App (single-page or multi-route Router)
↓ AST Parser
Workpeg IR (AppIR | RouterIR)
↓ JS Generator
app.js + workpeg-runtime.js + index.html
Scaffold, compile, and run in one command:
workpeg ui new counter
Creating counter...
counter/main.py
counter/dist/
Serving → http://localhost:8080
Watching → main.py
Stop → Ctrl+C
This creates a ready-to-run Counter app, compiles the Python to JavaScript, and opens a local dev server with live reload. Open http://localhost:8080 in any browser. Edit counter/main.py and save — the browser reloads automatically.
Project structure:
counter/
├── main.py ← Router entry point
├── pages/
│ ├── __init__.py
│ ├── home.py ← HomePage
│ └── counter.py ← CounterPage
└── dist/
├── index.html
├── app.js
└── workpeg-runtime.js
main.py — Router with routes declared:
from workpeg.ui import Router, Route
from pages.home import HomePage
from pages.counter import CounterPage
class Counter(Router):
routes = [
Route("/", HomePage),
Route("/counter", CounterPage),
]
pages/counter.py — counter logic:
from workpeg.ui import App, State, Column, Text, Button, Link
class CounterPage(App):
count = State(0)
def increment(self):
self.count += 1
def build(self):
return Column(
Text(f"Count: {self.count}"),
Button("Increment", on_click=self.increment),
Link("← Home", href="/"),
)
Options for new:
# Custom port
workpeg ui new counter --port 3000
# Scaffold and compile only, no server
workpeg ui new counter --no-serve
# Overwrite an existing project
workpeg ui new counter --force
Multi-page apps with routing:
from workpeg.ui import App, Router, Route, Column, Text, Link
class Home(App):
def build(self):
return Column(Text("Home"), Link("About", href="/about"))
class About(App):
def build(self):
return Column(Text("About"), Link("Home", href="/"))
class MyApp(Router):
routes = [
Route("/", Home),
Route("/about", About),
]
The compiler generates a History-API-based SPA. Clicking Link widgets with internal href values updates the URL and swaps the view — no full-page reload. The back and forward buttons work correctly.
Lists work too. State fields can hold lists, and Python list operations compile to idiomatic JavaScript — literals, slicing, comprehensions, map/filter/reduce, sorted/len/in, mutation (append/pop/sort/…), and for loops. Mutating a state list re-renders automatically:
class Todos(App):
items = State(["Buy milk", "Walk dog"])
def add(self):
self.items.append(f"Task {len(self.items) + 1}") # → push, re-renders
def build(self):
return Column(
Text(f"{len(self.items)} tasks"),
Text(f"sorted: {sorted(self.items)}"),
Text(f"with a: {[t for t in self.items if 'a' in t]}"),
Button("Add", on_click=self.add),
)
See the full Python→JavaScript mapping in the Core concepts docs.
Serve an existing project (with live reload):
# Pass the project directory — main.py is found automatically
workpeg ui serve counter/
# Pin a port
workpeg ui serve counter/ --port 3000
# Explicit file form (same result)
workpeg ui serve counter/main.py
# Serve a pre-built dist directory directly (no recompile)
workpeg ui serve counter/dist/
Compile only, no server:
# Pass the project directory — output goes to counter/dist/ automatically
workpeg ui build counter/
# Custom output directory
workpeg ui build counter/ --out counter/build
# Explicit file form
workpeg ui build counter/main.py
Full reference: docs/getting-started.md and the rest of the Peg UI docs (Core concepts, Widgets, Routing, Data & realtime, Styling, Examples, Reference).
Schema-based UI
For cases where you want to define UI as a data structure (for use with the Workpeg platform renderer rather than the JS compiler), the SDK also ships a schema API:
from workpeg.ui import PegApp, Page, Column, Text, Button
from workpeg.ui import State, Binding, IncrementStateAction
state = State({"counter": 0})
app = PegApp(
title="My Peg",
state=state,
child=Page(
title="Dashboard",
child=Column(
children=[
Text(Binding("counter")),
Button("Increment", action=IncrementStateAction("counter")),
]
),
),
)
print(app.to_schema())
Full reference: docs/schema-ui.md
Documentation
| Document | Contents |
|---|---|
| docs/functions.md | Function contract, context, runtime, Docker, publishing |
| docs/cdn.md | CDN uploads, paths, authentication, asset structure |
| docs/getting-started.md | Peg UI: how it works, quick start, CLI, live reload |
| docs/core-concepts.md | App, State, build(), supported Python, lists, reactivity |
| docs/widgets.md | Widget gallery + full per-widget reference |
| docs/routing.md · data-realtime.md · state-components.md · styling.md | Routing, data/realtime, global state, theming |
| docs/reference.md · examples.md | Internals (IR, JS, runtime, errors) + complete examples |
| docs/schema-ui.md | Schema-based UI, PegApp, widgets, bindings, actions |
| docs/architecture.md | Platform overview, pipeline diagrams, design decisions |
Authentication
Both function submit and cdn submit require a Workpeg token:
export WORKPEG_PK=<your-token>
Optional API override:
export WORKPEG_API_BASE=https://repo.workpeg.com
Configuration
Optional workpeg.json in your project root:
{
"function": {
"entrypoint": "app.main:main"
},
"runtime": {
"default": "docker",
"docker": {
"port": 8000
}
},
"build": {
"image": "workpeg-fn-hello"
},
"cdn": {
"assets_path": "assets"
}
}
Roadmap
| Feature | Status |
|---|---|
| Function runtime (local) | Available |
| Function runtime (Docker) | Available |
| Function publish | Available |
| CDN asset uploads | Available |
| UI Compiler (Python → JS) | Available |
workpeg ui new (scaffold + serve + live reload) |
Available |
| Schema-based UI | Available |
| Firecracker runtime | Planned |
| Peg packaging workflows | Planned |
| PegStore publishing | Planned |
| Additional widgets | Planned |
| UI widget library | Planned |
| Multi-page routing (History API SPA) | Available |
Method expressions (arithmetic, comparisons, ternary, min/max/abs) |
Available |
Control flow — if / elif / else, for loops |
Available |
Conditional rendering in build() (if/else → different widget trees) |
Available |
Reusable Component classes — props, optional own State (independent per instance), per-instance handlers, callback props |
Available |
Layout widgets — Column/Row, Center/Align (single-child), GridView (multi-child), ListView; custom single-child component slots |
Available |
Async data loading — async/await, http.get/post/put/patch/delete, on_mount, try/except |
Available |
http.* blocked from Workpeg domains (compile + runtime); reach the platform via the namespaced workpeg.* client |
Available |
workpeg.get/post/put/patch/delete — Workpeg-domains-only client; resolves paths against apiBase |
Available |
workpeg.* sends a Namespace whoami header (explicit > serving host > baked peg-namespace meta) |
Available |
Method local variables (step = 5; self.count += step) |
Available |
Console logging (print() → console.log()) |
Available |
| Dev error overlay (compile + runtime errors in the browser) | Available |
Fake cloud (--fake-cloud: local https://dev.<app>.workpeg.com, macOS/Linux/Windows) |
Available |
| Widget categories — layout / display / interactive (Flutter-style) | Available |
ListView with lazy, virtualized ListView.builder |
Available |
Center layout widget |
Available |
Image widget (object-fit, rounding, lazy loading, reactive src) |
Available |
TextInput widget (two-way binding, on_change/on_submit, focus-preserving) |
Available |
List support — literals, slicing, comprehensions, map/filter/reduce, mutation, for loops |
Available |
Reactive state arrays (in-place append/sort/… re-render) |
Available |
Contributing
External contributions follow GitLab Flow — fork, feature branch, merge
request against main at https://gitlab.com/workpeg/workpeg-sdk.
See CONTRIBUTING.md for the workflow, commit message
format, and development setup.
License
MIT — see LICENSE.
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 workpeg-0.31.0.tar.gz.
File metadata
- Download URL: workpeg-0.31.0.tar.gz
- Upload date:
- Size: 254.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e173cf093d3311009b320d60e6409b648c5177af4959bfb32e80eb5b2a37cab3
|
|
| MD5 |
33e5f35d1aa2fbed0d08558e1f53dd1b
|
|
| BLAKE2b-256 |
d418f8d2bcd2362c11bade7e3ba405fe16f40ec043e2c434195b73099c8759d2
|
File details
Details for the file workpeg-0.31.0-py3-none-any.whl.
File metadata
- Download URL: workpeg-0.31.0-py3-none-any.whl
- Upload date:
- Size: 254.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f7adb9845cc9e5c0097c252c4e578458ca48953589ce6f6e8b314f3d9b1e617a
|
|
| MD5 |
f8e5b654e5ba26d18bd429fe09d1470e
|
|
| BLAKE2b-256 |
333be3e1a67a06843367624d4c9d0c3787ad68967c75cac6d27dffea6faaa564
|