Skip to content

Commit

Permalink
✨ [#175] added expand for detail endpoints in redoc
Browse files Browse the repository at this point in the history
  • Loading branch information
bart-maykin committed Apr 10, 2024
1 parent 0f7d5ba commit 49ac3bd
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@
from openklant.components.utils.filters import ExpandFilter


class KlantcontactDetailFilterSet(FilterSet):
expand = ExpandFilter(
serializer_class=KlantcontactSerializer,
help_text=_(
"Sluit de gespecifieerde gerelateerde resources in in het antwoord."
),
)


class KlantcontactFilterSet(FilterSet):
had_betrokkene__url = filters.CharFilter(
help_text=_("Zoek klantcontact object op basis van het betrokkene url"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@
from openklant.components.utils.filters import ExpandFilter


class PartijDetailFilterSet(FilterSet):
expand = ExpandFilter(
serializer_class=PartijSerializer,
help_text=_(
"Sluit de gespecifieerde gerelateerde resources in in het antwoord."
),
)


class PartijFilterSet(FilterSet):
vertegenwoordigde_partij__uuid = filters.UUIDFilter(
help_text=_(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from openklant.components.klantinteracties.api.filterset.klantcontacten import (
ActorKlantcontactFilterSet,
BetrokkeneFilterSet,
KlantcontactDetailFilterSet,
KlantcontactFilterSet,
)
from openklant.components.klantinteracties.api.serializers.klantcontacten import (
Expand Down Expand Up @@ -68,10 +69,18 @@ class KlantcontactViewSet(ExpandMixin, viewsets.ModelViewSet):
serializer_class = KlantcontactSerializer
lookup_field = "uuid"
pagination_class = PageNumberPagination
filterset_class = KlantcontactFilterSet
authentication_classes = (TokenAuthentication,)
permission_classes = (TokenPermissions,)

@property
def filterset_class(self):
"""
support expand in the detail endpoint
"""
if self.detail:
return KlantcontactDetailFilterSet
return KlantcontactFilterSet


@extend_schema(tags=["betrokkenen"])
@extend_schema_view(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from openklant.components.klantinteracties.api.filterset.partijen import (
CategorieRelatieFilterSet,
PartijDetailFilterSet,
PartijFilterSet,
VertegenwoordigdenFilterSet,
)
Expand Down Expand Up @@ -72,10 +73,18 @@ class PartijViewSet(ExpandMixin, viewsets.ModelViewSet):
serializer_class = PartijSerializer
lookup_field = "uuid"
pagination_class = PageNumberPagination
filterset_class = PartijFilterSet
authentication_classes = (TokenAuthentication,)
permission_classes = (TokenPermissions,)

@property
def filterset_class(self):
"""
support expand in the detail endpoint
"""
if self.detail:
return PartijDetailFilterSet
return PartijFilterSet


@extend_schema(tags=["vertegenwoordigingen"])
@extend_schema_view(
Expand Down
86 changes: 86 additions & 0 deletions src/openklant/components/klantinteracties/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1577,6 +1577,30 @@ paths:
description: Een specifiek klant contact opvragen.
summary: Een specifiek klant contact opvragen.
parameters:
- in: query
name: expand
schema:
type: array
items:
type: string
enum:
- gingOverOnderwerpobjecten
- hadBetrokkenen
- hadBetrokkenen.digitaleAdressen
- hadBetrokkenen.wasPartij
- leiddeTotInterneTaken
- omvatteBijlagen
description: |-
Sluit de gespecifieerde gerelateerde resources in in het antwoord.
* `hadBetrokkenen` - had_betrokkenen
* `leiddeTotInterneTaken` - leidde_tot_interne_taken
* `gingOverOnderwerpobjecten` - ging_over_onderwerpobjecten
* `omvatteBijlagen` - omvatte_bijlagen
* `hadBetrokkenen.wasPartij` - had_betrokkenen.was_partij
* `hadBetrokkenen.digitaleAdressen` - had_betrokkenen.digitale_adressen
explode: false
style: form
- in: path
name: uuid
schema:
Expand Down Expand Up @@ -2175,6 +2199,26 @@ paths:
description: Een specifiek partij opvragen.
summary: Een specifiek partij opvragen.
parameters:
- in: query
name: expand
schema:
type: array
items:
type: string
enum:
- betrokkenen
- betrokkenen.hadKlantcontact
- categorieRelaties
- digitaleAdressen
description: |-
Sluit de gespecifieerde gerelateerde resources in in het antwoord.
* `digitaleAdressen` - digitale_adressen
* `betrokkenen` - betrokkenen
* `categorieRelaties` - categorie_relaties
* `betrokkenen.hadKlantcontact` - betrokkenen.had_klantcontact
explode: false
style: form
- in: path
name: uuid
schema:
Expand Down Expand Up @@ -3488,6 +3532,9 @@ components:
maxLength: 200
PaginatedActorKlantcontactList:
type: object
required:
- count
- results
properties:
count:
type: integer
Expand All @@ -3508,6 +3555,9 @@ components:
$ref: '#/components/schemas/ActorKlantcontact'
PaginatedActorList:
type: object
required:
- count
- results
properties:
count:
type: integer
Expand All @@ -3528,6 +3578,9 @@ components:
$ref: '#/components/schemas/Actor'
PaginatedBetrokkeneList:
type: object
required:
- count
- results
properties:
count:
type: integer
Expand All @@ -3548,6 +3601,9 @@ components:
$ref: '#/components/schemas/Betrokkene'
PaginatedBijlageList:
type: object
required:
- count
- results
properties:
count:
type: integer
Expand All @@ -3568,6 +3624,9 @@ components:
$ref: '#/components/schemas/Bijlage'
PaginatedCategorieList:
type: object
required:
- count
- results
properties:
count:
type: integer
Expand All @@ -3588,6 +3647,9 @@ components:
$ref: '#/components/schemas/Categorie'
PaginatedCategorieRelatieList:
type: object
required:
- count
- results
properties:
count:
type: integer
Expand All @@ -3608,6 +3670,9 @@ components:
$ref: '#/components/schemas/CategorieRelatie'
PaginatedDigitaalAdresList:
type: object
required:
- count
- results
properties:
count:
type: integer
Expand All @@ -3628,6 +3693,9 @@ components:
$ref: '#/components/schemas/DigitaalAdres'
PaginatedInterneTaakList:
type: object
required:
- count
- results
properties:
count:
type: integer
Expand All @@ -3648,6 +3716,9 @@ components:
$ref: '#/components/schemas/InterneTaak'
PaginatedKlantcontactList:
type: object
required:
- count
- results
properties:
count:
type: integer
Expand All @@ -3668,6 +3739,9 @@ components:
$ref: '#/components/schemas/Klantcontact'
PaginatedOnderwerpobjectList:
type: object
required:
- count
- results
properties:
count:
type: integer
Expand All @@ -3688,6 +3762,9 @@ components:
$ref: '#/components/schemas/Onderwerpobject'
PaginatedPartijIdentificatorList:
type: object
required:
- count
- results
properties:
count:
type: integer
Expand All @@ -3708,6 +3785,9 @@ components:
$ref: '#/components/schemas/PartijIdentificator'
PaginatedPartijList:
type: object
required:
- count
- results
properties:
count:
type: integer
Expand All @@ -3728,6 +3808,9 @@ components:
$ref: '#/components/schemas/Partij'
PaginatedRekeningnummerList:
type: object
required:
- count
- results
properties:
count:
type: integer
Expand All @@ -3748,6 +3831,9 @@ components:
$ref: '#/components/schemas/Rekeningnummer'
PaginatedVertegenwoordigdenList:
type: object
required:
- count
- results
properties:
count:
type: integer
Expand Down
6 changes: 0 additions & 6 deletions src/openklant/components/utils/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,3 @@ class ExpandMixin:

def include_allowed(self):
return self.action in ["list", "retrieve"]

def get_requested_inclusions(self, request):
# Pull expand parameter from request body in case of _zoek operation
if request.method == "POST":
return ",".join(request.data.get(self.expand_param, []))
return request.GET.get(self.expand_param)
3 changes: 2 additions & 1 deletion src/openklant/conf/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
REST_FRAMEWORK["DEFAULT_PAGINATION_CLASS"] = (
"rest_framework.pagination.PageNumberPagination"
)
REST_FRAMEWORK["DEFAULT_SCHEMA_CLASS"] = "drf_spectacular.openapi.AutoSchema"
REST_FRAMEWORK["DEFAULT_SCHEMA_CLASS"] = "openklant.utils.schema.AutoSchema"


SPECTACULAR_SETTINGS = {
"SERVE_INCLUDE_SCHEMA": False,
Expand Down
66 changes: 66 additions & 0 deletions src/openklant/utils/schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# SPDX-License-Identifier: EUPL-1.2
# Copyright (C) 2019 - 2020 Dimpact
import logging
from typing import List

from django.conf import settings
from django.utils.translation import gettext_lazy as _

from drf_spectacular.openapi import AutoSchema as _AutoSchema
from drf_spectacular.utils import OpenApiParameter
from furl import furl
from rest_framework import serializers, status
from vng_api_common.inspectors.view import COMMON_ERRORS
from vng_api_common.serializers import FoutSerializer, ValidatieFoutSerializer

logger = logging.getLogger(__name__)


COMMON_ERROR_STATUSES = [e.status_code for e in COMMON_ERRORS]
# error responses
COMMON_ERROR_RESPONSES = {status: FoutSerializer for status in COMMON_ERROR_STATUSES}
VALIDATION_ERROR_RESPONSES = {status.HTTP_400_BAD_REQUEST: ValidatieFoutSerializer}
FILE_ERROR_RESPONSES = {status.HTTP_413_REQUEST_ENTITY_TOO_LARGE: FoutSerializer}
PRECONDITION_ERROR_RESPONSES = {status.HTTP_412_PRECONDITION_FAILED: FoutSerializer}


def get_component_from_serializer(serializer: serializers.Serializer) -> str:
return serializer.Meta.model._meta.app_label


def get_external_schema_ref(serializer: serializers.Serializer) -> str:
"""
Constructs the schema references for external resource
"""
component = get_component_from_serializer(serializer)
oas_url = settings.EXTERNAL_API_MAPPING[component].oas_url
resource_name = serializer.Meta.model._meta.object_name

f = furl(oas_url)
f.fragment.path = f"/components/schemas/{resource_name}"
return f.url


class AutoSchema(_AutoSchema):
def get_content_type_headers(self) -> List[OpenApiParameter]:
if self.method not in ["POST", "PUT", "PATCH"]:
return []

return [
OpenApiParameter(
name="Content-Type",
type=str,
location=OpenApiParameter.HEADER,
description=_("Content type of the request body."),
enum=["application/json"],
required=True,
)
]

def get_filter_backends(self):
"""support expand for detail views"""
include_allowed = getattr(self.view, "include_allowed", lambda: False)()
if self.method == "GET" and include_allowed:
return getattr(self.view, "filter_backends", [])

return super().get_filter_backends()

0 comments on commit 49ac3bd

Please sign in to comment.