This release is a pre-release and may not be stable for production use.
metal-cdn
PyPI: pymergetic-metal-cdn · Client: pymergetic-metal-cdn-client
Live demo: cdn.pymergetic.com/cdn · Pack format: wasmmod
Async FastAPI channel for signed wasmmod packs — browse, publish, inspect, and try them in a browser MicroPython shell.
Experimental. Data on the public demo is wiped often. Short tests only — not for production.
Channel state (artifacts + index.json) lives in object storage.
Publisher identity (users + ACL) lives in SQL.
Devices still verify pack signatures with wasmmod — this service does not replace that.
What you get
| Surface | What it does |
|---|---|
| Browse | Package tree, lead / @version pins, dependents |
| Artifacts | Expand a .wasm / .elf / .zlib / AOT blob → pack file list |
| Source viewer | Highlighted text (py / c / rs / toml / …) or hex for binaries |
| µPy shell | In-browser MicroPython + wasmmod: ▶ → import + exports() |
| Sessions | Per-browser loader sessions — autoexec / pack / index hits |
| Publish | Multipart UI + CLI / thin client for CI |
Inspect a pack
Click an artifact to open its guts — embedded Python (.py / .mpy / .pyc), natives, and optional wasmmod.source.
Text files open with syntax highlighting; bytecode and other binaries get a hex dump.
Install
pip install pymergetic-metal-cdn
# from this repo (client first — server depends on it):
pip install -e ./client -e ".[dev]" --config-settings editable_mode=compat
Thin publish/download wheel (no FastAPI): pymergetic-metal-cdn-client
→ pymergetic.metal.cdn_client — docs/CLIENT.md · client/README.md.
Version comes from git tags via setuptools-scm (metal-cdn --version).
Quick start
cd packages/metal-cdn
python3 -m venv .venv && source .venv/bin/activate
pip install -e ./client -e ".[dev]" --config-settings editable_mode=compat
cp .env.example .env
metal-cdn serve --reload
# → http://127.0.0.1:8000/cdn/ UI
# → http://127.0.0.1:8000/cdn/docs OpenAPI
Docker one-shot
Rebuild browser µPy (if needed), sync REPL assets, docker build/run, seed sample packs:
./scripts/dev-up.sh
# → http://127.0.0.1:8000/cdn/ (µPy: packages() | import hello)
Flags: --no-upy, --no-seed, --seed-only.
Env: METALPYTHON, METAL_CDN_URL, METAL_CDN_PORT, METAL_CDN_SESSION_SECRET.
Public TLS edge
https://cdn.pymergetic.com/cdn/ — see docs/PROXY.md.
./scripts/dev-up.sh --no-upy
docker compose --profile proxy up -d nginx
curl -sf https://cdn.pymergetic.com/cdn/health
Try packs in the shell
The floating µPy panel warms MicroPython in the background. When status is ready, hit ▶ on an artifact (or type it yourself):
import hello
exports(hello) # public names + types (+ docstring line when set)
hello.greet()
loaded hello · 5 public
add (WasmFunc)
hello (WasmFunc)
greet (function)
answer (function)
util (module)
Dotted trees work too (missing middle packs become namespaces):
import test_a2.test_b2.test_c2
exports(test_a2.test_b2.test_c2)
test_a2.test_b2.test_c2.c2_answer() # → 42
packages()— live lead catalog (or autoexec snapshot)exports(mod)— shipped in autoexec (same place ashelp())GET /repl/autoexec.pymints/reuses aShellSession, setswasm.cdn+ import hook +SESSION_ID- Pack/index hits with the session cookie show up under Sessions
- Login claims prior anon sessions; Logout mints a fresh anon
▶ on a .wasm / .zlib / AOT row runs exactly import <pkg> then exports(<pkg>).
Client CLI
metal-cdn login --url http://127.0.0.1:8000/cdn --email you@example.com --register
metal-cdn claim hello
metal-cdn publish hello 0.1.0 ./hello.wasm ./hello.wasm.zlib
metal-cdn whoami
Web publish UI: {BASE_PATH}/publish after login.
One-shot pack→AOT→sign→zlib→upload: wasmmod.py publish (docs/CLIENT.md).
Releases / PyPI tags: docs/RELEASE.md.
Optional Postgres: docker compose up -d db + METAL_CDN_DATABASE_URL=….
Layout
client/pyproject.toml # pymergetic-metal-cdn-client
pymergetic/metal/
cdn_client/ # thin HTTP client (shared sources)
cdn/ # FastAPI server + UI + REPL
screenshots/ # UI stills for this README
from pymergetic.metal.cdn.main import create_app
from pymergetic.metal.cdn_client import CdnClient
API sketch
| Method | Path | Role |
|---|---|---|
| GET | /health /ready /metrics |
Liveness / readiness / Prometheus |
| POST | /auth/* |
Register, login, token, API keys |
| GET | /api/sessions |
Shell sessions for cookie principal |
| GET | /repl/autoexec.py |
Browser µPy bootstrap |
| POST | /packages/{name}/claim |
Claim ownership |
| GET | /index/lead |
Device-facing index.json |
| GET | /packages/{name}/closure |
Exact-deps install order |
| POST | /publish |
Multipart publish |
| GET | /artifacts/… |
Download / inspect / embedded files |
metal-cdn db upgrade # Alembic
Related
- docs/LAYOUT.md · docs/INDEX.md · docs/PROXY.md
- docs/CLIENT.md · docs/RELEASE.md · docs/ROADMAP.md
- Pack format: wasmmod PACK.md
License
MIT — Rouven Raudzus (raudzus@pymergetic.com)
Metadata
Release files for pymergetic-metal-cdn 0.1.0a6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pymergetic_metal_cdn-0.1.0a6.tar.gz | 799.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pymergetic_metal_cdn-0.1.0a6-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.0 MB
Release files / pymergetic_metal_cdn-0.1.0a6.tar.gz
| Download URL | pymergetic_metal_cdn-0.1.0a6.tar.gz |
|---|---|
| Size | 799.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
786257dd6502ec0f35686c86de458ceea808ae4ae38e0f261222bbb9364ee2e5
|
|
BLAKE2b-256 checksum How to use checksums |
494b6dbe3c737eea8a9aeb315f24dd35362540aa6758f352f6e74c8073ffba9c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / pymergetic_metal_cdn-0.1.0a6-py3-none-any.whl
| Download URL | pymergetic_metal_cdn-0.1.0a6-py3-none-any.whl |
|---|---|
| Size | 210.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b46f0aa5d1b0c07bded155644a597b6eb5be084379cf4b1a944b09e4a98b49d2
|
|
BLAKE2b-256 checksum How to use checksums |
89ab9a8b893f6bc572fe7cf423fe45a3461cd5c73f864119473944a91d120a55
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|