반응형
fastapi(starlette) RedirectResponse 대신 post로 리디렉션 메서드 가져오기
RedirectResponse 개체를 반환한 후 이상한 리디렉션 동작이 발생했습니다.
events.py
router = APIRouter()
@router.post('/create', response_model=EventBase)
async def event_create(
request: Request,
user_id: str = Depends(get_current_user),
service: EventsService = Depends(),
form: EventForm = Depends(EventForm.as_form)
):
event = await service.post(
...
)
redirect_url = request.url_for('get_event', **{'pk': event['id']})
return RedirectResponse(redirect_url)
@router.get('/{pk}', response_model=EventSingle)
async def get_event(
request: Request,
pk: int,
service: EventsService = Depends()
):
....some logic....
return templates.TemplateResponse(
'event.html',
context=
{
...
}
)
라우터.파이의
api_router = APIRouter()
...
api_router.include_router(events.router, prefix="/event")
이 코드는 결과를 반환합니다.
127.0.0.1:37772 - "POST /event/22 HTTP/1.1" 405 Method Not Allowed
알겠습니다, 어떤 이유에서인지 GET 요청 대신 POST 요청이 호출되는 것 같습니다. 설명을 검색하면 RedirectResponse 개체가 기본적으로 코드 307로 설정되고 POST를 호출합니다.
나는 조언을 따르고 상태를 추가한다.
redirect_url = request.url_for('get_event', **{'pk': event['id']}, status_code=status.HTTP_302_FOUND)
그리고 get
starlette.routing.NoMatchFound
실험을 위해, 나는 다음으로 바꿀 것이다.
리다이렉트는 성공적으로 완료되지만 포스트 요청은 여기에 적합하지 않습니다. 내가 뭘 잘못하고 있는 거야?
업디
논리 실행을 위한 html 형식
기지를 두다
<form action="{{ url_for('event_create')}}" method="POST">
...
</form>
밑면의파이의
@router.get('/', response_class=HTMLResponse)
async def main_page(request: Request,
activity_service: ActivityService = Depends()):
activity = await activity_service.get()
return templates.TemplateResponse('base.html', context={'request': request,
'activities': activity})
POST 후 GET로 리디렉션하려면 다음과 같이 코드를 업데이트하는 것이 좋습니다.
# ...
return RedirectResponse(redirect_url, status_code=303)
눈치채셨겠지만...
완전히 작동하는 예:
from fastapi import FastAPI, APIRouter, Request
from fastapi.responses import RedirectResponse, HTMLResponse
router = APIRouter()
@router.get('/form')
def form():
return HTMLResponse("""
<html>
<form action="/event/create" method="POST">
<button>Send request</button>
</form>
</html>
""")
@router.post('/create')
async def event_create(
request: Request
):
event = {"id": 123}
redirect_url = request.url_for('get_event', **{'pk': event['id']})
return RedirectResponse(redirect_url, status_code=303)
@router.get('/{pk}')
async def get_event(
request: Request,
pk: int,
):
return f'<html>oi pk={pk}</html>'
app = FastAPI(title='Test API')
app.include_router(router, prefix="/event")
실행, 설치 및 실행 방법:
uvicorn --reload --host 0.0.0.0 --port 3000 example:app
그런 다음 브라우저에서 http://localhost:3000/event/form을 가리킵니다.
예를 들어 를 통해 엔드포인트에 액세스하려고 하기 때문에 언급한 오류가 발생합니다. 그러나 루트가 요청을 처리하기 때문에 요청은 (정수 대신 문자열을 전달하기 때문에) 엔드포인트에 도달합니다.
따라서 예를 들어 엔드포인트에 요청을 제출하려면 가 필요합니다. 다음은 에 있는 HTML에 액세스하는 데 사용할 수 있는 작업 예입니다(원하는 대로 포트 번호를 조정). 요청을 전송하면 이 요청이 트리거됩니다.
@tiangolo가 언급한 바와 같이, 요청 경로에서 요청 경로로 a를 수행할 때, to. 예:
return RedirectResponse(redirect_url, status_code=status.HTTP_303_SEE_OTHER)
작업 예:
from fastapi import APIRouter, FastAPI, Request, status
from fastapi.responses import RedirectResponse, HTMLResponse
router = APIRouter()
# This endpoint can be accessed at http://127.0.0.1:8000/event/
@router.get('/', response_class=HTMLResponse)
def event_create_form(request: Request):
return """
<html>
<body>
<h1>Create an event</h1>
<form method="POST" action="/event/create">
<input type="submit" value="Create Event">
</form>
</body>
</html>
"""
@router.post('/create')
def event_create(request: Request):
event = {"id": 1}
redirect_url = request.url_for('get_event', **{'pk': event['id']})
return RedirectResponse(redirect_url, status_code=status.HTTP_303_SEE_OTHER)
@router.get('/{pk}')
def get_event(request: Request, pk: int):
return {"pk": pk}
app = FastAPI()
app.include_router(router, prefix="/event")
반응형
'개발하자' 카테고리의 다른 글
ipython 및 jupyter의 메모리 사용량을 나열합니다. (0) | 2022.12.24 |
---|---|
(Terform, Cloud Run) 오류: 금지됨 클라이언트에 이 서버에서 URL/을(를) 가져올 수 있는 권한이 없습니다. (0) | 2022.12.24 |
논리적 및 논리적으로 스크립트 스위치 대/소문자 입력 (0) | 2022.12.23 |
Python 작업자가 다시 연결하지 못함 (0) | 2022.12.22 |
파이썬 밴디트 보안 문제 보고서에서 일부 문제를 무시하거나 건너뛰는 방법은 무엇입니까? (1) | 2022.12.22 |