sanic-org / sanic-ext

Extended Sanic functionality
https://sanic.dev/en/plugins/sanic-ext/getting-started.html
MIT License
50 stars 35 forks source link

[Bug]Post json string array with pydantic error #198

Open Jenuce opened 1 year ago

Jenuce commented 1 year ago

Environment (please complete the following information):

Describe the bug ex: curl --location --request POST 'http://127.0.0.1:8080/testarray' \ --header 'Content-Type: application/json' \ --data-raw '[ "dog","cat"]' the pydantic example: https://docs.pydantic.dev/latest/usage/models/ Custom Root Types

class Pets(BaseModel):
    __root__: List[str]

class Controller(HTTPMethodView):
     @validate(json=Pets)
    async def post(self, req: request.Request, body: Pets):
        return json({})

Expected behavior sanic_ext.exceptions.ValidationError: Invalid request body: EncryptVO. Error: ModelMetaclass object argument after ** must be a mapping, not list

Additional context how to fix:

  1. extra/validation/validators.py line 33 [old]
    def _validate_instance(model, body, allow_coerce):
      data = clean_data(model, body) if allow_coerce else body
      return model(**data)

    [new]

    def _validate_instance(model, body, allow_coerce):
     data = clean_data(model, body) if allow_coerce else body
     from sanic_ext.utils.typing import is_pydantic
     if is_pydantic(model) and isinstance(body,list):
          return model.parse_obj(body)
     return model(**data)

    2.extensions/openapi/types.py line 301 [old]

              if is_pydantic(value):
                try:
                    value = value.__pydantic_model__
                except AttributeError:
                    ...
                extra = value.schema()["properties"]

    [new]

             if is_pydantic(value):
                try:
                    value = value.__pydantic_model__
                except AttributeError:
                    ...
                value_schema = value.schema()
                if "properties" in value_schema:
                    extra = value_schema["properties"]
                else:
                    extra = value_schema
ahopkins commented 1 year ago

Can you add some code formatting so it is easier to read?

Panaetius commented 3 months ago

I'm seeing the same issue. I took a stab at fixing it, but using model_validate instead of the proposed fix above.