Skip to content

Commit

Permalink
Add REST API
Browse files Browse the repository at this point in the history
  • Loading branch information
timobrembeck committed Dec 17, 2022
1 parent 31cbc9a commit c2ce050
Show file tree
Hide file tree
Showing 11 changed files with 174 additions and 0 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ Django users have to be created in the CRUD backend, available at https://leeway

The program regularly fetches incoming mails via IMAP and starts simulations from key-value-pairs in the mail subject or text body. The sender of the mail needs to have an associated account. Allowed keys via e-mail are: `longitude`, `latitude`, `object_type`, `radius`, `duration`, `start_time`. The separator between key and value is `=`. Key-value-pairs are separated by `;` in the subject and by new lines in the text body. The date format for start date is `YYYY-MM-DD HH:MM:SS`.

# API usage

API documentation can be found at: https://leeway.tuerantuer.org/api/docs/

Authentication can be provided in two ways:
1. Via your session cookie, obtained from the normal login
2. Via an authentication token, can be obtained via [/api/auth/login/](https://leeway.tuerantuer.org/api/v1/docs/#/auth/auth_login_create)

# Installation

**Prerequisite:** _Python 3.8 or later is required._
Expand Down
Empty file.
13 changes: 13 additions & 0 deletions opendrift_leeway_webgui/api/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from django.apps import AppConfig
from django.utils.translation import gettext_lazy as _


class ApiConfig(AppConfig):
"""
Application settings for the `api` app,
which is the app providing the REST API.
Inherits from `AppConfig`.
"""

name = "opendrift_leeway_webgui.api"
verbose_name = _("API")
13 changes: 13 additions & 0 deletions opendrift_leeway_webgui/api/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"""
URL patterns for the Opendrift Leeway Webgui API
"""
from django.urls import include, path

#: The namespace for this URL config (see :attr:`django.urls.ResolverMatch.app_name`)
app_name = "api"

#: The url patterns of this module (see :doc:`django:topics/http/urls`)
urlpatterns = [
path("", include("opendrift_leeway_webgui.api.v1.urls", namespace="default")),
path("v1/", include("opendrift_leeway_webgui.api.v1.urls", namespace="v1")),
]
3 changes: 3 additions & 0 deletions opendrift_leeway_webgui/api/v1/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""
The first version of the Opendrift Leeway Webgui API.
"""
35 changes: 35 additions & 0 deletions opendrift_leeway_webgui/api/v1/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from rest_framework import serializers

from ...leeway.models import LeewaySimulation


class LeewaySimulationSerializer(serializers.ModelSerializer):
"""
Serializer for the Leeway Simulations. Inherits from
`serializers.ModelSerializer`.
"""

#: Show username instead of id
username = serializers.ReadOnlyField(source="user.username")

class Meta:
"""
Define model and the corresponding fields
"""

#: The model class for this serializer
model = LeewaySimulation

#: Exclude user field because the username is shown instead
exclude = ["user"]

#: Define fields which are shown when retrieving simulations,
#: but cannot be set when creating new ones
read_only_fields = [
"uuid",
"img",
"netcdf",
"traceback",
"simulation_started",
"simulation_finished",
]
27 changes: 27 additions & 0 deletions opendrift_leeway_webgui/api/v1/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"""
URL patterns for the first version of the Opendrift Leeway Webgui API
"""
from django.urls import include, path
from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView
from rest_framework.routers import DefaultRouter

from . import views

#: The namespace for this URL config (see :attr:`django.urls.ResolverMatch.app_name`)
app_name = "v1"

#: Router for dynamic url patterns
router = DefaultRouter()
router.register("simulations", views.LeewaySimulationViewSet, "simulations")

#: The url patterns of this module (see :doc:`django:topics/http/urls`)
urlpatterns = [
path("", include(router.urls)),
path("auth/", include("knox.urls")),
path("schema/", SpectacularAPIView.as_view(), name="schema"),
path(
"docs/",
SpectacularSwaggerView.as_view(url_name="api:v1:schema"),
name="swagger-ui",
),
]
38 changes: 38 additions & 0 deletions opendrift_leeway_webgui/api/v1/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from rest_framework import mixins, viewsets
from rest_framework.permissions import IsAuthenticated

from .serializers import LeewaySimulationSerializer


# pylint: disable=too-many-ancestors
class LeewaySimulationViewSet(
mixins.CreateModelMixin,
mixins.ListModelMixin,
mixins.RetrieveModelMixin,
viewsets.GenericViewSet,
):
"""
A viewset for simulations of the authenticated user, with the option to
- Create new simulations
- List all existing simulations
- Retrieve a single simulation record
"""

#: Only enable this viewset for authenticated users
permission_classes = (IsAuthenticated,)

#: The serializer to use for simulations
serializer_class = LeewaySimulationSerializer

def get_queryset(self):
"""
Only return the simulations of the current user
"""
return self.request.user.leewaysimulation_set.all()

def perform_create(self, serializer):
"""
Automatically set the user field on creation
"""
serializer.save(user=self.request.user)
33 changes: 33 additions & 0 deletions opendrift_leeway_webgui/core/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@
"django.contrib.messages",
"django.contrib.staticfiles",
"opendrift_leeway_webgui.leeway",
"rest_framework",
"drf_spectacular",
"knox",
]

#: Activated middlewares (see :setting:`django:MIDDLEWARE`)
Expand Down Expand Up @@ -281,6 +284,36 @@
CELERY_RESULT_BACKEND = "redis://localhost:6379/0"


#############################
# DJANGO REST API FRAMEWORK #
#############################

#: The configuration for django-rest-framework (drf)
REST_FRAMEWORK = {
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
"DEFAULT_AUTHENTICATION_CLASSES": (
"rest_framework.authentication.SessionAuthentication",
"knox.auth.TokenAuthentication",
),
"DEFAULT_VERSIONING_CLASS": "rest_framework.versioning.NamespaceVersioning",
"ALLOWED_VERSIONS": ("v1"),
"DEFAULT_VERSION": "default",
}

#: The configuration for the API documentation by drf-spectacular
SPECTACULAR_SETTINGS = {
"TITLE": "Opendrift Leeway Webgui API",
"DESCRIPTION": "The API documentation for the Opendrift Leeway Webgui",
"VERSION": None,
"SCHEMA_PATH_PREFIX": "/api(/v[0-9])?",
"CONTACT": {"email": "tech@integreat-app.de"},
"LICENSE": {
"name": "Apache 2.0",
"url": "https://www.apache.org/licenses/LICENSE-2.0.html",
},
}


##########
# EMAILS #
##########
Expand Down
1 change: 1 addition & 0 deletions opendrift_leeway_webgui/core/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@
path("", include("opendrift_leeway_webgui.leeway.urls")),
path("accounts/", include("django.contrib.auth.urls")),
path("admin/", admin.site.urls),
path("api/", include("opendrift_leeway_webgui.api.urls", namespace="api")),
]
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ classifiers = [
dependencies = [
"celery",
"django>=4.1",
"djangorestframework",
"django-rest-knox",
"dms2dec",
"drf-spectacular",
"redis",
]

Expand Down

0 comments on commit c2ce050

Please sign in to comment.