Aggrescan3D webserver may be operated throught RESTful services, using following URIs:
{{url_for('rest_submit_job', pdbcode='2pcy', _external=True)}} submit new job (2pcy pdb entry){{url_for('rest_submit_userfile', _external=True)}} submit user pdb file{{url_for('rest_submit_job', pdbcode='2pcy', chain='A', _external=True)}} submit new job (chain A of 2pcy pdb)
name project nameemail email (info about job will be send to this email)distance ("10" or "5") distance of aggregationdynamic ("True" or "False") use dynamic modehide ("True" or "False") if True - do not show job on the queue pagemutate - list of residues to mutate before A3D analysis. This option will be explained below.{{url_for('get_jobstatus', jobid='somejobidentifier', _external=True)}} check job status{{url_for('get_out_structure', jobid='somejobidentifier', _external=True)}} get output structure with A3D values in the temperature factor column{{url_for('get_job_info', jobid='somejobidentifier', _external=True)}} get full information about submitted job (aggrescan3D values for individual residues, average A3D score, etc.){{url_for('a3d_avg', jobid='somejobidentifier', _external=True)}} Get average A3D score{{url_for('a3d_min', jobid='somejobidentifier', _external=True)}} Get minimal A3D score{{url_for('a3d_max', jobid='somejobidentifier', _external=True)}} Get maximal A3D score{{url_for('a3d_sum', jobid='somejobidentifier', _external=True)}} Get total (sum) A3D score{{url_for('a3d_gt0', jobid='somejobidentifier', _external=True)}} Get residues with A3D score > 0.0000Submit job for 2PCY protein, using cURL, with default parameters (i.e. distance of aggregation = 10Å, without mutation of residues, without distance mode, without hiding project on the queue page, without email address and with default project name): curl -i {{url_for('rest_submit_job', pdbcode='2pcy', _external=True)}}.
Submit chain B of 1hui: curl -i {{url_for('rest_submit_job', pdbcode='1hui', chain='B', _external=True)}}
User should get output like:
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 57
Server: Werkzeug/0.9.6 Python/2.7.8
Date: Wed, 12 Nov 2014 13:52:56 GMT
{
"jobid": "a0ae2bb71feeaf0",
"status": "submitted"
}
where jobid is job identifier assigned to the just submitted job. Otherwise (for example if pdbcode doesn't exists or input data doesn't fullfill requirements), user should get output similar to:
HTTP/1.0 404 NOT FOUND Content-Type: text/html; charset=utf-8 Content-Length: 5521 Server: Werkzeug/0.9.6 Python/2.7.8 Date: Wed, 12 Nov 2014 13:56:48 GMT <!doctype html> <html lang='en'> [...]
To override default parameters, user may post additional options, i.e.: curl -i -X POST -d '{"email": "john@doe.com", "dynamic": "True", "name": "some project name"}' -H 'Content-Type: application/json' {{url_for('rest_submit_job', pdbcode='2pcy', _external=True)}}. Specified parameters will override default parameters, not specified ones would left unchanged (in this example job will be submitted with distance of aggregation = 10Å, with dynamic mode, and with specified email and project name).
The simplest Python script for submitting new job may looks like:
#!/usr/bin/env python
import requests
req = requests.post('{{url_for('rest_submit_job', pdbcode='2pcy', _external=True)}}')
print(req.status_code)
print(req.json())
Submitting with parameters (mutation) from Python script:
#!/usr/bin/env python
import requests
import json
# define which residues to mutate. If specified residues not exists within pdb
# job will not be submitted (got 404 error)
mutation_table = [{'idx': "1", 'chain': 'A', 'oldres': 'I', 'newres': 'W'},
{'idx': "2", 'chain': 'A', 'oldres': 'D', 'newres': 'W'}]
# specify additional options
options = {'dynamic': True,
'distance': 5,
'email': 'john@doe.gov',
'name': 'some project name',
'hide': True,
'mutate': mutation_table}
req = requests.post('{{url_for('rest_submit_job', pdbcode='2pcy', _external=True)}}',
data=json.dumps(options),
headers={'content-type': 'application/json'})
print(req.status_code) # get HTTP code. If 200 = OK. Otherwise = problems
print(req.json()) # get query returned data
The simplest Python script for submitting new job may looks like:
#!/usr/bin/env python
import requests
req = requests.post('{{url_for('rest_submit_userfile', _external=True)}}', files={'inputfile': open('some_file.pdb', 'rb')})
print(req.status_code)
Submitting user file with parameters (mutation) from Python script:
#!/usr/bin/env python
import requests
import json
# define which residues to mutate. If specified residues not exists within pdb
# job will not be submitted (got 404 error)
mutation_table = [{'idx': "1", 'chain': 'A', 'oldres': 'I', 'newres': 'W'},
{'idx': "2", 'chain': 'A', 'oldres': 'D', 'newres': 'W'}]
# specify additional options
options = {'dynamic': True,
'distance': 5,
'email': 'john@doe.gov',
'name': 'some project name',
'hide': True,
'mutate': mutation_table}
req = requests.post('{{url_for('rest_submit_userfile', _external=True)}}', data=options, files={'inputfile': open('some_file.pdb', 'rb')})
print(req.status_code) # get HTTP code. If 200 = OK. Otherwise = problems
By running curl -i {{url_for('get_jobstatus', jobid='somejobidentifier', _external=True)}} user should get:
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 19
Server: Werkzeug/0.9.6 Python/2.7.8
Date: Wed, 12 Nov 2014 14:27:49 GMT
{
"done": false
}
if job is running/pending, or
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 18
Server: Werkzeug/0.9.6 Python/2.7.8
Date: Wed, 12 Nov 2014 14:28:33 GMT
{
"done": true
}
if job got done/error status.
To get protein structure with A3D values in the temperature factor column and save it to out file:
curl -o out {{url_for('get_out_structure', jobid='somejobidentifier', _external=True)}}
To get full information about submitted job, user may create Python script like:
#!/usr/bin/env python
import requests
req = requests.get('{{url_for('get_job_info', jobid='somejobidentifier', _external=True)}}')
print(req.status_code)
data = req.json()
for k in data.keys():
print("key: %s: %s" % (k, data[k]))
getting output similar to:
200
key: chain_sequence: A: GSFTMPGLVDSNPAPPESQEKKPLKPCCACPETKKARDACIIEKGEEHCGHLIEAHKECMRALGFKI
key: status: done
key: mutated_residues: None
key: dynamic_mode: 0
key: mutate_mode: 0
key: last_status_change_date: 2014-11-06 12:01:04
key: project_name: b530f472611c285
key: aggregation_distance: 10
key: aggrescan3Dscore: {u'max_value': 1.664, u'total_value': -95.41120000000001, u'min_value': -4.1893, u'average_value': -1.424, u'table': [{u'res_name': u'G', u'res_idx': u'1', u'chain': u'A', u'a3d': u'-0.3367'}, ... ]}
key: submission_date: 2014-11-06 11:53:12
If user would like to get Aggrescan3D score table, she may use script like:
#!/usr/bin/env python
import requests
req = requests.get('{{url_for('get_job_info', jobid='somejobidentifier', _external=True)}}')
data = req.json()
a3d = data['aggrescan3Dscore']
print("AVG A3D: %s" % (a3d['average_value'])) # data is a dictionary
print("MIN A3D: %s" % (a3d['min_value']))
for row in a3d['table'][:6]:
print(row['res_idx'], row['a3d'])
to get output like:
AVG A3D: -1.424 MIN A3D: -4.1893 (u'1', u'-0.3367') (u'2', u'0.3541') (u'3', u'1.6640') (u'4', u'0.8468') (u'5', u'1.2976') (u'6', u'0.5633')
Combine two RESTful URI to wait until job is done:
#!/usr/bin/env python
import requests
import time
server = '{{url_for('index_page', _external=True)}}RESTful/job/'
jobid = "caaaffa24b4bcad"
v = False
while not v:
req = requests.get(server+jobid+'/isdone/')
v = req.json()['done']
time.sleep(60) # 1 min intervals
req = requests.get(server+jobid)
data = req.json()
a3d = data['aggrescan3Dscore']
print("AVG A3D: %s" % (a3d['average_value']))
Above script will print average A3D score as soon as job get 'done' status.
Some fun with RESTful and Bash scripting. Script below should say something as soon as job is completed:
#!/usr/bin/env bash
v="false"
while [ "$v" == "false" ]
do
v=`curl -s {{url_for('get_jobstatus', jobid='somejobidentifier', _external=True)}} | grep 'done' |grep -o 'false'`
sleep 6
done
mplayer -user-agent Mozilla "http://translate.google.com/translate_tts?q=Job+completed.Aggrescan+3D+is+wonderful&tl=en"