Skip to content

Commit

Permalink
Merge pull request #90 from daanklijn/89-class-based-view-routes-not-…
Browse files Browse the repository at this point in the history
…shown-in-swagger-ui

Class based view routes not shown in UI when adding via add_route
  • Loading branch information
cr0hn authored Jul 2, 2020
2 parents 644903e + d1ebf19 commit aaea290
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 59 deletions.
23 changes: 16 additions & 7 deletions aiohttp_swagger/helpers/builders.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,8 @@ def _extract_swagger_docs(end_point_doc, method="get"):
def _build_doc_from_func_doc(route):

out = {}

if isclass(route.handler) and issubclass(route.handler, web.View) and route.method == METH_ANY:
method_names = {
attr for attr in dir(route.handler)
if attr.upper() in METH_ALL
}
for method_name in method_names:
if isclass(route.handler) and issubclass(route.handler, web.View):
for method_name in _get_method_names_for_handler(route):
method = getattr(route.handler, method_name)
if method.__doc__ is not None and "---" in method.__doc__:
end_point_doc = method.__doc__.splitlines()
Expand All @@ -61,6 +56,20 @@ def _build_doc_from_func_doc(route):
out.update(_extract_swagger_docs(end_point_doc, method=str(route.method).lower()))
return out

def _get_method_names_for_handler(route):
# Return all valid method names in handler if the method is *,
# otherwise return the specific method.
if route.method == METH_ANY:
return {
attr for attr in dir(route.handler)
if attr.upper() in METH_ALL
}
else:
return {
attr for attr in dir(route.handler)
if attr.upper() in METH_ALL and attr.upper() == route.method
}


def generate_doc_from_each_end_point(
app: web.Application,
Expand Down
48 changes: 24 additions & 24 deletions tests/test_openapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ async def ping_partial(request):
return web.Response(text="pong")


async def test_swagger_ui(test_client, loop):
async def test_swagger_ui(aiohttp_client, loop):
TESTS_PATH = abspath(join(dirname(__file__)))

app = web.Application(loop=loop)
Expand All @@ -102,7 +102,7 @@ async def test_swagger_ui(test_client, loop):
ui_version=3
)

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


async def test_swagger_file_url(test_client, loop):
async def test_swagger_file_url(aiohttp_client, loop):
TESTS_PATH = abspath(join(dirname(__file__)))

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

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


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

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


async def test_custom_swagger(test_client, loop):
async def test_custom_swagger(aiohttp_client, loop):
app = web.Application(loop=loop)
app.router.add_route('GET', "/ping", ping)
description = "Test Custom Swagger"
Expand All @@ -154,15 +154,15 @@ async def test_custom_swagger(test_client, loop):
api_version="1.0.0",
contact="[email protected]")

client = await test_client(app)
client = await aiohttp_client(app)
resp1 = await client.get('/api/v1/doc/swagger.json')
assert resp1.status == 200
result = await resp1.json()
assert '/ping' in result['paths']
assert 'Test Custom Title' in result['info']['title']


async def test_swagger_home_decorator(test_client, loop):
async def test_swagger_home_decorator(aiohttp_client, loop):
app = web.Application(loop=loop)
app.router.add_route('GET', "/ping", ping)
description = "Test Custom Swagger"
Expand All @@ -175,15 +175,15 @@ async def test_swagger_home_decorator(test_client, loop):
contact="[email protected]",
swagger_home_decor=lambda x: x)

client = await test_client(app)
client = await aiohttp_client(app)
resp1 = await client.get('/api/v1/doc/swagger.json')
assert resp1.status == 200
result = await resp1.json()
assert '/ping' in result['paths']
assert 'Test Custom Title' in result['info']['title']


async def test_swagger_def_decorator(test_client, loop):
async def test_swagger_def_decorator(aiohttp_client, loop):
app = web.Application(loop=loop)
app.router.add_route('GET', "/ping", ping)
description = "Test Custom Swagger"
Expand All @@ -196,7 +196,7 @@ async def test_swagger_def_decorator(test_client, loop):
contact="[email protected]",
swagger_def_decor=lambda x: x)

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


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

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


async def test_undocumented_fn(test_client, loop):
async def test_undocumented_fn(aiohttp_client, loop):
app = web.Application(loop=loop)
app.router.add_route('GET', "/undoc_ping", undoc_ping)
setup_swagger(app, ui_version=3)
client = await test_client(app)
client = await aiohttp_client(app)
resp = await client.get('/undoc_ping')
assert resp.status == 200
swagger_resp1 = await client.get('/api/doc/swagger.json')
Expand All @@ -241,11 +241,11 @@ async def test_undocumented_fn(test_client, loop):
assert not result['paths']


async def test_wrong_method(test_client, loop):
async def test_wrong_method(aiohttp_client, loop):
app = web.Application(loop=loop)
app.router.add_route('POST', "/post_ping", ping)
setup_swagger(app, ui_version=3)
client = await test_client(app)
client = await aiohttp_client(app)
# GET
swagger_resp1 = await client.get('/api/doc/swagger.json')
assert swagger_resp1.status == 200
Expand All @@ -256,12 +256,12 @@ async def test_wrong_method(test_client, loop):
assert resp.status == 405


async def test_class_view(test_client, loop):
async def test_class_view(aiohttp_client, loop):
app = web.Application(loop=loop)
app.router.add_route('*', "/class_view", ClassView)
setup_swagger(app, ui_version=3)

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


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

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


async def test_sub_app(test_client, loop):
async def test_sub_app(aiohttp_client, loop):
sub_app = web.Application(loop=loop)
sub_app.router.add_route('*', "/class_view", ClassView)
setup_swagger(sub_app, ui_version=3, api_base_url='/sub_app')
app = web.Application(loop=loop)
app.add_subapp(prefix='/sub_app', subapp=sub_app)

client = await test_client(app)
client = await aiohttp_client(app)
# GET
resp = await client.get('/sub_app/class_view')
assert resp.status == 200
Expand Down
Loading

0 comments on commit aaea290

Please sign in to comment.