Skip to content

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:

conda install -c conda-forge amorphouspy-api

Alternatively, you can install via pip:

pip install amorphouspy[api]

Starting the server

pixi run serve

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: pendingrunningcompleted/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 /mcp via fastapi-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=slurm
  • LAMMPS_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 name
  • SLURM_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 1648 (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>

Managing the service

# Check status
systemctl status amorphouspy-api

# Restart
systemctl restart amorphouspy-api

# View logs (follow mode)
journalctl -u amorphouspy-api -f