Skip to main content

lacelang-executor (python)

PyPI

Canonical Python executor for Lace — the reference implementation with 100% spec conformance. Runs .lace scripts against real HTTP endpoints and emits ProbeResult JSON.

This is the executor that the Lace specification is developed and tested against. Conformance vectors, error codes, and wire-format schemas are verified against this implementation before each spec release.

Parsing and semantic validation are delegated to lacelang-validator — this package contains only the runtime (HTTP client, assertion evaluation, cookie jars, extension dispatch). See lace-spec.md §15 for the validator / executor package separation rule.

Install

pip install lacelang-executor

This automatically installs lacelang-validator as a dependency.

Or from source:

pip install git+https://github.com/tracedown/lacelang-python-executor.git

Usage

# Parse (delegates to validator)
lacelang-executor parse script.lace

# Validate (delegates to validator)
lacelang-executor validate script.lace --context context.json --vars-list vars.json

# Run — full HTTP execution
lacelang-executor run script.lace \
    --vars vars.json \
    --prev prev.json \
    --bodies-dir ./bodies

# Enable extensions (laceNotifications is built in)
lacelang-executor run script.lace --enable-extension laceNotifications

All subcommands support --pretty for indented JSON.

Library usage

Project layout

The executor expects Lace files under a dedicated lace/ directory:

my-project/
  lace/
    lace.config                      # executor config (auto-discovered)
    config.staging.json              # env-specific overrides (optional)
    extensions/                      # third-party extensions
      myext/
        myext.laceext
        myext.config
    scripts/
      health/
        health.lace                  # script (name = directory name)
        vars.json                    # default variables
        vars.staging.json            # env-specific variables
      auth-flow/
        auth-flow.lace
        vars.json

All paths are overridable at runtime — the layout is a convention, not a requirement.

LaceExecutor + LaceProbe

from lacelang_executor import LaceExecutor

# Point to the lace/ directory — config loaded once
executor = LaceExecutor("lace")

# Or override the config path directly
executor = LaceExecutor(config="path/to/lace.config", env="staging")

# Register third-party extensions
executor.extension("lace/extensions/myext")           # directory (finds myext.laceext + myext.config)
executor.extension("path/to/custom.laceext", "path/to/custom.config")  # explicit paths

# Prepare a probe by name — resolves to lace/scripts/health/health.lace
# AST is parsed and validated once, reused across runs
probe = executor.probe("health")

# Run — returns a ProbeResult dict
result = probe.run(vars={"base_url": "https://api.example.com"})

# Run again — prev result from last run injected automatically
result = probe.run()

# All inputs accept file paths or dicts
result = probe.run(
    vars="lace/scripts/health/vars.staging.json",
    prev="results/last_run.json",    # explicit prev overrides auto-tracking
)

One-shot execution

# No probe caching, no prev tracking
result = executor.run("lace/scripts/health/health.lace", vars={"key": "val"})

# Inline source
result = executor.run('''
get("https://api.example.com/health")
    .expect(status: 200)
''')

Development mode

# Re-read and re-parse the script file on every run()
probe = executor.probe("health", always_reparse=True)

API reference

LaceExecutor(root, *, config, env, extensions, track_prev)

Parameter Type Default Description
root str | None None Path to the lace/ directory. Discovers lace.config and resolves script names relative to {root}/scripts/.
config str | None None Explicit path to lace.config (overrides root-based discovery).
env str | None None Selects [lace.config.{env}] section (overrides LACE_ENV).
extensions list[str] | None None Built-in extensions to activate (e.g. ["laceNotifications"]).
track_prev bool True Auto-store last result as prev for next run on each probe.

executor.extension(path, config_path=None) — register a third-party extension.

executor.probe(script, *, vars, always_reparse) — prepare a reusable probe.

Parameter Type Default Description
script str — Script name ("health"), file path ("path/to.lace"), or inline source.
always_reparse bool False Re-read script file on every run().

probe.run(vars, prev, *, reparse) — execute and return ProbeResult.

Parameter Type Default Description
vars str | dict | None None Script variables — dict or path to JSON.
prev str | dict | None None Previous result — dict or path to JSON. Overrides auto-tracking.
reparse bool False Re-read script from disk for this run only.

Config and environment overrides

There is exactly one config file per executor. The env parameter selects a section within that file, not a different file.

# lace/lace.config

[executor]
maxRedirects = 10
maxTimeoutMs = 300000

# Staging overlay — deep-merged on top of base.
# Only the keys you specify are overridden; the rest is inherited.
[lace.config.staging]
[lace.config.staging.executor]
maxTimeoutMs = 60000           # overridden
# maxRedirects is inherited (10)

[lace.config.production]
[lace.config.production.executor]
user_agent = "lace-probe/0.9.1 (acme-platform)"

Resolution by constructor arguments:

Constructor Config file Env overlay
LaceExecutor("lace") lace/lace.config none (base only)
LaceExecutor("lace", env="staging") lace/lace.config [lace.config.staging] merged on base
LaceExecutor(config="/path/lace.config", env="prod") /path/lace.config [lace.config.prod] merged on base
LaceExecutor("lace", config="/other/lace.config") /other/lace.config none (root still used for script names)
LACE_ENV=staging + LaceExecutor("lace") lace/lace.config [lace.config.staging] (from env var)
LACE_ENV=staging + LaceExecutor("lace", env="prod") lace/lace.config [lace.config.prod] (kwarg wins)

The config= kwarg overrides where the file is loaded from. The env= kwarg (or LACE_ENV) selects which section inside that file is overlaid. They are independent — setting one does not affect the other.

Return value

Both probe.run() and executor.run() return a dict matching the ProbeResult wire format (spec §9):

{
    "outcome": "success",        # "success" | "failure" | "timeout"
    "startedAt": "2026-04-20T10:00:00.000Z",
    "endedAt":   "2026-04-20T10:00:01.234Z",
    "elapsedMs": 1234,
    "runVars":   {},             # run-scoped variables from .store()
    "calls":     [...],          # per-call result records
    "actions":   {},             # write-back variables, notifications, etc.
}

Low-level API

The stateless run_script() function is available for callers that need full control over parsing, validation, and config:

from lacelang_validator.parser import parse
from lacelang_executor.executor import run_script
from lacelang_executor.config import load_config

ast = parse(open("script.lace").read())
config = load_config(explicit_path="lace.config")

result = run_script(ast, script_vars={"key": "val"}, config=config)

User-Agent

Per lace-spec.md §3.6, this executor sets a default User-Agent on outgoing requests:

User-Agent: lace-probe/<version> (lacelang-python)

Precedence (highest first): per-request headers: { "User-Agent": ... } → lace.config [executor].user_agent → the default above.

Responsible use

This software is designed for monitoring endpoints you own or have explicit authorization to probe. You are solely responsible for ensuring your use complies with all applicable laws, terms of service, and acceptable use policies. See NOTICE for the full statement.

License

Apache License 2.0

Release files for lacelang-executor 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for lacelang-executor 0.2.1
File Size Uploaded
lacelang_executor-0.2.1.tar.gz 73.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for lacelang-executor 0.2.1
File Interpreter ABI Platform
lacelang_executor-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 150.4 kB

Release files / lacelang_executor-0.2.1.tar.gz

Download URL lacelang_executor-0.2.1.tar.gz
Size 73.9 kB
Tags Source
SHA-256 checksum
How to use checksums
411e6c72c057295ccf0a01189e7e98d253c179b85c02011f81911f0febe1157c
BLAKE2b-256 checksum
How to use checksums
0becd3fe88b6e7d10b362f0a6cd2670e58fe074bc1e5a6305975124a41afbf05
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release files / lacelang_executor-0.2.1-py3-none-any.whl

Download URL lacelang_executor-0.2.1-py3-none-any.whl
Size 76.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5d1666bdfa7cd65b34fb2794bf319106268b70b721ccb491c7a3f4a5d4ecd97b
BLAKE2b-256 checksum
How to use checksums
951b362b61cc6f31cf4f9ba436b309be845378713cf5e0acddaf475b8154c520
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 release files

0.2.0

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release 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