1
1
import inspect
2
+ import re
2
3
import typing
3
4
4
5
from starlette .requests import Request
@@ -49,10 +50,11 @@ def get_endpoints(
49
50
50
51
for route in routes :
51
52
if isinstance (route , Mount ):
53
+ path = self ._remove_converter (route .path )
52
54
routes = route .routes or []
53
55
sub_endpoints = [
54
56
EndpointInfo (
55
- path = "" .join ((route . path , sub_endpoint .path )),
57
+ path = "" .join ((path , sub_endpoint .path )),
56
58
http_method = sub_endpoint .http_method ,
57
59
func = sub_endpoint .func ,
58
60
)
@@ -64,23 +66,32 @@ def get_endpoints(
64
66
continue
65
67
66
68
elif inspect .isfunction (route .endpoint ) or inspect .ismethod (route .endpoint ):
69
+ path = self ._remove_converter (route .path )
67
70
for method in route .methods or ["GET" ]:
68
71
if method == "HEAD" :
69
72
continue
70
73
endpoints_info .append (
71
- EndpointInfo (route . path , method .lower (), route .endpoint )
74
+ EndpointInfo (path , method .lower (), route .endpoint )
72
75
)
73
76
else :
77
+ path = self ._remove_converter (route .path )
74
78
for method in ["get" , "post" , "put" , "patch" , "delete" , "options" ]:
75
79
if not hasattr (route .endpoint , method ):
76
80
continue
77
81
func = getattr (route .endpoint , method )
78
- endpoints_info .append (
79
- EndpointInfo (route .path , method .lower (), func )
80
- )
82
+ endpoints_info .append (EndpointInfo (path , method .lower (), func ))
81
83
82
84
return endpoints_info
83
85
86
+ def _remove_converter (self , path : str ) -> str :
87
+ """
88
+ Remove the converter from the path.
89
+ For example, a route like this:
90
+ Route("/users/{id:int}", endpoint=get_user, methods=["GET"])
91
+ Should be represented as `/users/{id}` in the OpenAPI schema.
92
+ """
93
+ return re .sub (r":\w+}" , "}" , path )
94
+
84
95
def parse_docstring (self , func_or_method : typing .Callable ) -> dict :
85
96
"""
86
97
Given a function, parse the docstring as YAML and return a dictionary of info.
0 commit comments