Skip to content

Commit 607b559

Browse files
authored
Chore/setup update api v2 (#138)
* chore: update Dockerfile and requirements, cleanup settings * chore: add /env template * fix: fix error TypeError 'bool' object is not callable * chore: add Now api endpoint, cleanup router * chore: update v1 route to only push sensors data, add statistics view * update: fix push-sensors-url * update: update NodesView * update: update NodesView * Update README docker setup * update: modify NodeView permissions * chore: update views docstrings * chore: modify data stats url * chore: add .dockerignore file --------- Co-authored-by: Xavier Frankline <xavier@codeforafrica.org>
1 parent d8d6aba commit 607b559

File tree

12 files changed

+268
-82
lines changed

12 files changed

+268
-82
lines changed

.dockerignore

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Git
2+
.git
3+
.gitignore
4+
5+
# Docker
6+
docker-compose.yml
7+
.docker
8+
9+
# Byte-compiled / optimized / DLL files
10+
__pycache__/
11+
*/__pycache__/
12+
*/*/__pycache__/
13+
*/*/*/__pycache__/
14+
*.py[cod]
15+
*/*.py[cod]
16+
*/*/*.py[cod]
17+
*/*/*/*.py[cod]
18+
19+
# Distribution / packaging
20+
.Python
21+
env/
22+
build/
23+
develop-eggs/
24+
dist/
25+
downloads/
26+
eggs/
27+
lib/
28+
lib64/
29+
parts/
30+
sdist/
31+
var/
32+
*.egg-info/
33+
.installed.cfg
34+
*.egg
35+
36+
# PyInstaller
37+
# Usually these files are written by a python script from a template
38+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
39+
*.manifest
40+
*.spec
41+
42+
# Installer logs
43+
pip-log.txt
44+
pip-delete-this-directory.txt
45+
46+
# Translations
47+
*.mo
48+
*.pot
49+
50+
# Django stuff:
51+
*.log
52+
53+
# Sphinx documentation
54+
docs/_build/
55+
56+
# PyBuilder
57+
target/
58+
59+
# Virtual environment
60+
.env/
61+
.venv/
62+
venv/
63+
64+
# PyCharm
65+
.idea
66+
67+
# Python mode for VIM
68+
.ropeproject
69+
*/.ropeproject
70+
*/*/.ropeproject
71+
*/*/*/.ropeproject
72+
73+
# Vim swap files
74+
*.swp
75+
*/*.swp
76+
*/*/*.swp
77+
*/*/*/*.swp

.env.template

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
SENSORSAFRICA_DATABASE_URL=""
2+
SENSORSAFRICA_DEBUG=""
3+
SENSORSAFRICA_FLOWER_ADMIN_PASSWORD=""
4+
SENSORSAFRICA_FLOWER_ADMIN_USERNAME=""
5+
SENSORSAFRICA_RABBITMQ_URL=""
6+
SENSORSAFRICA_SENTRY_DSN=""

Dockerfile

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,21 @@ FROM python:3.6.3
22

33
ENV PYTHONUNBUFFERED 1
44

5-
# Create root directory for our project in the container
6-
RUN mkdir /src
7-
8-
# Create application subdirectories
5+
# Create application root directory
96
WORKDIR /src
7+
108
RUN mkdir media static logs
119
VOLUME [ "/src/logs" ]
1210

13-
# Copy the current directory contents into the container at sensorsafrica
14-
ADD . /src/
15-
16-
# Upgrade pip and setuptools
17-
RUN pip install -q -U pip setuptools
11+
# Upgrade pip and setuptools with trusted hosts
12+
RUN python -m pip install --trusted-host pypi.python.org --trusted-host files.pythonhosted.org --trusted-host pypi.org --upgrade pip setuptools
1813

19-
# Install feinstaub from opendata-stuttgart
20-
RUN pip install -q git+https://github.com/opendata-stuttgart/feinstaub-api
14+
# Copy the current directory contents into the container at sensorsafrica
15+
COPY . /src/
2116

22-
# Install sensors.AFRICA-api and its dependencies
23-
RUN pip install -q -U .
17+
# Install dependencies
18+
RUN pip install -q git+https://github.com/opendata-stuttgart/feinstaub-api && \
19+
pip install -q .
2420

2521
# Expose port server
2622
EXPOSE 8000
@@ -31,3 +27,4 @@ COPY ./contrib/entrypoint.sh /entrypoint.sh
3127

3228
ENTRYPOINT ["/entrypoint.sh"]
3329
CMD [ "/start.sh" ]
30+

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ API to save and access data from deployed sensors in cities all around Africa.
44

55
## Documentation
66

7-
The API is documented [here.](https://github.com/CodeForAfricaLabs/sensors.AFRICA-api/wiki/API-Documentation)
7+
The API is documented [here.](https://github.com/CodeForAfricaLabs/sensors.AFRICA-api/wiki/API-Documentation)
88

99
## Development
1010

@@ -29,11 +29,17 @@ GRANT ALL PRIVILEGES ON DATABASE sensorsafrica TO sensorsafrica;
2929

3030
- Migrate the database; `python manage.py migrate`
3131
- Run the server; `python manage.py runserver`
32+
- Create super user for admin login; `python manage.py createsuperuser`
33+
34+
username: `<username>`
35+
email: blank
36+
password: `<password>`
3237

3338
### Docker
3439

3540
Using docker compose:
3641

42+
- Create a `.env` file using `.env.template` . ***docker-compose has some default values for these variables***
3743
- Build the project; `docker-compose build` or `make build`
3844
- Run the project; `docker-compose up -d` or `make up`
3945

docker-compose.yml

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,20 @@ version: '3.3'
22

33
services:
44
rabbitmq:
5-
image: rabbitmq:3.5.1
5+
image: rabbitmq:3.12.7-management
66
ports:
7-
- 4369:4369
8-
- 5672:5672
9-
- 25672:25672
10-
- 15672:15672
7+
- "5672:5672"
8+
# GUI port
9+
- "15672:15672"
1110
environment:
12-
- RABBITMQ_USERNAME=sensorsafrica
13-
- RABBITMQ_PASSWORD=sensorsafrica
11+
- RABBITMQ_DEFAULT_USER=sensorsafrica
12+
- RABBITMQ_DEFAULT_PASS=sensorsafrica
13+
healthcheck:
14+
test: [ "CMD-SHELL", "rabbitmq-diagnostics -q ping" ]
15+
interval: 10s
16+
timeout: 5s
17+
retries: 2
18+
1419
postgres:
1520
image: postgres:13.7
1621
ports:
@@ -25,12 +30,11 @@ services:
2530
build:
2631
context: .
2732
environment:
28-
SENSORSAFRICA_DATABASE_URL: postgres://sensorsafrica:sensorsafrica@postgres:5432/sensorsafrica
29-
SENSORSAFRICA_READ_DATABASE_URLS: postgres://sensorsafrica:sensorsafrica@postgres:5432/sensorsafrica
30-
SENSORSAFRICA_RABBITMQ_URL: amqp://sensorsafrica:sensorsafrica@rabbitmq//
31-
SENSORSAFRICA_FLOWER_ADMIN_USERNAME: admin
32-
SENSORSAFRICA_FLOWER_ADMIN_PASSWORD: password
33-
DOKKU_APP_NAME: sensorsafrica
33+
SENSORSAFRICA_DATABASE_URL: ${SENSORSAFRICA_DATABASE_URL:-postgres://sensorsafrica:sensorsafrica@postgres:5432/sensorsafrica}
34+
SENSORSAFRICA_RABBITMQ_URL: ${SENSORSAFRICA_RABBITMQ_URL:-amqp://sensorsafrica:sensorsafrica@rabbitmq/}
35+
SENSORSAFRICA_FLOWER_ADMIN_USERNAME: ${SENSORSAFRICA_FLOWER_ADMIN_USERNAME:-admin}
36+
SENSORSAFRICA_FLOWER_ADMIN_PASSWORD: ${SENSORSAFRICA_FLOWER_ADMIN_PASSWORD:-password}
37+
DOKKU_APP_NAME: ${DOKKU_APP_NAME:-sensorsafrica}
3438
depends_on:
3539
- postgres
3640
- rabbitmq

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ ckanapi==4.1
1818

1919
celery-slack==0.3.0
2020

21-
urllib3<1.25,>=1.21.1 #requests 2.21.0
21+
urllib3<2
2222

2323
django-cors-headers==3.0.2
2424

sensorsafrica/api/v1/router.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
from rest_framework import routers
1919

2020
router = routers.DefaultRouter()
21-
router.register(r"push-sensor-data", PostSensorDataView)
2221
router.register(r"node", NodeView)
2322
router.register(r"sensor", SensorView)
2423
router.register(r"data", VerboseSensorDataView)
@@ -31,3 +30,8 @@
3130
router.register(r"filter", FilterView, basename="filter")
3231

3332
api_urls = router.urls
33+
34+
push_sensor_data_router = routers.DefaultRouter()
35+
push_sensor_data_router.register(r"push-sensor-data", PostSensorDataView)
36+
37+
push_sensor_data_urls = push_sensor_data_router.urls

sensorsafrica/api/v1/views.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class NodeView(
5454
filter_class = NodeFilter
5555

5656
def get_queryset(self):
57-
if self.request.user.is_authenticated():
57+
if self.request.user.is_authenticated:
5858
if self.request.user.groups.filter(name="show_me_everything").exists():
5959
return Node.objects.all()
6060

@@ -92,7 +92,7 @@ class PostSensorDataView(mixins.CreateModelMixin,
9292
permission_classes = tuple()
9393
serializer_class = LastNotifySensorDataSerializer
9494
queryset = SensorData.objects.all()
95-
95+
9696

9797
class VerboseSensorDataView(SensorDataView):
9898
filter_class = SensorFilter

sensorsafrica/api/v2/router.py

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,42 +4,28 @@
44
from .views import (
55
CitiesView,
66
NodesView,
7+
NowView,
78
SensorDataStatsView,
89
SensorDataView,
910
SensorLocationsView,
1011
SensorTypesView,
1112
SensorsView,
13+
StatisticsView,
1214
meta_data,
1315
)
1416

15-
stat_data_router = routers.DefaultRouter()
16-
stat_data_router.register(r"", SensorDataStatsView)
17-
18-
data_router = routers.DefaultRouter()
19-
data_router.register(r"", SensorDataView)
20-
21-
cities_router = routers.DefaultRouter()
22-
cities_router.register(r"", CitiesView, basename="cities")
23-
24-
nodes_router = routers.DefaultRouter()
25-
nodes_router.register(r"", NodesView, basename="map")
26-
27-
sensors_router = routers.DefaultRouter()
28-
sensors_router.register(r"", SensorsView, basename="sensors")
29-
30-
sensor_locations_router = routers.DefaultRouter()
31-
sensor_locations_router.register(r"", SensorLocationsView, basename="locations")
32-
33-
sensor_types_router = routers.DefaultRouter()
34-
sensor_types_router.register(r"", SensorTypesView, basename="sensor_types")
17+
router = routers.DefaultRouter()
18+
router.register(r"data", SensorDataView, basename="sensor-data")
19+
router.register(r"data/stats/(?P<sensor_type>[air]+)", SensorDataStatsView, basename="sensor-data-stats")
20+
router.register(r"cities", CitiesView, basename="cities")
21+
router.register(r"nodes", NodesView, basename="nodes")
22+
router.register(r"now", NowView, basename="now")
23+
router.register(r"locations", SensorLocationsView, basename="sensor-locations")
24+
router.register(r"sensors", SensorsView, basename="sensors")
25+
router.register(r"sensor-types", SensorTypesView, basename="sensor-types")
26+
router.register(r"statistics", StatisticsView, basename="statistics")
3527

3628
api_urls = [
37-
url(r"data/(?P<sensor_type>[air]+)/", include(stat_data_router.urls)),
38-
url(r"data/", include(data_router.urls)),
39-
url(r"cities/", include(cities_router.urls)),
40-
url(r"nodes/", include(nodes_router.urls)),
41-
url(r"locations/", include(sensor_locations_router.urls)),
42-
url(r"sensors/", include(sensors_router.urls)),
43-
url(r"sensor-types/", include(sensor_types_router.urls)),
44-
url(r"meta/", meta_data),
29+
url(r"^", include(router.urls)),
30+
url(r"^meta/", meta_data),
4531
]

0 commit comments

Comments
 (0)