Skip to content

I con‘t get requests.body when I set a new route_class #3726

@yintian710

Description

@yintian710

First Check

  • I added a very descriptive title to this issue.
  • I used the GitHub search to find a similar issue and didn't find it.
  • I searched the FastAPI documentation, with the integrated search.
  • I already searched in Google "How to X in FastAPI" and didn't find any information.
  • I already read and followed all the tutorial in the docs and didn't find an answer.
  • I already checked if it is not related to FastAPI but to Pydantic.
  • I already checked if it is not related to FastAPI but to Swagger UI.
  • I already checked if it is not related to FastAPI but to ReDoc.

Commit to Help

  • I commit to help with one of those options 👆

Example Code

from typing import Callable

from fastapi import Request, Response
from fastapi.routing import APIRoute
from starlette.datastructures import Headers


class Text2Json(Request):
    @property
    def headers(self) -> Headers:
        old_headers = self.scope['headers']
        new_headers = []
        for _ in old_headers:
            if _[0] != b'content-type':
                new_headers.append(_)
        new_headers.append((b'content-type', b'application/json'))
        self.scope['headers'] = new_headers
        self._headers = Headers(scope=self.scope)
        return self._headers


class Text2JsonRoute(APIRoute):
    def get_route_handler(self) -> Callable:
        original_route_handler = super().get_route_handler()

        async def custom_route_handler(request: Request) -> Response:
            content_type = request.headers.get('content-type', '')
            body1 = await request.body()
            if 'text' in content_type and 'json' not in content_type or not content_type:
                request = Text2Json(request.scope, request.receive)
            body2 = await request.body()
            return await original_route_handler(request)
        return custom_route_handler



from fastapi import APIRouter

from component.pn_tv_gs.HoGsVerifyData import HoGsVerifyData
from component.pn_tv_gs.TvVerifyData import TvVerifyData
from component.pn_tv_gs.verify_gs_pn import start as pn_tv_start
from component.pn_tv_gs.verify_tv import start as tv_start
from middleware.xx_text_to_json_type import Text2JsonRoute

pn_tv_gs = APIRouter(
    # prefix="/",
    tags=["pn_tv_gs"],
    # dependencies=[Depends(get_token_header)],
    # responses={404: {"description": "Not found"}},
)
pn_tv_gs.route_class = Text2JsonRoute


@pn_tv_gs.post('/verify_pn_gs')
async def _(data: HoGsVerifyData):
    result = pn_tv_start(data)
    return result


@pn_tv_gs.post('/verify_tv')
async def _(data: TvVerifyData):
    result = tv_start(data)
    return result

Description

I added a Text2JsonRoute that converts the content-type of the request from text to JSON,
But when I use POSTMAN to request http://host:port/verify_pn_gs and carry the body:{" body ", "body"}, which is fine when content-type is JSON, but when content-type is text, I can get body1, but I can't get body2, which seems to be stuck at line 205 in the requests module:Message = await self._receive().

Operating System

Linux

Operating System Details

ubutun 20.04

FastAPI Version

0.65.2

Python Version

3.8.10

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions