diff --git a/.env.template b/.env.template new file mode 100644 index 0000000..84c2e1f --- /dev/null +++ b/.env.template @@ -0,0 +1,8 @@ +SENSORSAFRICA_CELERY_SLACK_WEBHOOK="" +SENSORSAFRICA_CELERY_SLACK_WEBHOOK_FAILURES_ONLY="" +SENSORSAFRICA_DATABASE_URL="" +SENSORSAFRICA_DEBUG="" +SENSORSAFRICA_FLOWER_ADMIN_PASSWORD="" +SENSORSAFRICA_FLOWER_ADMIN_USERNAME="" +SENSORSAFRICA_RABBITMQ_URL="" +SENSORSAFRICA_SENTRY_DSN="" diff --git a/Dockerfile b/Dockerfile index 0ccc619..22c7de7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,6 +13,9 @@ VOLUME [ "/src/logs" ] # Copy the current directory contents into the container at sensorsafrica ADD . /src/ +# Upgrade pip from trusted hosts +RUN python -m pip install --trusted-host pypi.python.org --trusted-host files.pythonhosted.org --trusted-host pypi.org --upgrade pip + # Upgrade pip and setuptools RUN pip install -q -U pip setuptools diff --git a/README.md b/README.md index 1f70360..d364d80 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,12 @@ CREATE DATABASE sensorsafrica; CREATE USER sensorsafrica WITH ENCRYPTED PASSWORD 'sensorsafrica'; GRANT ALL PRIVILEGES ON DATABASE sensorsafrica TO sensorsafrica; ``` - - Migrate the database; `python manage.py migrate` +- Create super user for admin login; `python manage.py createsuperuser` + username: `sensorsafrica` + email: blank + password: `sensorsafrica` + - Run the server; `python manage.py runserver` ### Docker diff --git a/docker-compose.yml b/docker-compose.yml index 49c12ef..f8d7571 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,15 +2,20 @@ version: '3.3' services: rabbitmq: - image: rabbitmq:3.5.1 + image: rabbitmq:3.12.7-management ports: - - 4369:4369 - - 5672:5672 - - 25672:25672 - - 15672:15672 + - "5672:5672" + # GUI port + - "15672:15672" environment: - - RABBITMQ_USERNAME=sensorsafrica - - RABBITMQ_PASSWORD=sensorsafrica + - RABBITMQ_DEFAULT_USER=sensorsafrica + - RABBITMQ_DEFAULT_PASS=sensorsafrica + healthcheck: + test: [ "CMD-SHELL", "rabbitmq-diagnostics -q ping" ] + interval: 10s + timeout: 5s + retries: 2 + postgres: image: postgres:13.7 ports: @@ -21,15 +26,15 @@ services: - POSTGRES_DB=sensorsafrica volumes: - postgres_data:/var/lib/postgresql/data/ + api: build: context: . environment: - SENSORSAFRICA_DATABASE_URL: postgres://sensorsafrica:sensorsafrica@postgres:5432/sensorsafrica - SENSORSAFRICA_READ_DATABASE_URLS: postgres://sensorsafrica:sensorsafrica@postgres:5432/sensorsafrica - SENSORSAFRICA_RABBITMQ_URL: amqp://sensorsafrica:sensorsafrica@rabbitmq// - SENSORSAFRICA_FLOWER_ADMIN_USERNAME: admin - SENSORSAFRICA_FLOWER_ADMIN_PASSWORD: password + SENSORSAFRICA_DATABASE_URL: ${SENSORSAFRICA_DATABASE_URL} + SENSORSAFRICA_RABBITMQ_URL: ${SENSORSAFRICA_RABBITMQ_URL} + SENSORSAFRICA_FLOWER_ADMIN_USERNAME: ${SENSORSAFRICA_FLOWER_ADMIN_USERNAME} + SENSORSAFRICA_FLOWER_ADMIN_PASSWORD: ${SENSORSAFRICA_FLOWER_ADMIN_PASSWORD} DOKKU_APP_NAME: sensorsafrica depends_on: - postgres diff --git a/requirements.txt b/requirements.txt index 92145ee..086b243 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,7 +18,7 @@ ckanapi==4.1 celery-slack==0.3.0 -urllib3<1.25,>=1.21.1 #requests 2.21.0 +urllib3<2 django-cors-headers==3.0.2 diff --git a/sensorsafrica/api/v1/router.py b/sensorsafrica/api/v1/router.py index c923328..4a93a11 100644 --- a/sensorsafrica/api/v1/router.py +++ b/sensorsafrica/api/v1/router.py @@ -1,11 +1,3 @@ -# The base version is entirely based on feinstaub -from feinstaub.main.views import UsersView -from feinstaub.sensors.views import ( - SensorView, - StatisticsView, - SensorDataView, -) - from .views import ( FilterView, NodeView, @@ -13,6 +5,9 @@ PostSensorDataView, SensorsAfricaSensorDataView, VerboseSensorDataView, + SensorView, + StatisticsView, + UsersView, ) from rest_framework import routers diff --git a/sensorsafrica/api/v1/views.py b/sensorsafrica/api/v1/views.py index 6c6a83a..cd37171 100644 --- a/sensorsafrica/api/v1/views.py +++ b/sensorsafrica/api/v1/views.py @@ -5,18 +5,22 @@ from django.conf import settings -from django.db.models import ExpressionWrapper, F, FloatField, Max, Min, Sum, Avg, Q -from django.db.models.functions import Cast, TruncDate -from dateutil.relativedelta import relativedelta +from django.db.models import Q from django.utils import timezone -from rest_framework import mixins, pagination, viewsets +from rest_framework import mixins,viewsets from rest_framework.authentication import SessionAuthentication, TokenAuthentication -from rest_framework.exceptions import ValidationError -from rest_framework.permissions import IsAuthenticatedOrReadOnly +from rest_framework.permissions import IsAuthenticatedOrReadOnly, IsAuthenticated +from feinstaub.main.views import UsersView as FeinstaubUsersView from feinstaub.sensors.models import Node, SensorData from feinstaub.sensors.serializers import NowSerializer -from feinstaub.sensors.views import SensorDataView, StandardResultsSetPagination +from feinstaub.sensors.views import ( + SensorDataView, + StandardResultsSetPagination, + SensorView as FeinstaubSensorView, + StatisticsView as FeinstaubStatisticsView + +) from feinstaub.sensors.authentication import NodeUidAuthentication from .filters import NodeFilter, SensorFilter @@ -72,8 +76,8 @@ def get_queryset(self): class NowView(mixins.ListModelMixin, viewsets.GenericViewSet): """Show all public sensors active in the last 5 minutes with newest value""" - - permission_classes = [] + authentication_classes=[SessionAuthentication, TokenAuthentication] + permission_classes = [IsAuthenticated] serializer_class = NowSerializer queryset = SensorData.objects.none() @@ -92,9 +96,11 @@ class PostSensorDataView(mixins.CreateModelMixin, permission_classes = tuple() serializer_class = LastNotifySensorDataSerializer queryset = SensorData.objects.all() - + class VerboseSensorDataView(SensorDataView): + authentication_classes=[SessionAuthentication, TokenAuthentication] + permission_classes=[IsAuthenticated] filter_class = SensorFilter class SensorsAfricaSensorDataView(mixins.ListModelMixin, viewsets.GenericViewSet): @@ -110,3 +116,15 @@ def get_queryset(self): .prefetch_related("sensordatavalues") ) + +class UsersView(FeinstaubUsersView): + authentication_classes=[SessionAuthentication, TokenAuthentication] + permission_classes = [IsAuthenticated] + +class SensorView(FeinstaubSensorView): + authentication_classes=[SessionAuthentication, TokenAuthentication] + permission_classes = [IsAuthenticated] + +class StatisticsView(FeinstaubStatisticsView): + authentication_classes=[SessionAuthentication, TokenAuthentication] + permission_classes = [IsAuthenticated] diff --git a/sensorsafrica/migrations/0004_auto_20190509_1145.py b/sensorsafrica/migrations/0004_auto_20190509_1145.py index 112353b..c673fbe 100644 --- a/sensorsafrica/migrations/0004_auto_20190509_1145.py +++ b/sensorsafrica/migrations/0004_auto_20190509_1145.py @@ -9,10 +9,7 @@ class Migration(migrations.Migration): - dependencies = [ - ('sensors', '0020_auto_20190314_1232'), - ('sensorsafrica', '0003_auto_20190222_1137'), - ] + dependencies = [('sensorsafrica', '0003_auto_20190222_1137')] operations = [ migrations.CreateModel( diff --git a/sensorsafrica/settings.py b/sensorsafrica/settings.py index fcbbf17..2377373 100644 --- a/sensorsafrica/settings.py +++ b/sensorsafrica/settings.py @@ -113,13 +113,6 @@ DATABASES = {"default": dj_database_url.parse(DATABASE_URL), } -READ_DATABASE_URLS = os.getenv("SENSORSAFRICA_READ_DATABASE_URLS", DATABASE_URL).split(",") - -for index, read_database_url in enumerate(READ_DATABASE_URLS,start=1): - DATABASES[f"read_replica_{index}"] = dj_database_url.parse(read_database_url) - -DATABASE_ROUTERS = ["sensorsafrica.router.ReplicaRouter", ] - # Password validation # https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators