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:12If 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"