반응형
FastAPI에서 동일한 앱에서 다른 API를 호출하는 방법은 무엇입니까?
(SO에서 다음과 같은 질문을 찾았지만 도움이 되지 않았습니다.)
나는 Fastapi를 사용하여 다음과 같은 폴더 구조로 앱을 만들고 있다
앱의 진입점이다
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from app.api.v1 import lines, upload
from app.core.config import settings
app = FastAPI(
title=settings.PROJECT_NAME,
version=0.1,
openapi_url=f'{settings.API_V1_STR}/openapi.json',
root_path=settings.ROOT_PATH
)
app.add_middleware(
CORSMiddleware,
allow_origins=settings.BACKEND_CORS_ORIGINS,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
app.include_router(upload.router, prefix=settings.API_V1_STR)
app.include_router(lines.router, prefix=settings.API_V1_STR)
에 GET 엔드포인트가 2개 있습니다:
- --> 파일에서 임의 행을 반환합니다
- --> 의 출력을 반환해야 합니다
두 번째 GET 엔드포인트의 출력은 첫 번째 GET 엔드포인트의 출력의 문자열과 반대여야 하므로 다음 단계를 수행하려고 했습니다
코드:
import random
from fastapi import APIRouter, Request
from starlette.responses import RedirectResponse
router = APIRouter(
prefix="/get-info",
tags=["Get Information"],
responses={
200: {'description': 'Success'},
400: {'description': 'Bad Request'},
403: {'description': 'Forbidden'},
500: {'description': 'Internal Server Error'}
}
)
@router.get('/one-random-line')
def get_one_random_line(request: Request):
lines = open('netflix_list.txt').read().splitlines()
if request.headers.get('accept') in ['application/json', 'application/xml']:
random_line = random.choice(lines)
else:
random_line = 'This is an example'
return {'line': random_line}
@router.get('/one-random-line-backwards')
def get_one_random_line_backwards():
url = router.url_path_for('get_one_random_line')
response = RedirectResponse(url=url)
return {'message': response[::-1]}
이렇게 하면 다음과 같은 오류가 발생합니다:
TypeError: 'RedirectResponse' object is not subscriptable
두 번째 GET 끝점의 를 로 변경하면 다음과 같은 출력이 나타납니다
내가 하는 실수가 뭐지?
예:
엔드포인트의 출력이 'Maverick'인 경우 의 출력은 'kcirevam'이어야 합니다
코드를 리팩터해서 공통 부품을 호출하는 기능으로 사용합니다. 일반적으로 컨트롤러 외부의 모듈에 이 기능이 있습니다.
# this function could live as LineService.get_random_line for example
# its responsibility is to fetch a random line from a file
def get_random_line(path="netflix_list.txt"):
lines = open(path).read().splitlines()
return random.choice(lines)
# this function encodes the rule that "if the accepted response is json or xml
# we do the random value, otherwise we return a default value"
def get_random_or_default_line_for_accept_value(accept, path="netflix_list.txt", default_value="This is an example"):
if accept not in ("application/json", "application/xml"):
return default_value
return get_random_line(path=path)
@router.get('/one-random-line')
def get_one_random_line(request: Request):
return {
"line": get_random_or_default_line_for_accept_value(
accept=request.headers.get('accept'),
),
}
@router.get('/one-random-line-backwards')
def get_one_random_line_backwards(request: Request):
return {
"line": get_random_or_default_line_for_accept_value(
accept=request.headers.get('accept'),
)[::-1],
}
당신은 당신의 코드에서 임의의 엔드포인트를 함수 호출로 직접 호출할 수 있고, 당신은 처리하거나 할 필요가 없다. 다음은 이 기능이 현재 상태로 실행되고 실행되는 방법에 대한 예입니다:
from fastapi import FastAPI, Request
app = FastAPI()
@app.get("/one-random-line")
async def get_one_random_line(request: Request):
# implement your own logic here, this will only return a static line
return {"line": "This is an example"}
@app.get("/one-random-line-backwards")
async def get_one_random_line_backwards(request: Request):
# You don't have to do fancy http stuff, just call your endpoint:
one_line = await get_one_random_line(request)
return {"line": one_line["line"][::-1]}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
사용하면 다음과 같은 결과를 얻을 수 있습니다:
% curl localhost:8000/one-random-line
{"line":"This is an example"}%
% curl localhost:8000/one-random-line-backwards
{"line":"elpmaxe na si sihT"}%
실제로 이 API의 다른 엔드포인트에서 API 엔드포인트를 호출할 수 있습니다. 다른 스레드에서 호출하면 됩니다. 따라서 통화를 위한 함수를 만들고 엔드포인트 내부에서 다음과 같은 것을 사용합니다:
thread = threading.Thread(target=request_foo, args=(arg1, arg2))
thread.start()
나쁜 관행이란 걸 알아둬요. 외부 파일에 공유 코드를 만들어 원하는 엔드포인트에서 사용하는 것이 좋습니다.
반응형
'개발하자' 카테고리의 다른 글
여러 줄 문자열 내에서 파이썬 대체 (0) | 2023.09.25 |
---|---|
vscode 주피터에서 파이토치 진행률 막대가 사라짐 (0) | 2023.09.24 |
주피터 노트북 셀의 내용을 이미지로 내보내기 (0) | 2023.09.23 |
하나의 YAML 파일에서 여러 종류의 Kubernetes API에 대해 client-go to 'kubectl apply'를 직접 사용하는 것 (1) | 2023.09.22 |
스크립트 열거값을 배열로 입력합니다 (0) | 2023.09.22 |