Getting Started¶
Installation¶
The PyPI distribution name is molcrafts-molq; the import name is molq.
For local development:
The two-axis model in 30 seconds¶
Two classes, two responsibilities:
| Class | Owns | Knows about |
|---|---|---|
Cluster |
scheduler kind, transport, scheduler options | where jobs run |
Submitor |
JobStore, reconciler, monitor, defaults | how jobs are tracked |
Read Concepts for the full picture. The rest of this page is a hands-on walk-through.
First Cluster + Submitor¶
Start with the local scheduler so you can validate your workflow without a cluster:
The first argument to Cluster is a name — it scopes persisted records and
appears in CLI listings. The second argument is the scheduler kind. For a
remote SLURM cluster you'd write:
Passing host= switches the Transport from LocalTransport to
SshTransport. molq shells out to your system ssh/rsync/scp, so it
inherits ~/.ssh/config, agent forwarding, ProxyJump, ControlMaster, and
Kerberos for free.
Submit a Job¶
Every job uses exactly one command form: argv, command, or script.
handle = submitor.submit_job(argv=["echo", "hello from molq"])
print(handle.job_id)
print(handle.status()) # cached state, no scheduler I/O
submit_job returns a JobHandle. submitor.list_jobs() returns
persisted JobRecords for this Cluster.
Wait for Completion¶
JobHandle.wait() blocks until the job reaches a terminal state and
returns an immutable JobRecord.
Add Typed Resources¶
import molq as mq
handle = submitor.submit_job(
argv=["python", "experiment.py"],
resources=mq.JobResources(
cpu_count=4,
memory=mq.Memory.gb(8),
time_limit=mq.Duration.hours(2),
),
scheduling=mq.JobScheduling(partition="gpu"),
)
Resource values are typed objects, not raw scheduler strings:
Note: the field is named
partition, notqueue. Old SQLite rows and TOML profiles usingqueuestill load (one-release deprecation).
Use a Script¶
Inline scripts are useful for multi-step workflows:
handle = submitor.submit_job(
script=mq.Script.inline("""
cd /workspace
python preprocess.py
python train.py
""")
)
You can also submit an existing file:
Snapshot the cluster's queue¶
cluster.get_queue() returns a parsed snapshot of the scheduler's current
queue (squeue --me for SLURM, qstat -u $USER for PBS, bjobs for LSF).
Local clusters return an empty list.
This is a live scheduler view — distinct from submitor.list_jobs(),
which is the persisted molq record.
Stage files into a remote project¶
For SSH clusters, Workspace and Project give you remote-directory
handles whose file ops go through the cluster's Transport:
ws = cluster.get_workspace("scratch", path="/scratch/$USER")
proj = ws.get_project("alphafold")
proj.ensure() # mkdir -p
proj.upload("./inputs", recursive=True) # rsync local → cluster
handle = proj.submit_job(submitor, argv=["python", "run.py"])
proj.download("results.csv", "./out.csv")
Project.submit_job is sugar that overrides JobExecution.cwd to the
project path before forwarding to submitor.submit_job(...).
Multi-cluster¶
Multi-cluster on one process is just multiple Submitors — they share the JobStore by default but each filters by their target's name:
sub_local = mq.Submitor(target=mq.Cluster("dev", "local"))
sub_hpc = mq.Submitor(target=mq.Cluster("hpc", "slurm", host="..."))
sub_local.list_jobs() # only "dev" records
sub_hpc.list_jobs() # only "hpc" records
CLI Basics¶
molq submit local echo "hello"
molq list local
molq status <job-id> local
molq watch <job-id> local
molq logs <job-id> local --stream stdout
The monitor command opens a full-screen dashboard across all clusters:
Next Steps¶
- Concepts — Cluster, Submitor, Scheduler, Transport, Workspace, Project
- Schedulers — scheduler-specific options
- Monitoring — lifecycle, reconciliation, dashboards
- API Reference — full exported surface
- CLI Reference — command syntax