From f8f6b3abd428fb5ee5443a71b1b41b144fe8d565 Mon Sep 17 00:00:00 2001 From: Nick Pope Date: Fri, 17 Sep 2021 20:02:43 +0100 Subject: [PATCH] Add missing types defined in specification. See the following links: - https://spec.openapis.org/oas/v3.0.3#data-types - https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-validation-00#section-7.3 --- docs/drf_yasg.rst | 9 +++++++++ drf_spectacular/types.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/docs/drf_yasg.rst b/docs/drf_yasg.rst index b630ca32..1fdb5f99 100644 --- a/docs/drf_yasg.rst +++ b/docs/drf_yasg.rst @@ -122,8 +122,17 @@ provides the :py:class:`~drf_spectacular.types.OpenApiTypes` enum: - :py:attr:`~drf_spectacular.types.OpenApiTypes.ANY` for which you can use :py:class:`typing.Any`. - :py:attr:`~drf_spectacular.types.OpenApiTypes.DURATION` for which you can use :py:class:`datetime.timedelta`. - :py:attr:`~drf_spectacular.types.OpenApiTypes.HOSTNAME` + - :py:attr:`~drf_spectacular.types.OpenApiTypes.IDN_EMAIL` + - :py:attr:`~drf_spectacular.types.OpenApiTypes.IDN_HOSTNAME` + - :py:attr:`~drf_spectacular.types.OpenApiTypes.IRI_REF` + - :py:attr:`~drf_spectacular.types.OpenApiTypes.IRI` + - :py:attr:`~drf_spectacular.types.OpenApiTypes.JSON_PTR_REL` + - :py:attr:`~drf_spectacular.types.OpenApiTypes.JSON_PTR` - :py:attr:`~drf_spectacular.types.OpenApiTypes.NONE` for which you can use :py:data:`None`. + - :py:attr:`~drf_spectacular.types.OpenApiTypes.REGEX` for which you can use :py:class:`re.Pattern`. - :py:attr:`~drf_spectacular.types.OpenApiTypes.TIME` for which you can use :py:class:`datetime.time`. + - :py:attr:`~drf_spectacular.types.OpenApiTypes.URI_REF` + - :py:attr:`~drf_spectacular.types.OpenApiTypes.URI_TPL` Parameter Location ------------------ diff --git a/drf_spectacular/types.py b/drf_spectacular/types.py index 28543f89..d1a1b720 100644 --- a/drf_spectacular/types.py +++ b/drf_spectacular/types.py @@ -3,6 +3,7 @@ from datetime import date, datetime, time, timedelta from decimal import Decimal from ipaddress import IPv4Address, IPv6Address +from re import Pattern from uuid import UUID from drf_spectacular.settings import spectacular_settings @@ -54,6 +55,14 @@ class OpenApiTypes(enum.Enum): UUID = enum.auto() #: Converted to ``{"type": "string", "format": "uri"}``. URI = enum.auto() + #: Converted to ``{"type": "string", "format": "uri-reference"}``. + URI_REF = enum.auto() + #: Converted to ``{"type": "string", "format": "uri-template"}``. + URI_TPL = enum.auto() + #: Converted to ``{"type": "string", "format": "iri"}``. + IRI = enum.auto() + #: Converted to ``{"type": "string", "format": "iri-reference"}``. + IRI_REF = enum.auto() #: Converted to ``{"type": "string", "format": "ipv4"}``. #: Equivalent to :py:class:`~ipaddress.IPv4Address`. IP4 = enum.auto() @@ -62,6 +71,8 @@ class OpenApiTypes(enum.Enum): IP6 = enum.auto() #: Converted to ``{"type": "string", "format": "hostname"}``. HOSTNAME = enum.auto() + #: Converted to ``{"type": "string", "format": "idn-hostname"}``. + IDN_HOSTNAME = enum.auto() #: Converted to ``{"type": "number", "format": "double"}``. #: The same as :py:attr:`~drf_spectacular.types.OpenApiTypes.DOUBLE`. #: Equivalent to :py:class:`~decimal.Decimal`. @@ -81,6 +92,15 @@ class OpenApiTypes(enum.Enum): DURATION = enum.auto() #: Converted to ``{"type": "string", "format": "email"}``. EMAIL = enum.auto() + #: Converted to ``{"type": "string", "format": "idn-email"}``. + IDN_EMAIL = enum.auto() + #: Converted to ``{"type": "string", "format": "json-pointer"}``. + JSON_PTR = enum.auto() + #: Converted to ``{"type": "string", "format": "relative-json-pointer"}``. + JSON_PTR_REL = enum.auto() + #: Converted to ``{"type": "string", "format": "regex"}``. + #: Equivalent to :py:class:`~re.Pattern`. + REGEX = enum.auto() #: Converted to ``{"type": "object", ...}``. #: Use this for arbitrary free-form objects (usually a :py:class:`dict`). #: The ``additionalProperties`` item is added depending on the ``GENERIC_ADDITIONAL_PROPERTIES`` setting. @@ -117,15 +137,24 @@ def build_generic_type(): OpenApiTypes.INT64: {'type': 'integer', 'format': 'int64'}, OpenApiTypes.UUID: {'type': 'string', 'format': 'uuid'}, OpenApiTypes.URI: {'type': 'string', 'format': 'uri'}, + OpenApiTypes.URI_REF: {'type': 'string', 'format': 'uri-reference'}, + OpenApiTypes.URI_TPL: {'type': 'string', 'format': 'uri-template'}, + OpenApiTypes.IRI: {'type': 'string', 'format': 'iri'}, + OpenApiTypes.IRI_REF: {'type': 'string', 'format': 'iri-reference'}, OpenApiTypes.IP4: {'type': 'string', 'format': 'ipv4'}, OpenApiTypes.IP6: {'type': 'string', 'format': 'ipv6'}, OpenApiTypes.HOSTNAME: {'type': 'string', 'format': 'hostname'}, + OpenApiTypes.IDN_HOSTNAME: {'type': 'string', 'format': 'idn-hostname'}, OpenApiTypes.DECIMAL: {'type': 'number', 'format': 'double'}, OpenApiTypes.DATETIME: {'type': 'string', 'format': 'date-time'}, OpenApiTypes.DATE: {'type': 'string', 'format': 'date'}, OpenApiTypes.TIME: {'type': 'string', 'format': 'time'}, OpenApiTypes.DURATION: {'type': 'string', 'format': 'duration'}, # ISO 8601 OpenApiTypes.EMAIL: {'type': 'string', 'format': 'email'}, + OpenApiTypes.IDN_EMAIL: {'type': 'string', 'format': 'idn-email'}, + OpenApiTypes.JSON_PTR: {'type': 'string', 'format': 'json-pointer'}, + OpenApiTypes.JSON_PTR_REL: {'type': 'string', 'format': 'relative-json-pointer'}, + OpenApiTypes.REGEX: {'type': 'string', 'format': 'regex'}, OpenApiTypes.OBJECT: build_generic_type(), OpenApiTypes.ANY: {}, OpenApiTypes.NONE: None, @@ -145,6 +174,7 @@ def build_generic_type(): timedelta: OpenApiTypes.DURATION, IPv4Address: OpenApiTypes.IP4, IPv6Address: OpenApiTypes.IP6, + Pattern: OpenApiTypes.REGEX dict: OpenApiTypes.OBJECT, typing.Any: OpenApiTypes.ANY, None: OpenApiTypes.NONE,