Maillol / aiohttp-pydantic

Aiohttp View that validates request body and query sting regarding the annotations declared in the View method
MIT License
65 stars 21 forks source link

GET requests documentation issues #46

Open Addovej opened 1 year ago

Addovej commented 1 year ago

Hello!

There are two issues with generating open api specification for get requests:

1) While parsing group signature, in the _get_group_signature function you decide that param is optional by default value. But it's a lit incorrect because if I write in this way:

class QueryParams(Group):
    some_param: Optional[int] = None

it will be still required in the swagger: in _add_http_method_to_oas:

 if name in defaults:
     attrs["__root__"] = defaults[name]
     oas_operation.parameters[i].required = False
 else:
     oas_operation.parameters[i].required = True

So if name is not in defaults, then parameter will be required.

in _get_group_signature:

for attr_name, type_ in base.__annotations__.items():
    if (default := attrs.get(attr_name)) is None:
        defaults.pop(attr_name, None)
    else:
        defaults[attr_name] = default

If default value is None then it value will be removed from defaults even if param type marked as Optional.

I suggest following solution: in _get_group_signature:

for attr_name, type_ in base.__annotations__.items():
    _is_optional = getattr(type_, '_name', '') == 'Optional'
    if (default := attrs.get(attr_name)) is None and not _is_optional:
        defaults.pop(attr_name, None)
     else:
         defaults[attr_name] = default

Here I make a new variable _is_optional and decide that field is not required if it's marked as Optional.

2) The second issue: when you specify query param as any enum type, then enum model schema doesn't being added to open api schema as for body or response schema.

To fix it, you need to modify _add_http_method_to_oas function:

query_param_schema = type(name, (BaseModel,), attrs).schema(
    ref_template="#/components/schemas/{model}"
)
if def_sub_schemas := query_param_schema.pop("definitions", None):
    oas.components.schemas.update(def_sub_schemas)
oas_operation.parameters[i].schema = query_param_schema

Above I extracted sub_schema from param schema and set it to common components schema.

Could you please fix it? If not, can I fix it myself and make a PR?

Maillol commented 1 year ago

Hi,

About the first point,

We should consider this case:

class QueryParams(Group):
    some_param: int | None = None

You can make a PR, I will merge it this month.

Maillol commented 2 months ago

First part is fixed by https://github.com/Maillol/aiohttp-pydantic/issues/56.

Your contribution to fix the 2nd issue is welcome.