Use the Web API¶
Installation¶
When using the pixi environment, the API dependencies will already be installed.
When using the pip/conda approach, install the API server and its dependencies via conda-forge:
Alternatively, you can install via pip:
Starting the server¶
The API will be available at:
- REST API: http://localhost:8000
- API Docs: http://localhost:8000/docs
- MCP SSE: http://localhost:8000/mcp
Key features¶
- Each simulation request is hashed based on composition, potential, and simulation parameters.
- Automatic cache lookups prevent duplicate simulations.
-
Results persist across server restarts.
-
All job metadata stored in SQLite database (
jobs.db). - Tracks job states:
pending→running→completed/failed/cancelled. - Supports local execution (
TestClusterExecutor) or SLURM cluster (SlurmClusterExecutor/FluxClusterExecutor). -
Built-in job caching at the executor level: Re-submitting same job returns cached result or running future.
-
Exposes simulation capabilities as MCP tools at
/mcpviafastapi-mcp. - Compatible with Claude, VS Code, and other MCP clients.
Using the API¶
The API follows a two-layer design:
- Jobs layer (
/jobs): Simulation-centric. "Run this computation." - Materials layer (
/glasses): Read-only, property-centric. "What do we know about this glass?"
Both layers share the same underlying data store. The materials layer is a view over completed jobs.
Full endpoint documentation is available via the auto-generated OpenAPI docs at /docs.
Authentication¶
The API supports optional bearer-token authentication via the API_TOKEN environment variable.
Without API_TOKEN (default): The API is open — no credentials required. A warning is logged at startup.
With API_TOKEN set: All requests (except docs endpoints) must include the token:
# Set the token when starting the server
API_TOKEN=my-secret-token pixi run serve
# Include it in requests
curl -H "Authorization: Bearer my-secret-token" http://localhost:8000/jobs
The docs UI (/docs, /redoc) and OpenAPI schema (/openapi.json) remain accessible without a token.
Configuring the executor backend¶
The API uses executorlib to run simulation jobs.
The backend is selected via the EXECUTOR_TYPE environment variable.
EXECUTOR_TYPE |
Executor | Description |
|---|---|---|
single |
SingleNodeExecutor |
Runs jobs locally (default for development) |
slurm |
SlurmClusterExecutor |
Submits jobs to a SLURM scheduler |
flux |
FluxClusterExecutor |
Submits jobs to a Flux scheduler |
Local execution¶
No extra configuration needed — this is the default.
SLURM cluster¶
Set the following environment variables before running pixi run serve
(see the Web API Reference for the full list):
EXECUTOR_TYPE=slurmLAMMPS_MAX_CORES— Maximum MPI cores per LAMMPS job (default:4). The API scales down from this when a job is too small to use it efficiently (each potential defines a minimum atoms-per-core).SLURM_PARTITION— SLURM partition nameSLURM_RUN_TIME_MAX— Max run time per job in seconds (optional)SLURM_MEMORY_MAX— Max memory per job in GB (optional)
For most setups, EXECUTOR_TYPE, LAMMPS_MAX_CORES, and SLURM_PARTITION are sufficient.
Choosing LAMMPS_MAX_CORES
The default of 4 is fine for demos but too low for production. Set it to:
- The number of cores on a node if your cluster has a slow interconnect, so a job stays within a single node and avoids cross-node MPI traffic.
- The per-job core limit of your SLURM queue otherwise, so large jobs can span multiple nodes.
Typical values are 16–48 (a common node size). The API never uses more
cores than this, and scales down for small systems to keep each potential's
minimum atoms-per-core, so setting a high maximum is safe.
To override auto-selection for a single job, set simulation.cores in the
POST /jobs body. The resolved value (explicit or auto-selected) is recorded
in the job's settings (GET /jobs/{id}/settings).
Custom submission template¶
For advanced control (e.g. account, QOS, custom flags), place a Jinja2
submission template
at <AMORPHOUSPY_PROJECTS>/submission_template.sh (defaults to amorphouspy_api/projects/submission_template.sh).
If present, it is automatically picked up:
#!/bin/bash
#SBATCH --output=time.out
#SBATCH --job-name={{job_name}}
#SBATCH --chdir={{working_directory}}
#SBATCH --get-user-env=L
#SBATCH --partition={{partition}}
#SBATCH --account=myproject
{%- if run_time_max %}
#SBATCH --time={{ [1, run_time_max // 60]|max }}
{%- endif %}
{%- if dependency %}
#SBATCH --dependency=afterok:{{ dependency | join(',') }}
{%- endif %}
{%- if memory_max %}
#SBATCH --mem={{memory_max}}G
{%- endif %}
#SBATCH --cpus-per-task={{cores}}
{{command}}
Example:
EXECUTOR_TYPE=slurm \
SLURM_PARTITION=batch \
LAMMPS_MAX_CORES=8 \
SLURM_RUN_TIME_MAX=7200 \
pixi run serve
Systemd service (production)¶
The repository includes systemd unit files in docs/system-service/ for running the API as a persistent service that starts on boot and auto-restarts on failure.
Installation¶
As root (or via sudo):
# Copy the unit files
cp docs/system-service/amorphouspy-api.service /etc/systemd/system/
cp docs/system-service/amorphouspy-api.path /etc/systemd/system/
# Reload, enable, and start
systemctl daemon-reload
systemctl enable --now amorphouspy-api.service
systemctl enable --now amorphouspy-api.path
The .path unit watches the source directory for changes and automatically restarts the service when code is updated.
Configuration¶
Edit the [Service] section of the unit file to set environment variables
(see the Web API Reference for the full list):
Environment=EXECUTOR_TYPE=slurm
Environment=SLURM_PARTITION=main_queue
Environment=LAMMPS_MAX_CORES=16
Environment=AMORPHOUSPY_PROJECTS=/path/to/data
Environment=AMORPHOUSPY_VERSION_PROJECTS=0
Environment=API_TOKEN=<your-secret-token>