Skip to content

Commit

Permalink
OAS 3.1
Browse files Browse the repository at this point in the history
  • Loading branch information
tfranzel committed Sep 23, 2023
1 parent 6e4180b commit e25b897
Show file tree
Hide file tree
Showing 11 changed files with 2,207 additions and 18 deletions.
5 changes: 4 additions & 1 deletion drf_spectacular/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,10 @@ def create_enum_component(name, schema):
if '' in prop_enum_original_list:
components.append(create_enum_component('BlankEnum', schema={'enum': ['']}))
if None in prop_enum_original_list:
components.append(create_enum_component('NullEnum', schema={'enum': [None]}))
if spectacular_settings.OAS_VERSION.startswith('3.1'):
components.append(create_enum_component('NullEnum', schema={'type': 'null'}))

Check warning on line 138 in drf_spectacular/hooks.py

View check run for this annotation

Codecov / codecov/patch

drf_spectacular/hooks.py#L138

Added line #L138 was not covered by tests
else:
components.append(create_enum_component('NullEnum', schema={'enum': [None]}))

if len(components) == 1:
prop_schema.update(components[0].ref)
Expand Down
1 change: 1 addition & 0 deletions drf_spectacular/openapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,7 @@ def _get_serializer_field_meta(self, field, direction):
if field.write_only:
meta['writeOnly'] = True
if field.allow_null:
# this will be converted later in case of OAS 3.1
meta['nullable'] = True
if isinstance(field, serializers.CharField) and not field.allow_blank:
# blank check only applies to inbound requests
Expand Down
14 changes: 13 additions & 1 deletion drf_spectacular/plumbing.py
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ def build_root_object(paths, components, version):
else:
version = settings.VERSION or version or ''
root = {
'openapi': '3.0.3',
'openapi': settings.OAS_VERSION,
'info': {
'title': settings.TITLE,
'version': version,
Expand Down Expand Up @@ -507,6 +507,18 @@ def safe_ref(schema):


def append_meta(schema, meta):
if spectacular_settings.OAS_VERSION.startswith('3.1'):
schema_nullable = meta.pop('nullable', None)
meta_nullable = schema.pop('nullable', None)

if schema_nullable or meta_nullable:
if 'type' in schema:
schema['type'] = [schema['type'], 'null']
elif '$ref' in schema:
schema = {'oneOf': [schema, {'type': 'null'}]}

Check warning on line 518 in drf_spectacular/plumbing.py

View check run for this annotation

Codecov / codecov/patch

drf_spectacular/plumbing.py#L517-L518

Added lines #L517 - L518 were not covered by tests
else:
assert False, 'Invalid nullable case'

Check warning on line 520 in drf_spectacular/plumbing.py

View check run for this annotation

Codecov / codecov/patch

drf_spectacular/plumbing.py#L520

Added line #L520 was not covered by tests

return safe_ref({**schema, **meta})


Expand Down
3 changes: 3 additions & 0 deletions drf_spectacular/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@
# accurately modeled when request and response components are separated.
'ENFORCE_NON_BLANK_FIELDS': False,

#
'OAS_VERSION': '3.0.3',

# Configuration for serving a schema subset with SpectacularAPIView
'SERVE_URLCONF': None,
# complete public schema or a subset based on the requesting user
Expand Down
17 changes: 13 additions & 4 deletions drf_spectacular/validation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,28 @@

import jsonschema

JSON_SCHEMA_SPEC_PATH = os.path.join(os.path.dirname(__file__), 'openapi3_schema.json')


def validate_schema(api_schema):
"""
Validate generated API schema against OpenAPI 3.0.X json schema specification.
Note: On conflict, the written specification always wins over the json schema.
OpenApi3 schema specification taken from:
https://github.com/OAI/OpenAPI-Specification/blob/master/schemas/v3.0/schema.json
https://github.com/OAI/OpenAPI-Specification/blob/6d17b631fff35186c495b9e7d340222e19d60a71/schemas/v3.0/schema.json
https://github.com/OAI/OpenAPI-Specification/blob/9dff244e5708fbe16e768738f4f17cf3fddf4066/schemas/v3.0/schema.json
https://github.com/OAI/OpenAPI-Specification/blob/main/schemas/v3.1/schema.json
https://github.com/OAI/OpenAPI-Specification/blob/9dff244e5708fbe16e768738f4f17cf3fddf4066/schemas/v3.1/schema.json
"""
with open(JSON_SCHEMA_SPEC_PATH) as fh:
if api_schema['openapi'].startswith("3.0"):
schema_spec_path = os.path.join(os.path.dirname(__file__), 'openapi_3_0_schema.json')
elif api_schema['openapi'].startswith("3.1"):
schema_spec_path = os.path.join(os.path.dirname(__file__), 'openapi_3_1_schema.json')
else:
raise RuntimeError('No validation specification available')

Check warning on line 25 in drf_spectacular/validation/__init__.py

View check run for this annotation

Codecov / codecov/patch

drf_spectacular/validation/__init__.py#L25

Added line #L25 was not covered by tests

with open(schema_spec_path) as fh:
openapi3_schema_spec = json.load(fh)

# coerce any remnants of objects to basic types
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "https://spec.openapis.org/oas/3.0/schema/2019-04-02",
"id": "https://spec.openapis.org/oas/3.0/schema/2021-09-28",
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "Validation schema for OpenAPI Specification 3.0.X.",
"description": "The description of OpenAPI v3.0.x documents, as defined by https://spec.openapis.org/oas/v3.0.3",
"type": "object",
"required": [
"openapi",
Expand Down Expand Up @@ -1358,9 +1358,8 @@
"description": "Bearer",
"properties": {
"scheme": {
"enum": [
"bearer"
]
"type": "string",
"pattern": "^[Bb][Ee][Aa][Rr][Ee][Rr]$"
}
}
},
Expand All @@ -1374,9 +1373,8 @@
"properties": {
"scheme": {
"not": {
"enum": [
"bearer"
]
"type": "string",
"pattern": "^[Bb][Ee][Aa][Rr][Ee][Rr]$"
}
}
}
Expand Down Expand Up @@ -1489,7 +1487,8 @@
"PasswordOAuthFlow": {
"type": "object",
"required": [
"tokenUrl"
"tokenUrl",
"scopes"
],
"properties": {
"tokenUrl": {
Expand All @@ -1516,7 +1515,8 @@
"ClientCredentialsFlow": {
"type": "object",
"required": [
"tokenUrl"
"tokenUrl",
"scopes"
],
"properties": {
"tokenUrl": {
Expand Down Expand Up @@ -1544,7 +1544,8 @@
"type": "object",
"required": [
"authorizationUrl",
"tokenUrl"
"tokenUrl",
"scopes"
],
"properties": {
"authorizationUrl": {
Expand Down Expand Up @@ -1628,7 +1629,14 @@
"headers": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/Header"
"oneOf": [
{
"$ref": "#/definitions/Header"
},
{
"$ref": "#/definitions/Reference"
}
]
}
},
"style": {
Expand All @@ -1648,6 +1656,10 @@
"default": false
}
},
"patternProperties": {
"^x-": {
}
},
"additionalProperties": false
}
}
Expand Down
Loading

0 comments on commit e25b897

Please sign in to comment.