Flask 및 Django와 같은 Python 웹 프레임워크가 처음으로 두각을 나타냈을 때 Python은 오늘날과는 다소 다른 언어였습니다. 비동기 실행 및 ASGI(Asynchronous Server Gateway Interface) 표준과 같은 최신 Python의 많은 요소는 초기 단계에 있거나 아직 존재하지 않았습니다.
FastAPI는 최신 Python 기능을 통합하기 위해 처음부터 구축된 Python 웹 프레임워크입니다. 클라이언트와의 비동기 동시 연결을 위해 ASGI 표준을 사용하며 필요한 경우 WSGI와 함께 작동할 수 있습니다. 경로와 엔드포인트에 비동기 기능이 내장되어 있습니다. FastAPI를 사용하면 유형 힌트가 포함된 깔끔하고 현대적인 Python 코드를 사용하여 웹 애플리케이션을 효율적으로 개발할 수 있습니다.
이름에서 알 수 있듯이 FastAPI의 주요 사용 사례는 API 엔드포인트를 빠르게 구축하는 것입니다. 이는 Python 사전 데이터를 JSON으로 반환하거나 대화형 Swagger UI가 포함된 OpenAPI 표준을 사용하여 쉽게 수행할 수 있습니다. 그러나 FastAPI는 결코 API에만 국한되지 않습니다. Jinja2 템플릿 엔진을 사용하여 일반 웹 페이지를 제공하는 것부터 WebSocket으로 구동되는 애플리케이션을 제공하는 것까지 웹 프레임워크가 수행하는 거의 모든 작업에 이를 사용할 수 있습니다.
FastAPI 설치
FastAPI는 자체적으로 꽤 많은 구성 요소를 설치할 수 있으므로 FastAPI 프로젝트를 새롭고 깨끗한 가상 환경에서 시작하는 것이 가장 좋습니다. 핵심 FastAPI 구성 요소는 다음과 같이 설치할 수 있습니다. pip install fastapi
.
또한 로컬 테스트를 위해 ASGI 서버를 설치해야 합니다. FastAPI는 Uvicorn과 잘 작동하므로 여기 예제에서는 이를 사용하겠습니다. 당신이 사용할 수있는 pip install uvicorn[standard]
C 라이브러리를 사용하여 최적의 구성 요소 세트로 Uvicorn을 설치하거나 pip install uvicorn
최소한의 순수 Python 버전을 설치합니다.
간단한 FastAPI 예
다음은 간단한 FastAPI 애플리케이션입니다.
from fastapi import FastAPI
app = FastAPI()
@app.get("https://www.infoworld.com/")
async def root():
return {"greeting":"Hello world"}
이것을 다른 이름으로 저장 main.py
그런 다음 “venv” 내에서 다음 명령을 사용하여 실행하세요. uvicorn main:app
. 그만큼 app
개체는 ASGI 서버에 사용하는 것입니다. (ASGI-WSGI 어댑터와 함께 WSGI를 사용할 수도 있지만 ASGI를 사용하는 것이 가장 좋습니다.)
작업이 실행되면 다음으로 이동하세요. localhost:8000
(Uvicorn 테스트 서버의 기본값) 당신은 볼 수 {"greeting":"Hello world"}
브라우저에서 – 사전에서 생성된 유효한 JSON 응답입니다.
이를 통해 FastAPI가 엔드포인트에서 JSON을 전달하는 것이 얼마나 쉬운지 알 수 있습니다. 여러분이 해야 할 일은 경로를 생성하고 Python 사전을 반환하는 것뿐입니다. Python 사전은 자동으로 JSON으로 직렬화됩니다. 까다로운 데이터 유형을 직렬화하기 위해 취할 수 있는 단계가 있으며 이에 대해서는 나중에 설명하겠습니다.
FastAPI 애플리케이션의 일반적인 개요는 Flask와 같은 시스템을 사용해 본 사람이라면 누구나 익숙할 것입니다.
- 그만큼
app
객체는 ASGI 또는 WSGI 서버로 가져와 애플리케이션을 실행하는 데 사용됩니다. - 데코레이터를 사용하여 애플리케이션에 경로를 추가할 수 있습니다. 예를 들어,
@app.get("https://www.infoworld.com/")
생성GET
래핑된 함수에서 반환된 결과와 함께 사이트 루트의 메서드 경로입니다.
그러나 몇 가지 차이점이 이미 눈에 띕니다. 우선, 경로 기능은 비동기식이므로 배포하는 모든 비동기 구성 요소(예: 비동기 데이터베이스 미들웨어 연결)도 해당 기능에서 실행될 수 있습니다.
필요한 경우 일반 동기 함수를 사용하는 것을 막을 수 있는 방법은 없습니다. 실제로 I/O를 기다리는 작업( async 의 가장 좋은 사용 사례)과 달리 계산 비용이 많이 드는 작업이 있는 경우 동기화 기능을 사용하고 FastAPI가 이를 정렬하도록 하는 것이 가장 좋습니다. 나머지 시간에는 비동기를 사용하세요.
FastAPI의 경로 유형
그만큼 @app
데코레이터를 사용하면 경로에 사용되는 방법을 설정할 수 있습니다. 예: @app.get
또는 @app.post
. GET
, POST
, PUT
, DELETE
덜 사용되는 OPTIONS
, HEAD
, PATCH
그리고 TRACE
모두 이런 식으로 지원됩니다.
여러 경로 함수를 래핑하여 특정 경로에서 여러 메서드를 지원할 수도 있습니다. 예: @app.get("https://www.infoworld.com/")
하나의 기능에 대해 @app.post("https://www.infoworld.com/")
또 다른.
FastAPI의 경로, 쿼리 및 양식 매개변수
경로 경로에서 변수를 추출하려면 경로 선언에서 해당 변수를 정의한 다음 경로 함수에 전달하면 됩니다.
@app.get("/users/{user_id}")
async def user(user_id: str):
return {"user_id":user_id}
URL에서 쿼리 매개변수를 추출하려면 FastAPI가 자동으로 감지하는 경로 함수에 형식화된 선언을 사용할 수 있습니다.
userlist = ["Spike","Jet","Ed","Faye","Ein"]
@app.get("/userlist")
async def userlist_(start: int = 0, limit: int = 3):
return userlist[start:start+limit]
이렇게 하면 쿼리 매개변수가 start
그리고 limit
URL에서 자동으로 추출되어 해당 명명된 변수에 전달됩니다. 해당 매개변수가 존재하지 않으면 기본값이 해당 매개변수에 할당됩니다.
양식 데이터 처리는 좀 더 복잡합니다. 먼저 추가 라이브러리를 설치해야 합니다. python-multipart
양식 데이터를 구문 분석하기 위해(pip install python-multipart
). 그런 다음 쿼리 매개변수 구문과 유사하지만 몇 가지 변경 사항이 있는 구문을 사용합니다.
from fastapi import Form
@app.post("/lookup")
async def userlookup(username: str = Form(...), user_id: str = Form("")):
return {"username": username, "user_id":user_id}
그만큼 Form
객체는 명명된 매개변수(username
, user_id
) 제출된 양식을 복사하여 전달합니다. 참고해서 사용하시면 Form(...)
선언에는 문제의 매개변수가 다음과 같다는 힌트가 있습니다. 필수의와 같은 username
여기. 대한 선택 과목 양식 요소에 해당 요소의 기본값을 전달합니다. Form
와 같은 user_id
여기 (Form("")
).
FastAPI의 응답 유형
FastAPI의 기본 응답 유형은 JSON이며, 지금까지 모든 예제는 자동으로 JSON으로 직렬화된 데이터를 반환합니다. 하지만 다른 종류의 응답도 반환할 수 있습니다. 예를 들어:
from fastapi.responses import HTMLResponse
@app.get("https://www.infoworld.com/")
def root():
return HTMLResponse("<b>Hello world</b>")
그만큼 fastapi.responses
모듈은 다음과 같은 다양한 일반적인 응답 유형을 지원합니다.
HTMLResponse
또는PlainTextResponse
: 텍스트를 HTML 또는 일반 텍스트로 반환합니다.RedirectResponse
: 제공된 URL로 리디렉션됩니다.FileResponse
: 제공된 경로에서 비동기적으로 스트리밍된 파일을 반환합니다.StreamingResponse
: 생성기를 가져와 결과를 클라이언트로 스트리밍합니다.
일반을 사용할 수도 있습니다. Response
개체를 생성하고 사용자 정의된 상태 코드, 헤더, 콘텐츠 및 미디어 유형을 제공합니다.
프로그래밍 방식으로 HTML을 생성하려는 경우 HTMLResponse
Jinja2 또는 원하는 다른 템플릿 엔진을 사용하여 이를 수행할 수 있습니다.
FastAPI의 응답 객체
예를 들어 쿠키를 설정하거나 헤더를 설정하는 등 응답 작업을 수행하려는 경우 Response
경로 함수의 매개변수로 개체를 사용합니다.
from fastapi import Response
@app.get("https://www.infoworld.com/")
def modify_header(response:Response):
response.headers["X-New-Header"] = "Hi, I'm a new header!"
return {"msg":"Headers modified in response"}
FastAPI의 쿠키
클라이언트에서 쿠키를 검색하는 것은 쿼리 또는 양식 매개변수를 처리하는 것과 유사하게 작동합니다.
from fastapi import Cookie
@app.get("https://www.infoworld.com/")
async def main(user_nonce: Optional[str]=Cookie(none)):
return {"user_nonce": user_nonce}
쿠키 설정은 다음을 사용하여 수행됩니다. .set_cookie()
방법 Response
물체:
from fastapi import Response
@app.post("https://www.infoworld.com/")
async def main(response: Response):
response.set_cookie(key="user_nonce", value="")
return {"msg":"User nonce cookie cleared"}
FastAPI와 함께 Pydantic 모델 사용
Python의 유형은 일반적으로 선택 사항이지만 FastAPI는 다른 많은 Python 프레임워크보다 유형 사용에 대해 더 엄격합니다. FastAPI는 Pydantic 라이브러리를 사용하여 제출된 데이터를 선언적으로 확인하므로 이를 수행하기 위한 논리를 직접 작성할 필요가 없습니다.
다음은 Pydantic을 사용하여 수신 JSON을 검증하는 방법의 예입니다.
from typing import List, Optional
from fastapi import FastAPI
from pydantic import BaseModel, EmailStr
app = FastAPI()
class Movie(BaseModel):
name: str
year: int
rating: Optional[int] = None
tags: List[str] = []
@app.post("/movies/", response_model=Movie)
async def create_movie(movie: Movie):
return movie
이 스니펫은 POST를 통해 JSON 데이터를 허용합니다(~ 아니다 HTML 양식!) 필드 포함 name
, year
, rating
그리고 tags
. 그러면 이러한 각 필드의 유형이 검증됩니다. 예를 들어 다음 데이터가 유효합니다.
{
"name":"Blade Runner 2049",
"year": 2018,
"rating": 5,
"tags": ["science fiction","dystopia"]
}
만약에 year
정수로 해석될 수 있는 문자열이었습니다(예: "2018"
) 올바른 데이터 유형으로 자동 변환됩니다. 하지만 우리에게 year
정수로 해석될 수 없는 값은 거부됩니다.
FastAPI에서 WebSocket 사용
FastAPI의 WebSocket 엔드포인트도 간단합니다.
from fastapi import FastAPI, WebSocket
@app.websocket("/ws")
async def ws_connection(websocket: WebSocket):
await websocket.accept()
while True:
data = await websocket.receive_text()
await websocket.send_text(f"You said: {data}")
이 예는 엔드포인트에서 연결을 수신합니다. /ws
일반적으로 JavaScript로 설정됩니다. WebSocket
그런 다음 입력을 기다리고 루프에서 응답을 다시 에코합니다.
일반적으로 WebSocket은 인증 보안에 큰 방해가 되지 않습니다. 일반적인 방법은 보안 WebSocket 연결을 만든 다음 사용자를 인증하는 일종의 토큰이나 자격 증명을 소켓에 첫 번째 메시지로 보내는 것입니다. FastAPI는 WebSocket 연결 보안을 위한 추가 메커니즘을 제공하지 않으므로 해당 기능을 직접 구축해야 합니다.
FastAPI에서 Swagger/OpenAPI 사용
이전에 Swagger로 알려진 OpenAPI는 API 엔드포인트를 설명하기 위한 JSON 형식의 표준입니다. 클라이언트는 엔드포인트에 대한 OpenAPI 정의를 읽고 웹 사이트의 API에서 보내고 받는 데이터의 스키마를 자동으로 결정할 수 있습니다.
FastAPI는 웹사이트의 모든 엔드포인트에 대한 OpenAPI 정의를 자동으로 생성합니다. 방문하시면 /openapi.json
FastAPI 사이트의 루트에는 각 엔드포인트, 수신할 수 있는 데이터 및 반환하는 데이터를 설명하는 JSON 파일이 있습니다.
FastAPI가 제공하는 또 다른 편리함은 웹 인터페이스를 통해 상호 작용할 수 있는 API용 문서 인터페이스가 자동으로 생성된다는 것입니다. 다음으로 이동하면 /docs
, ReDoc에서 생성된 API 페이지가 표시됩니다. 이동 /docs
Swagger UI(이전, 덜 고급)에서 생성된 것을 볼 수 있습니다. 두 문서 사용자 인터페이스 모두 구성 가능합니다.
FastAPI는 자동 생성된 스키마를 확장 또는 수정하거나 조건부로 생성하거나 비활성화하기 위한 후크도 제공합니다.
FastAPI는 모든 엔드포인트에 대한 OpenAPI 사양을 자동으로 생성하며, FastAPI에서 자동으로 생성된 웹 인터페이스를 통해 상호 작용할 수 있습니다. 필요한 경우 이 인터페이스를 비활성화할 수 있습니다.
결론
Python이 발전하고 적응함에 따라 일반적인 작업에 사용되는 라이브러리도 발전합니다. FastAPI는 최신 웹 프레임워크 중 하나일 수 있지만 미래 지향적인 디자인 덕분에 이미 큰 명성을 얻었습니다. 사소하지 않은 모든 Python 웹 프로젝트는 이를 후보로 고려할 가치가 있습니다.
저작권 © 2023 IDG Communications, Inc.