Skip to content

Commit

Permalink
Merge pull request #201 from hltcoe/api
Browse files Browse the repository at this point in the history
Fixes #32 Adds a REST API to Turkle
  • Loading branch information
cash committed Jun 15, 2023
2 parents c9a22dd + 709addf commit 935f63c
Show file tree
Hide file tree
Showing 27 changed files with 1,621 additions and 459 deletions.
1 change: 0 additions & 1 deletion Dockerfile-MySQL
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ RUN set -eux; \

COPY turkle /opt/turkle/turkle
COPY manage.py /opt/turkle/manage.py
COPY scripts /opt/turkle/scripts
COPY turkle_site /opt/turkle/turkle_site

COPY docker-config/entrypoint.sh /usr/local/bin/entrypoint.sh
Expand Down
1 change: 0 additions & 1 deletion Dockerfile-sqlite
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ RUN pip install --no-cache-dir --upgrade pip && \

COPY turkle /opt/turkle/turkle
COPY manage.py /opt/turkle/manage.py
COPY scripts /opt/turkle/scripts
COPY turkle_site /opt/turkle/turkle_site
COPY docker-config/create_turkle_admin.sh /opt/turkle/create_turkle_admin.sh
COPY docker-config/entrypoint.sh /usr/local/bin/entrypoint.sh
Expand Down
173 changes: 173 additions & 0 deletions docs/API.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
REST API
==========

Turkle has a REST API for administration of users, groups, projects, and batches.
A full OpenAPI schema of the API is available at `/api/schema/`.

The API uses integer identifiers for all the objects.
These identifiers are included in the response when creating or listing objects.
In the admin UI, the identifier is included in any URL for that object.

Client
----------
ToDo

Authentication
---------------
It requires token-based authentication and tokens can be created per user in the admin UI.
Once a token has been created, it is passed as a header in the request::

token = 'ABCDEF'
headers = {'Authorization': f'TOKEN {token}'}
resp = requests.get('http://localhost:8000/api/users/', headers=headers)

Users
--------
Listing users
`````````````````
Perform a **get** on `/api/users/`.
The response is paginated and includes next and previous links to walk the user list.

Creating a user
`````````````````
Perform a **post** on `/api/users/`.
The payload at a minimum must include username and password::

{
"username": "jsmith",
"first_name": "John",
"last_name": "Smith",
"email": "[email protected]",
"password": "p@ssw0rd"
}

Retrieving a user
`````````````````
Perform a **get** on `/api/users/{id}/` where id is the user's integer identifier.

To retrieve based on username. perform a **get** on `/api/users/username/{username}/`.

Update a user
`````````````````
Perform a **patch** on `/api/users/{id}/` where id is the user's integer identifier.
The JSON payload is a dictionary of fields to update.

Groups
---------
Listing groups
`````````````````
Perform a **get** on `/api/groups/`.
The response is paginated and includes next and previous links to walk the list.

Creating a group
`````````````````
Perform a **post** on `/api/groups/`.
The payload must include the name of the group and a list of user integer identifiers::

{
"name": "Spanish",
"users": [7, 34, 35, 36]
}

Retrieving a group
``````````````````
Perform a **get** on `/api/groups/{id}/` where id is the group's integer identifier.

To retrieve based on a group name. perform a **get** on `/api/groups/name/{name}/`.
This will return a list of groups that exactly match that group name.
It is a list since group names are not required to be unique in Turkle.

Adding users to a group
```````````````````````````
Perform a **post** on `/api/groups/{id}/users/` where id is the group's integer identifier.

The payload is a dictionary with a key of *users* which is a list of user integer identifiers.

Projects
----------
Listing projects
`````````````````
Perform a **get** on `/api/projects/`.
The response is paginated and includes next and previous links to walk the list.

Creating a project
```````````````````
Perform a **post** on `/api/projects/`.
The payload must include the name of the project, the html template, and the template filename::

{
"name": "Image Contains",
"html_template": "<html>template as a string here</html>,
"filename": "image_contains.html"
}

Optional fields include active, allotted_assignment_time, assignments_per_task, and login_required.

Retrieving a project
`````````````````````
Perform a **get** on `/api/projects/{id}/` where id is the project's integer identifier.

Update a project
`````````````````
Perform a **patch** on `/api/projects/{id}/` where id is the project's integer identifier.
The JSON payload is a dictionary of fields to update and can include the html_template.

Batches
----------
Listing batches
`````````````````
Perform a **get** on `/api/batches/`.
The response is paginated and includes next and previous links to walk the list.

Creating a batch
```````````````````
Perform a **post** on `/api/batches/`.
The payload must include the name of the batch, the project identifier,
and the csv data and filename::

{
"name": "Bird Photos",
"project": 20,
"filename": "image_contains.csv",
"csv_text": "csv as string"
}

Optional fields include active, allotted_assignment_time, assignments_per_task, and login_required.

Retrieving a batch
`````````````````````
Perform a **get** on `/api/batches/{id}/` where id is the batch's integer identifier.

Update a batch
`````````````````
Perform a **patch** on `/api/batches/{id}/` where id is the batch's integer identifier.
The JSON payload is a dictionary of fields to update and cannot include the csv data.
If a bad batch was created, delete it using the admin UI.

Additional tasks can be added to an existing batch by a **post** to `/api/batches/{id}/tasks/`.
The payload is a dictionary with a key of *csv_text*.
The fields in the CSV data must match the fields in html template of the project.

Batch status
`````````````````
To download the input data for a batch as a CSV file, do a **get** on `/api/batches/{id}/input/`.

To download the results data for a batch as a CSV file, do a **get** on `/api/batches/{id}/results/`.

To get up-to-date progress for a batch, do a **get** on `/api/batches/{id}/progress/`.

Permissions
------------
Projects and Batches can be restricted to particular users or groups.
To retrieve the current permissions, perform a **get** on `/api/projects/{id}/permissions/`
(replacing "projects" with "batches" to get a batch's permissions).

To add additional users and groups to a project's permissions, perform a **post** on
`/api/projects/{id}/permissions/` with a payload of users and groups::

{
"users": [],
"groups": [29, 63]
}

To replace the current permissions for a project, perform a **put** on the endpoint.
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Welcome to Turkle's documentation!
ADMINISTRATION.rst
DOCKER.rst
APP.rst
API.rst
REQUESTERS.rst
TEMPLATE-GUIDE.rst

Expand Down
4 changes: 3 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ beautifulsoup4
Django~=3.2.16
django-admin-autocomplete-list-filter==1.0.1
django-guardian==2.4.0
djangorestframework==3.13.1
drf-nested-routers==0.93.4
humanfriendly
jsonfield==3.1.0
requests
uritemplate
26 changes: 0 additions & 26 deletions scripts/README.md

This file was deleted.

25 changes: 0 additions & 25 deletions scripts/add_user.py

This file was deleted.

Loading

0 comments on commit 935f63c

Please sign in to comment.