Skip to content

Support multi content type in request body and responses #214

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

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

luolingchun
Copy link
Owner

@luolingchun luolingchun commented Jan 4, 2025

Checklist:

  • Run pytest tests and no failed.
  • Run ruff check flask_openapi3 tests examples and no failed.
  • Run mypy flask_openapi3 and no failed.
  • Run mkdocs serve and no failed.

Many people have multi content-type needs:

Here is a solution that can specify different content types for each class.

from flask import Request
from pydantic import BaseModel

from flask_openapi3 import OpenAPI

app = OpenAPI(__name__)


class DogBody(BaseModel):
    a: int = None
    b: str = None

    model_config = {
        "openapi_extra": {
            "content_type": "application/vnd.dog+json"
        }
    }


class CatBody(BaseModel):
    c: int = None
    d: str = None

    model_config = {
        "openapi_extra": {
            "content_type": "application/vnd.cat+json"
        }
    }


class BsonModel(BaseModel):
    e: int = None
    f: str = None

    model_config = {
        "openapi_extra": {
            "content_type": "application/bson"
        }
    }


class ContentTypeModel(BaseModel):
    model_config = {
        "openapi_extra": {
            "content_type": "text/csv"
        }
    }


@app.post("/a", responses={200: DogBody | CatBody | ContentTypeModel | BsonModel})
def index_a(body: DogBody | CatBody | ContentTypeModel | BsonModel):
    """
    This may be confusing, if the content-type is application/json, the type of body will be auto parsed to
    DogBody or CatBody, otherwise it cannot be parsed to ContentTypeModel or BsonModel.
    The body is equivalent to the request variable in Flask, and you can use body.data, body.text, etc ...
    """
    print(body)
    if isinstance(body, Request):
        if body.mimetype == "text/csv":
            # processing csv data
            ...
        elif body.mimetype == "application/bson":
            # processing bson data
            obj = BSON(body.data).decode()
            new_body = body.model_validate(obj=obj)
            print(new_body)
    else:
        # DogBody or CatBody
        ...
    return {"hello": "world"}


if __name__ == '__main__':
    app.run(debug=True)

As a result, some break changes had to be generated:

  1. openapi_extra no longer supports description and required in request body, and instead uses request_body_description and request_body_required.
    @app.post("/body", request_body_description="This is post RequestBody")
    def api_error_json(body: BookBody):
        ...
  2. openapi_extra no longer supports description , headers and links in response, and replace with the following form.
    @app.get(
         "/test",
         responses={
             "201": {
                 "model": BaseResponse,
                 "description": "Custom description",
                 "headers": {
                     "location": {
                         "description": "URL of the new resource",
                         "schema": {"type": "string"}
                     }
                 },
                 "links": {
                     "dummy": {
                         "description": "dummy link"
                     }
                 }
             }
         }
     )
     def endpoint_test():
         ...

@luolingchun luolingchun force-pushed the Support-multi-content-type-in-request-body-and-responses branch from e27a27e to 57be463 Compare January 4, 2025 02:16
@luolingchun luolingchun added this to the v4.1.0 milestone Jan 4, 2025
@luolingchun luolingchun force-pushed the Support-multi-content-type-in-request-body-and-responses branch from 8912d40 to d7d0294 Compare January 4, 2025 02:22
@luolingchun
Copy link
Owner Author

luolingchun commented Jan 4, 2025

@joaopedroft @raisachatterjee @iongion

I'm sorry to bother you, but I hope you can do some testing and give some advice.

I have already released a beta version 4.1.0rc1.

Update in 2025.2.8 4.2.0rc1.

@luolingchun luolingchun force-pushed the Support-multi-content-type-in-request-body-and-responses branch 3 times, most recently from e8b91d5 to e0152cd Compare January 6, 2025 09:42
@luolingchun luolingchun force-pushed the Support-multi-content-type-in-request-body-and-responses branch from dce38f5 to 1661587 Compare January 14, 2025 07:07
@luolingchun luolingchun modified the milestones: v4.1.0, v4.2.0 Feb 8, 2025
@luolingchun luolingchun force-pushed the Support-multi-content-type-in-request-body-and-responses branch from 1661587 to 2064eea Compare February 8, 2025 02:16
@github-actions github-actions bot added the Stale label May 1, 2025
@github-actions github-actions bot closed this Jun 1, 2025
@luolingchun luolingchun reopened this Jun 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant