.. _api: RESTful API =========== The RESTful API is located at:: http://{pybossa-site-url}/api It expects and returns JSON. .. autoclass:: pybossa.api.api_base.APIBase :members: .. autoclass:: pybossa.api.AppAPI :members: .. autoclass:: pybossa.api.ProjectAPI :members: .. autoclass:: pybossa.api.TaskAPI :members: .. autoclass:: pybossa.api.TaskRunAPI :members: .. autoclass:: pybossa.api.CategoryAPI :members: .. autoclass:: pybossa.api.GlobalStatsAPI :members: .. autoclass:: pybossa.api.VmcpAPI :members: Some requests will need an **API-KEY** to authenticate & authorize the operation. You can get your API-KEY in your *profile* account. The returned objects will have a **links** and **link** fields, not included in the model in order to support `Hypermedia as the Engine of Application State`_ (also known as HATEOAS), so you can know which are the relations between objects. All objects will return a field **link** which will be the absolute URL for that specific object within the API. If the object has some parents, you will find the relations in the **links** list. For example, for a Task Run you will get something like this: .. code-block:: javascript { "info": 65, "user_id": null, "links": [ "", "" ], "task_id": 5894, "created": "2012-07-07T17:23:45.714184", "finish_time": "2012-07-07T17:23:45.714210", "calibration": null, "project_id": 90, "user_ip": "X.X.X.X", "link": "", "timeout": null, "id": 8969 } The object link will have a tag **rel** equal to **self**, while the parent objects will be tagged with **parent**. The **title** field is used to specify the type of the object: task, taskrun or project. Projects will not have a **links** field, because these objects do not have parents. Tasks will have only one parent: the associated project. Task Runs will have only two parents: the associated task and associated project. .. _`Hypermedia as the Engine of Application State`: http://en.wikipedia.org/wiki/HATEOAS .. _rate-limiting: Rate Limiting ------------- Rate Limiting has been enabled for all the API endpoints (since PyBossa v2.0.1). The rate limiting gives any user, using the IP, **a window of 15 minutes to do at most 300 requests per endpoint**. This new feature includes in the headers the following values to throttle your requests without problems: * **X-RateLimit-Limit**: the rate limit ceiling for that given request * **X-RateLimit-Remaining**: the number of requests left for the 15 minute window * **X-RateLimit-Reset**: the remaining window before the rate limit resets in UTC epoch seconds We recommend to use the Python package **requests** for interacting with PyBossa, as it is really simple to check those values: .. code-block:: python import requests import time res = requests.get('http://SERVER/api/project') if int(res.headers['X-RateLimit-Remaining']) < 10: time.sleep(300) # Sleep for 5 minutes else: pass # Do your stuff Operations ---------- The following operations are supported: List ~~~~ List domain objects:: GET http://{pybossa-site-url}/api/{domain-object} For example, you can get a list of registered Projects like this:: GET http://{pybossa-site-url}/api/project Or a list of Categories:: GET http://{pybossa-site-url}/api/category Or a list of Tasks:: GET http://{pybossa-site-url}/api/task For a list of TaskRuns use:: GET http://{pybossa-site-url}/api/taskrun Finally, you can get a list of users by doing:: GET http://{pybossa-site-url}/api/user .. note:: Please, notice that in order to keep users privacy, only their locale and nickname will be shared by default. Optionally, users can disable privacy mode in their settings. By doing so, also their fullname and account creation date will be visible for everyone through the API. .. note:: By default PyBossa limits the list of items to 20. If you want to get more items, use the keyword **limit=N** with **N** being a number to get that amount. There is a maximum of 100 to the **limit** keyword, so if you try to get more items at once it won't work. .. note:: **DEPRECATED (see next Note for a better and faster solution)** You can use the keyword **offset=N** in any **GET** query to skip that many rows before beginning to get rows. If both **offset** and **limit** appear, then **offset** rows are skipped before starting to count the **limit** rows that are returned. .. note:: You can paginate the results of any GET query using the last ID of the domain object that you have received and the parameter: **last_id**. For example, to get the next 20 items after the last project ID that you've received you will write the query like this: GET /api/project?last_id={{last_id}}. Get ~~~ Get a specific domain object by id (by default any GET action will return only 20 objects, you can get more or less objects using the **limit** option). Returns domain object.:: GET http://{pybossa-site-url}/api/{domain-object}/{id}[?api_key=API-KEY] .. note:: Some GET actions may require to authenticate & authorize the request. Use the ?api_key argument to pass the **API-KEY**. If the object is not found you will get a JSON object like this: .. code-block:: js { "status": "failed", "action": "GET", "target": "project", "exception_msg": "404 Not Found", "status_code": 404, "exception_cls": "NotFound" } Any other error will return the same object but with the proper status code and error message. Search ~~~~~~ Get a list of domain objects by its fields. Returns a list of domain objects matching the query:: GET http://{pybossa-site-url}/api/{domain-object}[?domain-object-field=value] Multiple fields can be used separated by the **&** symbol:: GET http://{pybossa-site-url}/api/{domain-object}[?field1=value&field2=value2] It is possible to limit the number of returned objects:: GET http://{pybossa-site-url}/api/{domain-object}[?field1=value&limit=20] .. note:: By default all GET queries return a maximum of 20 objects unless the **limit** keyword is used to get more: limit=50. However, a maximum amount of 100 objects can be retrieved at once. .. note:: If the search does not find anything, the server will return an empty JSON list [] Create ~~~~~~ Create a domain object. Returns created domain object.:: POST http://{pybossa-site-url}/api/{domain-object}[?api_key=API-KEY] .. note:: Some POST actions may require to authenticate & authorize the request. Use the ?api_key argument to pass the **API-KEY**. If an error occurs, the action will return a JSON object like this: .. code-block:: js { "status": "failed", "action": "POST", "target": "project", "exception_msg": "type object 'Project' has no attribute 'short_ame'", "status_code": 415, "exception_cls": "AttributeError" } Where **target** will refer to a Project, Task or TaskRun object. Update ~~~~~~ Update a domain object:: PUT http://{pybossa-site-url}/api/{domain-object}/{id}[?api_key=API-KEY] .. note:: Some PUT actions may require to authenticate & authorize the request. Use the ?api_key argument to pass the **API-KEY**. If an error occurs, the action will return a JSON object like this: .. code-block:: js { "status": "failed", "action": "PUT", "target": "project", "exception_msg": "type object 'Project' has no attribute 'short_ame'", "status_code": 415, "exception_cls": "AttributeError" } Where **target** will refer to a project, Task or TaskRun object. Delete ~~~~~~ Delete a domain object:: DELETE http://{pybossa-site-url}/api/{domain-object}/{id}[?api_key=API-KEY] .. note:: Some DELETE actions may require to authenticate & authorize the request. Use the ?api_key argument to pass the **API-KEY**. If an error occurs, the action will return a JSON object like this: .. code-block:: js { "status": "failed", "action": "DELETE", "target": "project", "exception_msg": "type object 'Project' has no attribute 'short_ame'", "status_code": 415, "exception_cls": "AttributeError" } Where **target** will refer to a Project, Task or TaskRun object. Requesting a new task for current user ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can request a new task for the current user (anonymous or authenticated) by:: GET http://{pybossa-site-url}/api/{project.id}/newtask This will return a domain Task object in JSON format if there is a task available for the user, otherwise it will return **None**. .. note:: Some projects will want to pre-load the next task for the current user. This is possible by passing the argument **?offset=1** to the **newtask** endpoint. Requesting the user's oAuth tokens ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A user who has registered or signed in with any of the third parties supported by PyBossa (currently Twitter, Facebook and Google) can request his own oAuth tokens by doing:: GET http://{pybossa-site-url}/api/token?api_key=API-KEY Additionally, the user can specify any of the tokens if only its retrieval is desired:: GET http://{pybossa-site-url}/api/token/{provider}?api_key=API-KEY Where 'provider' will be any of the third parties supported, i.e. 'twitter', 'facebook' or 'google'. Example Usage ------------- Create a Project object:: .. code-block:: bash curl -X POST -H "Content-Type:application/json" -s -d '{"name":"myproject", "info":{"xyz":1}}' 'http://localhost:5000/api/project?api_key=API-KEY'