mirror of
https://github.com/daniviga/bite.git
synced 2024-12-23 00:31:25 +01:00
API improvements (#22)
* Add swagger ui * API improvements * Fix nginx and pre-compile python to speedup start * Add flake8 testing
This commit is contained in:
parent
b15b88aab4
commit
165ae3d3c0
@ -42,6 +42,11 @@ jobs:
|
||||
- docker-compose -f docker/docker-compose.yml up -d
|
||||
script:
|
||||
- docker-compose -f docker/docker-compose.yml exec bite python manage.py test
|
||||
- stage: django
|
||||
install:
|
||||
- pip3 -q install flake8
|
||||
script:
|
||||
- flake8 bite --exclude migrations,settings.py
|
||||
- <<: *iot-simulator
|
||||
env: IOT_TL=http
|
||||
- <<: *iot-simulator
|
||||
|
@ -26,16 +26,3 @@ from api.serializers import DeviceSerializer
|
||||
class APISubscribe(ModelViewSet):
|
||||
queryset = Device.objects.all()
|
||||
serializer_class = DeviceSerializer
|
||||
|
||||
# def post(self, request):
|
||||
# serializer = DeviceSerializer(data=request.data)
|
||||
# if serializer.is_valid():
|
||||
# serializer.save()
|
||||
# return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||
# return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# def get(self, request):
|
||||
# devices = Device.objects.all()
|
||||
# import pdb; pdb.set_trace()
|
||||
# serializer = DeviceSerializer(devices)
|
||||
# return Response(serializer.serial)
|
||||
|
24
bite/bite/templates/swagger.html
Normal file
24
bite/bite/templates/swagger.html
Normal file
@ -0,0 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Swagger</title>
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" type="text/css" href="//unpkg.com/swagger-ui-dist@3/swagger-ui.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="swagger-ui"></div>
|
||||
<script src="//unpkg.com/swagger-ui-dist@3/swagger-ui-bundle.js"></script>
|
||||
<script>
|
||||
const ui = SwaggerUIBundle({
|
||||
url: "{% url schema_url %}",
|
||||
dom_id: '#swagger-ui',
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIBundle.SwaggerUIStandalonePreset
|
||||
],
|
||||
layout: "BaseLayout"
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -34,6 +34,7 @@ Including another URLconf
|
||||
"""
|
||||
|
||||
from django.contrib import admin
|
||||
from django.conf import settings
|
||||
from django.urls import include, path
|
||||
|
||||
from api import urls as api_urls
|
||||
@ -45,3 +46,19 @@ urlpatterns = [
|
||||
path('api/', include(api_urls)),
|
||||
path('telemetry/', include(telemetry_urls)),
|
||||
]
|
||||
|
||||
if settings.DEBUG:
|
||||
from django.views.generic import TemplateView
|
||||
from rest_framework.schemas import get_schema_view
|
||||
|
||||
urlpatterns += [
|
||||
path('swagger/', TemplateView.as_view(
|
||||
template_name='swagger.html',
|
||||
extra_context={'schema_url': 'openapi-schema'}
|
||||
), name='swagger'),
|
||||
path('openapi', get_schema_view(
|
||||
title="BITE - A Basic/IoT/Example",
|
||||
description="BITE API for IoT",
|
||||
version="1.0.0"
|
||||
), name='openapi-schema'),
|
||||
]
|
||||
|
@ -22,6 +22,17 @@ from api.models import Device
|
||||
from telemetry.models import Telemetry
|
||||
|
||||
|
||||
class TelemetryStatsSerializer(serializers.Serializer):
|
||||
count_samples = serializers.IntegerField()
|
||||
first_sample = serializers.DateTimeField()
|
||||
last_sample = serializers.DateTimeField()
|
||||
|
||||
|
||||
class TelemetrySummarySerializer(serializers.Serializer):
|
||||
device = serializers.CharField()
|
||||
stats = TelemetryStatsSerializer()
|
||||
|
||||
|
||||
class TelemetrySerializer(serializers.ModelSerializer):
|
||||
device = serializers.SlugRelatedField(
|
||||
slug_field='serial',
|
||||
|
@ -33,14 +33,15 @@ Including another URLconf
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
from django.urls import path
|
||||
from telemetry.views import TelemetryView, TelemetryLatest, TelemetryRange
|
||||
from telemetry.views import (TelemetryView, TelemetrySummaryView,
|
||||
TelemetryLatest, TelemetryRange)
|
||||
|
||||
urlpatterns = [
|
||||
path('',
|
||||
TelemetryView.as_view({'post': 'create'}),
|
||||
name='telemetry'),
|
||||
path('<str:device>/',
|
||||
TelemetryView.as_view({'get': 'list'}),
|
||||
TelemetrySummaryView.as_view(),
|
||||
name='device-telemetry'),
|
||||
path('<str:device>/last/',
|
||||
TelemetryLatest.as_view({'get': 'retrieve'}),
|
||||
|
@ -19,10 +19,12 @@
|
||||
|
||||
from datetime import datetime
|
||||
from django.http import Http404
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
from telemetry.models import Telemetry
|
||||
from telemetry.serializers import TelemetrySerializer
|
||||
from telemetry.serializers import (TelemetrySerializer,
|
||||
TelemetrySummarySerializer)
|
||||
from rest_framework.response import Response
|
||||
|
||||
|
||||
@ -39,15 +41,36 @@ class TelemetryView(ModelViewSet):
|
||||
return Response(serializer.data)
|
||||
|
||||
|
||||
class TelemetrySummaryView(APIView):
|
||||
def get(self, request, device, format=None):
|
||||
count = Telemetry.objects.filter(device__serial=device).count()
|
||||
if count == 0:
|
||||
raise Http404
|
||||
first = Telemetry.objects.filter(
|
||||
device__serial=device).order_by('-time')[:1][0]
|
||||
last = Telemetry.objects.filter(
|
||||
device__serial=device).order_by('time')[:1][0]
|
||||
data = {
|
||||
'device': device,
|
||||
'stats': {
|
||||
'count_samples': count,
|
||||
'first_sample': first.time,
|
||||
'last_sample': last.time}
|
||||
}
|
||||
serializer = TelemetrySummarySerializer(data)
|
||||
return Response(serializer.data)
|
||||
|
||||
|
||||
class TelemetryRange(ModelViewSet):
|
||||
queryset = Telemetry.objects.all()
|
||||
serializer_class = TelemetrySerializer
|
||||
lookup_field = 'device'
|
||||
|
||||
def list(self, request, device, time_from, time_to=None):
|
||||
time_to = datetime.now() if time_to is None else time_to
|
||||
queryset = Telemetry.objects.filter(
|
||||
device__serial=device,
|
||||
time__range=[time_from, datetime.now()])
|
||||
time__range=[time_from, time_to])
|
||||
if not queryset:
|
||||
raise Http404
|
||||
serializer = TelemetrySerializer(queryset, many=True)
|
||||
@ -61,7 +84,7 @@ class TelemetryLatest(ModelViewSet):
|
||||
|
||||
def retrieve(self, request, device=None):
|
||||
queryset = Telemetry.objects.filter(
|
||||
device__serial=device).order_by('-time')
|
||||
device__serial=device).order_by('-time')[:1]
|
||||
if not queryset:
|
||||
raise Http404
|
||||
serializer = TelemetrySerializer(queryset[0])
|
||||
|
@ -35,6 +35,7 @@ COPY --chown=1000:1000 bite /srv/app/bite
|
||||
COPY --chown=1000:1000 requirements.txt /srv/app/bite/requirements.txt
|
||||
|
||||
RUN pip3 install -r /srv/app/bite/requirements.txt \
|
||||
&& python3 -m compileall -q /srv/app/bite \
|
||||
&& mkdir -p /srv/appdata/bite/static \
|
||||
&& chown -R 1000:1000 /srv/appdata/bite
|
||||
|
||||
|
@ -48,13 +48,13 @@ http {
|
||||
'' close;
|
||||
}
|
||||
|
||||
upstream bite {
|
||||
upstream django {
|
||||
# We point to the Docker 'service' instead of directly to the container
|
||||
# Docker does then a DNS round-robin internally
|
||||
server bite:8000;
|
||||
}
|
||||
|
||||
upstream broker {
|
||||
upstream mqtt {
|
||||
# We point to the Docker 'service' instead of directly to the container
|
||||
# Docker does then a DNS round-robin internally
|
||||
server broker:9001;
|
||||
@ -69,7 +69,7 @@ http {
|
||||
keepalive_timeout 60 60;
|
||||
|
||||
location / {
|
||||
proxy_pass http://bite;
|
||||
proxy_pass http://django;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
@ -85,7 +85,7 @@ http {
|
||||
}
|
||||
|
||||
location /mqtt {
|
||||
proxy_pass http://broker;
|
||||
proxy_pass http://mqtt;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
|
@ -4,5 +4,7 @@ django-health-check
|
||||
psycopg2-binary
|
||||
paho-mqtt==1.5.0
|
||||
asyncio-mqtt==0.5.0
|
||||
PyYAML
|
||||
uritemplate
|
||||
pygments
|
||||
gunicorn
|
||||
|
Loading…
Reference in New Issue
Block a user