Skip to main content

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 project ...
workpeg function ...
workpeg cdn ...
workpeg ui ...
Namespace Purpose
project Scaffold a whole peg — UI, function and manifest
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 project --help
workpeg function --help
workpeg cdn --help
workpeg ui --help

Pegs

A peg is two halves and a manifest that binds them. Scaffold all three:

workpeg project create my-peg
Created my-peg/
  workpeg.json   namespace: my-peg
  ui/            the interface
  function/      the backend

The sections below cover each half on its own.

Full reference: docs/projects.md


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/projects.md workpeg project create: the peg layout, the manifest, naming rules, working on each half
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. namespace records the peg the project belongs to — workpeg project create writes it, workpeg function new does not:

{
  "namespace": "my-peg",
  "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 project create (scaffold UI + function + manifest) 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://<app>.dev.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.

Download files

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

Source Distribution

workpeg-0.117.3.tar.gz (1.9 MB view details)

Uploaded Source

Built Distribution

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

workpeg-0.117.3-py3-none-any.whl (1.9 MB view details)

Uploaded Python 3

File details

Details for the file workpeg-0.117.3.tar.gz.

File metadata

  • Download URL: workpeg-0.117.3.tar.gz
  • Upload date:
  • Size: 1.9 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.13

File hashes

Hashes for workpeg-0.117.3.tar.gz
Algorithm Hash digest
SHA256 b74fe03f9d59729dce34d0f96b55d2db39d3acf2bb86940d711349ec92c5d325
MD5 1031580388660acd4022c78a0149f853
BLAKE2b-256 517573f94960fece0400288be18035d9777015d3580484cd1c32b40fbaf769ca

See more details on using hashes here.

File details

Details for the file workpeg-0.117.3-py3-none-any.whl.

File metadata

  • Download URL: workpeg-0.117.3-py3-none-any.whl
  • Upload date:
  • Size: 1.9 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.13

File hashes

Hashes for workpeg-0.117.3-py3-none-any.whl
Algorithm Hash digest
SHA256 76136131c0b8208ce370a3511120898a17b10a9c24537ecc9eeeee3dd5189f19
MD5 f8e17758209144151a151fe9a8be48fa
BLAKE2b-256 62aa5221f8d798e2f7a599aee1f383465e8b890985225645e52808270c5e7408

See more details on using hashes here.

Release history Release notifications | RSS feed

0.142.0

2 files

0.141.0

2 files

0.140.2

2 files

0.140.1

2 files

0.140.0

2 files

0.139.0

2 files

0.138.0

2 files

0.137.0

2 files

0.136.1

2 files

0.136.0

2 files

0.135.0

2 files

0.134.1

2 files

0.133.0

2 files

0.132.0

2 files

0.131.0

2 files

0.130.0

2 files

0.129.0

2 files

0.128.0

2 files

0.127.0

2 files

0.126.0

2 files

0.125.0

2 files

0.124.0

2 files

0.123.0

2 files

0.122.0

2 files

0.121.0

2 files

0.120.0

2 files

0.119.0

2 files

0.118.0

2 files

0.117.4

2 files

This release

0.117.3 This release

2 files

0.117.2

2 files

0.117.1

2 files

0.117.0

2 files

0.116.0

2 files

0.115.0

2 files

0.114.1

2 files

0.114.0

2 files

0.113.11

2 files

0.113.10

2 files

0.113.9

2 files

0.113.8

2 files

0.113.7

2 files

0.113.6

2 files

0.113.5

2 files

0.113.4

2 files

0.113.3

2 files

0.113.2

2 files

0.113.1

2 files

0.112.0

2 files

0.111.2

2 files

0.111.1

2 files

0.111.0

2 files

0.110.0

2 files

0.109.1

2 files

0.108.0

2 files

0.107.0

2 files

0.106.2

2 files

0.106.1

2 files

0.106.0

2 files

0.105.0

2 files

0.104.1

2 files

0.104.0

2 files

0.103.0

2 files

0.102.0

2 files

0.101.2

2 files

0.100.0

2 files

0.99.0

2 files

0.98.1

2 files

0.98.0

2 files

0.97.2

2 files

0.97.1

2 files

0.97.0

2 files

0.96.5

2 files

0.96.4

2 files

0.96.3

2 files

0.96.2

2 files

0.96.1

2 files

0.96.0

2 files

0.95.0

2 files

0.94.4

2 files

0.94.3

2 files

0.94.2

2 files

0.94.1

2 files

0.93.1

2 files

0.93.0

2 files

0.92.0

2 files

0.91.0

2 files

0.90.0

2 files

0.89.0

2 files

0.88.0

2 files

0.87.0

2 files

0.86.0

2 files

0.85.0

2 files

0.84.0

2 files

0.83.0

2 files

0.82.0

2 files

0.81.0

2 files

0.80.0

2 files

0.79.1

2 files

0.79.0

2 files

0.78.0

2 files

0.77.0

2 files

0.76.0

2 files

0.75.0

2 files

0.74.0

2 files

0.73.1

2 files

0.73.0

2 files

0.72.0

2 files

0.71.0

2 files

0.70.0

2 files

0.69.0

2 files

0.68.0

2 files

0.67.0

2 files

0.66.0

2 files

0.65.0

2 files

0.64.0

2 files

0.63.0

2 files

0.62.0

2 files

0.61.0

2 files

0.60.0

2 files

0.59.0

2 files

0.58.0

2 files

0.57.0

2 files

0.56.0

2 files

0.55.0

2 files

0.54.0

2 files

0.53.0

2 files

0.52.0

2 files

0.51.0

2 files

0.50.0

2 files

0.49.0

2 files

0.48.0

2 files

0.47.0

2 files

0.46.0

2 files

0.45.0

2 files

0.44.0

2 files

0.43.0

2 files

0.42.0

2 files

0.41.0

2 files

0.40.0

2 files

0.39.0

2 files

0.38.0

2 files

0.37.0

2 files

0.36.0

2 files

0.35.0

2 files

0.34.0

2 files

0.33.0

2 files

0.32.0

2 files

0.31.0

2 files

0.30.0

2 files

0.29.0

2 files

0.28.0

2 files

0.27.0

2 files

0.26.0

2 files

0.25.0

2 files

0.24.0

2 files

0.23.0

2 files

0.22.0

2 files

0.21.0

2 files

0.20.0

2 files

0.19.0

2 files

0.18.0

2 files

0.17.0

2 files

0.16.0

2 files

0.15.0

2 files

0.14.0

2 files

0.13.0

2 files

0.12.0

2 files

0.11.0

2 files

0.10.0

2 files

0.9.0

2 files

0.8.1

2 files

0.8.0

2 files

0.7.0

2 files

0.6.1

2 files

0.6.0

2 files

0.5.3

2 files

0.5.2

2 files

0.5.1

2 files

0.5.0

2 files

0.4.3

2 files

0.4.2

2 files

0.4.1

2 files

0.4.0

2 files

0.3.2

2 files

0.3.1

2 files

0.3.0

2 files

0.2.1

2 files

0.2.0

2 files

0.1.5

2 files

0.1.4

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page