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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions flask_openapi3/api_blueprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def __init__(
abp_security: Optional[List[Dict[str, List[str]]]] = None,
abp_responses: Optional[Dict[str, Type[BaseModel]]] = None,
doc_ui: bool = True,
operation_id_callback: Callable = get_operation_id_for_path,
**kwargs: Any
) -> None:
"""
Expand All @@ -39,6 +40,9 @@ def __init__(
abp_security: APIBlueprint security for every api
abp_responses: APIBlueprint response model
doc_ui: add openapi document UI(swagger and redoc). Defaults to True.
operation_id_callback: Callback function for custom operation_id generation.
Receives name (str), path (str) and method (str) parameters.
Defaults to `get_operation_id_for_path` from utils
kwargs: Flask Blueprint kwargs
"""
super(APIBlueprint, self).__init__(name, import_name, **kwargs)
Expand All @@ -52,6 +56,7 @@ def __init__(
self.abp_security = abp_security or []
self.abp_responses = abp_responses or {}
self.doc_ui = doc_ui
self.operation_id_callback: Callable = operation_id_callback

def _do_decorator(
self,
Expand Down Expand Up @@ -112,10 +117,9 @@ def _do_decorator(
if deprecated:
operation.deprecated = True
# Unique string used to identify the operation.
if operation_id:
operation.operationId = operation_id
else:
operation.operationId = get_operation_id_for_path(name=func.__name__, path=rule, method=method)
operation.operationId = operation_id or self.operation_id_callback(
name=func.__name__, path=rule, method=method
)
# store tags
tags = tags + self.abp_tags if tags else self.abp_tags
parse_and_store_tags(tags, self.tags, self.tag_names, operation)
Expand Down
12 changes: 8 additions & 4 deletions flask_openapi3/openapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ def __init__(
redoc_url: str = "/redoc",
rapidoc_url: str = "/rapidoc",
servers: Optional[List[Server]] = None,
operation_id_callback: Callable = get_operation_id_for_path,
**kwargs: Any
) -> None:
"""
Expand All @@ -65,6 +66,9 @@ def __init__(
redoc_url: The Redoc UI documentation. Defaults to `/redoc`.
rapidoc_url: The RapiDoc UI documentation. Defaults to `/rapidoc`.
servers: An array of Server Objects, which provide connectivity information to a target server.
operation_id_callback: Callback function for custom operation_id generation.
Receives name (str), path (str) and method (str) parameters.
Defaults to `get_operation_id_for_path` from utils
kwargs: Flask kwargs
"""
super(OpenAPI, self).__init__(import_name, **kwargs)
Expand Down Expand Up @@ -94,6 +98,7 @@ def __init__(
self.init_doc()
self.doc_expansion = doc_expansion
self.severs = servers
self.operation_id_callback: Callable = operation_id_callback

def init_doc(self) -> None:
"""
Expand Down Expand Up @@ -254,10 +259,9 @@ def _do_decorator(
if deprecated:
operation.deprecated = True
# Unique string used to identify the operation.
if operation_id:
operation.operationId = operation_id
else:
operation.operationId = get_operation_id_for_path(name=func.__name__, path=rule, method=method)
operation.operationId = operation_id or self.operation_id_callback(
name=func.__name__, path=rule, method=method
)
# store tags
parse_and_store_tags(tags, self.tags, self.tag_names, operation)
# parse parameters
Expand Down
2 changes: 2 additions & 0 deletions tests/test_api_blueprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ def test_openapi(client):
resp = client.get("/openapi/openapi.json")
assert resp.status_code == 200
assert resp.json == app.api_doc
assert resp.json["paths"]["/api/book/{bid}"]["put"]["operationId"] == "update"
assert resp.json["paths"]["/api/book/{bid}"]["delete"]["operationId"] == "delete_book_book__int_bid__delete"


def test_post(client):
Expand Down
16 changes: 14 additions & 2 deletions tests/test_restapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,18 @@ class NotFoundResponse(BaseModel):
code: int = Field(-1, description="Status Code")
message: str = Field("Resource not found!", description="Exception Information")

def get_operation_id_for_path_callback(*, name: str, path: str, method: str) -> str:
return name

app = OpenAPI(__name__, info=info, security_schemes=security_schemes, responses={"404": NotFoundResponse})

app = OpenAPI(
__name__,
info=info,
security_schemes=security_schemes,
responses={"404": NotFoundResponse},
operation_id_callback=get_operation_id_for_path_callback,

)
app.config["TESTING"] = True
security = [{"jwt": []}]
book_tag = Tag(name='book', description='Book')
Expand Down Expand Up @@ -121,7 +131,7 @@ def update_book1(path: BookPath, body: BookBody):
return {"code": 0, "message": "ok"}


@app.delete('/book/<int:bid>', tags=[book_tag])
@app.delete('/book/<int:bid>', tags=[book_tag], operation_id="delete")
def delete_book(path: BookPath):
assert path.bid == 1
return {"code": 0, "message": "ok"}
Expand All @@ -132,6 +142,8 @@ def test_openapi(client):
print(resp.json)
assert resp.status_code == 200
assert resp.json == app.api_doc
assert resp.json["paths"]["/book"]["get"]["operationId"] == "get_books"
assert resp.json["paths"]["/book/{bid}"]["delete"]["operationId"] == "delete"


def test_get(client):
Expand Down