Compare commits

..

No commits in common. "v1.120.8" and "main" have entirely different histories.

19 changed files with 198 additions and 311 deletions

View File

@ -1,12 +0,0 @@
stages:
- package
publish-pypi:
stage: package
image: python:3.10
script:
- sed -i -e "s/1.12.1/${CI_COMMIT_TAG:1}/g" aiohttp_pydantic/__init__.py
- pip install -U setuptools wheel pip; pip install invoke
- invoke upload --pypi-user ${PYPI_REPO_USER} --pypi-password ${PYPI_REPO_PASSWORD} --pypi-url ${PYPI_REPO_URL}
only:
- tags

View File

@ -68,10 +68,7 @@ class BodyGetter(AbstractInjector):
def __init__(self, args_spec: dict, default_values: dict):
self.arg_name, self.model = next(iter(args_spec.items()))
schema = self.model.schema()
if "type" not in schema:
schema["type"] = "object"
self._expect_object = schema["type"] == "object"
self._expect_object = self.model.schema()["type"] == "object"
async def inject(self, request: BaseRequest, args_view: list, kwargs_view: dict):
try:

View File

@ -15,12 +15,11 @@ def setup(
enable: bool = True,
version_spec: Optional[str] = None,
title_spec: Optional[str] = None,
custom_template: Optional[jinja2.Template] = None
):
if enable:
oas_app = web.Application()
oas_app["apps to expose"] = tuple(apps_to_expose) or (app,)
oas_app["index template"] = custom_template or jinja2.Template(
oas_app["index template"] = jinja2.Template(
resources.read_text("aiohttp_pydantic.oas", "index.j2")
)
oas_app["version_spec"] = version_spec

View File

@ -120,19 +120,6 @@ def tags(docstring: str) -> List[str]:
return []
def operation_id(docstring: str) -> str | None:
"""
Extract the "OperationId:" block of the docstring.
"""
iterator = LinesIterator(docstring)
for line in iterator:
if re.fullmatch("operation_?id\\s*:.*", line, re.IGNORECASE):
iterator.rewind()
return line.split(":")[1].strip(' ')
return None
def operation(docstring: str) -> str:
"""
Extract all docstring except the "Status Code:" block.
@ -140,7 +127,7 @@ def operation(docstring: str) -> str:
lines = LinesIterator(docstring)
ret = []
for line in lines:
if re.fullmatch("status\\s+codes?\\s*:|tags\\s*:.*|operation_?id\\s*:.*", line, re.IGNORECASE):
if re.fullmatch("status\\s+codes?\\s*:|tags\\s*:.*", line, re.IGNORECASE):
lines.rewind()
for _ in _i_extract_block(lines):
pass

View File

@ -1,27 +1,45 @@
{# This updated file is part of swagger_ui_bundle (https://github.com/bartsanchez/swagger_ui_bundle) #}
{# This updated file is part of swagger_ui_bundle (https://github.com/dtkav/swagger_ui_bundle) #}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{ title | default('Swagger UI') }}</title>
<link rel="stylesheet" type="text/css" href="{{ static_url | trim('/') }}/swagger-ui.css" />
<link rel="stylesheet" type="text/css" href="{{ static_url | trim('/') }}/index.css" />
<link rel="stylesheet" type="text/css" href="{{ static_url | trim('/') }}/swagger-ui.css" >
<link rel="icon" type="image/png" href="{{ static_url | trim('/') }}/favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="{{ static_url | trim('/') }}/favicon-16x16.png" sizes="16x16" />
<style>
html
{
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after
{
box-sizing: inherit;
}
body
{
margin:0;
background: #fafafa;
}
</style>
</head>
<body>
<div id="swagger-ui"></div>
<script src="{{ static_url | trim('/') }}/swagger-ui-bundle.js" charset="UTF-8"> </script>
<script src="{{ static_url | trim('/') }}/swagger-ui-standalone-preset.js" charset="UTF-8"> </script>
<script src="{{ static_url | trim('/') }}/swagger-ui-bundle.js"> </script>
<script src="{{ static_url | trim('/') }}/swagger-ui-standalone-preset.js"> </script>
<script>
window.onload = function() {
// Begin Swagger UI call region
const ui = SwaggerUIBundle({
url: "{{ openapi_spec_url }}",
{% if urls is defined %}
urls: {{ urls|tojson|safe }},
{% endif %}
validatorUrl: {{ validatorUrl | default('null') }},
{% if configUrl is defined %}
configUrl: "{{ configUrl }}",
@ -36,15 +54,16 @@
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
});
})
{% if initOAuth is defined %}
ui.initOAuth(
{{ initOAuth|tojson|safe }}
)
{% endif %}
// End Swagger UI call region
window.ui = ui;
};
window.ui = ui
}
</script>
</body>
</html>

View File

@ -207,17 +207,6 @@ class OperationObject:
else:
self._spec.pop("tags", None)
@property
def operation_id(self) -> str | None:
return self._spec.get("operationId", None)
@operation_id.setter
def operation_id(self, operation_id: str | None) -> None:
if operation_id:
self._spec["operationId"] = operation_id
else:
self._spec.pop("operationId", None)
class PathItem:
def __init__(self, spec: dict):

View File

@ -34,8 +34,7 @@ class _OASResponseBuilder:
).copy()
if def_sub_schemas := response_schema.pop("definitions", None):
self._oas.components.schemas.update(def_sub_schemas)
self._oas.components.schemas.update({response_schema['title']: response_schema})
return {'$ref': f'#/components/schemas/{response_schema["title"]}'}
return response_schema
return {}
def _handle_list(self, obj):
@ -88,7 +87,6 @@ def _add_http_method_to_oas(
if description:
oas_operation.description = docstring_parser.operation(description)
oas_operation.tags = docstring_parser.tags(description)
oas_operation.operation_id = docstring_parser.operation_id(description)
status_code_descriptions = docstring_parser.status_code(description)
else:
status_code_descriptions = {}
@ -128,10 +126,6 @@ def _add_http_method_to_oas(
ref_template="#/components/schemas/{model}"
)
# move definitions
if def_sub_schemas := oas_operation.parameters[i].schema.pop("definitions", None):
oas.components.schemas.update(def_sub_schemas)
return_type = get_type_hints(handler).get("return")
if return_type is not None:
_OASResponseBuilder(oas, oas_operation, status_code_descriptions).build(
@ -191,8 +185,6 @@ async def oas_ui(request):
static_url = request.app.router["static"].url_for(filename="")
spec_url = request.app.router["spec"].url_for()
if request.scheme != request.headers.get('x-forwarded-proto', request.scheme):
request = request.clone(scheme=request.headers['x-forwarded-proto'])
host = request.url.origin()
return Response(

View File

@ -4,6 +4,3 @@ requires = [
"wheel",
]
build-backend = "setuptools.build_meta"
[tool.pytest.ini_options]
asyncio_mode = "auto"

View File

@ -1,42 +1,42 @@
aiohttp==3.8.1
aiosignal==1.2.0
async-timeout==4.0.2
atomicwrites==1.4.1
attrs==21.4.0
bleach==5.0.1
certifi==2022.6.15
charset-normalizer==2.1.0
codecov==2.1.12
colorama==0.4.5
commonmark==0.9.1
coverage==6.4.2
docutils==0.19
frozenlist==1.3.0
idna==3.3
importlib-metadata==4.12.0
async-timeout==3.0.1
attrs==21.2.0
bleach==4.0.0
certifi==2021.5.30
cffi==1.14.6
chardet==4.0.0
charset-normalizer==2.0.4
codecov==2.1.11
colorama==0.4.4
coverage==5.5
cryptography==3.4.7
docutils==0.17.1
idna==3.2
importlib-metadata==4.6.3
iniconfig==1.1.1
keyring==23.7.0
multidict==6.0.2
packaging==21.3
pkginfo==1.8.3
pluggy==1.0.0
py==1.11.0
Pygments==2.12.0
pyparsing==3.0.9
pytest==7.1.2
pytest-aiohttp==1.0.4
pytest-asyncio==0.19.0
pytest-cov==3.0.0
pywin32-ctypes==0.2.0
readme-renderer==35.0
requests==2.28.1
jeepney==0.7.1
keyring==23.0.1
multidict==5.1.0
packaging==21.0
pkginfo==1.7.1
pluggy==0.13.1
py==1.10.0
pycparser==2.20
Pygments==2.9.0
pyparsing==2.4.7
pytest==6.1.2
pytest-aiohttp==0.3.0
pytest-cov==2.10.1
readme-renderer==29.0
requests==2.26.0
requests-toolbelt==0.9.1
rfc3986==2.0.0
rich==12.5.1
rfc3986==1.5.0
SecretStorage==3.3.1
six==1.16.0
tomli==2.0.1
twine==4.0.1
urllib3==1.26.11
toml==0.10.2
tqdm==4.62.0
twine==3.4.2
typing-extensions==3.10.0.0
urllib3==1.26.6
webencodings==0.5.1
yarl==1.7.2
zipp==3.8.1
yarl==1.6.3
zipp==3.5.0

View File

@ -1,28 +1,23 @@
aiohttp==3.8.1
aiosignal==1.2.0
async-timeout==4.0.2
atomicwrites==1.4.1
attrs==21.4.0
bleach==5.0.1
charset-normalizer==2.1.0
colorama==0.4.5
coverage==6.4.2
docutils==0.19
frozenlist==1.3.0
idna==3.3
async-timeout==3.0.1
attrs==21.2.0
bleach==4.0.0
chardet==4.0.0
coverage==5.5
docutils==0.17.1
idna==3.2
iniconfig==1.1.1
multidict==6.0.2
packaging==21.3
pluggy==1.0.0
py==1.11.0
Pygments==2.12.0
pyparsing==3.0.9
pytest==7.1.2
pytest-aiohttp==1.0.4
pytest-asyncio==0.19.0
pytest-cov==3.0.0
readme-renderer==35.0
multidict==5.1.0
packaging==21.0
pluggy==0.13.1
py==1.10.0
Pygments==2.9.0
pyparsing==2.4.7
pytest==6.1.2
pytest-aiohttp==0.3.0
pytest-cov==2.10.1
readme-renderer==29.0
six==1.16.0
tomli==2.0.1
toml==0.10.2
typing-extensions==3.10.0.0
webencodings==0.5.1
yarl==1.7.2
yarl==1.6.3

View File

@ -32,18 +32,18 @@ python_requires = >=3.8
install_requires =
aiohttp
pydantic>=1.7
swagger-4-ui-bundle
swagger-ui-bundle
[options.extras_require]
test =
pytest==7.1.2
pytest-aiohttp==1.0.4
pytest-cov==3.0.0
readme-renderer==35.0
pytest==6.1.2
pytest-aiohttp==0.3.0
pytest-cov==2.10.1
readme-renderer==29.0
ci =
%(test)s
codecov==2.1.12
twine==4.0.1
codecov==2.1.11
twine==3.4.2
[options.packages.find]
exclude =

View File

@ -102,9 +102,8 @@ def test(c, isolate=False):
"""
Launch tests
"""
#opt = "I" if isolate else ""
#c.run(f"python -{opt}m pytest --cov-report=xml --cov=aiohttp_pydantic tests/")
pass
opt = "I" if isolate else ""
c.run(f"python -{opt}m pytest --cov-report=xml --cov=aiohttp_pydantic tests/")
@task()
@ -137,7 +136,6 @@ def prepare_ci_env(c):
title("Installing wheel", "=")
package_version = read_configuration("./setup.cfg")["metadata"]["version"]
print([x for x in Path("dist").glob('*')])
dist = next(Path("dist").glob(f"aiohttp_pydantic-{package_version}-*.whl"))
c.run(f"dist_venv/bin/python -m pip install {dist}")
@ -158,7 +156,7 @@ def prepare_upload(c):
@task(tag_eq_version, prepare_upload)
def upload(c, pypi_user=None, pypi_password=None, pypi_url=None):
def upload(c, pypi_user=None, pypi_password=None):
"""
Upload on pypi
"""
@ -167,9 +165,8 @@ def upload(c, pypi_user=None, pypi_password=None, pypi_url=None):
if pypi_user is not None and pypi_password is not None:
c.run(
f"dist_venv/bin/twine upload --non-interactive"
f" -u {pypi_user} -p {pypi_password} {dist}"
f" --repository-url {pypi_url}",
f" -u {pypi_user} -p {pypi_password} {dist}",
hide=True,
)
else:
c.run(f"dist_venv/bin/twine upload --repository-url {pypi_url} --repository aiohttp-pydantic {dist}")
c.run(f"dist_venv/bin/twine upload --repository aiohttp-pydantic {dist}")

View File

@ -37,14 +37,13 @@ class ArticleView(PydanticView):
async def test_post_an_article_with_wrong_type_field_should_return_an_error_message(
aiohttp_client, event_loop
aiohttp_client, loop
):
app = web.Application()
app.router.add_view("/article", ArticleView)
client = await aiohttp_client(app)
resp = await client.post("/article", json={"name": "foo", "nb_page": "foo"})
assert resp.status == 400
assert resp.content_type == "application/json"
assert await resp.json() == [

View File

@ -1,17 +1,16 @@
from __future__ import annotations
from enum import Enum
from typing import List, Optional, Union, Literal, Annotated
from typing import List, Optional, Union, Literal
from uuid import UUID
import pytest
from aiohttp import web
from pydantic import Field
from pydantic.main import BaseModel
from aiohttp_pydantic import PydanticView, oas
from aiohttp_pydantic.injectors import Group
from aiohttp_pydantic.oas.typing import r200, r201, r204, r404, r400
from aiohttp_pydantic.oas.typing import r200, r201, r204, r404
from aiohttp_pydantic.oas.view import generate_oas
@ -21,11 +20,6 @@ class Color(str, Enum):
PINK = "pink"
class Lang(str, Enum):
EN = 'en'
FR = 'fr'
class Toy(BaseModel):
name: str
color: Color
@ -33,32 +27,13 @@ class Toy(BaseModel):
class Pet(BaseModel):
id: int
name: Optional[str] = Field(None)
name: str
toys: List[Toy]
class Error(BaseModel):
code: int
text: str
class Cat(BaseModel):
pet_type: Literal['cat']
meows: int
class Dog(BaseModel):
pet_type: Literal['dog']
barks: float
class Animal(BaseModel):
__root__: Annotated[Union[Cat, Dog], Field(discriminator='pet_type')]
class PetCollectionView(PydanticView):
async def get(
self, format: str, lang: Lang = Lang.EN, name: Optional[str] = None, *, promo: Optional[UUID] = None
self, format: str, name: Optional[str] = None, *, promo: Optional[UUID] = None
) -> r200[List[Pet]]:
"""
Get a list of pets
@ -66,7 +41,6 @@ class PetCollectionView(PydanticView):
Tags: pet
Status Codes:
200: Successful operation
OperationId: createPet
"""
return web.json_response()
@ -82,7 +56,7 @@ class PetItemView(PydanticView):
/,
size: Union[int, Literal["x", "l", "s"]],
day: Union[int, Literal["now"]] = "now",
) -> Union[r200[Pet], r404[Error], r400[Error]]:
) -> Union[r200[Pet], r404]:
return web.json_response()
async def put(self, id: int, /, pet: Pet):
@ -105,11 +79,6 @@ class ViewResponseReturnASimpleType(PydanticView):
return web.json_response()
class DiscriminatedView(PydanticView):
async def post(self, /, request: Animal) -> r200[int]:
return web.json_response()
async def ensure_content_durability(client):
"""
Reload the page 2 times to ensure that content is always the same
@ -129,12 +98,11 @@ async def ensure_content_durability(client):
@pytest.fixture
async def generated_oas(aiohttp_client, event_loop) -> web.Application:
async def generated_oas(aiohttp_client, loop) -> web.Application:
app = web.Application()
app.router.add_view("/pets", PetCollectionView)
app.router.add_view("/pets/{id}", PetItemView)
app.router.add_view("/simple-type", ViewResponseReturnASimpleType)
app.router.add_view("/animals", DiscriminatedView)
oas.setup(app)
return await ensure_content_durability(await aiohttp_client(app))
@ -142,40 +110,12 @@ async def generated_oas(aiohttp_client, event_loop) -> web.Application:
async def test_generated_oas_should_have_components_schemas(generated_oas):
assert generated_oas["components"]["schemas"] == {
'Cat': {'properties': {'meows': {'title': 'Meows', 'type': 'integer'},
'pet_type': {'enum': ['cat'],
'title': 'Pet Type',
'type': 'string'}},
'required': ['pet_type', 'meows'],
'title': 'Cat',
'type': 'object'},
"Color": {
"description": "An enumeration.",
"enum": ["red", "green", "pink"],
"title": "Color",
"type": "string",
},
'Dog': {'properties': {'barks': {'title': 'Barks', 'type': 'number'},
'pet_type': {'enum': ['dog'],
'title': 'Pet Type',
'type': 'string'}},
'required': ['pet_type', 'barks'],
'title': 'Dog',
'type': 'object'},
'Error': {
'properties': {
'code': {'title': 'Code', 'type': 'integer'},
'text': {'title': 'Text', 'type': 'string'}},
'required': ['code', 'text'],
'title': 'Error',
'type': 'object'
},
'Lang': {
'description': 'An enumeration.',
'enum': ['en', 'fr'],
'title': 'Lang',
'type': 'string'
},
"Toy": {
"properties": {
"color": {"$ref": "#/components/schemas/Color"},
@ -185,20 +125,6 @@ async def test_generated_oas_should_have_components_schemas(generated_oas):
"title": "Toy",
"type": "object",
},
'Pet': {
'properties': {
'id': {'title': 'Id', 'type': 'integer'},
'name': {'title': 'Name', 'type': 'string'},
'toys': {
'items': {'$ref': '#/components/schemas/Toy'},
'title': 'Toys',
'type': 'array'
}
},
'required': ['id', 'toys'],
'title': 'Pet',
'type': 'object'
}
}
@ -209,7 +135,6 @@ async def test_generated_oas_should_have_pets_paths(generated_oas):
async def test_pets_route_should_have_get_method(generated_oas):
assert generated_oas["paths"]["/pets"]["get"] == {
"description": "Get a list of pets",
"operationId": "createPet",
"tags": ["pet"],
"parameters": [
{
@ -218,16 +143,6 @@ async def test_pets_route_should_have_get_method(generated_oas):
"required": True,
"schema": {"title": "format", "type": "string"},
},
{
'in': 'query',
'name': 'lang',
'required': False,
'schema': {
'allOf': [{'$ref': '#/components/schemas/Lang'}],
'default': 'en',
'title': 'lang'
}
},
{
"in": "query",
"name": "name",
@ -247,7 +162,20 @@ async def test_pets_route_should_have_get_method(generated_oas):
"content": {
"application/json": {
"schema": {
"items": {'$ref': '#/components/schemas/Pet'},
"items": {
"properties": {
"id": {"title": "Id", "type": "integer"},
"name": {"title": "Name", "type": "string"},
"toys": {
"items": {"$ref": "#/components/schemas/Toy"},
"title": "Toys",
"type": "array",
},
},
"required": ["id", "name", "toys"],
"title": "Pet",
"type": "object",
},
"type": "array",
}
}
@ -273,7 +201,7 @@ async def test_pets_route_should_have_post_method(generated_oas):
"type": "array",
},
},
"required": ["id", "toys"],
"required": ["id", "name", "toys"],
"title": "Pet",
"type": "object",
}
@ -285,7 +213,20 @@ async def test_pets_route_should_have_post_method(generated_oas):
"description": "",
"content": {
"application/json": {
"schema": {'$ref': '#/components/schemas/Pet'}
"schema": {
"properties": {
"id": {"title": "Id", "type": "integer"},
"name": {"title": "Name", "type": "string"},
"toys": {
"items": {"$ref": "#/components/schemas/Toy"},
"title": "Toys",
"type": "array",
},
},
"required": ["id", "name", "toys"],
"title": "Pet",
"type": "object",
}
}
},
}
@ -344,15 +285,31 @@ async def test_pets_id_route_should_have_get_method(generated_oas):
},
},
],
'responses': {
'200': {'content': {'application/json': {'schema': {'$ref': '#/components/schemas/Pet'}}},
'description': ''},
'400': {'content': {'application/json': {'schema': {'$ref': '#/components/schemas/Error'}}},
'description': ''},
'404': {'content': {'application/json': {'schema': {'$ref': '#/components/schemas/Error'}}},
'description': ''}
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"properties": {
"id": {"title": "Id", "type": "integer"},
"name": {"title": "Name", "type": "string"},
"toys": {
"items": {"$ref": "#/components/schemas/Toy"},
"title": "Toys",
"type": "array",
},
},
"required": ["id", "name", "toys"],
"title": "Pet",
"type": "object",
}
}
},
},
"404": {"description": "", "content": {}},
},
}
async def test_pets_id_route_should_have_put_method(generated_oas):
@ -378,7 +335,7 @@ async def test_pets_id_route_should_have_put_method(generated_oas):
"type": "array",
},
},
"required": ["id", "toys"],
"required": ["id", "name", "toys"],
"title": "Pet",
"type": "object",
}

View File

@ -29,7 +29,7 @@ class ArticleView(PydanticView):
async def test_post_an_article_without_required_field_should_return_an_error_message(
aiohttp_client, event_loop
aiohttp_client, loop
):
app = web.Application()
app.router.add_view("/article", ArticleView)
@ -49,7 +49,7 @@ async def test_post_an_article_without_required_field_should_return_an_error_mes
async def test_post_an_article_with_wrong_type_field_should_return_an_error_message(
aiohttp_client, event_loop
aiohttp_client, loop
):
app = web.Application()
app.router.add_view("/article", ArticleView)
@ -68,7 +68,7 @@ async def test_post_an_article_with_wrong_type_field_should_return_an_error_mess
]
async def test_post_an_array_json_is_supported(aiohttp_client, event_loop):
async def test_post_an_array_json_is_supported(aiohttp_client, loop):
app = web.Application()
app.router.add_view("/article", ArticleView)
@ -81,7 +81,7 @@ async def test_post_an_array_json_is_supported(aiohttp_client, event_loop):
async def test_post_an_array_json_to_an_object_model_should_return_an_error(
aiohttp_client, event_loop
aiohttp_client, loop
):
app = web.Application()
app.router.add_view("/article", ArticleView)
@ -101,7 +101,7 @@ async def test_post_an_array_json_to_an_object_model_should_return_an_error(
async def test_post_an_object_json_to_a_list_model_should_return_an_error(
aiohttp_client, event_loop
aiohttp_client, loop
):
app = web.Application()
app.router.add_view("/article", ArticleView)
@ -120,7 +120,7 @@ async def test_post_an_object_json_to_a_list_model_should_return_an_error(
]
async def test_post_a_valid_article_should_return_the_parsed_type(aiohttp_client, event_loop):
async def test_post_a_valid_article_should_return_the_parsed_type(aiohttp_client, loop):
app = web.Application()
app.router.add_view("/article", ArticleView)

View File

@ -61,7 +61,7 @@ class ArticleViewWithSignatureGroup(PydanticView):
async def test_get_article_without_required_header_should_return_an_error_message(
aiohttp_client, event_loop
aiohttp_client, loop
):
app = web.Application()
app.router.add_view("/article", ArticleView)
@ -81,7 +81,7 @@ async def test_get_article_without_required_header_should_return_an_error_messag
async def test_get_article_with_wrong_header_type_should_return_an_error_message(
aiohttp_client, event_loop
aiohttp_client, loop
):
app = web.Application()
app.router.add_view("/article", ArticleView)
@ -101,7 +101,7 @@ async def test_get_article_with_wrong_header_type_should_return_an_error_message
async def test_get_article_with_valid_header_should_return_the_parsed_type(
aiohttp_client, event_loop
aiohttp_client, loop
):
app = web.Application()
app.router.add_view("/article", ArticleView)
@ -116,7 +116,7 @@ async def test_get_article_with_valid_header_should_return_the_parsed_type(
async def test_get_article_with_valid_header_containing_hyphen_should_be_returned(
aiohttp_client, event_loop
aiohttp_client, loop
):
app = web.Application()
app.router.add_view("/article", ArticleView)
@ -130,7 +130,7 @@ async def test_get_article_with_valid_header_containing_hyphen_should_be_returne
assert await resp.json() == {"signature": "2020-10-04T18:01:00"}
async def test_wrong_value_to_header_defined_with_str_enum(aiohttp_client, event_loop):
async def test_wrong_value_to_header_defined_with_str_enum(aiohttp_client, loop):
app = web.Application()
app.router.add_view("/coord", ViewWithEnumType)
@ -153,7 +153,7 @@ async def test_wrong_value_to_header_defined_with_str_enum(aiohttp_client, event
assert resp.content_type == "application/json"
async def test_correct_value_to_header_defined_with_str_enum(aiohttp_client, event_loop):
async def test_correct_value_to_header_defined_with_str_enum(aiohttp_client, loop):
app = web.Application()
app.router.add_view("/coord", ViewWithEnumType)
@ -164,7 +164,7 @@ async def test_correct_value_to_header_defined_with_str_enum(aiohttp_client, eve
assert resp.content_type == "application/json"
async def test_with_signature_group(aiohttp_client, event_loop):
async def test_with_signature_group(aiohttp_client, loop):
app = web.Application()
app.router.add_view("/article", ArticleViewWithSignatureGroup)

View File

@ -11,7 +11,7 @@ class ArticleView(PydanticView):
async def test_get_article_with_correct_path_parameters_should_return_parameters_in_path(
aiohttp_client, event_loop
aiohttp_client, loop
):
app = web.Application()
app.router.add_view("/article/{author_id}/tag/{tag}/before/{date}", ArticleView)
@ -24,7 +24,7 @@ async def test_get_article_with_correct_path_parameters_should_return_parameters
async def test_get_article_with_wrong_path_parameters_should_return_error(
aiohttp_client, event_loop
aiohttp_client, loop
):
app = web.Application()
app.router.add_view("/article/{author_id}/tag/{tag}/before/{date}", ArticleView)

View File

@ -1,6 +1,5 @@
from __future__ import annotations
from enum import Enum
from typing import Optional, List
from pydantic import Field
from aiohttp import web
@ -55,22 +54,8 @@ class ArticleViewWithPaginationGroup(PydanticView):
)
class Lang(str, Enum):
EN = 'en'
FR = 'fr'
class ArticleViewWithEnumInQuery(PydanticView):
async def get(self, lang: Lang):
return web.json_response(
{
"lang": lang
}
)
async def test_get_article_without_required_qs_should_return_an_error_message(
aiohttp_client, event_loop
aiohttp_client, loop
):
app = web.Application()
app.router.add_view("/article", ArticleView)
@ -90,7 +75,7 @@ async def test_get_article_without_required_qs_should_return_an_error_message(
async def test_get_article_with_wrong_qs_type_should_return_an_error_message(
aiohttp_client, event_loop
aiohttp_client, loop
):
app = web.Application()
app.router.add_view("/article", ArticleView)
@ -110,7 +95,7 @@ async def test_get_article_with_wrong_qs_type_should_return_an_error_message(
async def test_get_article_with_valid_qs_should_return_the_parsed_type(
aiohttp_client, event_loop
aiohttp_client, loop
):
app = web.Application()
app.router.add_view("/article", ArticleView)
@ -129,7 +114,7 @@ async def test_get_article_with_valid_qs_should_return_the_parsed_type(
async def test_get_article_with_valid_qs_and_omitted_optional_should_return_default_value(
aiohttp_client, event_loop
aiohttp_client, loop
):
app = web.Application()
app.router.add_view("/article", ArticleView)
@ -148,7 +133,7 @@ async def test_get_article_with_valid_qs_and_omitted_optional_should_return_defa
async def test_get_article_with_multiple_value_for_qs_age_must_failed(
aiohttp_client, event_loop
aiohttp_client, loop
):
app = web.Application()
app.router.add_view("/article", ArticleView)
@ -168,7 +153,7 @@ async def test_get_article_with_multiple_value_for_qs_age_must_failed(
assert resp.content_type == "application/json"
async def test_get_article_with_multiple_value_of_tags(aiohttp_client, event_loop):
async def test_get_article_with_multiple_value_of_tags(aiohttp_client, loop):
app = web.Application()
app.router.add_view("/article", ArticleView)
@ -187,7 +172,7 @@ async def test_get_article_with_multiple_value_of_tags(aiohttp_client, event_loo
assert resp.content_type == "application/json"
async def test_get_article_with_one_value_of_tags_must_be_a_list(aiohttp_client, event_loop):
async def test_get_article_with_one_value_of_tags_must_be_a_list(aiohttp_client, loop):
app = web.Application()
app.router.add_view("/article", ArticleView)
@ -206,7 +191,7 @@ async def test_get_article_with_one_value_of_tags_must_be_a_list(aiohttp_client,
assert resp.content_type == "application/json"
async def test_get_article_without_required_field_page(aiohttp_client, event_loop):
async def test_get_article_without_required_field_page(aiohttp_client, loop):
app = web.Application()
app.router.add_view("/article", ArticleViewWithPaginationGroup)
@ -225,7 +210,7 @@ async def test_get_article_without_required_field_page(aiohttp_client, event_loo
assert resp.content_type == "application/json"
async def test_get_article_with_page(aiohttp_client, event_loop):
async def test_get_article_with_page(aiohttp_client, loop):
app = web.Application()
app.router.add_view("/article", ArticleViewWithPaginationGroup)
@ -237,7 +222,7 @@ async def test_get_article_with_page(aiohttp_client, event_loop):
assert resp.content_type == "application/json"
async def test_get_article_with_page_and_page_size(aiohttp_client, event_loop):
async def test_get_article_with_page_and_page_size(aiohttp_client, loop):
app = web.Application()
app.router.add_view("/article", ArticleViewWithPaginationGroup)
@ -251,21 +236,7 @@ async def test_get_article_with_page_and_page_size(aiohttp_client, event_loop):
assert resp.content_type == "application/json"
async def test_get_article_with_enum_in_query(aiohttp_client, event_loop):
app = web.Application()
app.router.add_view("/article", ArticleViewWithEnumInQuery)
client = await aiohttp_client(app)
resp = await client.get(
"/article", params={"lang": Lang.EN.value}
)
assert await resp.json() == {'lang': Lang.EN}
assert resp.status == 200
assert resp.content_type == "application/json"
async def test_get_article_with_page_and_wrong_page_size(aiohttp_client, event_loop):
async def test_get_article_with_page_and_wrong_page_size(aiohttp_client, loop):
app = web.Application()
app.router.add_view("/article", ArticleViewWithPaginationGroup)