Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
iongion committed Nov 30, 2024
1 parent 41334c3 commit cbb6d67
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 5 deletions.
12 changes: 12 additions & 0 deletions flask_openapi3/blueprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from flask import Blueprint

from .models import ExternalDocumentation
from .models import RequestBody
from .models import Server
from .models import Tag
from .scaffold import APIScaffold
Expand All @@ -30,6 +31,7 @@ def __init__(
*,
abp_tags: Optional[List[Tag]] = None,
abp_security: Optional[List[Dict[str, List[str]]]] = None,
abp_requestBody: Optional[RequestBody] | None = None,
abp_responses: Optional[ResponseDict] = None,
doc_ui: bool = True,
operation_id_callback: Callable = get_operation_id_for_path,
Expand All @@ -44,6 +46,7 @@ def __init__(
This helps locate the ``root_path`` for the blueprint.
abp_tags: APIBlueprint tags for every API.
abp_security: APIBlueprint security for every API.
abp_requestBody: API request body should be either a subclass of BaseModel or None.
abp_responses: API responses should be either a subclass of BaseModel, a dictionary, or None.
doc_ui: Enable OpenAPI document UI (Swagger UI, Redoc, and Rapidoc). Defaults to True.
operation_id_callback: Callback function for custom operation_id generation.
Expand All @@ -63,6 +66,8 @@ def __init__(
self.abp_tags = abp_tags or []
self.abp_security = abp_security or []

self.abp_requestBody = abp_requestBody

# Convert key to string
self.abp_responses = convert_responses_key_to_string(abp_responses or {})

Expand Down Expand Up @@ -116,6 +121,7 @@ def _collect_openapi_info(
description: Optional[str] = None,
external_docs: Optional[ExternalDocumentation] = None,
operation_id: Optional[str] = None,
requestBody: Optional[RequestBody] = None,
responses: Optional[ResponseDict] = None,
deprecated: Optional[bool] = None,
security: Optional[List[Dict[str, List[Any]]]] = None,
Expand All @@ -135,6 +141,7 @@ def _collect_openapi_info(
description: A verbose explanation of the operation behavior.
external_docs: Additional external documentation for this operation.
operation_id: Unique string used to identify the operation.
requestBody: API request body should be either a subclass of BaseModel or None.
responses: API responses should be either a subclass of BaseModel, a dictionary, or None.
deprecated: Declares this operation to be deprecated.
security: A declaration of which security mechanisms can be used for this operation.
Expand All @@ -146,12 +153,17 @@ def _collect_openapi_info(
# Convert key to string
new_responses = convert_responses_key_to_string(responses or {})

# Last declared requestBody has the highest priority
current_requestBody = requestBody or self.abp_requestBody

# Global response: combine API responses
combine_responses = {**self.abp_responses, **new_responses}

# Create operation
operation = get_operation(
func,
components_schemas=self.components_schemas,
requestBody=current_requestBody,
summary=summary,
description=description,
openapi_extensions=openapi_extensions
Expand Down
4 changes: 2 additions & 2 deletions flask_openapi3/models/request_body.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# @Author : llc
# @Time : 2023/7/4 9:53
from typing import Dict, Optional
from typing import Dict, Optional, Type, Union

from pydantic import BaseModel

Expand All @@ -14,7 +14,7 @@ class RequestBody(BaseModel):
"""

description: Optional[str] = None
content: Dict[str, MediaType]
content: Dict[str, Union[MediaType, BaseModel, dict, Type[BaseModel]]]
required: Optional[bool] = True

model_config = {
Expand Down
13 changes: 13 additions & 0 deletions flask_openapi3/openapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from .models import ExternalDocumentation
from .models import Info
from .models import OPENAPI3_REF_PREFIX
from .models import RequestBody
from .models import Schema
from .models import Server
from .models import Tag
Expand Down Expand Up @@ -52,6 +53,7 @@ def __init__(
*,
info: Optional[Info] = None,
security_schemes: Optional[SecuritySchemesDict] = None,
requestBody: Optional[RequestBody] = None,
responses: Optional[ResponseDict] = None,
servers: Optional[List[Server]] = None,
external_docs: Optional[ExternalDocumentation] = None,
Expand All @@ -74,6 +76,7 @@ def __init__(
See https://spec.openapis.org/oas/v3.1.0#info-object.
security_schemes: Security schemes for the API.
See https://spec.openapis.org/oas/v3.1.0#security-scheme-object.
requestBody: API request body should be either a subclass of BaseModel or None.
responses: API responses should be either a subclass of BaseModel, a dictionary, or None.
servers: An array of Server objects providing connectivity information to a target server.
external_docs: External documentation for the API.
Expand Down Expand Up @@ -103,6 +106,9 @@ def __init__(
self.openapi_version = "3.1.0"
self.info = info or Info(title="OpenAPI", version="1.0.0")

# Set request body
self.requestBody = requestBody

# Set security schemes, responses, paths and components
self.security_schemes = security_schemes

Expand Down Expand Up @@ -348,6 +354,7 @@ def _collect_openapi_info(
description: Optional[str] = None,
external_docs: Optional[ExternalDocumentation] = None,
operation_id: Optional[str] = None,
requestBody: Optional[RequestBody] = None,
responses: Optional[ResponseDict] = None,
deprecated: Optional[bool] = None,
security: Optional[List[Dict[str, List[Any]]]] = None,
Expand All @@ -367,6 +374,7 @@ def _collect_openapi_info(
description: A verbose explanation of the operation behavior.
external_docs: Additional external documentation for this operation.
operation_id: Unique string used to identify the operation.
requestBody: API request body should be either a subclass of BaseModel or None.
responses: API responses should be either a subclass of BaseModel, a dictionary, or None.
deprecated: Declares this operation to be deprecated.
security: A declaration of which security mechanisms can be used for this operation.
Expand All @@ -378,13 +386,18 @@ def _collect_openapi_info(
if doc_ui is True:
# Convert key to string
new_responses = convert_responses_key_to_string(responses or {})

# Last declared requestBody has the highest priority
current_requestBody = requestBody or self.abp_requestBody

# Global response: combine API responses
combine_responses = {**self.responses, **new_responses}

# Create operation
operation = get_operation(
func,
components_schemas=self.components_schemas,
requestBody=current_requestBody,
summary=summary,
description=description,
openapi_extensions=openapi_extensions
Expand Down
17 changes: 17 additions & 0 deletions flask_openapi3/scaffold.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from flask.wrappers import Response as FlaskResponse

from .models import ExternalDocumentation
from .models import RequestBody
from .models import Server
from .models import Tag
from .request import _validate_request
Expand All @@ -27,6 +28,7 @@ def _collect_openapi_info(
description: Optional[str] = None,
external_docs: Optional[ExternalDocumentation] = None,
operation_id: Optional[str] = None,
requestBody: Optional[RequestBody] = None,
responses: Optional[ResponseDict] = None,
deprecated: Optional[bool] = None,
security: Optional[List[Dict[str, List[Any]]]] = None,
Expand Down Expand Up @@ -131,6 +133,7 @@ def get(
description: Optional[str] = None,
external_docs: Optional[ExternalDocumentation] = None,
operation_id: Optional[str] = None,
requestBody: Optional[RequestBody] = None,
responses: Optional[ResponseDict] = None,
deprecated: Optional[bool] = None,
security: Optional[List[Dict[str, List[Any]]]] = None,
Expand All @@ -150,6 +153,7 @@ def get(
description: A verbose explanation of the operation behavior.
external_docs: Additional external documentation for this operation.
operation_id: Unique string used to identify the operation.
requestBody: API request body should be either a subclass of BaseModel or None.
responses: API responses should be either a subclass of BaseModel, a dictionary, or None.
deprecated: Declares this operation to be deprecated.
security: A declaration of which security mechanisms can be used for this operation.
Expand All @@ -168,6 +172,7 @@ def decorator(func) -> Callable:
description=description,
external_docs=external_docs,
operation_id=operation_id,
requestBody=requestBody,
responses=responses,
deprecated=deprecated,
security=security,
Expand All @@ -194,6 +199,7 @@ def post(
description: Optional[str] = None,
external_docs: Optional[ExternalDocumentation] = None,
operation_id: Optional[str] = None,
requestBody: Optional[RequestBody] = None,
responses: Optional[ResponseDict] = None,
deprecated: Optional[bool] = None,
security: Optional[List[Dict[str, List[Any]]]] = None,
Expand All @@ -213,6 +219,7 @@ def post(
description: A verbose explanation of the operation behavior.
external_docs: Additional external documentation for this operation.
operation_id: Unique string used to identify the operation.
requestBody: API request body should be either a subclass of BaseModel or None.
responses: API responses should be either a subclass of BaseModel, a dictionary, or None.
deprecated: Declares this operation to be deprecated.
security: A declaration of which security mechanisms can be used for this operation.
Expand All @@ -231,6 +238,7 @@ def decorator(func) -> Callable:
description=description,
external_docs=external_docs,
operation_id=operation_id,
requestBody=requestBody,
responses=responses,
deprecated=deprecated,
security=security,
Expand All @@ -257,6 +265,7 @@ def put(
description: Optional[str] = None,
external_docs: Optional[ExternalDocumentation] = None,
operation_id: Optional[str] = None,
requestBody: Optional[RequestBody] = None,
responses: Optional[ResponseDict] = None,
deprecated: Optional[bool] = None,
security: Optional[List[Dict[str, List[Any]]]] = None,
Expand All @@ -276,6 +285,7 @@ def put(
description: A verbose explanation of the operation behavior.
external_docs: Additional external documentation for this operation.
operation_id: Unique string used to identify the operation.
requestBody: API request body should be either a subclass of BaseModel or None.
responses: API responses should be either a subclass of BaseModel, a dictionary, or None.
deprecated: Declares this operation to be deprecated.
security: A declaration of which security mechanisms can be used for this operation.
Expand All @@ -294,6 +304,7 @@ def decorator(func) -> Callable:
description=description,
external_docs=external_docs,
operation_id=operation_id,
requestBody=requestBody,
responses=responses,
deprecated=deprecated,
security=security,
Expand All @@ -320,6 +331,7 @@ def delete(
description: Optional[str] = None,
external_docs: Optional[ExternalDocumentation] = None,
operation_id: Optional[str] = None,
requestBody: Optional[RequestBody] = None,
responses: Optional[ResponseDict] = None,
deprecated: Optional[bool] = None,
security: Optional[List[Dict[str, List[Any]]]] = None,
Expand All @@ -339,6 +351,7 @@ def delete(
description: A verbose explanation of the operation behavior.
external_docs: Additional external documentation for this operation.
operation_id: Unique string used to identify the operation.
requestBody: API request body should be either a subclass of BaseModel or None.
responses: API responses should be either a subclass of BaseModel, a dictionary, or None.
deprecated: Declares this operation to be deprecated.
security: A declaration of which security mechanisms can be used for this operation.
Expand All @@ -357,6 +370,7 @@ def decorator(func) -> Callable:
description=description,
external_docs=external_docs,
operation_id=operation_id,
requestBody=requestBody,
responses=responses,
deprecated=deprecated,
security=security,
Expand All @@ -383,6 +397,7 @@ def patch(
description: Optional[str] = None,
external_docs: Optional[ExternalDocumentation] = None,
operation_id: Optional[str] = None,
requestBody: Optional[RequestBody] = None,
responses: Optional[ResponseDict] = None,
deprecated: Optional[bool] = None,
security: Optional[List[Dict[str, List[Any]]]] = None,
Expand All @@ -402,6 +417,7 @@ def patch(
description: A verbose explanation of the operation behavior.
external_docs: Additional external documentation for this operation.
operation_id: Unique string used to identify the operation.
requestBody: API request body should be either a subclass of BaseModel or None.
responses: API responses should be either a subclass of BaseModel, a dictionary, or None.
deprecated: Declares this operation to be deprecated.
security: A declaration of which security mechanisms can be used for this operation.
Expand All @@ -420,6 +436,7 @@ def decorator(func) -> Callable:
description=description,
external_docs=external_docs,
operation_id=operation_id,
requestBody=requestBody,
responses=responses,
deprecated=deprecated,
security=security,
Expand Down
Loading

0 comments on commit cbb6d67

Please sign in to comment.