API
This document describes how to use the Folding@home Application Programming Interface to create and control Folding@home projects. This API is also known as the Adaptive Sampling API because it can be used to implement adaptive sampling on Folding@home.
Definitions
- AS:
Folding@home Assignment Server
- WS:
Folding@home Work Server
- JSON:
- HTTP:
- CA:
Usage
This section describes how to use the API to create and run a project on F@H. Examples will use Python 3 and the “requests” module. It will also use the OpenSSL command line tools. On Debian Linux, you can install these with:
sudo apt-get install -y python3-requests openssl
Authentication
In order to access the API you will need an RSA certificate signed by a Folding@home AS. This section describes how to acquire a certificate.
Create a Private Key
Next create an RSA private key with this command:
openssl genrsa -out private.pem 4096
Your private key is now in private.pem
. Never share its contents.
Create the CSR
Now, create a Certificate Signing Request from key. If your email address was joe@example.com, you would create the CSR like this:
openssl req -out csr.pem -key private.pem -new -subj "/CN=joe@example.com/"
The CSR is now in csr.pem
.
Acquire the Certificate
Next, login to the AS and click on the Certificate
tab. Paste the contents
of csr.pem
in to the form and click Submit CSR
. Your browser should
automatically download the signed certificate.
You can check your certificate like this:
openssl x509 -text -noout -in fah-cert-chain-joe@example.com.pem
Connecting to the API
In order to connect to the API on either the AS or WS you will need a signed
certificate and private key as described in the Authentication section.
We will assume the certificate is in the file certificate.pem
and the
private key in private.pem
.
The certificate and key is read automatically by the Python “requests” module.
We will use the cert
variable in the following examples. Create this
variable like so:
cert = ('certificate.pem', 'private.pem')
You can then access the API like this:
import requests
import json
url = 'https://assign1.foldingathome.org/api/ws'
r = requests.get(url, cert = cert)
if r.status_code != 200:
raise Exception('Request failed with %d: %s' % (r.status_code, r.text))
print(json.dumps(r.json()))
The last line prints the resulting data to the screen.
See Error Handling for more information on possible HTTP status codes.
The remaining examples will omit error checking and assume the following Python imports:
import requests
import json
import socket
The examples will also assume the AS is at assign1.foldingathome.org
, the
WS is at ws.foldingathome.org
and the project number is 1234
.
Creating Projects
A project can be created or updated on a WS with an HTTP PUT
to
/api/projects/:project
where :project
is the project ID. Here’s an
example:
project_data = {
'core_id': 0x22,
'gens': 25000,
'atoms': 288449,
'credit': 56,
'timeout': 3600,
'deadline': 21600
}
url = 'https://ws.foldingathome.org/api/projects/1234'
requests.put(url, json = project_data, cert = cert)
When creating new projects, the contact
field will automatically be filled
using the email address associated with your certificate.
Note that when creating a project a timeout
or deadline
less than 300
is interpreted as the number of days but is always report in seconds. This
is for backwards compatibility.
Project Status
A project’s status can be queried with an HTTP GET
, like this:
url = 'https://ws.foldingathome.org/api/projects/1234'
r = requests.get(url, cert = cert)
print(json.dumps(r.json()))
Deleting Projects
Delete a project with the following:
url = 'https://ws.foldingathome.org/api/projects/1234'
requests.delete(url, cert = cert)
This will delete the project and all its associated data. It cannot be undone but the data can be recovered for up to 90 days with manual intervection.
Managing Files
Files can be queried, uploaded, downloaded and deleted from several file endpoints on the WS. These are:
- Project Files:
/api/projects/:project/files
- Job Files:
/api/projects/:project/runs/:run/clones/:clone/files
- Result Files:
/api/projects/:project/runs/:run/clones/:clone/gens/:gen/files
Project files are used to start jobs. Job files represent the current state of a trajectory. Result files are the trajectory data return by Folding@home clients.
Listing Files
You can list the files at one of the file endpoints with an HTTP GET
.
url = 'https://ws.foldingathome.org/api/projects/1234/files'
r = requests.get(url, cert = cert)
print(json.dumps(r.json()))
This will return a list of FileData which contain file path, size and modification times.
Uploading Files
Upload a file with an HTTP PUT
by appending the file name to one of the
the file endpoints.
filename = 'system.xml.bz2'
url = 'https://ws.foldingathome.org/api/projects/1234/files/' + filename
with open(filename, 'rb') as f:
requests.put(url, data = f, cert = cert)
Downloading Files
A file can be downloaded like this.
filename = 'system.xml.bz2'
url = 'https://ws.foldingathome.org/api/projects/1234/files/' + filename
r = requests.get(url, cert = cert, stream = True)
with open(filename, 'wb') as f:
for chunk in r.iter_content(chunk_size = 8192):
f.write(chunk)
r.close()
Deleting Files
Delete a file with an HTTP DELETE
.
filename = 'system.xml.bz2'
url = 'https://ws.foldingathome.org/api/projects/1234/files/' + filename
requests.delete(url, cert = cert)
The file will actually be moved to the WS trash bin but it can not be recovered through this API. Contact a server admin to recover lost data.
Starting Jobs
Jobs are not automatically started when a project is created. This provides a chance to uploaded the necessary files first. You can then start jobs either one at a time or start all of the jobs in a run. For example, start all the clones in run 0:
url = 'https://ws.foldingathome.org/api/projects/1234/runs/0/create'
requests.put(url, cert = cert)
Configuring the AS
In order for a project to get assignments, both the WS and project must be configured on the AS.
Configuring a WS
To set a weight of one and no constraints for a WS on the AS run the following:
ws_config = {
'weight': 1,
'constraints': ''
}
ip = socket.gethostbyname('ws.foldingathome.org') # Get the WS IPv4 address
url = 'https://assign1.foldingathome.org/api/ws/' + ip
requests.put(url, json = ws_config, cert = cert)
Configuring a Project
Similarly you can configure a project with a weight and constraints.
project_config = {
'weight': 1,
'constraints': 'ProjectKey=1234567890'
}
ip = socket.gethostbyname('ws.foldingathome.org') # Get the WS IPv4 address
url = 'https://assign1.foldingathome.org/api/ws/%s/projects/%d' % (ip, 1234)
requests.put(url, json = project_config, cert = cert)
A project key should be used when testing a new project. This ensures that it only gets assigned to clients with the same project key.
Monitoring Progress
Once the project has been created, its files uploaded and the WS and project have been configured on the AS, the project should be able to get assignments. Initially, you should use a project key and will need to run your own client using that project key to get job assignments.
You can monitor the progress of your project pragmatically by calling the Project Jobs endpoint.
import json
import time
import requests
ws = 'ws.foldingathome.org'
project = 1234
cert = ('certificate.pem', 'private.pem')
url = 'https://%s/api/projects/%d/jobs' % (ws, project)
req = {}
while True:
r = requests.get(url, data = req, cert = cert)
if r.status_code != 200:
raise Exception('Request failed with %d: %s' % (r.status_code, r.text))
data = r.json()
req['since'] = data['ts']
for job in data['jobs']:
# Do something with the job
print('Job P:%(project)d R:%(run)d C:%(clone)d G:%(gen)d %(state)s' % job)
time.sleep(60)
Controlling Jobs
Other actions can be performed on jobs by appending a JobAction to a job endpoint. For example, you could stop clone 0 of run 0 like this:
url = 'https://ws.foldingathome.org/api/projects/1234/runs/0/clones/0/stop'
requests.put(url, cert = cert)
These actions can be performed either on a specific job or on all the jobs in a run. See JobAction for more info.
Protocol
This section describes the API protocol in more detail.
API clients communicate with the WS and AS via HTTP over TLS, also known as
https. Requests are made to endpoints on the WS and AS at various paths
prefixed with /api/
. Data will is set to the servers either as HTTP
request parameters or JSON data. The WS will respond with JSON data and HTTP
status codes.
Request Methods
The API supports GET
, PUT
, POST
and DELETE
HTTP request methods.
Content-Type HTTP Header
HTTP messages utilize the Content-Type
header which will normally be
application/json
except when uploading or downloading file data in which
case should be application/octet-stream
.
Content-Length HTTP Header
HTTP messages must contain a Content-Length
header.
Error Handling
API errors are signaled via HTTP status codes. The following codes are used:
- 400 Bad Request
If any URL parameter or JSON data is formatted incorrectly or of the wrong type.
- 401 Unauthorized
If no client certificate was presented or the client certificate does not authorize the requested operation.
- 404 Not Found
If the requested entity does not exist on the server or if the entity exists but the HTTP request method is not supported.
- 411 Length Required
When sending files or JSON data, if the
Content-Length
header is missing.- 413 Request Entity Too Large
When sending JSON data if the
Content-Length
header is greater than 5MiB.When uploading file data if the
Content-Length
header is greater than 1GiB.
Security
Folding@home uses x509 certificates
to authenticate it’s servers and clients. Each certificate is signed by the
F@H Certificate Authority (CA) or one of the AS which hold intermediate
certificates signed by the F@H CA. The certificates contain the
fahKeyUsage
extension which defines what the certificate authorizes the
holder to do on the Folding@home network. The fahKeyUsage
extension has
OID 1.2.3.4.70.64.72
.
Clients of the Adaptive Sampling API are issued F@H certificates with
fahKeyUsage
set to manager:<ip>,...,<ip>
where <ip>
is an IP
address or IP address range in
CIDR format.
Each WS verifies that the presented certificate’s fahKeyUsage
includes
it’s IP address before granting access. The AS only allows changes to
projects and WS which the client is authorized for.
Certificates contain an expiration date and Certificate Revocation Lists (CRL) are used to revoke certificates before the expiration date. CRLs are stored on the AS and automatically disseminated to the WS.
API certificates are presented by clients to the WS and AS via the TLS protocol.
Certificate Acquisition
The authorization configuration is managed on the AS by users in the “admin” group. To acquire an API certificate a user is first authorized by an admin to login to the AS using a Google email address. The admin will set which WS the user is allowed to modify. A user can modify any projects on the WS on which they are authorized.
To acquire a certificate the user must login to one of the AS and submit a
Certificate Signing Request (CSR). The CSR can be generated from an RSA key
pair using readily available tools such as openssl or Python library. The AS
will respond with a signed certificate with the correct fahKeyUsage
. The
certificate can then be used to access both the AS and WS.
Certificate Renewal
A certificate will need to be renewed before it expires or if changes are made to the user’s authorization. For example, an admin might grant access to a new WS. The certificate can be renewed automatically by submitting a CSR via the API if the current certificate has not yet expired or been revoked. This can be handled transparently via the API Python library so the user will not need to log into the AS to update the API certificate manually.
Reference
Relevant API endpoints on the WS and AS are described in this section. The
endpoint definitions list the HTTP method (GET
, PUT
or DELETE
)
followed by the endpoint path. Sections of the path which begin with a colon
represent parameters that you should replace with a value. For example, an
actual example of the endpoint /api/projects/:project
is
/api/projects/1234
.
WS Endpoints
Projects
- GET /api/projects
Get all projects on the WS.
- Response:
{uint32: ProjectData, …}
Project
- GET /api/projects/:project
Get a specific project.
- Parameters:
project (uint32) – Project ID.
- Response:
- PUT /api/projects/:project
Create a new project or update an existing project’s configuration.
- Parameters:
project (uint32) – Project ID.
- Send:
- DELETE /api/projects/:project
Delete a project.
- Parameters:
project (uint32) – Project ID.
Project Files
Project File
- GET /api/projects/:project/files/:path
Download a project file.
- Parameters:
project (uint32) – Project ID.
path (string) – File path relative to the project directory.
- Response:
raw file contents
- PUT /api/projects/:project/files/:path
Upload a project file.
- Parameters:
project (uint32) – Project ID.
path (string) – File path relative to the project directory.
- Send:
raw file contents
- DELETE /api/projects/:project/files/:path
Delete a project file.
- Parameters:
project (uint32) – Project ID.
path (string) – File path relative to the project directory.
Project Jobs
- GET /api/projects/:project/jobs
Get a list of the active jobs for the project. Optionally restrict the list to only those jobs which have been updated since the last time. Only jobs which are active will be returned. Some new jobs that have not yet been created may not have records in the work server.
- Parameters:
project (uint32) – Project ID.
since (time) – (optional) Return jobs which have changed after this time.
- Response:
Project Run Action
Project Clone
Project Clone Action
Project Clone Files
Project Clone File
- GET /api/projects/:project/runs/:run/clones/:clone/files/:path
Download a file.
- Parameters:
project (uint32) – Project ID.
run (uint16) – Run ID.
clone (uint16) – Clone ID.
path (string) – File path relative to the job directory.
- Response:
raw file contents
- PUT /api/projects/:project/runs/:run/clones/:clone/files/:path
Upload a new or replace an existing file.
- Parameters:
project (uint32) – Project ID.
run (uint16) – Run ID.
clone (uint16) – Clone ID.
path (string) – File path relative to the job directory.
- Send:
raw file contents
- DELETE /api/projects/:project/runs/:run/clones/:clone/files/:path
Delete an existing file.
- Parameters:
project (uint32) – Project ID.
run (uint16) – Run ID.
clone (uint16) – Clone ID.
path (string) – File path relative to the job directory.
Project Gen Files
Project Gen File
- GET /api/projects/:project/runs/:run/clones/:clone/gens/:gen/files/:path
Download a file.
- Parameters:
project (uint32) – Project ID.
run (uint16) – Run ID.
clone (uint16) – Clone ID.
gen (uint16) – Job generation.
path (string) – File path relative to the results directory.
- Response:
raw file contents
- DELETE /api/projects/:project/runs/:run/clones/:clone/gens/:gen/files/:path
Delete an existing file.
- Parameters:
project (uint32) – Project ID.
run (uint16) – Run ID.
clone (uint16) – Clone ID.
gen (uint16) – Job generation.
path (string) – File path relative to the results directory.
AS Endpoints
WS Config
- GET /api/ws/:ws
Get the current WS configuration.
- Parameters:
ws (ip) – The WS IP address.
- Response:
- PUT /api/ws/:ws
Set the WS configuration. Caller must be authorized to modify this WS.
- Parameters:
ws (ip) – The WS IP address.
- Send:
Project Config
- GET /api/ws/:ws/projects/:project
Get the current project configuration.
- Parameters:
ws (ip) – The WS IP address.
project (uint32) – Project ID.
- Response:
- PUT /api/ws/:ws/projects/:project
Set the project configuration. Caller must be authorized to modify this WS.
- Parameters:
ws (ip) – The WS IP address.
project (uint32) – Project ID.
- Send:
CSR Submission
- POST /api/auth/csr
Submit a CSR in PEM format and receive a signed x509 certificate chain also in PEM. The chain will contain not only the certificate but the CA certificate and any intermediate certificates.
The CN or Common Name of the CSR must be the Google mail of the requestor. Access will be granted based on the authorization of this user.
To use this API you must already have a valid certificate. So this is only used for renewing certificates before their expiration. For this reason, the CN of the CSR and requesting certificate must be the same.
- Send:
{‘csr’: string}
- Response:
string
Data Types
Simple Types
Type |
Description |
---|---|
uint8 |
Unsigned 8-bit integer |
uint16 |
Unsigned 16-bit integer |
uint32 |
Unsigned 32-bit integer |
uint64 |
Unsigned 64-bit integer |
float |
A JSON number. |
string |
A JSON string. |
time |
A time in ISO8601 format. |
addr-spec defined in RFC 5322. |
|
ip |
IPv4 address in <uint8>.<uint8>.<uint8>.<uint8> format. |
Enumerations
JobAction
Name |
Description |
---|---|
create |
Create jobs if they don’t already exist. |
fail |
Mark the job as failed and stop further execution. |
reset |
Clear any errors and continue job execution. |
stop |
Stop further execution of the job. |
restart |
Restart job execution from the beginning. |
CompressionType
Name |
Description |
---|---|
none |
No compression. |
bzip2 |
Bzip2 compression. |
zlib |
Zlib compression. |
gzip |
GZip compression |
lz4 |
LZ4 compression. |
JobState
Name |
Description |
---|---|
new |
Job is not yet created but is ready to run. |
ready |
Job is ready to run. |
assigned |
One or more WUs are outstanding. |
finished |
The maximum number of gens has been completed. |
failed |
Consecutive failed or faulty WUs exceeded the maximum. |
stopped |
The job was stopped. |
held |
The job cannot be assigned. |
processing |
An operation on the job is in progress. |
Compound Types
ProjectData
ProjectData contains a projects configuration and is based on the format currently used by the Folding@home WS.
Field |
Type |
Description |
---|---|---|
core_id |
uint8 |
The core ID. E.g. 0xa8. |
contact |
The person responsible for the project. |
|
runs |
uint16 |
The number of runs. |
clones |
uint16 |
The number of clones. |
gens |
uint32 |
Maximum number of generations per job. |
atoms |
uint64 |
Approximate number of atoms in the simulations. |
credit |
uint64 |
The base credit awarded for the WU. |
timeout |
uint64 |
Seconds before the WU can be reassigned. |
deadline |
uint64 |
Seconds in which the WU can be returned for credit. |
compression |
Enable WU compression. |
The format of variable references and the variables available to each argument are described in detail in the WS online and command line help.
Additional data is read-only and will be returned when querying a project.
JobData
Field |
Type |
Description |
---|---|---|
project |
uint32 |
The project ID. |
run |
uint16 |
The job run. |
clone |
uint16 |
The job clone. |
gen |
uint16 |
The latest job generation. |
state |
The current job state. |
|
last |
time |
Last time the job state changed. |
JobResults
Field |
Type |
Description |
---|---|---|
jobs |
List of jobs. |
|
ts |
time |
Timestamp for these results |
FileData
Field |
Type |
Description |
---|---|---|
path |
string |
File path relative to the project, job or gen directory. |
size |
uint64 |
The file size in bytes. |
modified |
time |
The file modification time. |
ASWorkServerData
Field |
Type |
Description |
---|---|---|
max-assign-rate |
float |
The maximum assigns/sec allowed for this WS. |
weight |
float |
The WS weight. |
constraints |
string |
WS constraints as defined in the AS online help. |
ASProjectData
Field |
Type |
Description |
---|---|---|
ws |
ip |
IP Address of the WS. |
weight |
float |
The project weight. |
constraints |
string |
Project constraints as defined in the AS online help. |