Skip to content

Commit aaea290

Browse files
author
cr0hn
authored
Merge pull request #90 from daanklijn/89-class-based-view-routes-not-shown-in-swagger-ui
Class based view routes not shown in UI when adding via add_route
2 parents 644903e + d1ebf19 commit aaea290

File tree

3 files changed

+91
-59
lines changed

3 files changed

+91
-59
lines changed

aiohttp_swagger/helpers/builders.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,8 @@ def _extract_swagger_docs(end_point_doc, method="get"):
4141
def _build_doc_from_func_doc(route):
4242

4343
out = {}
44-
45-
if isclass(route.handler) and issubclass(route.handler, web.View) and route.method == METH_ANY:
46-
method_names = {
47-
attr for attr in dir(route.handler)
48-
if attr.upper() in METH_ALL
49-
}
50-
for method_name in method_names:
44+
if isclass(route.handler) and issubclass(route.handler, web.View):
45+
for method_name in _get_method_names_for_handler(route):
5146
method = getattr(route.handler, method_name)
5247
if method.__doc__ is not None and "---" in method.__doc__:
5348
end_point_doc = method.__doc__.splitlines()
@@ -61,6 +56,20 @@ def _build_doc_from_func_doc(route):
6156
out.update(_extract_swagger_docs(end_point_doc, method=str(route.method).lower()))
6257
return out
6358

59+
def _get_method_names_for_handler(route):
60+
# Return all valid method names in handler if the method is *,
61+
# otherwise return the specific method.
62+
if route.method == METH_ANY:
63+
return {
64+
attr for attr in dir(route.handler)
65+
if attr.upper() in METH_ALL
66+
}
67+
else:
68+
return {
69+
attr for attr in dir(route.handler)
70+
if attr.upper() in METH_ALL and attr.upper() == route.method
71+
}
72+
6473

6574
def generate_doc_from_each_end_point(
6675
app: web.Application,

tests/test_openapi.py

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ async def ping_partial(request):
9393
return web.Response(text="pong")
9494

9595

96-
async def test_swagger_ui(test_client, loop):
96+
async def test_swagger_ui(aiohttp_client, loop):
9797
TESTS_PATH = abspath(join(dirname(__file__)))
9898

9999
app = web.Application(loop=loop)
@@ -102,7 +102,7 @@ async def test_swagger_ui(test_client, loop):
102102
ui_version=3
103103
)
104104

105-
client = await test_client(app)
105+
client = await aiohttp_client(app)
106106
resp1 = await client.get('/api/doc')
107107
assert resp1.status == 200
108108
retrieved = await resp1.text()
@@ -113,15 +113,15 @@ async def test_swagger_ui(test_client, loop):
113113
assert retrieved == loaded
114114

115115

116-
async def test_swagger_file_url(test_client, loop):
116+
async def test_swagger_file_url(aiohttp_client, loop):
117117
TESTS_PATH = abspath(join(dirname(__file__)))
118118

119119
app = web.Application(loop=loop)
120120
setup_swagger(app,
121121
ui_version=3,
122122
swagger_from_file=TESTS_PATH + "/data/example_swagger.yaml")
123123

124-
client = await test_client(app)
124+
client = await aiohttp_client(app)
125125
resp1 = await client.get('/api/doc/swagger.json')
126126
assert resp1.status == 200
127127
result = await resp1.json()
@@ -130,19 +130,19 @@ async def test_swagger_file_url(test_client, loop):
130130
assert 'API Title' in result['info']['title']
131131

132132

133-
async def test_partial_swagger_file(test_client, loop):
133+
async def test_partial_swagger_file(aiohttp_client, loop):
134134
app = web.Application(loop=loop)
135135
app.router.add_route('GET', "/ping-partial", ping_partial)
136136
setup_swagger(app, ui_version=3)
137137

138-
client = await test_client(app)
138+
client = await aiohttp_client(app)
139139
resp1 = await client.get('/api/doc/swagger.json')
140140
assert resp1.status == 200
141141
result = await resp1.json()
142142
assert '/ping-partial' in result['paths']
143143

144144

145-
async def test_custom_swagger(test_client, loop):
145+
async def test_custom_swagger(aiohttp_client, loop):
146146
app = web.Application(loop=loop)
147147
app.router.add_route('GET', "/ping", ping)
148148
description = "Test Custom Swagger"
@@ -154,15 +154,15 @@ async def test_custom_swagger(test_client, loop):
154154
api_version="1.0.0",
155155
contact="my.custom.contact@example.com")
156156

157-
client = await test_client(app)
157+
client = await aiohttp_client(app)
158158
resp1 = await client.get('/api/v1/doc/swagger.json')
159159
assert resp1.status == 200
160160
result = await resp1.json()
161161
assert '/ping' in result['paths']
162162
assert 'Test Custom Title' in result['info']['title']
163163

164164

165-
async def test_swagger_home_decorator(test_client, loop):
165+
async def test_swagger_home_decorator(aiohttp_client, loop):
166166
app = web.Application(loop=loop)
167167
app.router.add_route('GET', "/ping", ping)
168168
description = "Test Custom Swagger"
@@ -175,15 +175,15 @@ async def test_swagger_home_decorator(test_client, loop):
175175
contact="my.custom.contact@example.com",
176176
swagger_home_decor=lambda x: x)
177177

178-
client = await test_client(app)
178+
client = await aiohttp_client(app)
179179
resp1 = await client.get('/api/v1/doc/swagger.json')
180180
assert resp1.status == 200
181181
result = await resp1.json()
182182
assert '/ping' in result['paths']
183183
assert 'Test Custom Title' in result['info']['title']
184184

185185

186-
async def test_swagger_def_decorator(test_client, loop):
186+
async def test_swagger_def_decorator(aiohttp_client, loop):
187187
app = web.Application(loop=loop)
188188
app.router.add_route('GET', "/ping", ping)
189189
description = "Test Custom Swagger"
@@ -196,7 +196,7 @@ async def test_swagger_def_decorator(test_client, loop):
196196
contact="my.custom.contact@example.com",
197197
swagger_def_decor=lambda x: x)
198198

199-
client = await test_client(app)
199+
client = await aiohttp_client(app)
200200
resp1 = await client.get('/api/v1/doc/swagger.json')
201201
assert resp1.status == 200
202202
result = await resp1.json()
@@ -210,7 +210,7 @@ def swagger_info():
210210
return yaml.full_load(open(filename).read())
211211

212212

213-
async def test_swagger_info(test_client, loop, swagger_info):
213+
async def test_swagger_info(aiohttp_client, loop, swagger_info):
214214
app = web.Application(loop=loop)
215215
app.router.add_route('GET', "/ping", ping)
216216
description = "Test Custom Swagger"
@@ -219,7 +219,7 @@ async def test_swagger_info(test_client, loop, swagger_info):
219219
swagger_url="/api/v1/doc",
220220
swagger_info=swagger_info)
221221

222-
client = await test_client(app)
222+
client = await aiohttp_client(app)
223223
resp1 = await client.get('/api/v1/doc/swagger.json')
224224
assert resp1.status == 200
225225
result = await resp1.json()
@@ -228,11 +228,11 @@ async def test_swagger_info(test_client, loop, swagger_info):
228228
assert 'API Title' in result['info']['title']
229229

230230

231-
async def test_undocumented_fn(test_client, loop):
231+
async def test_undocumented_fn(aiohttp_client, loop):
232232
app = web.Application(loop=loop)
233233
app.router.add_route('GET', "/undoc_ping", undoc_ping)
234234
setup_swagger(app, ui_version=3)
235-
client = await test_client(app)
235+
client = await aiohttp_client(app)
236236
resp = await client.get('/undoc_ping')
237237
assert resp.status == 200
238238
swagger_resp1 = await client.get('/api/doc/swagger.json')
@@ -241,11 +241,11 @@ async def test_undocumented_fn(test_client, loop):
241241
assert not result['paths']
242242

243243

244-
async def test_wrong_method(test_client, loop):
244+
async def test_wrong_method(aiohttp_client, loop):
245245
app = web.Application(loop=loop)
246246
app.router.add_route('POST', "/post_ping", ping)
247247
setup_swagger(app, ui_version=3)
248-
client = await test_client(app)
248+
client = await aiohttp_client(app)
249249
# GET
250250
swagger_resp1 = await client.get('/api/doc/swagger.json')
251251
assert swagger_resp1.status == 200
@@ -256,12 +256,12 @@ async def test_wrong_method(test_client, loop):
256256
assert resp.status == 405
257257

258258

259-
async def test_class_view(test_client, loop):
259+
async def test_class_view(aiohttp_client, loop):
260260
app = web.Application(loop=loop)
261261
app.router.add_route('*', "/class_view", ClassView)
262262
setup_swagger(app, ui_version=3)
263263

264-
client = await test_client(app)
264+
client = await aiohttp_client(app)
265265
# GET
266266
resp = await client.get('/class_view')
267267
assert resp.status == 200
@@ -294,15 +294,15 @@ async def test_class_view(test_client, loop):
294294
assert "patch" not in result['paths']["/class_view"]
295295

296296

297-
async def test_data_defs(test_client, loop):
297+
async def test_data_defs(aiohttp_client, loop):
298298
TESTS_PATH = abspath(join(dirname(__file__)))
299299
file = open(TESTS_PATH + "/data/example_data_definitions.json")
300300
app = web.Application(loop=loop)
301301
app.router.add_route('GET', "/users", users_with_data_def)
302302
setup_swagger(app, ui_version=3, definitions=json.loads(file.read()))
303303
file.close()
304304

305-
client = await test_client(app)
305+
client = await aiohttp_client(app)
306306
swagger_resp1 = await client.get('/api/doc/swagger.json')
307307
assert swagger_resp1.status == 200
308308
result = await swagger_resp1.json()
@@ -311,14 +311,14 @@ async def test_data_defs(test_client, loop):
311311
assert result['components']['schemas']['User']['properties']['permissions']['items']['$ref'] is not None
312312

313313

314-
async def test_sub_app(test_client, loop):
314+
async def test_sub_app(aiohttp_client, loop):
315315
sub_app = web.Application(loop=loop)
316316
sub_app.router.add_route('*', "/class_view", ClassView)
317317
setup_swagger(sub_app, ui_version=3, api_base_url='/sub_app')
318318
app = web.Application(loop=loop)
319319
app.add_subapp(prefix='/sub_app', subapp=sub_app)
320320

321-
client = await test_client(app)
321+
client = await aiohttp_client(app)
322322
# GET
323323
resp = await client.get('/sub_app/class_view')
324324
assert resp.status == 200

0 commit comments

Comments
 (0)