Skip to content

Commit

Permalink
Merge pull request #158 from manuGil/api-v2
Browse files Browse the repository at this point in the history
Api v2
  • Loading branch information
manuGil authored Mar 27, 2024
2 parents a864edd + 9b56cb2 commit b8044a0
Show file tree
Hide file tree
Showing 43 changed files with 10,328 additions and 630 deletions.
19 changes: 10 additions & 9 deletions .github/workflows/django-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
branches:
- devel
- main

push:
branches:
- devel
Expand All @@ -19,14 +19,14 @@ jobs:
services:
postgres:
image: postgis/postgis:14-master
env: # environmental variables required for the job
env: # environmental variables required for the job
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: github_actions
ports:
ports:
- 5432:5432

options: >-
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
Expand All @@ -40,15 +40,15 @@ jobs:
path: ~/.cache/zip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
${{ runner.os }}-pip-
- name: Setup python environment
uses: actions/setup-python@v3
with:
python-version: "3.x"
python-version: '3.x'
- name: Install GDAL library
run: |
sudo add-apt-repository ppa:ubuntugis/ubuntugis-unstable
sudo apt-get update
sudo add-apt-repository ppa:ubuntugis/ppa -y
sudo apt-get update -y
sudo apt-get install gdal-bin libgdal-dev -y
export CPLUS_INCLUDE_PATH=/usr/include/gdal
export C_INCLUDE_PATH=/usr/include/gdal
Expand All @@ -63,5 +63,6 @@ jobs:
run: |
nohup python citizenvoice/manage.py runserver &
sleep 5
- name: Stop Development Server
- name: Stop Development Server
run: pkill -f runserver

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ sdist/
vue/
node_modules/
package-lock.json
package.json
var/
wheels/
pip-wheel-metadata/
Expand Down
40 changes: 1 addition & 39 deletions README.dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,42 +73,4 @@ python manage.py test
### GitHub

1. Make sure that the GitHub-Zenodo integration is enabled for https://github.com/NLeSC/python-template
1. Go to https://github.com/NLeSC/python-template/releases and click `Draft a new release`

### The REST API and authentication

We are using Django rest knox for authentication. Knox authentication is token based, similar to the TokenAuthentication.
This means some API's are protected and can only be called with a authentication token.
To get an valid authentication token you need to have an account and then login with that account.
Example using postman:
Create a new POST request to `http://127.0.0.1:8000/api/auth/login/` in the body add the next key value pairs in `from-data`:
| key | value |
| -------- | ------------- |
| email | `<you email>` |
| password | `<your pass>` |
As a response you will receive:
```json
{
"expiry": "2023-01-24T11:00:24.545608Z",
"token": "<token>",
"user": {
"id": <id>,
"username": "<name>",
"email": "<email></email>"
}
}
```
Use the token string to fetch authenticated API's:
Create a new GET request in postman to `http://127.0.0.1:8000/api/auth/me`. In the `Headers` add the key value pair:

| key | value |
| ------------- | --------------- |
| Authorization | Token `<token>` |

Make sure your using the same capitals and have a space between `Token` and `<token>`.

Now you should get the authenticated user data.
1. Go to https://github.com/NLeSC/python-template/releases and click `Draft a new release`
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ If you use this software, please cite it as follows:

| [Role](https://credit.niso.org/contributor-roles-defined/) | Author |
|------|--------|
| Conceptulization | Goncalves, J. E., Forgaci, C., Verma, T., & Garcia Alvarez, M. |
| Conceptualization | Goncalves, J. E., Forgaci, C., Verma, T., & Garcia Alvarez, M. |
| Funding acquisition | Goncalves, J. E., Forgaci, C., & Verma, T.|
| Project administration | Goncalves, J. E., Forgaci, C., & Verma, T. |
| Investigation | Ioannou I. |
| Project management | Goncalves, J. E. |
| Research | Goncalves, J. E., Ioannou I., Forgaci, C., & Verma, T. |
| Software | van der Laarse, G., Ijpma, J., Aslan, Y., & Garcia Alvarez, M. |
| Supervision | Garcia Alvarez, M. |

Expand Down
14 changes: 7 additions & 7 deletions citizenvoice/apiapp/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@
import django.contrib.auth.models
from django.contrib import auth

from .models import ( Answer, Question, Survey, Response, PointLocation,
PolygonLocation, LineStringLocation, MapView,
Location)
from .models import ( Answer, Question, Survey, Response, PointFeature,
PolygonFeature, LineFeature, MapView,
LocationCollection)

# Register the models in the admin site in order to view, create and edit them from the admin page
admin.site.register(Answer)
admin.site.register(Question)
admin.site.register(Survey)
admin.site.register(Response)
admin.site.register(PointLocation)
admin.site.register(LineStringLocation)
admin.site.register(PolygonLocation)
admin.site.register(PointFeature)
admin.site.register(LineFeature)
admin.site.register(PolygonFeature)
admin.site.register(MapView)
admin.site.register(Location)
admin.site.register(LocationCollection)


# Unregister User and Group fields
Expand Down
86 changes: 40 additions & 46 deletions citizenvoice/apiapp/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generated by Django 5.0 on 2024-02-29 23:12
# Generated by Django 5.0 on 2024-03-27 09:43

import apiapp.models.mapview
import django.contrib.gis.db.models.fields
Expand All @@ -18,12 +18,11 @@ class Migration(migrations.Migration):

operations = [
migrations.CreateModel(
name='Answer',
name='LocationCollection',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateTimeField(auto_now_add=True, verbose_name='Creation date')),
('updated', models.DateTimeField(auto_now=True, verbose_name='Last edited')),
('body', models.TextField(verbose_name='Answer Body')),
('name', models.CharField(blank=True, max_length=100)),
('descripion', models.CharField(blank=True, max_length=300)),
],
),
migrations.CreateModel(
Expand All @@ -37,66 +36,54 @@ class Migration(migrations.Migration):
],
),
migrations.CreateModel(
name='Question',
name='LineStringLocation',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('text', models.TextField(verbose_name='Text of the Question')),
('order', models.IntegerField(verbose_name='Order of where question is placed')),
('required', models.BooleanField(default=True, verbose_name='Question must be filled out')),
('question_type', models.CharField(choices=[('text', 'text (multiple line)'), ('short-text', 'short text (one line)'), ('radio', 'radio'), ('select', 'select'), ('select-multiple', 'Select Multiple'), ('select_image', 'Select Image'), ('integer', 'integer'), ('float', 'float'), ('date', 'date')], default='text', max_length=150, verbose_name='Type of question')),
('choices', models.TextField(blank=True, null=True, verbose_name='Choices for answers')),
('is_geospatial', models.BooleanField(default=False, verbose_name='If the question must be answered geospatially or not')),
('map_view', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='apiapp.mapview')),
('geom', django.contrib.gis.db.models.fields.LineStringField(srid=4326)),
('description', models.CharField(blank=True, max_length=100, null=True)),
('location', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='apiapp.locationcollection')),
],
options={
'verbose_name': 'question',
'verbose_name_plural': 'questions',
'ordering': ('survey', 'order'),
},
),
migrations.CreateModel(
name='PolygonLocation',
name='PointLocation',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(blank=True, max_length=100)),
('location', django.contrib.gis.db.models.fields.PolygonField(srid=4326)),
('answer', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='apiapp.answer')),
('question', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='apiapp.question')),
('geom', django.contrib.gis.db.models.fields.PointField(srid=4326)),
('description', models.CharField(blank=True, max_length=100, null=True)),
('location', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='apiapp.locationcollection')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='PointLocation',
name='PolygonLocation',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(blank=True, max_length=100)),
('location', django.contrib.gis.db.models.fields.PointField(srid=4326)),
('answer', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='apiapp.answer')),
('question', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='apiapp.question')),
('geom', django.contrib.gis.db.models.fields.PolygonField(srid=4326)),
('description', models.CharField(blank=True, max_length=100, null=True)),
('location', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='apiapp.locationcollection')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='LineStringLocation',
name='Question',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(blank=True, max_length=100)),
('location', django.contrib.gis.db.models.fields.LineStringField(srid=4326)),
('answer', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='apiapp.answer')),
('question', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='apiapp.question')),
('text', models.TextField(verbose_name='Text of the Question')),
('order', models.IntegerField(verbose_name='Order of where question is placed')),
('required', models.BooleanField(default=True, verbose_name='Question must be filled out')),
('question_type', models.CharField(choices=[('text', 'text (multiple line)'), ('short-text', 'short text (one line)'), ('radio', 'radio'), ('select', 'select'), ('select-multiple', 'Select Multiple'), ('select_image', 'Select Image'), ('integer', 'integer'), ('float', 'float'), ('date', 'date')], default='text', max_length=150, verbose_name='Type of question')),
('choices', models.TextField(blank=True, null=True, verbose_name='Choices for answers')),
('is_geospatial', models.BooleanField(default=False, verbose_name='If the question must be answered geospatially or not')),
('map_view', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='apiapp.mapview')),
],
options={
'abstract': False,
'verbose_name': 'question',
'verbose_name_plural': 'questions',
'ordering': ('survey', 'order'),
},
),
migrations.AddField(
model_name='answer',
model_name='locationcollection',
name='question',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='apiapp.question'),
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='apiapp.question'),
),
migrations.CreateModel(
name='Response',
Expand All @@ -107,10 +94,17 @@ class Migration(migrations.Migration):
('respondent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.AddField(
model_name='answer',
name='response',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='apiapp.response'),
migrations.CreateModel(
name='Answer',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateTimeField(auto_now_add=True, verbose_name='Creation date')),
('updated', models.DateTimeField(auto_now=True, verbose_name='Last edited')),
('body', models.TextField(blank=True, verbose_name='Answer Body')),
('locations', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='apiapp.locationcollection')),
('question', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='apiapp.question')),
('response', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='apiapp.response')),
],
),
migrations.CreateModel(
name='Survey',
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 5.0 on 2024-03-27 09:58

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('apiapp', '0001_initial'),
]

operations = [
migrations.RemoveField(
model_name='locationcollection',
name='question',
),
]
19 changes: 19 additions & 0 deletions citizenvoice/apiapp/migrations/0003_mapview_location_collection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 5.0 on 2024-03-27 10:08

import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('apiapp', '0002_remove_locationcollection_question'),
]

operations = [
migrations.AddField(
model_name='mapview',
name='location_collection',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='apiapp.locationcollection'),
),
]

This file was deleted.

Loading

0 comments on commit b8044a0

Please sign in to comment.