Skip to main content

Run nanoodle visual AI workflows from Python — zero-dependency executor for saved noodle-graph.json files

Project description

nanoodle (Python)

Run visual AI workflows from Python. Design them in the nanoodle editor, save as noodle-graph.json, then load and re-run them here — same graph, same NanoGPT API, your own key.

Zero runtime dependencies (stdlib only). Library + CLI in one install.

Looking for JavaScript / Node? → nanoodle-js

At a glance

Pipeline: nanoodle editor → noodle-graph.json → Python executor → NanoGPT API

Build once, run anywhere. The browser app is for designing and testing. This package is for automating the same workflows in scripts, servers, and agents.

Execution: Workflow.load → wf.run → topological order / concurrent lanes → result

Package nanoodle on PyPI
Runtime Python ≥ 3.9 · stdlib only · no deps
Sibling JavaScript package (same graphs, same semantics)
Editor nanoodle.io — wire nodes, hit 💾, download the graph

Install

pip install nanoodle
export NANOGPT_API_KEY=...   # nano-gpt.com API key (or OAuth access token)

Quickstart (library)

from nanoodle import Workflow

wf = Workflow.load("noodle-graph.json")
result = wf.run({"Text": "a cozy ramen shop on a rainy night"})
result["Image"].save("ramen.png")            # media: MediaRef (url + bytes()/save())
print(result.cost_usd, result.remaining_balance)

With the app’s starter graph (text → LLM prompt-writer → image), that’s the whole program.

Discover a workflow’s interface

wf.inputs    # [InputSpec(key="Text", node_id="n1", field="text", kind="textarea", ...)]
wf.outputs   # [OutputSpec(key="Image", node_id="n3", type="image", ports=["image"])]
wf.settings  # [SettingSpec(key="n3.size", kind="select", default="1k", ...)]

Input keys are flexible (case-insensitive): the node’s custom name, nodeId.field ("n2.system"), or the input’s label when unique. A workflow with exactly one required input also accepts a bare value: wf.run("hello").

Media inputs

from nanoodle import media_from_file

wf.run({"Image": media_from_file("photo.jpg")})            # local file
wf.run({"Image": "https://example.com/photo.jpg"})         # hosted or data: URL
wf.run({"Image": raw_bytes})                               # raw bytes (MIME sniffed)

Media is sent inline as base64 (NanoGPT has no upload endpoint). Files over ~4.4 MB (~3.5 MB for transcription) are refused locally with a clear error before any paid call.

Settings, progress, errors

result = wf.run(
    {"Text": "sunset harbor"},
    settings={"n3.model": "flux-dev", "n3.size": "1k"},
    timeout=600,
    on_progress=lambda evt: print(evt["type"], evt.get("name", "")),
)

run() raises RunError when an output (sink) node fails — error.result still has partial results, per-node statuses, and cost so far. Failures in lanes no output depends on only appear in result.errors. Unknown/unsupported node types, missing required inputs, bad keys, and a missing API key all fail before anything is spent.

CLI

Installed as nanoodle-py (and python -m nanoodle always works):

nanoodle-py inspect graph.json
nanoodle-py run graph.json --input Text="a cozy ramen shop" --set n3.size=1k --out ./out
nanoodle-py run graph.json --input n2.system=@style.txt --json
nanoodle-py run graph.json --env-file .env --input Text="hello"   # NANOGPT_API_KEY from a .env file
  • --out DIR — save media outputs to files
  • --json — machine-readable result
  • --env-file PATH — load .env-style KEY=VALUE lines (existing env vars win)

Supported nodes

runs node types
local text, upload (image/audio/video), choice, join, comment
NanoGPT llm (incl. vision + audio input), image, draw, edit, inpaint*, vision, tvideo, ivideo, vedit, lipsync, music, remix, tts, transcribe
not supported (browser-only media processing) resize, vframes, combine, soundtrack, trim, extractaudio

Workflows with unsupported node types load with a warning and fail fast at run() with UnsupportedNodeError — before any network call.

* inpaint: the browser app composites the mask onto black at the source pixel size; this library passes your mask through verbatim. Supply a black/white mask matching the source dimensions.

Use it as an agent skill

A saved workflow plus a short SKILL.md playbook is a skill any coding agent can run — Claude Code, Cursor, Grok, or anything that reads markdown and runs shell. Recipe and template: docs/agent-skills.md.

Example skill (idea → LLM prompt → poster image):

npx skills add 255BITS/nanoodle-py@poster-generator -g -y
pip install nanoodle   # CLI used by the skill

Source: examples/agent-skill/poster-generator/. Media is saved as Poster.<ext> (MIME-derived; often .jpg) — use the path the CLI prints. The JavaScript package ships the same skill name; installing both overwrites — pick one runtime (see agent-skills.md).

Cost

Bring your own NanoGPT API key; NanoGPT bills your balance per generation and reports the price on each response.

  • result.cost_usd — total of prices returned
  • result.cost_exactFalse if any call omitted a price (total is then a floor)
  • result.remaining_balance — freshest balance the API reported

A price of 0 means known-included (subscription), not unknown. No telemetry, no analytics; the API key is never logged.

Testing

Tests run fully offline against a mock NanoGPT server (tests/harness/):

python -m unittest discover -s tests -t .

Opt-in live probe (spends a fraction of a cent): python3 scripts/live-spot-check.py (add --image to also run the starter graph’s image step).

Docs

Design contract and format/engine/io specs live in docs/: DESIGN.md, SPEC-format.md, SPEC-engine.md, SPEC-io.md.

Same contract as the JavaScript package.

License

MIT — see LICENSE. Not affiliated with NanoGPT. Build workflows at nanoodle.io.

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

nanoodle-0.1.2.tar.gz (49.5 kB view details)

Uploaded Source

Built Distribution

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

nanoodle-0.1.2-py3-none-any.whl (36.7 kB view details)

Uploaded Python 3

File details

Details for the file nanoodle-0.1.2.tar.gz.

File metadata

  • Download URL: nanoodle-0.1.2.tar.gz
  • Upload date:
  • Size: 49.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.10

File hashes

Hashes for nanoodle-0.1.2.tar.gz
Algorithm Hash digest
SHA256 6e07eecacf92ad63a73bd449d84ef45cad49865ccbce15a9b681c45c44ee7cb2
MD5 1cc38f39f4d68959091ef3e92ba417cb
BLAKE2b-256 e770fcd3f5b2a8429ff3f6ee5bbdd135f249bb8983242b27c34121f454d22d82

See more details on using hashes here.

File details

Details for the file nanoodle-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: nanoodle-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 36.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.10

File hashes

Hashes for nanoodle-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 546dbc9f67e5a8753c5135a596dc38b004983ec86a56a7a7b6927745daf4db4d
MD5 3d3a90eaf5b6c70f38afa7cf81eed33a
BLAKE2b-256 02c464450e5ccc1ef018932ec0327d91e29afd6b439cb0d00a37e467f234fa3d

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