fxtr init (see the
Quickstart). Launchers talk to it through the project client, which
stores entities and manages jobs, project arrays, and the cache.
Before you launch
- Commit first. A launch records the commit it runs and checks that the virtual environment
matches
uv.lock, so it refuses uncommitted changes. Passallow_staged=True(or--allow-stagedon the command line) to include staged changes. - Register your modules. Resuming a job,
fxtr run, and the viewer import the modules in[tool.fxtr] modules, not your launcher, so every step and workflow a job uses must be defined in one of them. - Use a scratch schema for trials. To keep trial jobs and cache entries apart from real
results, set
schemainfxtr.local.tomlto another name while experimenting, and set it back for real runs.
Launch from Python
The simplest launcher callslaunch_cli, which opens the client, submits the job, prints its
viewer link, waits, and reports the result:
launch.py
anchor=__file__ tells fxtr which project the launcher belongs to. max_concurrency caps how
many steps run at once. If the job doesn’t succeed, launch_cli exits with status 1.
For more control, such as choosing the root, loading datasets, or reading results, write an
async launcher with open_local_client and run_job:
launch.py
run_jobprints the viewer link before waiting, then the job’s status and result. It raisesJobNotFinishedErrorif the job doesn’t succeed.rootis the root workflow’s pathname, and so the start of every cache address in the job. See Caching and reruns.- Use
handle = await client.submit(...)when you need the job’s ID or want to control the waiting yourself;await wait_for_job(client, handle)provides the same reporting asrun_job. - In a notebook, call
await main()instead ofanyio.run(main).
Read results
run_job returns the root workflow’s result as an Array. Entity values in it are bare IDs, so
load them with their type:
on_result(storage, result)
callback to run_job or launch_cli; it replaces the default result printing and runs while
storage is open.
Launch from the command line
fxtr run launches a workflow by its registered name:
@NAME for a snapshot of a
project array. Anything richer needs a launcher script.
Resume a stopped job
A job stops when it can’t make further progress: a step raised, a step is held by the cache, or the job was cancelled. Resume it with its ID, which the launcher prints:[tool.fxtr] stale_after seconds (30 by default), then
takes the job over.
Inspect and cancel jobs
In Python,
handle = await client.job(job_id) attaches to an existing job without starting it.
Watch jobs in the viewer
Start the viewer from the project withuv run fxtr view, then open the link a launcher printed,
or pick a job in the viewer. Jobs appear as they run. See
Viewing results.