Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions docs/Example.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,38 @@ if __name__ == '__main__':
app.run(debug=True)
```

## Multiple media types

```python

@app.get(
'/book/<int:bid>',
tags=[book_tag],
summary='new summary',
description='new description',
responses={
200: {
"description": "Multiple media types under the same status code",
"content": {
"application/json": BookResponse,
"application/xml": BookResponse,
}
},
201: {"content": {"text/csv": {"schema": {"type": "string"}}}}
},
security=security
)
def get_book(path: BookPath):
"""Get a book
to get some book by id, like:
http://localhost:5000/book/3
"""
if path.bid == 4:
return NotFoundResponse().dict(), 404
return {"code": 0, "message": "ok", "data": {"bid": path.bid, "age": 3, "author": 'no'}}

```

## APIBlueprint

```python
Expand Down
40 changes: 33 additions & 7 deletions flask_openapi3/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,13 +328,44 @@ def get_responses(
_responses = {}
_schemas = {}

def register_schema(name, schema: Any) -> None:
_schemas[name] = Schema(**schema)
definitions = schema.get("$defs")
if definitions:
# Add schema definitions to _schemas
for name, value in definitions.items():
_schemas[normalize_name(name)] = Schema(**value)

for key, response in responses.items():
if response is None:
# If the response is None, it means HTTP status code "204" (No Content)
_responses[key] = Response(description=HTTP_STATUS.get(key, ""))
elif isinstance(response, dict):
response["description"] = response.get("description", HTTP_STATUS.get(key, ""))
_responses[key] = Response(**response)
if "content" in response:
response_content_map = {}
for content_type, model in response["content"].items():
if isinstance(model, dict):
# inline schema
response_content_map[content_type] = MediaType(
schema=Schema(**model["schema"])
) if "schema" in model else MediaType(
schema=Schema(type=DataType.STRING)
)
elif issubclass(model, BaseModel):
# pydantic model
schema = get_model_schema(model, mode="serialization")
original_title = schema.get("title") or model.__name__
name = normalize_name(original_title)
response_content_map[content_type] = MediaType(
schema=Schema(**{"$ref": f"{OPENAPI3_REF_PREFIX}/{name}"})
)
register_schema(name, schema)
_responses[key] = Response(
description=HTTP_STATUS.get(key, ""),
content=response_content_map)
else:
_responses[key] = Response(**response)
else:
# OpenAPI 3 support ^[a-zA-Z0-9\.\-_]+$ so we should normalize __name__
schema = get_model_schema(response, mode="serialization")
Expand Down Expand Up @@ -367,12 +398,7 @@ def get_responses(
_content["application/json"].encoding = openapi_extra.get("encoding") # type: ignore
_content.update(openapi_extra.get("content", {})) # type: ignore

_schemas[name] = Schema(**schema)
definitions = schema.get("$defs")
if definitions:
# Add schema definitions to _schemas
for name, value in definitions.items():
_schemas[normalize_name(name)] = Schema(**value)
register_schema(name, schema)

components_schemas.update(**_schemas)
operation.responses = _responses
Expand Down