So,
I'm documenting the following piece of code using drf-spectacular
:
from rest_framework import response
from rest_framework.decorators import api_view, permission_classes
from rest_framework.response import Response
from rest_framework.permissions import AllowAny
from rest_framework import status
from drf_spectacular.utils import extend_schema, OpenApiParameter
def passcode_generator:
return 0 # placeholder
@extend_schema(
parameters=[
OpenApiParameter(name="callsign", required=True, type=str),
],
description="Get an APRS-IS passcode for a given callsign",
)
@api_view(["POST"])
@permission_classes([AllowAny])
def get_passcode(request):
callsign = request.data.get("callsign", None)
if callsign is None:
raise Response(
{"error": "Missing callsign"}, status=status.HTTP_400_BAD_REQUEST
)
return Response({"passcode": passcode_generator(callsign)})
What I can't understand how to do is how to document the responses. Namely, there is OpenApiResponse
in drf_spectacular.utils
but the documentation is very slim. How can I document the responses of my API with this system?
In the meanwhile, I found out a satisfying answer that also keeps automatic documentation generators happy:
I created a couple serializers:
from rest_framework import serializers
class CallsignSerializer(serializers.Serializer):
callsign = serializers.CharField(max_length=200)
class PasscodeSerializer(serializers.Serializer):
passcode = serializers.CharField(max_length=200)
And in the views (notice the comment before the last line):
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import AllowAny
from drf_spectacular.utils import extend_schema
from aprs.api.serializers import CallsignSerializer, PasscodeSerializer
from aprs.vendor.passcode import passcode_generator
class PasscodeView(APIView):
"""
View to get the APRS passcode from a callsign
"""
permission_classes = [
AllowAny,
]
serializer_class = CallsignSerializer
@extend_schema(responses=PasscodeSerializer)
def post(self, request):
"""
Get the APRS passcode from a callsign
"""
serializer = CallsignSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
callsign = serializer.validated_data["callsign"]
passcode = passcode_generator(callsign)
passcode_serializer = PasscodeSerializer(data={"passcode": passcode})
passcode_serializer.is_valid(raise_exception=True)
# The serializer isn't passed here directly because otherwise DRF's browsable API
# will create a POST form for the PasscodeSerializer, instead of the
# CallsignSerializer. It is used in the lines above, instead of passing a
# dictionary here directly as a form of validation.
return Response(passcode_serializer.validated_data)