From 4da66b5e847bc194ec7b6e3f13db5e4bf3273949 Mon Sep 17 00:00:00 2001 From: ghazi Date: Tue, 3 Jun 2025 08:02:16 +0100 Subject: [PATCH 1/4] set the minimum version of drf-spectacular to 0.27.1 since the post-processing hook of this package references a drf-spectacular setting introduced in 0.27.1 --- docs/changelog.md | 1 + pyproject.toml | 2 +- tox.ini | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index e5bfacc..ed4d60a 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -34,6 +34,7 @@ message: "EXCEPTION_HANDLER_CLASS": "path.to.MyExceptionHandler" } ``` +- set minimum version of drf-spectacular to 0.27.1 ## [0.14.1] - 2024-08-10 ### Added diff --git a/pyproject.toml b/pyproject.toml index 567a952..8e12d82 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,7 +59,7 @@ release = [ "tbump", ] openapi = [ - "drf-spectacular>=0.27.0", + "drf-spectacular>=0.27.1", "inflection", ] diff --git a/tox.ini b/tox.ini index 8a5ce3e..d987c14 100644 --- a/tox.ini +++ b/tox.ini @@ -28,7 +28,7 @@ python = deps = pytest pytest-django - drf-spectacular>=0.27.0 + drf-spectacular>=0.27.1 django-filter dj32: Django>=3.2,<4.0 dj40: Django>=4.0,<4.1 From 21304d953370bd9a74b23af46bdf42511cb70389 Mon Sep 17 00:00:00 2001 From: ghazi Date: Tue, 3 Jun 2025 11:39:33 +0100 Subject: [PATCH 2/4] add a test for the expected response of a schema protected with admin permissions --- tests/test_openapi.py | 5 +++++ tests/urls.py | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/tests/test_openapi.py b/tests/test_openapi.py index d5d3531..928a9f0 100644 --- a/tests/test_openapi.py +++ b/tests/test_openapi.py @@ -630,6 +630,11 @@ def test_schema_generated(api_client): assert response.status_code == 200 +def test_protected_schema_response(api_client): + response = api_client.get("/protected-schema/") + assert response.status_code == 403 + + @extend_schema_serializer( examples=[ OpenApiExample( diff --git a/tests/urls.py b/tests/urls.py index 3e8ad1a..b623f0c 100644 --- a/tests/urls.py +++ b/tests/urls.py @@ -1,5 +1,6 @@ from django.urls import path from drf_spectacular.views import SpectacularAPIView +from rest_framework.permissions import IsAdminUser from .views import ( AuthErrorView, @@ -18,4 +19,8 @@ path("rate-limit-error/", RateLimitErrorView.as_view()), path("recursion-error/", RecursionView.as_view()), path("schema/", SpectacularAPIView.as_view(), name="api-schema"), + path( + "protected-schema/", + SpectacularAPIView.as_view(permission_classes=[IsAdminUser]), + ), ] From 77c790f14ad212ae583f0661d5fc258f9c16af9a Mon Sep 17 00:00:00 2001 From: ghazi Date: Tue, 3 Jun 2025 12:22:31 +0100 Subject: [PATCH 3/4] change `ErrorType` from an enum to a type hint and replace the enum members use cases with constants. This avoids triggering an exception when returning a yaml response since the yaml renderer used by drf-spectacular does not handle enums by default fixes #98 --- docs/changelog.md | 13 +++++++++++++ drf_standardized_errors/formatter.py | 16 ++++++++++++---- drf_standardized_errors/types.py | 11 +++++------ 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index ed4d60a..dc5b5f3 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -35,6 +35,19 @@ message: } ``` - set minimum version of drf-spectacular to 0.27.1 +- `drf_standardized_errors.types.ErrorType` is now the following type hint + ```python + from typing import Literal + ErrorType = Literal["validation_error", "client_error", "server_error"] + ``` + `ErrorType` was previously an enum. If you referenced its members in your code, make sure to replace their + use cases with the newly added constants: + ``` + from drf_standardized_errors.types import VALIDATION_ERROR, CLIENT_ERROR, SERVER_ERROR + ErrorType.VALIDATION_ERROR --> VALIDATION_ERROR + ErrorType.CLIENT_ERROR --> CLIENT_ERROR + ErrorType.SERVER_ERROR --> SERVER_ERROR + ``` ## [0.14.1] - 2024-08-10 ### Added diff --git a/drf_standardized_errors/formatter.py b/drf_standardized_errors/formatter.py index c13268d..62d2684 100644 --- a/drf_standardized_errors/formatter.py +++ b/drf_standardized_errors/formatter.py @@ -5,7 +5,15 @@ from rest_framework.status import is_client_error from .settings import package_settings -from .types import Error, ErrorResponse, ErrorType, ExceptionHandlerContext +from .types import ( + CLIENT_ERROR, + SERVER_ERROR, + VALIDATION_ERROR, + Error, + ErrorResponse, + ErrorType, + ExceptionHandlerContext, +) class ExceptionFormatter: @@ -42,11 +50,11 @@ def run(self) -> Any: def get_error_type(self) -> ErrorType: if isinstance(self.exc, exceptions.ValidationError): - return ErrorType.VALIDATION_ERROR + return VALIDATION_ERROR elif is_client_error(self.exc.status_code): - return ErrorType.CLIENT_ERROR + return CLIENT_ERROR else: - return ErrorType.SERVER_ERROR + return SERVER_ERROR def get_errors(self) -> List[Error]: """ diff --git a/drf_standardized_errors/types.py b/drf_standardized_errors/types.py index f10996e..a82acb9 100644 --- a/drf_standardized_errors/types.py +++ b/drf_standardized_errors/types.py @@ -1,6 +1,5 @@ from dataclasses import dataclass -from enum import Enum -from typing import List, Optional, TypedDict +from typing import Final, List, Literal, Optional, TypedDict from rest_framework.request import Request from rest_framework.views import APIView @@ -13,10 +12,10 @@ class ExceptionHandlerContext(TypedDict): request: Optional[Request] -class ErrorType(str, Enum): - VALIDATION_ERROR = "validation_error" - CLIENT_ERROR = "client_error" - SERVER_ERROR = "server_error" +VALIDATION_ERROR: Final = "validation_error" +CLIENT_ERROR: Final = "client_error" +SERVER_ERROR: Final = "server_error" +ErrorType = Literal["validation_error", "client_error", "server_error"] @dataclass From 8b0491f0cc7f3c89e2699899b01dc7046dfc859d Mon Sep 17 00:00:00 2001 From: ghazi Date: Tue, 3 Jun 2025 20:20:29 +0100 Subject: [PATCH 4/4] change `get_examples` to `_get_examples` since `AutoSchema` provided by this package now overrides `_get_examples` --- docs/openapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/openapi.md b/docs/openapi.md index 541a203..0b04c15 100644 --- a/docs/openapi.md +++ b/docs/openapi.md @@ -196,7 +196,7 @@ REST_FRAMEWORK = { ### Already using a custom `AutoSchema` class If you're already overriding the `AutoSchema` class provided by drf-spectacular, be sure to inherit from the -AutoSchema class provided by this package instead. Also, if you're overriding `get_examples` and/or +AutoSchema class provided by this package instead. Also, if you're overriding `_get_examples` and/or `_get_response_bodies`, be sure to call `super`.