async def test_two_uis_one_path(swagger_ui_settings, redoc_ui_settings, rapidoc_ui_settings): app = web.Application() with pytest.raises(Exception) as exc_info: SwaggerDocs( app, swagger_ui_settings=swagger_ui_settings(), redoc_ui_settings=redoc_ui_settings(), ) assert str(exc_info.value) == "cannot bind two UIs on the same path" with pytest.raises(Exception) as exc_info: SwaggerDocs( app, swagger_ui_settings=swagger_ui_settings(), rapidoc_ui_settings=rapidoc_ui_settings(), ) assert str(exc_info.value) == "cannot bind two UIs on the same path" with pytest.raises(Exception) as exc_info: SwaggerDocs( app, rapidoc_ui_settings=rapidoc_ui_settings(), redoc_ui_settings=redoc_ui_settings(), ) assert str(exc_info.value) == "cannot bind two UIs on the same path"
async def test_allow_head(aiohttp_client, loop): app = web.Application(loop=loop) s = SwaggerDocs(app, "/docs") async def handler(request, param_id: int): """ --- parameters: - name: param_id in: path required: true schema: type: integer responses: '200': description: OK. """ return web.json_response({"param_id": param_id}) s.add_get("/r1/{param_id}", handler) s.add_get("/r2/{param_id}", handler, allow_head=False) client = await aiohttp_client(app) resp = await client.head("/r1/1") assert resp.status == 200 resp = await client.head("/r2/1") assert resp.status == 405
async def test_fail_validation(aiohttp_client, loop): app = web.Application(loop=loop) s = SwaggerDocs(app, "/docs") async def handler(request, int32: int): """ --- parameters: - name: int32 in: cookie required: true schema: type: integer format: int32 responses: '200': description: OK. """ return web.json_response({"int32": int32}) s.add_route("POST", "/r", handler) client = await aiohttp_client(app) cookies = {"int32": "abc"} resp = await client.post(f"/r", cookies=cookies) assert resp.status == 400 error = error_to_json(await resp.text()) assert error == {"int32": "value should be type of int"}
async def test_wrong_item_in_array(aiohttp_client, loop): app = web.Application(loop=loop) s = SwaggerDocs(app, "/docs") async def handler(request): """ --- parameters: - name: array in: query required: true schema: type: array items: type: integer responses: '200': description: OK. """ return web.json_response() s.add_route("POST", "/r", handler) client = await aiohttp_client(app) params = {"array": ",".join(str(x) for x in [1, "abc", 3, True, 5])} resp = await client.post(f"/r", params=params) assert resp.status == 400 error = error_to_json(await resp.text()) assert error == {"array": {"1": "value should be type of int"}}
async def test_ref_parameter(aiohttp_client, loop): app = web.Application(loop=loop) s = SwaggerDocs(app, "/docs", components="tests/testdata/components.yaml") async def handler(request, month: int): """ --- parameters: - $ref: '#/components/parameters/Month' responses: '200': description: OK. """ return web.json_response({"month": month}) s.add_route("GET", "/r", handler) client = await aiohttp_client(app) params = {"month": 5} resp = await client.get("/r", params=params) assert resp.status == 200 assert await resp.json() == params
def main(): app = web.Application() s = SwaggerDocs(app, "/docs", title="Swagger Petstore", version="1.0.0") # register your handler before registering routes s.register_media_type_handler("my_cool/type", my_cool_handler) s.add_routes([web.post("/pets", create_pet)]) web.run_app(app)
async def test_required_no_content_type(aiohttp_client, loop): app = web.Application(loop=loop) s = SwaggerDocs(app, "/docs") async def handler(request, body: Dict): """ --- requestBody: required: true content: application/json: schema: type: object required: - required properties: required: type: integer responses: '200': description: OK. """ return web.json_response(body) s.add_route("POST", "/r", handler) client = await aiohttp_client(app) resp = await client.post("/r", skip_auto_headers=("Content-Type", )) assert resp.status == 400 error = error_to_json(await resp.text()) assert error == {"body": "is required"}
async def test_no_content_type(aiohttp_client, loop): app = web.Application(loop=loop) s = SwaggerDocs(app, "/docs") async def handler(request, body: Optional[Dict] = None): """ --- requestBody: content: application/json: schema: type: object required: - required properties: required: type: integer responses: '200': description: OK. """ return web.json_response(body) s.add_route("POST", "/r", handler) client = await aiohttp_client(app) resp = await client.post("/r", skip_auto_headers=("Content-Type", )) assert resp.status == 200 assert await resp.json() is None
async def test_basic_auth(aiohttp_client, loop): app = web.Application(loop=loop) s = SwaggerDocs(app, "/docs", components="tests/testdata/components.yaml") async def handler(request): """ --- security: - basicAuth: [] responses: '200': description: OK. """ assert "authorization" in request["data"] return web.json_response( {"authorization": request["data"]["authorization"]}) s.add_route("GET", "/r", handler) client = await aiohttp_client(app) authorization = "ZGVtbzpwQDU1dzByZA==" headers = {"Authorization": f"Basic {authorization}"} resp = await client.get("/r", headers=headers) assert resp.status == 200 assert await resp.json() == {"authorization": authorization}
async def test_bearer_auth(aiohttp_client, loop): app = web.Application(loop=loop) s = SwaggerDocs(app, "/docs", components="tests/testdata/components.yaml") async def handler(request): """ --- security: - bearerAuth: [] responses: '200': description: OK. """ assert "authorization" in request["data"] return web.json_response( {"authorization": request["data"]["authorization"]}) s.add_route("GET", "/r", handler) client = await aiohttp_client(app) authorization = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ1" headers = {"Authorization": f"Bearer {authorization}"} resp = await client.get("/r", headers=headers) assert resp.status == 200 assert await resp.json() == {"authorization": authorization}
async def test_wrong_body(aiohttp_client, loop): app = web.Application(loop=loop) s = SwaggerDocs(app, "/docs") async def handler(request, body: Dict): """ --- requestBody: required: true content: application/x-www-form-urlencoded: schema: type: object required: - required properties: required: type: integer responses: '200': description: OK. """ return web.json_response(body) s.add_route("POST", "/r", handler) client = await aiohttp_client(app) body = {"required": 10} resp = await client.post("/r", json=body) assert resp.status == 400 error = error_to_json(await resp.text()) assert error == {"body": "no handler for application/json"}
def main(): config = get_config() app = web.Application() aiohttp_jinja2.setup( app, loader=jinja2.FileSystemLoader("src/templates") ) app["controller"] = SDPController(config) app.on_startup.append(start_background_tasks) swagger = SwaggerDocs( app, swagger_ui_settings=SwaggerUiSettings(path="/api/doc"), title="Product controller PoC", version="1.0.0", # components="swagger.yaml", ) swagger.add_routes( [ web.get("/", home_page), web.post("/product-configure", product_configure_handle), web.post("/capture-init", capture_init_handle), web.post("/capture-done", capture_done_handle), web.post("/product-deconfigure", product_deconfigure_handle), web.get("/status", status_handle), web.get("/config", config_handle), ] ) web.run_app(app)
async def test_header(aiohttp_client, loop): app = web.Application(loop=loop) s = SwaggerDocs(app, "/docs") async def handler(request): """ --- parameters: - name: x-request-id in: header required: true schema: type: string responses: '200': description: OK. """ return web.json_response( {"x-request-id": request["data"]["x-request-id"]}) s.add_route("GET", "/r", handler) client = await aiohttp_client(app) headers = {"x-request-id": "some_request_id"} resp = await client.get("/r", headers=headers) assert resp.status == 200 assert await resp.json() == headers
async def test_header_always_lower_case(aiohttp_client, loop): app = web.Application(loop=loop) s = SwaggerDocs(app, "/docs") async def handler(request): """ --- parameters: - name: X-REQUEST-ID in: header required: true schema: type: string responses: '200': description: OK. """ assert "X-REQUEST-ID" not in request["data"] return web.json_response( {"x-request-id": request["data"]["x-request-id"]}) s.add_route("GET", "/r", handler) client = await aiohttp_client(app) header_name = "X-REQUEST-ID" header_value = "some_request_id" headers = {header_name: header_value} resp = await client.get("/r", headers=headers) assert resp.status == 200 assert await resp.json() == {header_name.lower(): header_value}
def main(): app = web.Application() s = SwaggerDocs(app) # register your custom string format validator s.register_string_format_validator("my_custom_sf", my_custom_validator) s.add_routes([web.get("/p", handler)]) web.run_app(app)
def _swagger_docs_with_components(**kwargs): app = web.Application() return SwaggerDocs( app, components="tests/testdata/components.yaml", **kwargs, )
async def test_optional_header(aiohttp_client, loop): app = web.Application(loop=loop) s = SwaggerDocs(app, "/docs") async def handler(request): """ --- parameters: - name: X-USER-ID in: header schema: type: integer responses: '200': description: OK. """ user_id = request["data"].get("x-user-id", 50) return web.json_response({"x-user-id": user_id}) s.add_route("GET", "/r", handler) client = await aiohttp_client(app) resp = await client.get("/r") assert resp.status == 200 assert await resp.json() == {"x-user-id": 50}
async def test_redirect(aiohttp_client, loop): app = web.Application(loop=loop) s = SwaggerDocs(app, "/docs") async def handler(request, param_id: int): """ --- parameters: - name: param_id in: path required: true schema: type: integer responses: '200': description: OK. """ return web.json_response({"param_id": param_id}) s.add_route("GET", "/r/{param_id}", handler) client = await aiohttp_client(app) resp = await client.get("/docs", allow_redirects=False) assert resp.status == 301 assert "/docs/" == resp.headers.get(hdrs.LOCATION) or resp.headers.get(hdrs.URI)
async def test_swagger_json_renders_datetime(aiohttp_client, loop): app = web.Application(loop=loop) s = SwaggerDocs( app, "/docs", title="test app", version="2.2.2", description="test description" ) async def handler(request): """ --- parameters: - name: date in: query schema: type: string format: date example: 2019-01-01 responses: '200': description: OK. """ return web.json_response() s.add_route("GET", "/r", handler) client = await aiohttp_client(app) resp = await client.get("/docs/swagger.json") assert resp.status == 200
async def test_index_html(aiohttp_client, loop): app = web.Application(loop=loop) s = SwaggerDocs(app, "/docs") async def handler(request, param_id: int): """ --- parameters: - name: param_id in: path required: true schema: type: integer responses: '200': description: OK. """ return web.json_response({"param_id": param_id}) s.add_route("GET", "/r/{param_id}", handler) client = await aiohttp_client(app) resp = await client.get("/docs/") assert resp.status == 200
async def test_missing_bearer_word_in_auth(aiohttp_client, loop): app = web.Application(loop=loop) s = SwaggerDocs(app, "/docs", components="tests/testdata/components.yaml") async def handler(request): """ --- security: - bearerAuth: [] responses: '200': description: OK. """ return web.json_response() s.add_route("GET", "/r", handler) client = await aiohttp_client(app) authorization = "ZGVtbzpwQDU1dzByZA==" headers = {"Authorization": authorization} resp = await client.get("/r", headers=headers) assert resp.status == 400 error = error_to_json(await resp.text()) assert error == {"authorization": "value should start with 'Bearer' word"}
async def test_missing_header_parameter(aiohttp_client, loop): app = web.Application(loop=loop) s = SwaggerDocs(app, "/docs") async def handler(request): """ --- parameters: - name: variable in: header required: true schema: type: integer responses: '200': description: OK. """ return web.json_response() s.add_route("GET", "/r", handler) client = await aiohttp_client(app) resp = await client.get("/r") assert resp.status == 400 error = error_to_json(await resp.text()) assert error == {"variable": "is required"}
async def test_file_upload(aiohttp_client, loop): app = web.Application(loop=loop) s = SwaggerDocs(app, "/docs") async def octet_stream_handler(request: web.Request) -> Tuple[bytes, bool]: return await request.read(), True s.register_media_type_handler("application/octet-stream", octet_stream_handler) async def handler(request, body: bytes): """ --- requestBody: required: true content: application/octet-stream: schema: type: string format: binary responses: '200': description: OK. """ return web.Response(body=body) s.add_route("POST", "/r", handler) client = await aiohttp_client(app) data = b"\x00Binary-data\x00" resp = await client.post("/r", data=data) assert resp.status == 200 assert await resp.read() == data
async def test_decorated_routes(aiohttp_client, loop): app = web.Application(loop=loop) routes = web.RouteTableDef() @routes.get("/r") async def handler(request, int32: int): """ --- parameters: - name: int32 in: query required: true schema: type: integer responses: '200': description: OK. """ return web.json_response({"int32": int32}) s = SwaggerDocs(app, "/docs") s.add_routes(routes) client = await aiohttp_client(app) params = {"int32": 15} resp = await client.get("/r", params=params) assert resp.status == 200 assert await resp.json() == params
async def test_ref(aiohttp_client, loop): app = web.Application(loop=loop) s = SwaggerDocs(app, "/docs", components="tests/testdata/components.yaml") async def handler(request, body: Dict): """ --- requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Pet' responses: '200': description: OK. """ return web.json_response(body) s.add_route("POST", "/r", handler) client = await aiohttp_client(app) body = {"name": "pet", "age": 15} resp = await client.post("/r", json=body) assert resp.status == 200 assert await resp.json() == body
async def test_validation_false(aiohttp_client, loop): app = web.Application(loop=loop) routes = web.RouteTableDef() @routes.post("/r") async def handler(request): """ --- parameters: - name: query in: query required: true schema: type: string responses: '200': description: OK. """ assert "data" not in request assert request.rel_url.query["query"] == "str" return web.json_response() s = SwaggerDocs(app, "/docs", validate=False) s.add_routes(routes) client = await aiohttp_client(app) params = {"query": "str"} resp = await client.post("/r", params=params) assert resp.status == 200 resp = await client.get("/docs/") assert resp.status == 200 resp = await client.get("/docs/swagger.json") assert resp.status == 200 spec = await resp.json() assert spec["paths"] == { "/r": { "post": { "parameters": [{ "name": "query", "in": "query", "required": True, "schema": { "type": "string" }, }], "responses": { "200": { "description": "OK." } }, } } }
async def test_array_in_object(aiohttp_client, loop): app = web.Application(loop=loop) s = SwaggerDocs(app, "/docs") async def handler(request, body: Dict): """ --- requestBody: required: true content: application/json: schema: type: object required: - array properties: array: type: array items: type: integer responses: '200': description: OK. """ return web.json_response(body) s.add_route("POST", "/r", handler) client = await aiohttp_client(app) body = {"array": []} resp = await client.post("/r", json=body) assert resp.status == 200 assert await resp.json() == body body = {"array": [1, 2, 3]} resp = await client.post("/r", json=body) assert resp.status == 200 assert await resp.json() == body body = {"array": ["1", 2, 3]} resp = await client.post("/r", json=body) assert resp.status == 400 error = error_to_json(await resp.text()) assert error == {"body": {"array": {"0": "value should be type of int"}}} body = {"array": [1, 2.2, 3]} resp = await client.post("/r", json=body) assert resp.status == 400 error = error_to_json(await resp.text()) assert error == {"body": {"array": {"1": "value should be type of int"}}} body = {"array": [1, 2, True]} resp = await client.post("/r", json=body) assert resp.status == 400 error = error_to_json(await resp.text()) assert error == {"body": {"array": {"2": "value should be type of int"}}}
def main(): app = web.Application() s = SwaggerDocs( app, components="components.yaml", swagger_ui_settings=SwaggerUiSettings(path="/docs"), ) s.add_routes([web.get("/", handler, allow_head=False)]) web.run_app(app)
async def test_one_of_auth(aiohttp_client, loop): app = web.Application(loop=loop) s = SwaggerDocs(app, "/docs", components="tests/testdata/components.yaml") async def handler(request): """ --- security: - bearerAuth: [] - apiKeyCookieAuth: [] responses: '200': description: OK. """ assert not ("C-API-KEY" in request["data"] and "authorization" in request["data"]) r = {} if "C-API-KEY" in request["data"]: assert "authorization" not in request["data"] r["api_key"] = request["data"]["C-API-KEY"] else: assert "authorization" in request["data"] assert "C-API-KEY" not in request["data"] r["authorization"] = request["data"]["authorization"] return web.json_response(r) s.add_route("GET", "/r", handler) client = await aiohttp_client(app) api_key = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ4" cookies = {"C-API-KEY": api_key} resp = await client.get("/r", cookies=cookies) assert resp.status == 200 assert await resp.json() == {"api_key": api_key} authorization = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ1" headers = {"Authorization": f"Bearer {authorization}"} resp = await client.get("/r", headers=headers) assert resp.status == 200 assert await resp.json() == {"authorization": authorization} resp = await client.get("/r", cookies=cookies, headers=headers) assert resp.status == 400 error = error_to_json(await resp.text()) assert error == "Only one auth must be provided" resp = await client.get("/r") assert resp.status == 400 error = error_to_json(await resp.text()) assert error == "One auth must be provided"
def main(): app = web.Application() s = SwaggerDocs( app, swagger_ui_settings=SwaggerUiSettings(path="/swagger"), redoc_ui_settings=ReDocUiSettings(path="/redoc"), rapidoc_ui_settings=RapiDocUiSettings(path="/rapidoc"), ) s.add_routes([web.get("/", handler, allow_head=True)]) web.run_app(app)