Skip to content

Commit 71c4ca9

Browse files
committed
[#32] Fix: parse_rule is deprecated in werkzeug>=2.2.0
1 parent 3c1bdf3 commit 71c4ca9

File tree

3 files changed

+76
-86
lines changed

3 files changed

+76
-86
lines changed

flask_openapi3/api_blueprint.py

+14-12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# -*- coding: utf-8 -*-
22
# @Author : llc
33
# @Time : 2022/4/1 16:54
4+
import re
45
from copy import deepcopy
56
from functools import wraps
67
from typing import Optional, List, Dict, Any, Type, Callable, Tuple
@@ -13,8 +14,8 @@
1314
from .http import HTTPMethod
1415
from .models import Tag, Components
1516
from .types import OpenAPIResponsesType
16-
from .utils import get_openapi_path, get_operation, get_responses, parse_and_store_tags, parse_parameters, \
17-
validate_responses_type, parse_method, get_operation_id_for_path
17+
from .utils import get_operation, get_responses, parse_and_store_tags, parse_parameters, validate_responses_type, \
18+
parse_method, get_operation_id_for_path
1819

1920

2021
class APIBlueprint(Blueprint):
@@ -64,12 +65,12 @@ def register_api(self, api: "APIBlueprint") -> None:
6465
self.tags.append(tag)
6566

6667
for path_url, path_item in api.paths.items():
67-
trail_slash = path_url.endswith('/')
68+
trail_slash = path_url.endswith("/")
6869
# merge url_prefix and new api blueprint path url
6970
uri = self.url_prefix.rstrip("/") + "/" + path_url.lstrip("/") if self.url_prefix else path_url
7071
# strip the right slash
7172
if not trail_slash:
72-
uri = uri.rstrip('/')
73+
uri = uri.rstrip("/")
7374
self.paths[uri] = path_item
7475

7576
self.components_schemas.update(**api.components_schemas)
@@ -147,12 +148,13 @@ def _do_decorator(
147148
parse_parameters(func, components_schemas=self.components_schemas, operation=operation)
148149
# parse response
149150
get_responses(combine_responses, extra_responses, self.components_schemas, operation)
150-
uri = get_openapi_path(rule)
151-
trail_slash = uri.endswith('/')
151+
# /pet/<petId> --> /pet/{petId}
152+
uri = re.sub(r"<([^<:]+:)?", "{", rule).replace(">", "}")
153+
trail_slash = uri.endswith("/")
152154
# merge url_prefix and uri
153155
uri = self.url_prefix.rstrip("/") + "/" + uri.lstrip("/") if self.url_prefix else uri
154156
if not trail_slash:
155-
uri = uri.rstrip('/')
157+
uri = uri.rstrip("/")
156158
# parse method
157159
parse_method(uri, method, self.paths, operation)
158160
return header, cookie, path, query, form, body, combine_responses
@@ -176,7 +178,7 @@ def get(
176178
doc_ui: bool = True,
177179
**options: Any
178180
) -> Callable:
179-
"""Decorator for rest api, like: app.route(methods=['GET'])"""
181+
"""Decorator for rest api, like: app.route(methods=["GET"])"""
180182

181183
def decorator(func) -> Callable:
182184
header, cookie, path, query, form, body, combine_responses = \
@@ -232,7 +234,7 @@ def post(
232234
doc_ui: bool = True,
233235
**options: Any
234236
) -> Callable:
235-
"""Decorator for rest api, like: app.route(methods=['POST'])"""
237+
"""Decorator for rest api, like: app.route(methods=["POST"])"""
236238

237239
def decorator(func) -> Callable:
238240
header, cookie, path, query, form, body, combine_responses = \
@@ -288,7 +290,7 @@ def put(
288290
doc_ui: bool = True,
289291
**options: Any
290292
) -> Callable:
291-
"""Decorator for rest api, like: app.route(methods=['PUT'])"""
293+
"""Decorator for rest api, like: app.route(methods=["PUT"])"""
292294

293295
def decorator(func) -> Callable:
294296
header, cookie, path, query, form, body, combine_responses = \
@@ -344,7 +346,7 @@ def delete(
344346
doc_ui: bool = True,
345347
**options: Any
346348
) -> Callable:
347-
"""Decorator for rest api, like: app.route(methods=['DELETE'])"""
349+
"""Decorator for rest api, like: app.route(methods=["DELETE"])"""
348350

349351
def decorator(func) -> Callable:
350352
header, cookie, path, query, form, body, combine_responses = \
@@ -400,7 +402,7 @@ def patch(
400402
doc_ui: bool = True,
401403
**options: Any
402404
) -> Callable:
403-
"""Decorator for rest api, like: app.route(methods=['PATCH'])"""
405+
"""Decorator for rest api, like: app.route(methods=["PATCH"])"""
404406

405407
def decorator(func) -> Callable:
406408
header, cookie, path, query, form, body, combine_responses = \

flask_openapi3/openapi.py

+30-28
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# @Time : 2021/4/30 14:25
44
import json
55
import os
6+
import re
67
from copy import deepcopy
78
from functools import wraps
89
from typing import Optional, List, Dict, Union, Any, Type, Callable, Tuple
@@ -20,8 +21,8 @@
2021
from .models.oauth import OAuthConfig
2122
from .models.security import SecurityScheme
2223
from .types import OpenAPIResponsesType
23-
from .utils import get_openapi_path, get_operation, get_responses, parse_and_store_tags, parse_parameters, \
24-
validate_responses_type, parse_method, get_operation_id_for_path
24+
from .utils import get_operation, get_responses, parse_and_store_tags, parse_parameters, validate_responses_type, \
25+
parse_method, get_operation_id_for_path
2526

2627

2728
class OpenAPI(Flask):
@@ -57,11 +58,11 @@ def __init__(
5758
doc_ui: add openapi document UI(swagger and redoc). Defaults to True.
5859
doc_expansion: String=["list"*, "full", "none"].
5960
Controls the default expansion setting for the operations and tags.
60-
It can be 'list' (expands only the tags),
61-
'full' (expands the tags and operations) or 'none' (expands nothing).
61+
It can be "list" (expands only the tags),
62+
"full" (expands the tags and operations) or "none" (expands nothing).
6263
see https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/configuration.md
63-
doc_prefix: URL prefix used for OpenAPI document and UI. Defaults to '/openapi'.
64-
api_doc_url: The OpenAPI Spec documentation. Defaults to '/openapi.json'.
64+
doc_prefix: URL prefix used for OpenAPI document and UI. Defaults to "/openapi".
65+
api_doc_url: The OpenAPI Spec documentation. Defaults to "/openapi.json".
6566
swagger_url: The Swagger UI documentation. Defaults to `/swagger`.
6667
redoc_url: The Redoc UI documentation. Defaults to `/redoc`.
6768
rapidoc_url: The RapiDoc UI documentation. Defaults to `/rapidoc`.
@@ -74,7 +75,7 @@ def __init__(
7475

7576
self.openapi_version = "3.0.3"
7677
if info is None:
77-
info = Info(title='OpenAPI', version='1.0.0')
78+
info = Info(title="OpenAPI", version="1.0.0")
7879
assert isinstance(info, Info), f"Info is required (got type {type(info)})"
7980
self.info = info
8081
self.security_schemes = security_schemes
@@ -106,55 +107,55 @@ def init_doc(self) -> None:
106107
Provide Swagger UI, Redoc and Rapidoc
107108
"""
108109
_here = os.path.dirname(__file__)
109-
template_folder = os.path.join(_here, 'templates')
110-
static_folder = os.path.join(template_folder, 'static')
110+
template_folder = os.path.join(_here, "templates")
111+
static_folder = os.path.join(template_folder, "static")
111112

112113
blueprint = Blueprint(
113-
'openapi',
114+
"openapi",
114115
__name__,
115116
url_prefix=self.doc_prefix,
116117
template_folder=template_folder,
117118
static_folder=static_folder
118119
)
119120
blueprint.add_url_rule(
120121
rule=self.api_doc_url,
121-
endpoint='api_doc',
122+
endpoint="api_doc",
122123
view_func=lambda: self.api_doc
123124
)
124125
blueprint.add_url_rule(
125126
rule=self.swagger_url,
126-
endpoint='swagger',
127+
endpoint="swagger",
127128
view_func=lambda: render_template(
128129
"swagger.html",
129-
api_doc_url=self.api_doc_url.lstrip('/'),
130+
api_doc_url=self.api_doc_url.lstrip("/"),
130131
doc_expansion=self.doc_expansion,
131132
oauth_config=self.oauth_config.dict() if self.oauth_config else None
132133
)
133134
)
134135
blueprint.add_url_rule(
135136
rule=self.redoc_url,
136-
endpoint='redoc',
137+
endpoint="redoc",
137138
view_func=lambda: render_template(
138139
"redoc.html",
139-
api_doc_url=self.api_doc_url.lstrip('/')
140+
api_doc_url=self.api_doc_url.lstrip("/")
140141
)
141142
)
142143
blueprint.add_url_rule(
143144
rule=self.rapidoc_url,
144-
endpoint='rapidoc',
145+
endpoint="rapidoc",
145146
view_func=lambda: render_template(
146147
"rapidoc.html",
147-
api_doc_url=self.api_doc_url.lstrip('/')
148+
api_doc_url=self.api_doc_url.lstrip("/")
148149
)
149150
)
150151
blueprint.add_url_rule(
151-
rule='/',
152-
endpoint='index',
152+
rule="/",
153+
endpoint="index",
153154
view_func=lambda: render_template(
154155
"index.html",
155-
swagger_url=self.swagger_url.lstrip('/'),
156-
redoc_url=self.redoc_url.lstrip('/'),
157-
rapidoc_url=self.rapidoc_url.lstrip('/')
156+
swagger_url=self.swagger_url.lstrip("/"),
157+
redoc_url=self.redoc_url.lstrip("/"),
158+
rapidoc_url=self.rapidoc_url.lstrip("/")
158159
)
159160
)
160161
self.register_blueprint(blueprint)
@@ -252,7 +253,8 @@ def _do_decorator(
252253
parse_parameters(func, components_schemas=self.components_schemas, operation=operation)
253254
# parse response
254255
get_responses(combine_responses, extra_responses, self.components_schemas, operation)
255-
uri = get_openapi_path(rule)
256+
# /pet/<petId> --> /pet/{petId}
257+
uri = re.sub(r"<([^<:]+:)?", "{", rule).replace(">", "}")
256258
# parse method
257259
parse_method(uri, method, self.paths, operation)
258260
return header, cookie, path, query, form, body, combine_responses
@@ -276,7 +278,7 @@ def get(
276278
doc_ui: bool = True,
277279
**options: Any
278280
) -> Callable:
279-
"""Decorator for rest api, like: app.route(methods=['GET'])"""
281+
"""Decorator for rest api, like: app.route(methods=["GET"])"""
280282

281283
def decorator(func) -> Callable:
282284
header, cookie, path, query, form, body, combine_responses = \
@@ -332,7 +334,7 @@ def post(
332334
doc_ui: bool = True,
333335
**options: Any
334336
) -> Callable:
335-
"""Decorator for rest api, like: app.route(methods=['POST'])"""
337+
"""Decorator for rest api, like: app.route(methods=["POST"])"""
336338

337339
def decorator(func) -> Callable:
338340
header, cookie, path, query, form, body, combine_responses = \
@@ -388,7 +390,7 @@ def put(
388390
doc_ui: bool = True,
389391
**options: Any
390392
) -> Callable:
391-
"""Decorator for rest api, like: app.route(methods=['PUT'])"""
393+
"""Decorator for rest api, like: app.route(methods=["PUT"])"""
392394

393395
def decorator(func) -> Callable:
394396
header, cookie, path, query, form, body, combine_responses = \
@@ -444,7 +446,7 @@ def delete(
444446
doc_ui: bool = True,
445447
**options: Any
446448
) -> Callable:
447-
"""Decorator for rest api, like: app.route(methods=['DELETE'])"""
449+
"""Decorator for rest api, like: app.route(methods=["DELETE"])"""
448450

449451
def decorator(func) -> Callable:
450452
header, cookie, path, query, form, body, combine_responses = \
@@ -500,7 +502,7 @@ def patch(
500502
doc_ui: bool = True,
501503
**options: Any
502504
) -> Callable:
503-
"""Decorator for rest api, like: app.route(methods=['PATCH'])"""
505+
"""Decorator for rest api, like: app.route(methods=["PATCH"])"""
504506

505507
def decorator(func) -> Callable:
506508
header, cookie, path, query, form, body, combine_responses = \

0 commit comments

Comments
 (0)