예제 #1
0
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"
예제 #2
0
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
예제 #3
0
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"}
예제 #4
0
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"}}
예제 #5
0
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
예제 #6
0
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)
예제 #7
0
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"}
예제 #8
0
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
예제 #9
0
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}
예제 #10
0
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}
예제 #11
0
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"}
예제 #12
0
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)
예제 #13
0
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
예제 #14
0
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}
예제 #15
0
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)
예제 #16
0
 def _swagger_docs_with_components(**kwargs):
     app = web.Application()
     return SwaggerDocs(
         app,
         components="tests/testdata/components.yaml",
         **kwargs,
     )
예제 #17
0
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}
예제 #18
0
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)
예제 #19
0
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
예제 #20
0
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
예제 #21
0
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"}
예제 #22
0
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
예제 #24
0
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
예제 #25
0
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."
                    }
                },
            }
        }
    }
예제 #27
0
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"}}}
예제 #28
0
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)
예제 #29
0
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"
예제 #30
0
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)