Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: Cannot provide examples of values other than str in the Schema examples for SwaggerUI #5573

Closed
tonsho opened this issue Nov 16, 2024 · 4 comments · Fixed by #5575
Closed
Assignees
Labels

Comments

@tonsho
Copy link
Contributor

tonsho commented Nov 16, 2024

Expected Behavior

examples field can reflect examples with float, int, and bool values in SwaggerUI.

class Todo(BaseModel):
    userId: int = Field(examples=[1])
    id_: int = Field(alias="id")
    title: str = Field(examples=["title 1"])
    completed: bool = Field(examples=[True])

"Todo": {
  "properties": {
    "userId": {
      "type": "integer",
      "title": "Userid",
      "examples": [
        1
      ]
    },
    "id": {
      "type": "integer",
      "title": "Id"
    },
    "title": {
      "type": "string",
      "title": "Title",
      "examples": [
        "title 1"
      ]
    },
    "completed": {
      "type": "boolean",
      "title": "Completed",
      "examples": [
        true
      ]
    }
  },
  "type": "object",
  "required": [
    "userId",
    "id",
    "title",
    "completed"
  ],
  "title": "Todo"
},

Current Behaviour

ValidationError occurs in api_gateway.py.

Code snippet

from typing import List

import requests
from aws_lambda_powertools.event_handler import APIGatewayRestResolver
from aws_lambda_powertools.utilities.typing import LambdaContext
from pydantic import BaseModel, Field

app = APIGatewayRestResolver(enable_validation=True)
app.enable_swagger(path="/swagger")  # (1)!


class Todo(BaseModel):
    userId: int = Field(examples=[1])
    id_: int = Field(alias="id")
    title: str = Field(examples=["title 1"])
    completed: bool = Field(examples=[True])


@app.post("/todos")
def create_todo(todo: Todo) -> str:
    response = requests.post("https://jsonplaceholder.typicode.com/todos", json=todo.dict(by_alias=True))
    response.raise_for_status()

    return response.json()["id"]


@app.get("/todos")
def get_todos() -> List[Todo]:
    todo = requests.get("https://jsonplaceholder.typicode.com/todos")
    todo.raise_for_status()

    return todo.json()


def lambda_handler(event: dict, context: LambdaContext) -> dict:
    return app.resolve(event, context)


if __name__ == "__main__":
    print(app.get_openapi_json_schema())

Possible Solution

Allow float, int, and bool values in the examples field.
https://github.com/aws-powertools/powertools-lambda-python/blob/v3.3.0/aws_lambda_powertools/event_handler/openapi/models.py#L204

    examples: Optional[Union[List["Example"], List[str], List[float], List[int], List[bool]]] = None

Steps to Reproduce

Run python.

Powertools for AWS Lambda (Python) version

latest

AWS Lambda function runtime

3.12

Packaging format used

PyPi

Debugging logs

$ python enabling_swagger.py
Traceback (most recent call last):
  File "/home/ec2-user/environment/PowertoolsSample/src/enabling_swagger.py", line 40, in <module>
    print(app.get_openapi_json_schema())
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ec2-user/environment/PowertoolsSample/.venv/lib/python3.12/site-packages/aws_lambda_powertools/event_handler/api_gateway.py", line 1763, in get_openapi_json_schema
    self.get_openapi_schema(
  File "/home/ec2-user/environment/PowertoolsSample/.venv/lib/python3.12/site-packages/aws_lambda_powertools/event_handler/api_gateway.py", line 1668, in get_openapi_schema
    return OpenAPI(**output)
           ^^^^^^^^^^^^^^^^^
  File "/home/ec2-user/environment/PowertoolsSample/.venv/lib/python3.12/site-packages/pydantic/main.py", line 212, in __init__
    validated_self = self.__pydantic_validator__.validate_python(data, self_instance=self)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pydantic_core._pydantic_core.ValidationError: 7 validation errors for OpenAPI
components.schemas.Todo.Schema.properties.userId.Schema.examples.list[Example].0
  Input should be a valid dictionary or instance of Example [type=model_type, input_value=1, input_type=int]
    For further information visit https://errors.pydantic.dev/2.9/v/model_type
components.schemas.Todo.Schema.properties.userId.Schema.examples.list[str].0
  Input should be a valid string [type=string_type, input_value=1, input_type=int]
    For further information visit https://errors.pydantic.dev/2.9/v/string_type
components.schemas.Todo.Schema.properties.userId.bool
  Input should be a valid boolean [type=bool_type, input_value={'examples': [1], 'title'...rid', 'type': 'integer'}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.9/v/bool_type
components.schemas.Todo.Schema.properties.completed.Schema.examples.list[Example].0
  Input should be a valid dictionary or instance of Example [type=model_type, input_value=True, input_type=bool]
    For further information visit https://errors.pydantic.dev/2.9/v/model_type
components.schemas.Todo.Schema.properties.completed.Schema.examples.list[str].0
  Input should be a valid string [type=string_type, input_value=True, input_type=bool]
    For further information visit https://errors.pydantic.dev/2.9/v/string_type
components.schemas.Todo.Schema.properties.completed.bool
  Input should be a valid boolean [type=bool_type, input_value={'examples': [True], 'tit...ted', 'type': 'boolean'}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.9/v/bool_type
components.schemas.Todo.Reference.$ref
  Field required [type=missing, input_value={'properties': {'userId':...Todo', 'type': 'object'}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.9/v/missing
@tonsho tonsho added bug Something isn't working triage Pending triage from maintainers labels Nov 16, 2024
Copy link

boring-cyborg bot commented Nov 16, 2024

Thanks for opening your first issue here! We'll come back to you as soon as we can.
In the meantime, check out the #python channel on our Powertools for AWS Lambda Discord: Invite link

@leandrodamascena
Copy link
Contributor

Hi @tonsho! Thanks for opening this issue, to be honest, this should be Any to accept any type of field. It can be basically anything that Pydantic can serialize: int, float, str, bool, dataclass, pydantic model or any other primitive.

Do you want to submit a PR to fix this? If so, please just add a test to validate this.

Thanks

@tonsho
Copy link
Contributor Author

tonsho commented Nov 17, 2024

Submitted #5575

Copy link
Contributor

⚠️COMMENT VISIBILITY WARNING⚠️

This issue is now closed. Please be mindful that future comments are hard for our team to see.

If you need more assistance, please either tag a team member or open a new issue that references this one.

If you wish to keep having a conversation with other community members under this issue feel free to do so.

@leandrodamascena leandrodamascena moved this from Coming soon to Shipped in Powertools for AWS Lambda (Python) Jan 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Shipped
2 participants