Skip to main content

Python bindings for model-language — a typed, safe template language for AI-agent prompts. Runs the exact same engine as the TypeScript package via a WebAssembly (WASI) module.

Project description

model-language (Python)

Python bindings for model-language — a typed, safe template language for AI-agent prompts.

Powered by the production model-language engine compiled to a WebAssembly module: templates render byte-for-byte identically in Python and JavaScript, a guarantee enforced by a shared conformance/ suite run in CI. Fast (parse once, render many), sandboxed, and it never crashes — template problems degrade to empty output plus a warning.

Live demo — try the language in a Tiptap editor (live validation, autocomplete, real-time render), powered by the same engine.

Filters format values — dates, numbers, text:

{{ user.created_at | date: "MMM D, YYYY" }}            →  Jul 5, 2026
{{ user.created_at | date: "h:mm A", "Europe/Kyiv" }}  →  5:37 PM
{{ user.last_seen  | time_ago }}                       →  3 days ago

Directives embed machine-readable constraints in a prompt. They are stripped from the rendered text and returned in directives:

from model_language import render, validate, parse

src = (
    "Help with billing.\n"
    "{{verify_before: payments}}\n"
    "{{identity: contact.email == payment.email}}\n"
    'Greet {{contact.first_name | default: "there"}}.'
)

directives = [
    {"name": "verify_before", "hasBody": False, "arg": {"kind": "scalar", "type": "enum", "values": ["payments", "calendar"]}},
    {"name": "identity",      "hasBody": False, "arg": {"kind": "comparison", "type": "field", "comparison": {"operators": ["=="], "operandType": "field"}}},
]
schema = [{"path": "contact.email", "type": "string"}, {"path": "contact.first_name", "type": "string"}]

out = render(
    src,
    data={"contact": {"first_name": "Vasyl"}},
    schema=schema,
)
print(out["text"])        # -> "Help with billing.\n\nGreet Vasyl."
print([d["name"] for d in out["directives"]])  # -> ["verify_before", "identity"]

Usage

from model_language import render, validate, parse

out = render(
    "Hi {{ user.name | default: 'there' }}!",
    data={"user": {"name": "Vasyl"}},
)
print(out["text"])          # -> "Hi Vasyl!"

diags = validate(
    "{{if user.plan == 'premium'}}x{{/if}}",
    schema=[{"path": "user.plan", "type": "enum", "values": ["free", "pro"]}],
)
print([d["code"] for d in diags["diagnostics"]])   # -> ["ML202"]
  • render(template, data=None, schema=None, options=None){"text", "warnings", "resolvedBranches", "directives", "tokenEstimate"}. Pass options={"now": <epoch_ms>} for datetime filters (the sandbox has no ambient clock; it defaults to 0). Pass options={"snippets": {...}} for {{include}}.
  • validate(template, schema=None, options=None){"diagnostics", "maxTokenEstimate"}. Pass options={"maxTokenEstimate": N} to raise ML213 over a token budget.
  • parse(template){"ast", "diagnostics"}.

Nothing raises for template problems — they degrade to empty output plus a warnings/diagnostics entry.

Build (from source)

The bindings host model_language.wasm, built from the TypeScript engine:

# 1. Build the WASI module (from the repo root, needs Node + pnpm + the javy CLI)
pnpm install && pnpm wasm:build

# 2. Run the conformance parity tests
pip install wasmtime pytest
cd hosts/python && python -m pytest -q

The loader finds the module at ../wasm/dist/model_language.wasm by default; set MODEL_LANGUAGE_WASM to point at a prebuilt one. Requires wasmtime>=25.

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

model_language-1.1.0.tar.gz (600.6 kB view details)

Uploaded Source

Built Distribution

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

model_language-1.1.0-py3-none-any.whl (599.9 kB view details)

Uploaded Python 3

File details

Details for the file model_language-1.1.0.tar.gz.

File metadata

  • Download URL: model_language-1.1.0.tar.gz
  • Upload date:
  • Size: 600.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for model_language-1.1.0.tar.gz
Algorithm Hash digest
SHA256 a538ad9d16e71c70ee84e069e82304be9318cfb7f6fa48eba0fc85a23833cae4
MD5 dc604f2f7fc0222ff5fc38f20dc7b79e
BLAKE2b-256 d0827b3a7a98bc343c33f8fd17a7d3c545afd34d23e27c71a0feef9c0a36a0fc

See more details on using hashes here.

File details

Details for the file model_language-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: model_language-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 599.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for model_language-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fa93602f5733e8e0cc1bf5d7e78436691b1b9ab2707b860161033e89639a52e9
MD5 61abbe78d06cd23d344a4cdc4b6b8e1a
BLAKE2b-256 c4f66f8ce7705e293582bb578f553584e56d8203b0c7ceab7cd3c0abfcdea102

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