Skip to content

Commit

Permalink
Modify response headers to be compliant with OAS 3.0.0+
Browse files Browse the repository at this point in the history
  • Loading branch information
tsokalski committed Dec 12, 2024
1 parent 5c4265a commit 210af01
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 17 deletions.
11 changes: 10 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
## Version 2.3.2

Released: -

- Fix response headers to be compliant with the OpenAPI specification for versions 3.0.0+ ([issue #631][issue_631]).

[issue_631]: https://github.com/apiflask/apiflask/issues/631


## Version 2.3.1

Released: 2024/12/7
Expand Down Expand Up @@ -79,7 +88,7 @@ Released: 2023/12/16
- Allow adding multiple media types for a response ([issue #494][issue_494]).
- Support adding headers to the response schema ([issue #507][issue_507]).
- Add support for adding decorators to the OpenAPI spec and documentation UI endpoints ([issue #483][issue_483]).
- Fix the base repsonse schema inconsistency issue.
- Fix the base response schema inconsistency issue.

[issue_494]: https://github.com/apiflask/apiflask/issues/494
[issue_507]: https://github.com/apiflask/apiflask/issues/507
Expand Down
10 changes: 6 additions & 4 deletions src/apiflask/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -1253,12 +1253,14 @@ def _add_response(
if links is not None:
operation['responses'][status_code]['links'] = links
if headers_schema is not None:
headers = self._ma_plugin.converter.schema2parameters( # type: ignore
header_params = self._ma_plugin.converter.schema2parameters( # type: ignore
headers_schema, location='headers'
)
operation['responses'][status_code]['headers'] = {
header['name']: header for header in headers
}
headers = {header['name']: header for header in header_params}
for header in headers.values():
header.pop('in', None)
header.pop('name', None)
operation['responses'][status_code]['headers'] = headers

def _add_response_with_schema(
self,
Expand Down
29 changes: 17 additions & 12 deletions tests/test_openapi_headers.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import openapi_spec_validator as osv
import pytest

from .schemas import Foo
from .schemas import ResponseHeader
from apiflask.fields import Boolean
Expand Down Expand Up @@ -25,36 +28,26 @@ def foo():
rv = client.get('/openapi.json')
assert rv.json['paths']['/foo']['get']['responses']['200']['headers'] == {
'X-boolean': {
'name': 'X-boolean',
'in': 'header',
'description': 'A boolean header',
'required': False,
'schema': {'type': 'boolean'},
},
'X-integer': {
'name': 'X-integer',
'in': 'header',
'description': 'An integer header',
'required': False,
'schema': {'type': 'integer'},
},
'X-number': {
'name': 'X-number',
'in': 'header',
'description': 'A number header',
'required': False,
'schema': {'type': 'number'},
},
'X-string': {
'name': 'X-string',
'in': 'header',
'description': 'A string header',
'required': False,
'schema': {'type': 'string'},
},
'X-array': {
'name': 'X-array',
'in': 'header',
'description': 'An array header',
'required': False,
'schema': {'items': {'type': 'string'}, 'type': 'array'},
Expand Down Expand Up @@ -83,10 +76,22 @@ def foo():
rv = client.get('/openapi.json')
assert rv.json['paths']['/foo']['get']['responses']['200']['headers'] == {
'X-Token': {
'name': 'X-Token',
'in': 'header',
'description': 'A custom token header',
'required': True,
'schema': {'type': 'string'},
},
}


@pytest.mark.parametrize('openapi_version', ['3.0.0', '3.1.0'])
def test_spec_validity_with_headers(app, client, openapi_version):
app.config['OPENAPI_VERSION'] = openapi_version

@app.route('/foo')
@app.output(Foo, headers=ResponseHeader)
def foo():
pass

rv = client.get('/openapi.json')
assert rv.status_code == 200
osv.validate(rv.json)

0 comments on commit 210af01

Please sign in to comment.