Skip to main content

BioArena CLI — manage tools, jobs, spaces, and more

Project description

Muni CLI

Command-line interface for BioArena. Manage tools, GPU jobs, spaces, canvas nodes, and account balance from the terminal.

HTTP uses stdlib urllib only. One runtime dependency (realtime, which pulls in Pydantic v2 — used to parse typed responses from the SDK schema). Requires Python 3.11+.

Install

# Recommended — isolated global install
pipx install .

# Or for development
pip install -e .

Both install the muni command and the muni Python package. pipx is preferred for regular use — it installs into its own virtualenv but makes the muni binary available globally on PATH.

Quick Start

# 1. Log in (no config needed — defaults are built in)
# Default: opens a browser to muni.bio/cli/authorize, you click Authorize,
# CLI captures the callback on a localhost port, done. No password in terminal.
muni login

# On a headless / SSH box with no browser:
muni login --device
# Prints a short code; open muni.bio/device on any device and enter it.

# CI / scripted (legacy email+password):
muni login --email user@example.com --password mypassword

# 3. Explore tools
muni tools
muni tools --category protein-design
muni tool bioarena_rfd3 --inputs

# 4. Run a job
muni run bioarena_rfd3 pdb_id=1UBQ num_designs=5
muni run bioarena_ipsae --batch ipsae_batch.jsonl
cat ipsae_batch.jsonl | muni run bioarena_ipsae --batch - --wait

# 5. Check status and get results
muni status job_<uuid>
muni results job_<uuid>
muni results job_<uuid> --fields sequence,iptm
muni results job_<uuid> --sequences
muni files job_<uuid>
muni download-all job_<uuid> -o ./results/
muni wait job_<uuid> job_<another-uuid>

# Or submit and wait in one step:
muni run bioarena_rfd3 pdb_id=1UBQ num_designs=5 --follow

# 6. Work with canvas nodes in a space
muni space use <space_id>
muni nodes
muni nodes search "PXDesign"
muni node show <node_id>
muni node show <node_id> --json

Job Identifiers

Every job the API creates has two IDs:

ID Format Purpose
job_id job_<uuid> DB primary key — the stable, provider-agnostic identifier. Shown first in all muni output. Prefer this.
call_id bioarena-<tool>-job_<uuid> (Anyscale) or rw-<workflow-uuid> (Rowan) External tracker the compute provider knows the job as. Useful for correlating with provider dashboards or webhooks.

All muni subcommands that take a job argument (status, results, files, logs, download, download-all, wait, job summary, job query) accept either form interchangeably — the API's getJob() branches on the job_ prefix. muni run prints Submitted: job_<uuid> by default; pass --json to see both fields.


Commands

Configuration

Command Description
muni config Interactive setup for API URL, Supabase URL, and publishable key
muni config show Show the active config profile, including the active space (masks long keys)
muni config profiles List all configured profiles and show which is active
muni config use <profile> Switch the default profile (creates it if it doesn't exist)

Authentication

The CLI uses OAuth 2.0 against the muni app. The default flow is authorization code + PKCE with a localhost loopback — no password is ever typed in the terminal. Supabase Auth sits underneath; refresh tokens are scoped to this CLI installation and won't collide with web sessions.

Command Description
muni login Browser + PKCE flow (default). Opens <app_url>/cli/authorize, captures the callback on 127.0.0.1
muni login --device RFC 8628 device code. Prints a code you enter at <app_url>/device on any device
muni login --no-browser Print the authorize URL instead of launching a browser
muni login --client-name "My laptop" Label the session in Connected Devices
muni login -e EMAIL -p PASS Legacy email/password flow (CI/scripted use)
muni login --password-flow Force the legacy flow with interactive prompts
muni logout Revoke the CLI refresh token server-side and clear local credentials
muni whoami Show current user email, user ID, profile name, credit balance, and active space

CLI sessions can be listed and revoked from the web at /account → Connected devices.

Account

Command Description
muni balance Show credit balance

Spaces

Spaces are shared workspaces for organizing jobs and collaborating with other users.

Command Description
muni spaces List your spaces and mark the active one
muni space create <name> Create a new space
muni space delete <space_id> Delete a space (owner only)
muni space members <space_id> List members with email, role, and user ID
muni space invite <space_id> <email> Invite a user to a space
muni space use <space_id-or-name> Set the active space for canvas node commands

The active space is persisted in your profile config (~/.muni/config.json). Once set, all muni nodes and muni node commands default to it. You can override per-command with --space-id.

Canvas Nodes

Canvas nodes are the visual elements on a space's canvas — structures, metrics, file trees, code, text, and more. Each node has a type, label, optional node script (tool configuration), and lifecycle state.

Listing & Searching

Command Description
muni nodes List all canvas nodes in the active space
muni nodes --type structure Filter by node type (structure, metric, filetree, text, code, json, markdown, image, molecule, note, results)
muni nodes -n 100 Set result limit (default: 50)
muni nodes --space-id <id> Override the active space for this command
muni nodes search <query> Search nodes by keyword (matches label, type, tool name, PDB ID, original name, text, markdown, SMILES, and metric columns)

muni nodes and muni nodes search now include canvas position, size, and connection count in both table and JSON output.

Inspecting

Command Description
muni node read <node_id> Read a node's full state (script, data, connections, Python code)
muni node read <node_id> --json Full node payload as JSON
muni node content <node_id> Stream the node's output content from storage

Creating

Command Description
muni node create <title> --type <type> Create a new node (types include metric, code, json, structure, chem, chart, text, image, job, group)
muni node create <title> --type code --python main.py Create a code node with main.py content
muni node create <title> --type <type> --script script.ts Create with an inline script (compiled + executed for non-job nodes)

Updating & Running

Command Description
muni node edit <node_id> --title "New Title" Rename a node
muni node edit <node_id> --script script.ts Update a node's script
muni node edit <node_id> --python main.py Update a code node's main.py
muni node run <node_id> Compile + execute the node, cascading downstream
muni node run <node_id> --wait Execute and wait for completion (default timeout: 60s)
muni node run <node_id> --timeout 300 Set wait timeout in seconds
muni node move <node_id> <x> <y> Move a node to an absolute canvas position
muni node select <page_id> <node_id>... Select one or more nodes on the canvas
muni node focus <page_id> <node_id> Focus the canvas viewport on a node
muni node connect <source_id> <target_id> Create a data edge between two nodes

Deleting

Command Description
muni node remove <node_id> Soft-delete a node (recoverable; disables connections)

All node mutations route through /api/sdk, which stamps the audit trail and broadcasts realtime updates — open canvases reflect changes without a refresh.

Metric nodes

Command Description
muni node metric-summary <node_id> Column names, detected types, and row count
muni node metric-query <node_id> --columns col1,col2 --sort-by col1 --limit 50 Sort / filter / paginate tabular data
muni node metric-select <node_id> <action> Check / uncheck rows; actions: get, select, deselect, clear

Typical workflow — explore a space from the terminal:

# Set your working space + page
muni space use 137df9fd-2634-4a99-bf7e-499799677d15
muni page use <page_id>

# See what's on the canvas
muni nodes
muni nodes --type metric

# Search for a specific run
muni nodes search "PXDesign"

# Inspect a metric node
muni node read <node_id> --json | jq '.currentData.preview'
muni node metric-query <node_id> --columns rank,af2_iptm,sequence --sort-by af2_iptm

# Create a new code node and run it
muni node create "Analysis" --type code --python analysis.py
muni node run <node_id> --wait

Tool Discovery

Command Description
muni tools List all available tools
muni tools -q <keyword> Search tools by keyword
muni tools -c <category> Filter by category (e.g. protein-design, peptide-science, structure-prediction)
muni tool <name> Full tool info: description, category, reference URL, and all inputs
muni tool <name> --inputs Input parameters table with types, defaults, required markers, and descriptions
muni tool <name> --examples Usage examples with sample muni run commands

Job Execution

Command Description
muni run <tool> [KEY=VALUE ...] Submit a job. Returns the call_id immediately
muni run <tool> --params-file request.json Load parameters from a JSON file
muni run bioarena_ipsae --batch batch.jsonl Submit many IPSAE jobs from a JSONL file
cat batch.jsonl | muni run bioarena_ipsae --batch - Submit a JSONL batch from stdin
muni run bioarena_ipsae --batch batch.jsonl --submit-concurrency 10 Set server-side batch submission concurrency
muni run <tool> ... --wait Submit and poll until completion (prints compact completion hints)
muni run <tool> ... --follow Submit and poll with richer live status output (provider, runtime)
muni run <tool> ... --timeout 300 Timeout in seconds for --wait/--follow (default: 1800)
muni run <tool> ... --space-id S Associate job with a space
muni run <tool> ... --title "My run" Set a human-readable job title
muni run <tool> ... --dry-run Validate and print the resolved request payload without submitting
muni run <tool> ... --no-validate Skip client-side schema validation before submitting
muni run <tool> ... --log-lines 200 Number of log tail lines to show after a failed --follow run (default: 120)

When using --wait or --follow, the CLI polls job status with escalating backoff (2s, 2s, 5s, 5s, then 10s intervals). In human mode, completion stays compact: instead of dumping huge result payloads, muni prints the result shape and the next useful command such as muni results <id> --fields ..., muni results <id> --sequences, or muni files <id>. On failure with --follow, the last N log lines are automatically shown.

Batch Submit

Batch submit is available in v1 for bioarena_ipsae.

Input format:

  • JSONL only
  • one JSON object per line
  • each line must already contain the final tool arguments
  • use --batch - to read JSONL from stdin

Examples:

# Submit 60 IPSAE jobs in one API request
muni run bioarena_ipsae --batch ipsae_batch.jsonl

# Submit from stdin
cat ipsae_batch.jsonl | muni run bioarena_ipsae --batch -

# Submit and wait for the successful items
muni run bioarena_ipsae --batch ipsae_batch.jsonl --wait --timeout 600

Behavior:

  • Batch submission is best effort: valid items submit, invalid items are reported individually.
  • --wait waits only on successfully submitted call IDs.
  • exit code is non-zero if any batch item fails submission or any waited job fails/times out.
  • --follow is not supported with --batch.
  • shared Anyscale job queues are enabled automatically for batched IPSAE runs.

Job Monitoring

Command Description
muni jobs List recent jobs (default: 20 most recent)
muni jobs -s completed Filter by status (submitted, running, completed, failed, cancelled)
muni jobs --space-id S Filter by space
muni jobs -n 50 Set result limit
muni status <call_id> Check job status (includes type, provider, runtime, timestamps)
muni wait <id1> <id2> ... Poll one or more jobs until they finish
muni wait <id1> <id2> ... --json Return a compact per-job summary for scripting
muni results <call_id> Get job results as JSON (prints "still running" for 202 responses)
muni results <call_id> --fields sequence,iptm Project selected fields from large structured result sets
muni results <call_id> --sequences Extract sequences from common protein-design result shapes

muni wait and muni run --wait treat a job as finished when the job row reaches a terminal status (completed, failed, cancelled). In JSON mode, wait returns compact metadata such as status, job_type, updated_at, completed_at, and the detected result family, without embedding the full result payload.

Logs

Command Description
muni logs <call_id> Fetch provider logs (default: last 200 lines)
muni logs <call_id> --max-lines 500 Fetch more log lines
muni logs <call_id> --follow Continuously poll logs until job reaches a terminal state
muni logs <call_id> --follow --interval 10 Set polling interval in seconds (default: 5)

File Management

Command Description
muni files <call_id> List output files as a tree (with file sizes)
muni files <call_id> --path designs Show only the designs/ subtree
muni download <call_id> <path> Download a single file (saves to current directory)
muni download <call_id> <path> -o out.pdb Download with a custom output path
muni download <call_id> <path> --stdout Write a single file directly to stdout
muni download <call_id> <path> -o - Alias for --stdout
muni download <call_id> designs Download an entire directory (auto-detected)
muni download-all <call_id> Download all files to ./<call_id>/
muni download-all <call_id> -o ./results/ Download all to a custom directory
muni download-all <call_id> --path designs Download only the designs/ folder
muni download-all <call_id> --glob "*.pdb" Download only .pdb files
muni download-all <call_id> -p designs -g "*.json" Combine: only .json files under designs/

Binary files are base64-decoded on download. Text files are written as UTF-8.

Use --stdout only for single files. It is designed for piping into tools like jq, head, and grep, and cannot be combined with --json.

Typical workflow — inspect then download:

# See what the job produced
muni files job_<uuid>

# Download just the designs folder
muni download-all job_<uuid> --path designs -o ./my-designs/

# Or grab only PDB files from anywhere in the output
muni download-all job_<uuid> --glob "*.pdb" -o ./structures/

# Or stream one file directly into another tool
muni download job_<uuid> summary.json --stdout | jq '.'

Global Flags

These flags work with any subcommand:

Flag Description
--json Output machine-readable JSON instead of human-formatted tables
--profile <name> Use a specific config/credentials profile for this command
--api-url <url> Override the API URL for this command only
--supabase-url <url> Override the Supabase URL for this command only
--supabase-publishable-key <key> Override the Supabase publishable key for this command only

Examples: muni config show --json muni space members <space_id> --json


Parameter Syntax

Parameters use KEY=VALUE format on the command line. Values are auto-parsed:

# Strings
muni run bioarena_rfd3 pdb_id=1UBQ

# Numbers (auto-detected via JSON parsing)
muni run bioarena_rfd3 pdb_id=1UBQ num_designs=10

# Booleans
muni run some_tool flag=true

# JSON arrays
muni run bioarena_rfd3 hotspot_residues='["A32","A35"]'

# JSON objects
muni run some_tool config='{"key": "value"}'

File References

Use @ to load parameter values from files:

# Auto-detect: JSON files parsed as JSON, others read as text
muni run bioarena_rfd3 target_pdb=@./my_protein.pdb
muni run bioarena_protenix input_json=@./request.json

# Force JSON parsing
muni run bioarena_protenix input_json=@json:./request.json

# Force text (no JSON parsing)
muni run bioarena_rfd3 target_pdb=@text:./target.pdb

Params File

Load all parameters from a JSON file (can be combined with KEY=VALUE args, which take precedence):

muni run bioarena_protenix --params-file ./request.json
muni run bioarena_protenix --params-file ./request.json num_designs=20  # override

Client-Side Validation

By default, muni run fetches the tool's JSON Schema and validates parameters locally before submitting. This catches type mismatches, unknown parameters, and missing required fields. Disable with --no-validate.

--validate here is client-side schema validation only. It does not perform a remote execution preflight against staged files or backend job readiness.

Result Shapes

Different tools store different result families in Supabase. Common shapes include:

  • record arrays such as rankings, top_designs, sequences, designs, and some array-shaped metrics
  • scorecard objects such as best_metrics, metrics_summary, ranking, object-shaped metrics, and object-shaped summary
  • file-heavy manifests such as pdb_files, summary_files, csv_files, json_files, and related output lists

muni results --fields works best for structured record arrays and scorecard objects. muni results --sequences is a convenience extractor for common protein-design outputs. For file-heavy jobs, start with muni files and then muni download or muni download-all.


Configuration

Config is stored in ~/.muni/config.json with named profile support:

{
  "current_profile": "default",
  "profiles": {
    "default": {
      "api_url": "https://api.bioarena.com",
      "supabase_url": "https://xxx.supabase.co",
      "supabase_publishable_key": "sb_publishable_..."
    },
    "local": {
      "api_url": "http://localhost:8000",
      "supabase_url": "https://xxx.supabase.co",
      "supabase_publishable_key": "sb_publishable_..."
    }
  }
}

Credentials are stored separately in ~/.muni/credentials.json per profile. Both files are created with 0600 permissions.

Environment Variables

Environment variables override config file values:

Variable Description
MUNI_API_URL BioArena Tools API URL
MUNI_SUPABASE_URL Supabase project URL
MUNI_SUPABASE_PUBLISHABLE_KEY Supabase publishable key
MUNI_SPACE_ID Override the active space for canvas node commands
MUNI_PROFILE Select a saved config/credentials profile

Token Management

Authentication tokens are automatically refreshed when within 60 seconds of expiry. If the refresh token is missing or invalid, you'll need to muni login again.


Python SDK

Use MuniClient programmatically for scripting and automation. The preferred API is the namespaced sub-clients — they return Pydantic v2 models parsed from the TypeScript SDK's Zod schemas, so IDE autocomplete and validation work out of the box. The flat methods (client.list_tools(...), client.run(...), etc.) remain available as stable dict-returning wrappers.

from muni import MuniClient

client = MuniClient()

# ── Sub-clients (preferred, typed) ────────────────────────────────

# Spaces
spaces = client.spaces.list()                      # list[SpacesListOutputItem]
print(spaces[0].name, spaces[0].id)
my_space = client.spaces.create("Experiments")     # SpacesCreateOutput

# Pages
pages = client.pages.list(my_space.id)             # list[PagesListOutputItem]
default = client.pages.get_default(my_space.id)    # PagesGetDefaultOutput
page_id = default.id

# Tools
tools = client.tools.list(category="protein-design")  # list[ToolsListOutputItem]
tool = client.tools.get("bioarena_rfd3")              # ToolsGetOutput (includes parameters, reference_url)

# Jobs
submit = client.jobs.submit(
    "bioarena_rfd3",
    {"pdb_id": "1UBQ", "num_designs": 5},
    title="RFD 1UBQ",
    space_id=my_space.id,
)                                                   # JobsSubmitOutput
results = client.jobs.wait(submit.call_id, timeout=600)

# Nodes (return dicts — augmented with runtime state post-create)
node = client.nodes.create(page_id, "Analysis", type="code",
                           python_code="print('hi')")
client.nodes.run(node["nodeId"])

# Connections
conn = client.connections.create(
    page_id=page_id,
    target_node_id=node["nodeId"],
    target_port="input",
    source_node_id="node_src",
    source_port="output",
)

# ── Flat wrappers (legacy; emit snake_case dicts) ─────────────────

tools_dict = client.list_tools(category="protein-design")        # {"tools": [...]}
job = client.run("bioarena_rfd3", {"pdb_id": "1UBQ", "num_designs": 5})
call_id = job["call_id"]

def on_status(data):
    print(f"Status: {data['status']}")

results = client.wait_for_job(call_id, timeout=600, on_status=on_status)
client.save_all_files(call_id, "./output/", glob_pattern="*.pdb")

Sub-clients

Namespace Example methods
client.user whoami(), balance()
client.spaces list(), get(), create(), delete(), members(), invite(), resolve()
client.pages list(), get(), get_default(), create(), delete(), reorder()
client.nodes list(), get(), create(), update(), remove(), run(), save(), move(), select(), focus(), metric_summary(), metric_query()
client.node_files list(), get(), create(), update() (Python files for code nodes)
client.node_data list(), get() (metric data)
client.connections list(), create(), remove(), enable(), disable()
client.tools list(), get(), examples()
client.jobs submit(), status(), wait(), results(), search(), cancel(), summary(), query(), logs(), batch()
client.files list(), get(), download()
client.chat / client.plans / client.sandbox / client.scripts see muni/clients/

Each sub-client routes through POST /api/sdk on the app server and (where wired) returns Pydantic models from muni._generated.models. Call .model_dump(by_alias=True) on any model to get a camelCase dict matching the TypeScript SDK's response shape.

Flat MuniClient methods (legacy, stable)

Method Returns Description
list_tools(query, category) dict List/search available tools (Tools API)
get_tool(name) dict Get tool schema (Tools API)
get_examples(name) dict Get usage examples (Tools API)
run(tool, args, space_id, title) dict Execute a tool, returns {"call_id": "..."}
run_batch(tool, items, space_id, title_prefix, submit_concurrency) dict Execute many items in one API request
job_status(call_id) dict Check job status
job_results(call_id) (int, dict) Get results (HTTP 202 = still running)
job_logs(call_id, max_lines) dict Fetch provider logs
cancel_job(call_id) (int, dict) Cancel a running job
wait_for_job(call_id, timeout, on_status) dict Poll until completion, raises on failure/timeout
list_jobs(space_id, status, limit) list[dict] List jobs from Supabase
list_files(call_id) dict List output files
download_file(call_id, path) (str, bool) Download file content (content, is_text)
save_file(call_id, path, dest) Path Download and write file to disk
save_all_files(call_id, output_dir, *, path_prefix, glob_pattern) list[Path] Bulk download, optionally filtered
get_balance() dict Credit balance (snake_case keys)
list_spaces() / create_space(name) / delete_space(id) Space management (snake_case dicts)
space_members(space_id) / invite_to_space(space_id, email) Membership
resolve_space_id(id_or_name) str Resolve a UUID or name to a space UUID
list_pages(space_id) / get_page(page_id) Page lookup (PostgREST)
search_nodes(page_id, *, node_type, query, limit) list[dict] Search nodes on a page
create_node(page_id, title, *, node_type, script, python_code, position_x, position_y) dict Create a node (delegates to client.nodes.create)
read_node(node_id) / edit_node(...) / remove_node(node_id) dict Node management
run_node(node_id, *, wait, timeout) dict Execute a node, optionally polling for completion
metric_summary(node_id) / metric_query(node_id, ...) / metric_select(node_id, action, ...) dict Metric node helpers

Exceptions

from muni import MuniError, AuthError, NotFoundError, JobFailedError, JobTimeoutError
from muni.exceptions import APIError, JobCancelledError

try:
    results = client.wait_for_job(call_id, timeout=300)
except JobFailedError as e:
    print(f"Job {e.call_id} failed: {e.error}")
except JobTimeoutError as e:
    print(f"Job {e.call_id} didn't finish in {e.timeout}s")
except JobCancelledError as e:
    print(f"Job {e.call_id} was cancelled")
except AuthError:
    print("Not logged in or token expired")
Exception Description
MuniError Base class for all muni errors
AuthError Login failed or no valid credentials
NotFoundError Tool, job, or file not found
APIError Unexpected HTTP error (has .status_code)
JobFailedError Job completed with failed status (has .call_id, .error)
JobCancelledError Job was cancelled (has .call_id)
JobTimeoutError Timed out waiting for job (has .call_id, .timeout)

Architecture

Derivation chain

The TypeScript SDK in muni-app is the canonical contract. The Python SDK is derived from it, and the CLI wraps the Python SDK:

TypeScript SDK (canonical)  →  Python SDK (derived)  →  CLI (wraps SDK)
   muni-app/src/lib/            muni/clients/*.py          muni/cli.py
   muni/sdk/client/             muni/_generated/models.py

Pydantic v2 models in muni/_generated/models.py are generated from the app's OpenAPI/Zod schemas — do not edit by hand. Regenerate via pnpm codegen:python in muni-app.

Three backends

  1. App server /api/sdk (canonical) — typed namespaced calls for nodes, pages, spaces, tools, jobs, connections, user, chat, plans, files, sandbox, scripts. Routed through SDKClientBase._call().
  2. Tools API (Elysia server, port 8000) — legacy path still used by muni run, muni results, muni logs, muni download, and the flat list_tools/get_tool wrappers.
  3. Supabase PostgREST (direct) — auth, muni jobs listing, and a handful of direct reads/writes on muni_nodes / muni_node_data for metric query/select.
muni login    →  Supabase Auth API                    →  ~/.muni/credentials.json
muni run      →  Tools API (POST /tools/:name/execute)
muni status   →  Tools API (GET /jobs/:callId/status)
muni spaces   →  App server /api/sdk (spaces.list)
muni nodes    →  App server /api/sdk (nodes.list)
muni node ... →  App server /api/sdk (nodes.create/read/edit/run/...)
muni jobs     →  Supabase PostgREST (GET /rest/v1/jobs)
muni tools    →  Tools API (GET /tools)

All HTTP uses stdlib urllib. The only external dependency is realtime (used for push-based job-status updates in muni wait), which transitively pulls in Pydantic v2 for typed SDK responses.

Project Structure

muni-cli/
├── muni/
│   ├── __init__.py       # MuniClient + exceptions re-export
│   ├── __main__.py       # python -m muni entry point
│   ├── cli.py            # argparse subcommands + KEY=VALUE parsing
│   ├── client.py         # MuniClient facade (legacy flat methods + sub-client wiring)
│   ├── clients/          # Namespaced sub-clients (nodes, spaces, pages, jobs, tools,
│   │   │                 #   user, connections, files, node_files, node_data, chat,
│   │   │                 #   plans, sandbox, scripts) — all route through /api/sdk
│   │   └── _base.py      # SDKClientBase: POST /api/sdk + optional Pydantic parsing
│   ├── _generated/       # Pydantic v2 models generated from the TS Zod schemas
│   │   └── models.py     # DO NOT EDIT — regenerate via `pnpm codegen:python`
│   ├── auth.py           # Email/password + PKCE login, logout, token refresh
│   ├── oauth.py          # OAuth 2.0 + PKCE + device-code flows
│   ├── realtime.py       # Supabase realtime subscriber for job-status updates
│   ├── api.py            # Tools API HTTP calls
│   ├── supabase.py       # PostgREST + Auth HTTP calls
│   ├── display.py        # Human-readable formatting (tables, trees, status)
│   ├── config.py         # ~/.muni/ file management + profile switching
│   ├── canvas.py         # Node connection geometry
│   ├── node_scripts.py   # Node script compile/validate helpers
│   ├── node_sources.py   # Node source DSL parser
│   └── exceptions.py     # MuniError hierarchy
├── pyproject.toml        # PEP 621 packaging (setuptools)
├── scripts/push          # Version-bumping push script
└── README.md

Versioning

Version is defined in muni/__init__.py (__version__) and read dynamically by pyproject.toml. Check it with:

muni --version

Auto-bump on push

Use ./scripts/push instead of git push to automatically bump the patch version after a successful push:

./scripts/push origin master

This will:

  1. Push your commits
  2. Bump the patch version (e.g. 0.1.30.1.4)
  3. Commit and push the version bump

For major or minor bumps, edit muni/__init__.py manually before pushing.

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

muni-0.1.13.tar.gz (108.8 kB view details)

Uploaded Source

Built Distribution

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

muni-0.1.13-py3-none-any.whl (98.8 kB view details)

Uploaded Python 3

File details

Details for the file muni-0.1.13.tar.gz.

File metadata

  • Download URL: muni-0.1.13.tar.gz
  • Upload date:
  • Size: 108.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for muni-0.1.13.tar.gz
Algorithm Hash digest
SHA256 560731efa5778606833e01bba857eece9dfbdfbb48c0092f6184e3e5a1e32a3b
MD5 5ff38e2fba8c82c067e0e59583d645b7
BLAKE2b-256 f0e8ac16075ce7d402707e330abbf4de62b1440eb700508c905d60e62cd3a7f3

See more details on using hashes here.

Provenance

The following attestation bundles were made for muni-0.1.13.tar.gz:

Publisher: publish.yml on bioArena/muni-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file muni-0.1.13-py3-none-any.whl.

File metadata

  • Download URL: muni-0.1.13-py3-none-any.whl
  • Upload date:
  • Size: 98.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for muni-0.1.13-py3-none-any.whl
Algorithm Hash digest
SHA256 4d8e35ecef736ef5ab1ab00c8b68f169c3e9a13bc6c3a04a650454d8860269f3
MD5 9e4a57eb18028d470a9a24345cd109d3
BLAKE2b-256 c3fd98199fcd2546db4a75e908e53c8302b3a2519bbec6e1df1aa1d089a87ca2

See more details on using hashes here.

Provenance

The following attestation bundles were made for muni-0.1.13-py3-none-any.whl:

Publisher: publish.yml on bioArena/muni-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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