Beispiel #1
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"}}
Beispiel #2
0
async def test_missing_query_parameter(aiohttp_client, loop):
    app = web.Application(loop=loop)
    s = SwaggerDocs(app, "/docs")

    async def handler(request):
        """
        ---
        parameters:

          - name: variable
            in: query
            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"}
Beispiel #3
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
Beispiel #4
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"}}}
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."
                    }
                },
            }
        }
    }
Beispiel #6
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)
Beispiel #7
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"
Beispiel #8
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)
async def test_no_docs(aiohttp_client, loop):
    app = web.Application(loop=loop)
    s = SwaggerDocs(app, "/docs")

    async def handler(request):
        return web.json_response()

    s.add_route("POST", "/r", handler)

    client = await aiohttp_client(app)
    resp = await client.post("/r", json={"array": "whatever"})
    assert resp.status == 200
async def test_swagger_json(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, 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/swagger.json")
    assert resp.status == 200
    assert await resp.json() == {
        "openapi": "3.0.0",
        "info": {
            "title": "test app",
            "version": "2.2.2",
            "description": "test description",
        },
        "paths": {
            "/r/{param_id}": {
                "get": {
                    "parameters": [
                        {
                            "in": "path",
                            "name": "param_id",
                            "required": True,
                            "schema": {"type": "integer"},
                        }
                    ],
                    "responses": {"200": {"description": "OK."}},
                }
            }
        },
    }
Beispiel #11
0
async def test_form_data(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
                properties:
                  integer:
                    type: integer
                  number:
                    type: number
                  string:
                    type: string
                  boolean:
                    type: boolean

        responses:
          '200':
            description: OK.

        """
        return web.json_response(body)

    s.add_route("POST", "/r", handler)

    client = await aiohttp_client(app)

    integer = 15
    number = 15.5
    string = "string"
    boolean = True
    data = {
        "integer": integer,
        "number": number,
        "string": string,
        "boolean": str(boolean).lower(),
    }
    resp = await client.post("/r", data=data)
    assert resp.status == 200
    assert await resp.json() == {
        "integer": integer,
        "number": number,
        "string": string,
        "boolean": boolean,
    }
async def test_named_resources(aiohttp_client, loop):
    app = web.Application(loop=loop)
    s = SwaggerDocs(app, "/docs")

    async def handler(request):
        return web.json_response()

    s.add_routes(
        [web.get("/", handler, name="get"), web.post("/", handler, name="post")]
    )

    assert "get" in app.router
    assert "post" in app.router
Beispiel #13
0
async def test_all_of_auth(aiohttp_client, loop):
    app = web.Application(loop=loop)
    s = SwaggerDocs(app, "/docs", components="tests/testdata/components.yaml")

    async def handler(request):
        """
        ---
        security:
          - basicAuth: []
            apiKeyCookieAuth: []

        responses:
          '200':
            description: OK.

        """
        assert "C-API-KEY" in request["data"]
        assert "authorization" in request["data"]
        return web.json_response({
            "api_key":
            request["data"]["C-API-KEY"],
            "authorization":
            request["data"]["authorization"],
        })

    s.add_route("GET", "/r", handler)

    client = await aiohttp_client(app)

    api_key = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ4"
    cookies = {"C-API-KEY": api_key}

    authorization = "ZGVtbzpwQDU1dzByZA=="
    headers = {"Authorization": f"Basic {authorization}"}

    resp = await client.get("/r", headers=headers, cookies=cookies)
    assert resp.status == 200
    assert await resp.json() == {
        "api_key": api_key,
        "authorization": authorization
    }

    resp = await client.get("/r", cookies=cookies)
    assert resp.status == 400
    error = error_to_json(await resp.text())
    assert error == {"authorization": "is required"}

    resp = await client.get("/r", headers=headers)
    assert resp.status == 400
    error = error_to_json(await resp.text())
    assert error == {"C-API-KEY": "is required"}
Beispiel #14
0
async def test_min_max_properties(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
                minProperties: 2
                maxProperties: 5

        responses:
          '200':
            description: OK.

        """
        return web.json_response(body)

    s.add_route("POST", "/r", handler)

    client = await aiohttp_client(app)

    body = {"str1": "str1", "str2": "str1", "str3": "str1"}
    resp = await client.post(f"/r", json=body)
    assert resp.status == 200
    assert await resp.json() == body

    body = {"str1": "str1"}
    resp = await client.post(f"/r", json=body)
    assert resp.status == 400
    error = error_to_json(await resp.text())
    assert error == {"body": "number or properties must be more than 2"}

    body = {
        "str1": "str1",
        "str2": "str1",
        "str3": "str1",
        "str4": "str1",
        "str5": "str1",
        "str6": "str1",
    }
    resp = await client.post(f"/r", json=body)
    assert resp.status == 400
    error = error_to_json(await resp.text())
    assert error == {"body": "number or properties must be less than 5"}
Beispiel #15
0
def main():
    app = web.Application()
    s = SwaggerDocs(app,
                    '/docs',
                    title="Swagger Petstore",
                    version="1.0.0",
                    components="components.yaml")
    s.add_routes([
        web.get("/pets", get_all_pets),
        web.get("/pets/{pet_id}", get_one_pet),
        web.delete("/pets/{pet_id}", delete_one_pet),
        web.post("/pets", create_pet),
    ])
    app['storage'] = {}
    web.run_app(app)
Beispiel #16
0
def main():
    app = web.Application()
    s = SwaggerDocs(
        app,
        title="Example",
        version="1.0.0",
        swagger_ui_settings=SwaggerUiSettings(path="/docs"),
    )
    s.add_routes(
        [
            web.get("/docstring", docstring_handler, allow_head=False),
            web.get("/decorator", decorator_handler, allow_head=False),
        ]
    )
    web.run_app(app)
Beispiel #17
0
 def _swagger_docs_with_components(**kwargs):
     app = web.Application()
     return SwaggerDocs(
         app,
         components="tests/testdata/components.yaml",
         **kwargs,
     )
Beispiel #18
0
async def test_two_uis_one_path(swagger_ui_settings, redoc_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"
Beispiel #19
0
async def test_query_array(aiohttp_client, loop):
    app = web.Application(loop=loop)
    s = SwaggerDocs(app, "/docs")

    async def handler(request, query1: List[int], query2: List[int] = None):
        """
        ---
        parameters:

          - name: query1
            in: query
            required: true
            schema:
              type: array
              items:
                type: integer
              uniqueItems: true
              minItems: 1

          - name: query2
            in: query
            schema:
              type: array
              items:
                type: integer
              uniqueItems: true
              minItems: 1

        responses:
          '200':
            description: OK.

        """
        return web.json_response({"query1": query1, "query2": query2})

    s.add_route("POST", "/r", handler)

    client = await aiohttp_client(app)

    query1 = [1, 2, 3, 4, 5]
    params = {"query1": ",".join(str(x) for x in query1)}
    resp = await client.post(f"/r", params=params)
    assert resp.status == 200
    assert await resp.json() == {"query1": query1, "query2": None}
Beispiel #20
0
def main():
    app = web.Application()
    s = SwaggerDocs(
        app,
        title="Swagger Petstore",
        version="1.0.0",
        components="components.yaml",
        swagger_ui_settings=SwaggerUiSettings(path="/docs"),
    )
    s.add_routes(
        [
            web.get("/pets", get_all_pets),
            web.get("/pets/{pet_id}", get_one_pet),
            web.delete("/pets/{pet_id}", delete_one_pet),
            web.post("/pets", create_pet),
        ]
    )
    app["storage"] = {}
    web.run_app(app)
Beispiel #21
0
async def test_body_with_no_additional_properties(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
                additionalProperties: false
                required:
                  - required
                properties:
                  required:
                    type: integer
                  optional:
                    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, "optional": 15, "str": "str", "int": 10}
    resp = await client.post("/r", json=body)
    assert resp.status == 400
    error = error_to_json(await resp.text())
    assert error == {
        "body": {
            "int": "additional property not allowed",
            "str": "additional property not allowed",
        }
    }
Beispiel #22
0
async def test_float_as_int(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:
                  - int_float
                  - int_double
                properties:
                  int_float:
                    type: number
                    format: float
                  int_double:
                    type: number
                    format: double

        responses:
          '200':
            description: OK.

        """
        return web.json_response(body)

    s.add_route("POST", "/r", handler)

    client = await aiohttp_client(app)

    int_float = 10
    int_double = 20
    body = {"int_float": int_float, "int_double": int_double}
    resp = await client.post(f"/r", json=body)
    assert resp.status == 200
    assert await resp.json() == body
Beispiel #23
0
async def test_object_can_have_optional_props(aiohttp_client, loop):
    app = web.Application(loop=loop)

    routes = web.RouteTableDef()

    @routes.post("/r")
    async def handler(request, body: Dict):
        """
        ---
        requestBody:
          required: true
          content:
            application/json:
              schema:
                type: object
                properties:
                  integer:
                    type: integer
                  string:
                    type: string
                  array:
                    type: array
                    items:
                      type: string
                  object:
                    type: object

        responses:
          '200':
            description: OK.
        """
        return web.json_response(body)

    s = SwaggerDocs(app, "/docs")
    s.add_routes(routes)

    client = await aiohttp_client(app)

    resp = await client.post("/r", json={})
    assert resp.status == 200
    assert await resp.json() == {}
Beispiel #24
0
async def test_incorrect_json_body(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
                  optional:
                    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",
                             data="{{",
                             headers={"content-type": "application/json"})
    assert resp.status == 400
    error = error_to_json(await resp.text())
    assert error == {
        "body":
        "Expecting property name enclosed in double quotes: line 1 column 2 (char 1)"
    }
Beispiel #25
0
async def test_unknown_security(aiohttp_client, loop):
    app = web.Application(loop=loop)
    s = SwaggerDocs(app, "/docs", components="tests/testdata/components.yaml")

    async def handler(request):
        """
        ---
        security:
          - wrongAuth: []

        responses:
          '200':
            description: OK.

        """
        return web.json_response()

    with pytest.raises(Exception) as exc_info:
        s.add_route("GET", "/r", handler)
    assert "security schema wrongAuth must be defined in components" == str(
        exc_info.value)
Beispiel #26
0
def main() -> None:
    settings = config.get_config()
    app = web.Application(
        client_max_size=5 * 1024**2,
        middlewares=[handler.response_time, handler.request_counter],
    )
    swagger = SwaggerDocs(
        app,
        swagger_ui_settings=SwaggerUiSettings(path="/api/docs/"),
        title="{{cookiecutter.project_name}}",
        version=__version__,
    )
    config.init_config(app, settings)
    app.on_startup.append(startup_handler)
    app.on_cleanup.append(shutdown_handler)
    swagger.add_routes(handler.routing_table(app))
    web.run_app(
        app,
        host=settings["app"]["host"],
        port=settings["app"]["port"],  # access_log=None,
    )
Beispiel #27
0
async def test_media_type_with_charset(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
                  optional:
                    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",
        data=json.dumps(body),
        headers={"content-type": "application/json; charset=UTF-8"},
    )
    assert resp.status == 200
    assert await resp.json() == body
Beispiel #28
0
async def test_body_with_optional_properties(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
                  optional:
                    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 == 200
    assert await resp.json() == body

    body = {"required": 10, "optional": 15}
    resp = await client.post("/r", json=body)
    assert resp.status == 200
    assert await resp.json() == body
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
Beispiel #30
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)