Commit 4c17c30b authored by Goran Pavlovic's avatar Goran Pavlovic
Browse files

Increased OpenApi document version to 3.0.1

parent f049157a
Version 1.0.13
=============
- Increased OpenApi document version to 3.0.1 for Swagger UI 3
Version 1.0.12
=============
- Dropped support for python 3.4
......
......@@ -64,7 +64,8 @@ def setup_swagger(app: web.Application,
swagger_info = load_doc_from_yaml_file(swagger_from_file)
else:
swagger_info = generate_doc_from_each_end_point(
app, api_base_url=api_base_url, description=description,
app, ui_version=ui_version,
api_base_url=api_base_url, description=description,
api_version=api_version, title=title, contact=contact,
template_path=swagger_template_path,
definitions=definitions,
......
......@@ -65,6 +65,7 @@ def _build_doc_from_func_doc(route):
def generate_doc_from_each_end_point(
app: web.Application,
*,
ui_version: int = None,
api_base_url: str = "/",
description: str = "Swagger API definition",
api_version: str = "1.0.0",
......@@ -97,7 +98,10 @@ def generate_doc_from_each_end_point(
jinja2_env.filters['nesteddict2yaml'] = nesteddict2yaml
if template_path is None:
template_path = join(SWAGGER_TEMPLATE, "swagger.yaml")
if ui_version == 3:
template_path = join(SWAGGER_TEMPLATE, "openapi.yaml")
else:
template_path = join(SWAGGER_TEMPLATE, "swagger.yaml")
with open(template_path, "r") as f:
swagger_base = (
......
openapi: 3.0.1
info:
title: {{ title }}
description: {{ description }}
version: "{{ version }}"
{% if contact %}
contact:
name: {{ contact }}
{% endif %}
servers:
- url: {{ base_path }}
components:
{% if definitions %}
schemas:
{{ definitions|nesteddict2yaml }}
{% endif %}
{% if security_definitions %}
securitySchemes:
{{ security_definitions|nesteddict2yaml }}
{% endif %}
paths:
import json
import pytest
import yaml
from os.path import join, dirname, abspath
from aiohttp import web
from aiohttp_swagger import *
async def ping(request):
"""
---
description: This end-point allow to test that service is up.
tags:
- Health check
produces:
- text/plain
responses:
"200":
description: successful operation. Return "pong" text
"405":
description: invalid HTTP Method
"""
return web.Response(text="pong")
async def undoc_ping(request):
return web.Response(text="pong")
async def users_with_data_def(request):
"""
---
description: This endpoint returns user which is defined though data definition during initialization.
tags:
- Users
produces:
- application/json
responses:
"200":
description: Successful operation, returns User object nested permisiion list
schema:
$ref: '#/definitions/User'
"""
return web.Response(text="pong")
class ClassView(web.View):
def _irrelevant_method(self):
pass
async def get(self):
"""
---
description: Get resources
tags:
- Class View
produces:
- text/plain
responses:
"200":
description: successful operation.
"405":
description: invalid HTTP Method
"""
return web.Response(text="OK")
async def post(self):
"""
---
description: Post resources
tags:
- Class View
produces:
- text/plain
responses:
"200":
description: successful operation.
"405":
description: invalid HTTP Method
"""
return web.Response(text="OK")
async def patch(self):
"""
This method is undocumented in the swagger sense.
"""
return web.Response(text="OK")
@swagger_path(abspath(join(dirname(__file__))) + '/data/partial_swagger.yaml')
async def ping_partial(request):
return web.Response(text="pong")
async def test_swagger_ui(test_client, loop):
TESTS_PATH = abspath(join(dirname(__file__)))
app = web.Application(loop=loop)
setup_swagger(app,
swagger_from_file=TESTS_PATH + "/data/example_swagger.yaml",
ui_version=3
)
client = await test_client(app)
resp1 = await client.get('/api/doc')
assert resp1.status == 200
retrieved = await resp1.text()
loaded = open(join(TESTS_PATH, "..", "aiohttp_swagger/swagger_ui3/index.html")).read()
loaded = loaded.replace("##STATIC_PATH##", "/api/doc/swagger_static")
loaded = loaded.replace("##SWAGGER_CONFIG##", "/api/doc/swagger.json")
loaded = loaded.replace("##SWAGGER_VALIDATOR_URL##", '')
assert retrieved == loaded
async def test_swagger_file_url(test_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)
resp1 = await client.get('/api/doc/swagger.json')
assert resp1.status == 200
result = await resp1.json()
assert '/example1' in result['paths']
assert '/example2' in result['paths']
assert 'API Title' in result['info']['title']
async def test_partial_swagger_file(test_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)
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):
app = web.Application(loop=loop)
app.router.add_route('GET', "/ping", ping)
description = "Test Custom Swagger"
setup_swagger(app,
ui_version=3,
swagger_url="/api/v1/doc",
description=description,
title="Test Custom Title",
api_version="1.0.0",
contact="my.custom.contact@example.com")
client = await test_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):
app = web.Application(loop=loop)
app.router.add_route('GET', "/ping", ping)
description = "Test Custom Swagger"
setup_swagger(app,
ui_version=3,
swagger_url="/api/v1/doc",
description=description,
title="Test Custom Title",
api_version="1.0.0",
contact="my.custom.contact@example.com",
swagger_home_decor=lambda x: x)
client = await test_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):
app = web.Application(loop=loop)
app.router.add_route('GET', "/ping", ping)
description = "Test Custom Swagger"
setup_swagger(app,
ui_version=3,
swagger_url="/api/v1/doc",
description=description,
title="Test Custom Title",
api_version="1.0.0",
contact="my.custom.contact@example.com",
swagger_def_decor=lambda x: x)
client = await test_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']
@pytest.fixture
def swagger_info():
filename = abspath(join(dirname(__file__))) + "/data/example_swagger.yaml"
return yaml.full_load(open(filename).read())
async def test_swagger_info(test_client, loop, swagger_info):
app = web.Application(loop=loop)
app.router.add_route('GET', "/ping", ping)
description = "Test Custom Swagger"
setup_swagger(app,
ui_version=3,
swagger_url="/api/v1/doc",
swagger_info=swagger_info)
client = await test_client(app)
resp1 = await client.get('/api/v1/doc/swagger.json')
assert resp1.status == 200
result = await resp1.json()
assert '/example1' in result['paths']
assert '/example2' in result['paths']
assert 'API Title' in result['info']['title']
async def test_undocumented_fn(test_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)
resp = await client.get('/undoc_ping')
assert resp.status == 200
swagger_resp1 = await client.get('/api/doc/swagger.json')
assert swagger_resp1.status == 200
result = await swagger_resp1.json()
assert not result['paths']
async def test_wrong_method(test_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)
# GET
swagger_resp1 = await client.get('/api/doc/swagger.json')
assert swagger_resp1.status == 200
result = await swagger_resp1.json()
assert "/post_ping" in result['paths']
assert "post" in result['paths']["/post_ping"]
resp = await client.get('/post_ping')
assert resp.status == 405
async def test_class_view(test_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)
# GET
resp = await client.get('/class_view')
assert resp.status == 200
text = await resp.text()
assert 'OK' in text
swagger_resp1 = await client.get('/api/doc/swagger.json')
assert swagger_resp1.status == 200
result = await swagger_resp1.json()
assert "/class_view" in result['paths']
assert "get" in result['paths']["/class_view"]
assert "post" in result['paths']["/class_view"]
# POST
resp = await client.post('/class_view')
assert resp.status == 200
text = await resp.text()
assert 'OK' in text
result = await swagger_resp1.json()
assert "/class_view" in result['paths']
assert "get" in result['paths']["/class_view"]
assert "post" in result['paths']["/class_view"]
# Undocumented PATCH
resp = await client.patch('/class_view')
assert resp.status == 200
text = await resp.text()
assert 'OK' in text
result = await swagger_resp1.json()
assert "/class_view" in result['paths']
assert "patch" not in result['paths']["/class_view"]
async def test_data_defs(test_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)
swagger_resp1 = await client.get('/api/doc/swagger.json')
assert swagger_resp1.status == 200
result = await swagger_resp1.json()
assert 'User' in result['components']['schemas']
assert 'Permission' in result['components']['schemas']
assert result['components']['schemas']['User']['properties']['permissions']['items']['$ref'] is not None
async def test_sub_app(test_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)
# GET
resp = await client.get('/sub_app/class_view')
assert resp.status == 200
text = await resp.text()
assert 'OK' in text
swagger_resp1 = await client.get('/sub_app/api/doc/swagger.json')
assert swagger_resp1.status == 200
result = await swagger_resp1.json()
assert "/class_view" in result['paths']
assert "get" in result['paths']["/class_view"]
assert "post" in result['paths']["/class_view"]
import asyncio
import json
import pytest
import yaml
......@@ -8,7 +7,6 @@ from aiohttp import web
from aiohttp_swagger import *
async def ping(request):
"""
---
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment