Skip to content

Instantly share code, notes, and snippets.

@vigneshjs
Last active October 8, 2024 04:37

Revisions

  1. vigneshjs revised this gist May 6, 2021. No changes.
  2. vigneshjs revised this gist May 4, 2021. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions app.py
    Original file line number Diff line number Diff line change
    @@ -1,10 +1,10 @@
    """
    FastAPI uses pydantic models to validate API request body and also generate swagger documentation. Since the schema generated
    by pydantic comply to JSON schema specification and not to openAPI specification, swagger documentation generated from pydantic
    models do not support adding multiple examples for a request body.
    FastAPI uses pydantic models to validate the API request body and also generate the swagger documentation. Since the schema
    generated by pydantic only comply to JSON schema specification and not to openAPI specification, swagger documentation
    generated from pydantic models do not support adding multiple examples for a request body.
    Ref: https://fastapi.tiangolo.com/tutorial/schema-extra-example/#technical-details
    In the following code I have extended fastAPI openAPI schema to include multiple request body examples.
    In the following code, I have extended fastAPI openAPI schema to include multiple request body examples.
    """

    import json
  3. vigneshjs created this gist May 4, 2021.
    100 changes: 100 additions & 0 deletions app.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,100 @@
    """
    FastAPI uses pydantic models to validate API request body and also generate swagger documentation. Since the schema generated
    by pydantic comply to JSON schema specification and not to openAPI specification, swagger documentation generated from pydantic
    models do not support adding multiple examples for a request body.
    Ref: https://fastapi.tiangolo.com/tutorial/schema-extra-example/#technical-details
    In the following code I have extended fastAPI openAPI schema to include multiple request body examples.
    """

    import json

    from fastapi import FastAPI, routing, status
    from fastapi.openapi.utils import get_openapi
    from fastapi.responses import Response
    from pydantic import BaseModel

    app = FastAPI()


    # Defining a basic pydantic class that will be used by fastAPI to validate request body and generate swagger
    class Sample(BaseModel):
    """
    This is a example pydantic model
    """

    name: str
    email: str
    mobile_number: str
    password: str
    otp: str

    class Config:
    # Follow openAPI 3.0 specification for defining examples. Ref: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md#example-object
    schema_extra = {
    "examples": {
    "Login with otp": {
    "description": "Allows to user to login with mobile_number and OTP",
    "value": {
    "mobile_number": "+9157878787878",
    "opt": "123321"
    }
    },
    "Login with email": {
    "description": "Allows to user to login with email and password",
    "value": {
    "email": "[email protected]",
    "password": "userPassword"
    }
    }
    }
    }

    @app.post("/login", status_code=200)
    async def login(body: Sample):
    """
    Login user
    """
    return Response({
    "status": "success"
    }, status_code=status.HTTP_200_OK)


    # Extending openapi
    def custom_openapi():
    if app.openapi_schema:
    return app.openapi_schema
    openapi_schema = get_openapi(
    title="Sample API",
    version="0.1.0",
    description="These APIs will be used to manage developer portal and configure applications and permissions",
    routes=app.routes,
    )

    # Adding examples present in pydancticModel.schema_extra into openAPI schema
    for route in app.routes:
    if isinstance(route, routing.APIRoute):
    # bodyField refers to the field present in the function that is called when route matches
    bodyField = route.body_field
    if bodyField:
    # Use pydantic schema_json() to get json schema representation (string) of the pydantic model
    modelSchema = bodyField.type_.schema_json()
    if modelSchema:
    # Parse dict object from json string
    jsonModelSchema = json.loads(modelSchema)
    if "examples" in jsonModelSchema:
    examples = jsonModelSchema['examples']
    for method in route.methods:
    # We can have requestBody examples only for POST and PUT methods
    if method == "POST":
    openapi_schema['paths'][route.path]["post"]['requestBody'][
    'content']['application/json']['examples'] = examples
    elif method == "PUT":
    openapi_schema['paths'][route.path]["put"]['requestBody'][
    'content']['application/json']['examples'] = examples

    app.openapi_schema = openapi_schema
    return app.openapi_schema


    app.openapi = custom_openapi