-
Notifications
You must be signed in to change notification settings - Fork 36
API Documentation Demo
This is a simple introduction to accessing the Specify API using
the curl
command line utility. For legibility, JSON output is piped
through a pretty-printer provided by the Python json library. It is
hoped that these examples illustrate how the API could be utilized by
any environment which supports HTTP and JSON.
These examples illustrate use with a demo server on localhost. Substitute an apropriate hostname as necessary.
To prevent unauthorized access to the API the browser session is tracked with a session cookie that must be associated with a logged in user.
A GET request to the login URL provides the available collections.
curl -i -c cookies.txt -b cookies.txt -X GET http://localhost:8000/context/login/
HTTP/1.0 200 OK
Date: Thu, 13 Apr 2017 21:54:55 GMT
Server: WSGIServer/0.1 Python/2.7.10
Cache-Control: no-cache, no-store, must-revalidate, max-age=0
Vary: Cookie
Expires: Thu, 13 Apr 2017 21:54:55 GMT
Content-Type: application/json
Last-Modified: Thu, 13 Apr 2017 21:54:55 GMT
Set-Cookie: csrftoken=8BetyLjqobHb; expires=Thu, 12-Apr-2018 21:54:55 GMT; Max-Age=31449600; Path=/
{"username": null, "password": null, "collections": {"KUFishtissue": 32768, "KUFishvoucher": 4}, "collection": null}
To log in as a user of the API for one of the listed collections issue a PUT request to the same URL. The csrftoken from the previous response must be passed as a header. The Referer header must be included when using HTTPS, but may be omitted when using HTTP.
curl -i -c cookies.txt -b cookies.txt -X PUT \
--data '{"username":"sp7demofish","password":"sp7demofish","collection":4}' \
-H "X-CSRFToken: 8BetyLjqobHb" \
-H "Referer: http://localhost:8000/" \
http://localhost:8000/context/login/
HTTP/1.0 204 No Content
Date: Thu, 13 Apr 2017 22:14:02 GMT
Server: WSGIServer/0.1 Python/2.7.10
Cache-Control: no-cache, no-store, must-revalidate, max-age=0
Vary: Cookie
Expires: Thu, 13 Apr 2017 22:14:02 GMT
Content-Type: text/html; charset=utf-8
Last-Modified: Thu, 13 Apr 2017 22:14:02 GMT
Set-Cookie: csrftoken=b9SUdhWCbMGG; expires=Thu, 12-Apr-2018 22:14:02 GMT; Max-Age=31449600; Path=/
Set-Cookie: sessionid=44kms3gdg6; httponly; Path=/
Set-Cookie: collection=4; expires=Fri, 13-Apr-2018 22:14:02 GMT; Max-Age=31536000; Path=/
Note that a new CSRF token is generated when logging in and should be used in subsequent data modifying requests.
The currently logged in user can be queried from the following resource:
curl -c cookies.txt -b cookies.txt -X GET http://localhost:8000/context/user.json \
| python -m json.tool
{
"accumminloggedin": null,
"agent": {
"abbreviation": "tcu",
"addresses": [],
"agentattachments": [],
"agentgeographies": [],
"agentspecialties": [],
"agenttype": 1,
"collcontentcontact": null,
"collectors": "/api/specify/agent/?agent=3",
"colltechcontact": null,
"createdbyagent": null,
"dateofbirth": null,
"dateofbirthprecision": 1,
"dateofdeath": null,
"dateofdeathprecision": 1,
"datetype": null,
"division": "/api/specify/division/2/",
"email": "[email protected]",
"firstname": "Test",
"groups": [],
"guid": "f2fec95a-7699-45f2-a794-337040b5bbc8",
"id": 3,
"initials": null,
"instcontentcontact": null,
"insttechcontact": null,
"interests": null,
"jobtitle": null,
"lastname": "User",
"members": "/api/specify/agent/?member=3",
"middleinitial": "C",
"modifiedbyagent": null,
"organization": null,
"orgmembers": "/api/specify/agent/?organization=3",
"remarks": null,
"resource_uri": "/api/specify/agent/3/",
"specifyuser": "/api/specify/specifyuser/1/",
"suffix": null,
"timestampcreated": "2012-08-09T12:29:16",
"timestampmodified": "2012-08-09T12:29:16",
"title": "mr",
"url": null,
"variants": [],
"version": 3
},
"agents": "/api/specify/specifyuser/?specifyuser=1",
"available_collections": [
[
4,
"KUFishvoucher"
],
[
32768,
"KUFishtissue"
]
],
"createdbyagent": null,
"email": "[email protected]",
"id": 1,
"isadmin": true,
"isauthenticated": true,
"isloggedin": true,
"isloggedinreport": false,
"logincollectionname": "KUFishtissue",
"logindisciplinename": "Ichthyology",
"loginouttime": "2017-04-11T16:03:08",
"message_set": "/api/specify/specifyuser/?user=1",
"modifiedbyagent": null,
"name": "Sp7demofish",
"resource_uri": "/api/specify/specifyuser/1/",
"spappresourcedirs": "/api/specify/specifyuser/?specifyuser=1",
"spappresources": "/api/specify/specifyuser/?specifyuser=1",
"spquerys": "/api/specify/specifyuser/?specifyuser=1",
"tasksemaphores": "/api/specify/specifyuser/?owner=1",
"timestampcreated": "2012-08-09T12:29:16",
"timestampmodified": "2012-08-09T12:29:16",
"usertype": "Manager",
"version": 349,
"workbenches": "/api/specify/specifyuser/?specifyuser=1",
"workbenchtemplates": "/api/specify/specifyuser/?specifyuser=1"
}
Logging out of the session is accomplished using the login URL with the username and password set to null.
curl -i -c cookies.txt -b cookies.txt -X PUT \
--data '{"username":null,"password":null,"collection":4}' \
-H "X-CSRFToken: 44kms3gdg6" \
-H "Referer: http://localhost:8000/" \
http://localhost:8000/context/login/
Once a logged-in session has been established and stored in the
cookie.txt
file, making API requests is easy. Let's fetch the
collection object with id 12.
curl -b cookies.txt http://localhost:8000/api/specify/collectionobject/12/ \
| python -m json.tool
{
"accession": "/api/specify/accession/614/",
"altcatalognumber": null,
"appraisal": null,
"availability": null,
"catalogeddate": "2006-06-13",
"catalogeddateprecision": 1,
"catalogeddateverbatim": null,
"cataloger": "/api/specify/agent/66/",
"catalognumber": "000038407",
"collectingevent": "/api/specify/collectingevent/8868/",
"collection": "/api/specify/collection/4/",
"collectionmemberid": 4,
"collectionobjectattachments": [],
"collectionobjectattribute": {
"bottomdistance": null,
"collectionmemberid": 4,
"collectionobjects": "/api/specify/collectionobjectattribute/?collectionobjectattribute=42336",
"createdbyagent": "/api/specify/agent/1/",
"direction": null,
"distanceunits": null,
"id": 42336,
"modifiedbyagent": null,
"number1": null,
"number10": null,
"number11": null,
"number12": null,
"number13": null,
"number14": null,
"number15": null,
"number16": null,
"number17": null,
"number18": null,
"number19": null,
"number2": null,
"number20": null,
"number21": null,
"number22": null,
"number23": null,
"number24": null,
"number25": null,
"number26": null,
"number27": null,
"number28": null,
"number29": null,
"number3": null,
"number30": null,
"number31": null,
"number32": null,
"number33": null,
"number34": null,
"number35": null,
"number36": null,
"number37": null,
"number38": null,
"number39": null,
"number4": null,
"number40": null,
"number41": null,
"number42": null,
"number5": null,
"number6": null,
"number7": null,
"number8": null,
"number9": null,
"positionstate": null,
"remarks": null,
"resource_uri": "/api/specify/collectionobjectattribute/42336/",
"text1": null,
"text10": null,
"text11": "45-51mm SL",
"text12": null,
"text13": null,
"text14": null,
"text15": null,
"text16": null,
"text17": null,
"text18": null,
"text2": null,
"text3": null,
"text4": null,
"text5": null,
"text6": null,
"text7": null,
"text8": null,
"text9": null,
"timestampcreated": "1999-10-25T12:32:15",
"timestampmodified": null,
"topdistance": null,
"version": 0,
"yesno1": null,
"yesno2": null,
"yesno3": null,
"yesno4": null,
"yesno5": null,
"yesno6": null,
"yesno7": null
},
"collectionobjectattrs": [],
"collectionobjectcitations": [],
"conservdescriptions": [],
"container": null,
"containerowner": null,
"countamt": 1,
"createdbyagent": "/api/specify/agent/1/",
"deaccessioned": false,
"description": null,
"determinations": [
{
"addendum": null,
"alternatename": null,
"collectionmemberid": 4,
"collectionobject": "/api/specify/collectionobject/12/",
"confidence": null,
"createdbyagent": "/api/specify/agent/1/",
"determinationcitations": [],
"determineddate": "2006-06-13",
"determineddateprecision": 1,
"determiner": "/api/specify/agent/66/",
"featureorbasis": null,
"guid": "df1929e3-1ed3-11e3-bfac-90b11c41863e",
"id": 41841,
"iscurrent": true,
"method": null,
"modifiedbyagent": "/api/specify/agent/1514/",
"nameusage": null,
"number1": 212.0,
"number2": null,
"preferredtaxon": "/api/specify/taxon/11486/",
"qualifier": null,
"remarks": null,
"resource_uri": "/api/specify/determination/41841/",
"subspqualifier": null,
"taxon": "/api/specify/taxon/11486/",
"text1": null,
"text2": null,
"timestampcreated": "1999-10-25T12:32:15",
"timestampmodified": "2006-09-19T10:37:01",
"typestatusname": null,
"varqualifier": null,
"version": 1,
"yesno1": false,
"yesno2": null
}
],
"dnasequences": [],
"exsiccataitems": [],
"fieldnotebookpage": null,
"fieldnumber": null,
"guid": "db192e8c-1ed3-11e3-bfac-90b11c41863e",
"id": 12,
"integer1": null,
"integer2": null,
"inventorydate": null,
"leftsiderels": "/api/specify/collectionobject/?leftside=12",
"modifiedbyagent": "/api/specify/agent/1514/",
"modifier": " ",
"name": null,
"notifications": null,
"number1": null,
"number2": null,
"objectcondition": null,
"ocr": null,
"otheridentifiers": [],
"paleocontext": null,
"preparations": [
{
"collectionmemberid": 4,
"collectionobject": "/api/specify/collectionobject/12/",
"countamt": 4,
"createdbyagent": "/api/specify/agent/1/",
"deaccessionpreparations": "/api/specify/preparation/?preparation=35011",
"description": null,
"exchangeinpreps": "/api/specify/preparation/?preparation=35011",
"exchangeoutpreps": "/api/specify/preparation/?preparation=35011",
"giftpreparations": "/api/specify/preparation/?preparation=35011",
"id": 35011,
"integer1": null,
"integer2": null,
"isonloan": false,
"loanpreparations": "/api/specify/preparation/?preparation=35011",
"modifiedbyagent": "/api/specify/agent/66/",
"number1": null,
"number2": null,
"preparationattachments": [],
"preparationattribute": null,
"preparationattrs": [],
"preparedbyagent": null,
"prepareddate": null,
"prepareddateprecision": 1,
"preptype": "/api/specify/preptype/2/",
"remarks": null,
"reservedinteger3": null,
"reservedinteger4": null,
"resource_uri": "/api/specify/preparation/35011/",
"samplenumber": null,
"status": null,
"storage": null,
"storagelocation": null,
"text1": null,
"text2": "Jar",
"timestampcreated": "2002-07-29T13:38:25",
"timestampmodified": "2006-06-13T10:13:09",
"version": 0,
"yesno1": null,
"yesno2": null,
"yesno3": null
}
],
"projectnumber": null,
"remarks": null,
"reservedinteger3": null,
"reservedinteger4": null,
"reservedtext": null,
"reservedtext2": null,
"reservedtext3": null,
"resource_uri": "/api/specify/collectionobject/12/",
"restrictions": null,
"rightsiderels": "/api/specify/collectionobject/?rightside=12",
"sgrstatus": null,
"text1": "known",
"text2": null,
"text3": null,
"timestampcreated": "1999-10-25T11:53:37",
"timestampmodified": "2006-09-19T10:37:01",
"totalvalue": null,
"treatmentevents": [],
"version": 1,
"visibility": 0,
"visibilitysetby": null,
"yesno1": null,
"yesno2": null,
"yesno3": null,
"yesno4": null,
"yesno5": null,
"yesno6": null
}
The result is a JSON representation of the requested object. The first thing to notice is that related objects can either be referenced by links to their resources or have their data included in line in the parent resource.
Example of a link:
"createdbyagent": "/api/specify/agent/1/",Example of inline:
"determinations": [ // Array of records here ... }Whether related object is inline or not depends on whether the relationship is marked as “Dependent” in the data model.
You can open the “Database Schema” from the “User Tools” menu, then click on the “Collection Object” table, and see that in the list of relationships, “Determinations” is dependent, whereas “Created By Agent” is not.
The URIs for resources take the form /api/specify/TABLE/ID/
. To
retrieve a collection of resources use URIs of the form
/api/specify/TABLE/
.
curl -b cookies.txt http://localhost:8000/api/specify/collectionobject/ \
| python -m json.tool
By default a maximum of twenty rows will be returned when requesting a
collection. The limit
query parameter can be used to adjust the
amount. Using limit=0
returns all rows.
curl -b cookies.txt http://localhost:8000/api/specify/taxon/?limit=2 \
| python -m json.tool
The offset
query parameter can be used along with limit
to
implement paging.
Often it will be necessary to retrieve a collection of resources that meet certain criteria. The API implements basic filtering for this purpose. E.g. to retrieve all preparation records for collection object with id 12:
curl -b cookies.txt http://localhost:8000/api/specify/preparation/?collectionobject=12 \
| python -m json.tool
Collection requests can also be filtered by domain, which means that only records which are in the same collection context as the user will be returned.
curl -b cookies.txt http://localhost:8000/api/specify/taxon/?domainfilter=true \
| python -m json.tool
Resources can be updated by making PUT requests to the corresponding URI. Because the API implements optimistic locking, it is necessary to obtain the current version of the resource before attempting an update.
curl -b cookies.txt http://localhost:8000/api/specify/agent/3/ | grep -o '\"version\": [0-9]*'
If the output is, for example, "version": 3
, then the resource
could be modified as follows:
curl -b cookies.txt -X PUT \
-H "X-CSRFToken: 44kms3gdg6" \
-H "Referer: http://localhost:8000/" \
--data '{"version": 3, "remarks":"test"}' \
http://localhost:8000/api/specify/agent/3/ \
| python -m json.tool
The response will be the data of the updated resource.
If the version if is omitted, the server will return a 400 Bad Request
. If the version does not match the current version in the
database, 409 Conflict
will be returned.
Resources can be created by issuing a POST request to the collection URI representing the target table. To create a new collection object:
curl -b cookies.txt -X POST \
-H "X-CSRFToken: 44kms3gdg6" \
-H "Referer: http://localhost:8000/" \
--data '{"collection":"/api/specify/collection/4/"}' \
http://localhost:8000/api/specify/collectionobject/ \
| python -m json.tool
The response will be the complete representation of the newly created resource.
Delete resources by issuing DELETE to the resource's URI. Because no
data is included in a DELETE request, the version information is
placed in the If-Match
HTTP header:
curl -b cookies.txt -X DELETE \
-H 'If-Match: 0' \
-H "X-CSRFToken: 44kms3gdg6" \
-H "Referer: http://localhost:8000/" \
http://localhost:8000/api/specify/collectionobject/123456789/
where 0
and 123456789
are replaced with the appropriate
values. Again, if the version info is missing or out of date, an error
will be returned.
Within every instance of Specify 7, there is API documentation using Swagger UI. This allows the REST API to be easily visualized and interacted with.
View our demo here: (Login and password is sp7demofish) https://sp7demofish.specifycloud.org/documentation/api/tables/ - Tables API https://sp7demofish.specifycloud.org/documentation/api/operations/ - Operations API
To view your instance's API, replace the base URL with your Specify 7 installation's hostname. (For example, sp7demofish.specifycloud.org
would be replaced withsp7.yourinstitution.org
)
On the Tables API page, you can view and test the parameters associated with each supported database table as well as modify and view the responses.
On the Operations API page, you can view and test the system operations endpoints requests and responses.