Python용 FastAPI를 사용하여 앱 빌드
게시 됨: 2022-11-29FastAPI는 Python 3.6 이상을 사용하여 최신 애플리케이션 프로그래밍 인터페이스를 구축하기 위한 빠르고 가벼운 웹 프레임워크입니다. 이 튜토리얼에서는 FastAPI를 사용하여 앱을 빌드하는 기본 사항을 살펴보고 FastAPI가 2021년 최고의 오픈 소스 프레임워크 중 하나로 지명된 이유를 알 수 있습니다.
고유한 FastAPI 앱을 개발할 준비가 되면 앱을 호스팅할 장소를 찾기 위해 멀리 볼 필요가 없습니다. Kinsta의 애플리케이션 호스팅 및 데이터베이스 호스팅 서비스는 Python에서 강력한 서비스로서의 플랫폼을 제공합니다.
먼저 기초부터 배워봅시다.
FastAPI의 장점
다음은 FastAPI 프레임워크가 프로젝트에 제공하는 몇 가지 이점입니다.
- 속도: 이름에서 알 수 있듯이 FastAPI는 매우 빠른 프레임워크입니다. 그 속도는 일반적으로 API 구축을 위한 가장 빠른 옵션 중 하나로 간주되는 Go 및 Node.js의 속도와 비슷합니다.
- 쉬운 학습 및 코딩: FastAPI는 프로덕션 준비가 된 API를 만드는 데 필요한 거의 모든 것을 이미 파악했습니다. FastAPI를 사용하는 개발자는 처음부터 모든 것을 코딩할 필요가 없습니다. 몇 줄의 코드만으로 RESTful API를 배포할 수 있습니다.
- 포괄적인 문서화: FastAPI는 OpenAPI 문서 표준을 사용하므로 문서를 동적으로 생성할 수 있습니다. 이 설명서는 FastAPI의 끝점, 응답, 매개 변수 및 반환 코드에 대한 자세한 정보를 제공합니다.
- 버그가 적은 API: FastAPI는 사용자 지정 데이터 유효성 검사를 지원하므로 개발자가 버그가 적은 API를 빌드할 수 있습니다. FastAPI의 개발자들은 프레임워크로 인해 사람이 유발한 버그가 최대 40% 감소했다고 자랑합니다.
- 유형 힌트: 유형 모듈은 Python 3.5에서 도입되었습니다. 이를 통해 변수
type
을 선언할 수 있습니다. 변수 유형이 선언되면 IDE는 더 나은 지원을 제공하고 오류를 더 정확하게 예측할 수 있습니다.
FastAPI를 시작하는 방법
이 자습서를 따라 FastAPI를 시작하려면 먼저 몇 가지 작업을 수행해야 합니다.
Visual Studio Code와 같은 프로그래머용 텍스트 편집기/IDE가 있는지 확인하십시오. 다른 옵션으로는 Sublime Text와 Espresso가 있습니다.
Python 앱과 해당 인스턴스를 가상 환경에서 실행하는 것이 일반적입니다. 가상 환경에서는 서로 다른 패키지 세트 및 구성을 동시에 실행할 수 있으며 호환되지 않는 패키지 버전으로 인한 충돌을 피할 수 있습니다.
가상 환경을 만들려면 터미널을 열고 다음 명령을 실행합니다.
$ python3 -m venv env
또한 가상 환경을 활성화해야 합니다. 이를 수행하는 명령은 사용 중인 운영 체제 및 셸에 따라 다릅니다. 다음은 여러 환경에 대한 몇 가지 CLI 활성화 예입니다.
# On Unix or MacOS (bash shell): /path/to/venv/bin/activate # On Unix or MacOS (csh shell): /path/to/venv/bin/activate.csh # On Unix or MacOS (fish shell): /path/to/venv/bin/activate.fish # On Windows (command prompt): \path\to\venv\Scripts\activate.bat # On Windows (PowerShell): \path\to\venv\Scripts\Activate.ps1
(일부 Python 인식 IDE는 현재 가상 환경을 활성화하도록 구성할 수도 있습니다.)
이제 FastAPI를 설치합니다.
$ pip3 install fastapi
FastAPI는 API 구축을 위한 프레임워크이지만 API를 테스트하려면 로컬 웹 서버가 필요합니다. Uvicorn은 개발에 적합한 Python용 초고속 ASGI(Asynchronous Server Gateway Interface) 웹 서버입니다. Uvicorn을 설치하려면 다음 명령을 실행합니다.
$ pip3 install "uvicorn[standard]"
성공적으로 설치되면 프로젝트의 작업 디렉터리 내에 main.py 라는 파일을 만듭니다. 이 파일은 애플리케이션 진입점이 됩니다.
빠른 FastAPI 예제
예제 엔드포인트를 빠르게 설정하여 FastAPI 설치를 테스트합니다. main.py 파일에 다음 코드를 붙여넣은 다음 파일을 저장합니다.
# main.py from fastapi import FastAPI app = FastAPI() @app.get("/") async def root(): return {"greeting":"Hello world"}
위 스니펫은 기본 FastAPI 엔드포인트를 생성합니다. 다음은 각 줄이 수행하는 작업에 대한 요약입니다.
-
from fastapi import FastAPI
: API 기능은 FastAPI Python 클래스에서 제공합니다. -
app = FastAPI()
: FastAPI 인스턴스를 생성합니다. -
@app.get("/")
: 아래 함수가 요청 처리를 담당하도록 FastAPI에 지정하는 파이썬 데코레이터입니다. -
@app.get("/")
: 경로를 지정하는 데코레이터입니다. 이렇게 하면 사이트 경로에GET
메서드가 생성됩니다. 그런 다음 래핑된 함수에 의해 결과가 반환됩니다. - 통신에 사용되는 다른 가능한 작업에는
@app.post()
,@app.put()
,@app.delete()
,@app.options()
,@app.head()
,@app.patch()
등이 있습니다. , 및@app.trace()
.
파일 디렉터리에서 터미널에서 다음 명령을 실행하여 API 서버를 시작합니다.
$ uvicorn main:app --reload
이 명령에서 main
은 모듈의 이름입니다. app
개체는 애플리케이션의 인스턴스이며 ASGI 서버로 가져옵니다. --reload
플래그는 변경 사항이 있을 때 서버가 자동으로 다시 로드하도록 지시합니다.
터미널에 다음과 같은 내용이 표시되어야 합니다.
$ uvicorn main:app --reload INFO: Will watch for changes in these directories: ['D:\\WEB DEV\\Eunit\\Tests\\fast-api'] INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) INFO: Started reloader process [26888] using WatchFiles INFO: Started server process [14956] INFO: Waiting for application startup. INFO: Application startup complete.
브라우저에서 http://localhost:8000
으로 이동하여 API가 작동하는지 확인합니다. 페이지에 "Hello": "World"가 JSON 개체로 표시되어야 합니다. 이는 FastAPI로 API를 생성하는 것이 얼마나 쉬운지 보여줍니다. 위 스니펫의 여섯 번째 줄에서 볼 수 있듯이 경로를 정의하고 Python 사전을 반환하기만 하면 됩니다.
유형 힌트 사용
Python을 사용하는 경우 int
, str
, float
및 bool
과 같은 기본 데이터 유형으로 변수에 주석을 다는 데 익숙합니다. 그러나 Python 버전 3.9부터 고급 데이터 구조가 도입되었습니다. 이를 통해 dictionaries
, tuples
및 lists
과 같은 데이터 구조로 작업할 수 있습니다. FastAPI의 유형 힌트를 사용하면 Pydantic 모델을 사용하여 데이터의 스키마를 구조화한 다음 Pydantic 모델을 사용하여 힌트를 입력하고 제공된 데이터 유효성 검사의 이점을 얻을 수 있습니다.
아래 예에서는 간단한 식사 가격 계산기인 calculate_meal_fee
를 사용하여 Python에서 유형 힌트를 사용하는 방법을 보여줍니다.
def calculate_meal_fee(beef_price: int, meal_price: int) -> int: total_price: int = beef_price + meal_price return total_price print("Calculated meal fee", calculate_meal_fee(75, 19))
유형 힌트는 코드 실행 방식을 변경하지 않습니다.
FastAPI 대화형 API 설명서
FastAPI는 Swagger UI를 사용하여 자동 대화형 API 문서를 제공합니다. 액세스하려면 http://localhost:8000/docs
로 이동하면 모든 엔드포인트, 메서드 및 스키마가 포함된 화면이 표시됩니다.
이 자동 브라우저 기반 API 설명서는 FastAPI에서 제공하며 이를 활용하기 위해 다른 작업을 수행할 필요가 없습니다.
역시 FastAPI에서 제공하는 대체 브라우저 기반 API 문서는 Redoc입니다. Redoc에 액세스하려면 http://localhost:8000/redoc
로 이동합니다. 그러면 엔드포인트, 메서드 및 해당 응답 목록이 표시됩니다.
FastAPI에서 경로 설정
@app
데코레이터를 사용하면 @app.get
또는 @app.post
와 같은 경로의 메서드를 지정할 수 있으며 GET
, POST
, PUT
및 DELETE
뿐만 아니라 덜 일반적인 옵션인 HEAD
, PATCH
및 TRACE
를 지원합니다.
FastAPI로 앱 구축
이 자습서에서는 FastAPI를 사용하여 CRUD 애플리케이션을 빌드하는 과정을 안내합니다. 애플리케이션은 다음을 수행할 수 있습니다.
- 사용자 만들기
- 사용자의 데이터베이스 레코드 읽기
- 기존 사용자 업데이트
- 특정 사용자 삭제
이러한 CRUD 작업을 실행하려면 API 끝점을 노출하는 메서드를 만듭니다. 그 결과 사용자 목록을 저장할 수 있는 메모리 내 데이터베이스가 생성됩니다.
pydantic 라이브러리를 사용하여 Python 유형 주석을 사용하여 데이터 유효성 검사 및 설정 관리를 수행합니다. 이 자습서의 목적을 위해 속성이 있는 클래스로 데이터의 모양을 선언합니다.
이 자습서에서는 메모리 내 데이터베이스를 사용합니다. 이는 FastAPI를 사용하여 API 구축을 신속하게 시작하기 위한 것입니다. 그러나 프로덕션의 경우 PostgreSQL, MySQL, SQLite 또는 Oracle과 같이 선택한 모든 데이터베이스를 사용할 수 있습니다.
앱 구축
사용자 모델을 만드는 것으로 시작합니다. 사용자 모델에는 다음 속성이 있습니다.
-
id
: 범용 고유 식별자(UUID) -
first_name
: 사용자의 이름 -
last_name
: 사용자의 성 -
gender
: 사용자의 성별 -
roles
-admin
및user
역할을 포함하는 목록입니다.
작업 디렉터리에 models.py 라는 새 파일을 생성한 후 다음 코드를 models.py 에 붙여넣어 모델을 생성합니다.
# models.py from typing import List, Optional from uuid import UUID, uuid4 from pydantic import BaseModel from enum import Enum from pydantic import BaseModel class Gender(str, Enum): male = "male" female = "female" class Role(str, Enum): admin = "admin" user = "user" class User(BaseModel): id: Optional[UUID] = uuid4() first_name: str last_name: str gender: Gender roles: List[Role]
위의 코드에서:
-
User
클래스는BaseModel
을 확장한 다음pydantic
에서 가져옵니다. - 위에서 설명한 대로 사용자의 속성을 정의했습니다.
다음 단계는 데이터베이스를 만드는 것입니다. main.py 파일의 내용을 다음 코드로 바꿉니다.
# main.py from typing import List from uuid import uuid4 from fastapi import FastAPI from models import Gender, Role, User app = FastAPI() db: List[User] = [ User( id=uuid4(), first_name="John", last_name="Doe", gender=Gender.male, roles=[Role.user], ), User( id=uuid4(), first_name="Jane", last_name="Doe", gender=Gender.female, roles=[Role.user], ), User( id=uuid4(), first_name="James", last_name="Gabriel", gender=Gender.male, roles=[Role.user], ), User( id=uuid4(), first_name="Eunit", last_name="Eunit", gender=Gender.male, roles=[Role.admin, Role.user], ), ]
main.py 에서 :
-
List
유형으로db
를 초기화하고User
모델을 전달했습니다. - 각각
first_name
,last_name
,gender
및roles
과 같은 필수 속성이 있는 4명의 사용자로 메모리 내 데이터베이스를 생성했습니다. 사용자Eunit
admin
및user
역할이 할당되고 다른 세 사용자에게는user
역할만 할당됩니다.
데이터베이스 레코드 읽기
메모리 내 데이터베이스를 성공적으로 설정하고 사용자로 채웠으므로 다음 단계는 모든 사용자 목록을 반환할 엔드포인트를 설정하는 것입니다. 이것은 FastAPI가 들어오는 곳입니다.
main.py 파일에서 Hello World
끝점 바로 아래에 다음 코드를 붙여넣습니다.
# main.py @app.get("/api/v1/users") async def get_users(): return db
이 코드는 엔드포인트 /api/v1/users
를 정의하고 데이터베이스 db
의 모든 콘텐츠를 반환하는 비동기 함수 get_users
를 생성합니다.
파일을 저장하면 사용자 엔드포인트를 테스트할 수 있습니다. 터미널에서 다음 명령을 실행하여 API 서버를 시작합니다.
$ uvicorn main:app --reload
브라우저에서 http://localhost:8000/api/v1/users
로 이동합니다. 그러면 아래와 같이 모든 사용자 목록이 반환됩니다.
이 단계에서 main.py 파일은 다음과 같습니다.
# main.py from typing import List from uuid import uuid4 from fastapi import FastAPI from models import Gender, Role, User app = FastAPI() db: List[User] = [ User( id=uuid4(), first_name="John", last_name="Doe", gender=Gender.male, roles=[Role.user], ), User( id=uuid4(), first_name="Jane", last_name="Doe", gender=Gender.female, roles=[Role.user], ), User( id=uuid4(), first_name="James", last_name="Gabriel", gender=Gender.male, roles=[Role.user], ), User( id=uuid4(), first_name="Eunit", last_name="Eunit", gender=Gender.male, roles=[Role.admin, Role.user], ), ] @app.get("/") async def root(): return {"Hello": "World",} @app.get("/api/v1/users") async def get_users(): return db
데이터베이스 레코드 생성
다음 단계는 엔드포인트를 생성하여 데이터베이스에 새 사용자를 생성하는 것입니다. 다음 스니펫을 main.py 파일에 붙여넣습니다.
# main.py @app.post("/api/v1/users") async def create_user(user: User): db.append(user) return {"id": user.id}
이 스니펫에서는 새 사용자를 제출하기 위해 엔드포인트를 정의하고 @app.post
데코레이터를 사용하여 POST
메서드를 생성했습니다.
또한 User
모델의 user
를 허용하는 create_user
함수를 생성하고 새로 생성된 user
를 데이터베이스 db
에 추가(추가)했습니다. 마지막으로 엔드포인트는 새로 생성된 사용자 id
의 JSON 개체를 반환합니다.
위와 같이 엔드포인트를 테스트하려면 FastAPI에서 제공하는 자동 API 문서를 사용해야 합니다. 웹 브라우저를 사용하여 게시 요청을 할 수 없기 때문입니다. http://localhost:8000/docs
로 이동하여 SwaggerUI에서 제공하는 설명서를 사용하여 테스트합니다.
데이터베이스 레코드 삭제
CRUD 앱을 빌드하고 있으므로 애플리케이션에 지정된 리소스를 삭제할 수 있는 기능이 있어야 합니다. 이 자습서에서는 사용자를 삭제할 엔드포인트를 생성합니다.
다음 코드를 main.py 파일에 붙여넣습니다.
# main.py from uuid import UUID from fastapi HTTPException @app.delete("/api/v1/users/{id}") async def delete_user(id: UUID): for user in db: if user.id == id: db.remove(user) return raise HTTPException( status_code=404, detail=f"Delete user failed, id {id} not found." )
다음은 해당 코드가 작동하는 방식을 한 줄씩 분석한 것입니다.
-
@app.delete("/api/v1/users/{id}")
:@app.delete()
데코레이터를 사용하여 삭제 엔드포인트를 생성했습니다. 경로는 여전히/api/v1/users/{id}
이지만 사용자 ID에 해당하는 경로 변수인id
를 검색합니다. -
async def delete_user(id: UUID):
: URL에서id
를 검색하는delete_user
함수를 만듭니다. -
for user in db:
: 이것은 데이터베이스의 사용자를 반복하고 전달된id
가 데이터베이스의 사용자와 일치하는지 확인하도록 앱에 지시합니다. -
db.remove(user)
:id
가 사용자와 일치하면 사용자가 삭제됩니다. 그렇지 않으면 상태 코드가 404인HTTPException
이 발생합니다.
데이터베이스 레코드 업데이트
사용자의 세부 정보를 업데이트하기 위해 엔드포인트를 생성하려고 합니다. 업데이트할 수 있는 세부 정보에는 first_name
, last_name
및 roles
매개변수가 포함됩니다.
models.py 파일에서 User(BaseModel):
클래스 뒤에 있는 User
모델 아래에 다음 코드를 붙여넣습니다.
# models.py class UpdateUser(BaseModel): first_name: Optional[str] last_name: Optional[str] roles: Optional[List[Role]]
이 스니펫에서 UpdateUser
클래스는 BaseModel
을 확장합니다. 그런 다음 first_name
, last_name
및 roles
와 같은 업데이트 가능한 사용자 매개변수를 선택 사항으로 설정합니다.
이제 특정 사용자의 세부 정보를 업데이트하는 엔드포인트를 생성합니다. main.py 파일에서 @app.delete
데코레이터 뒤에 다음 코드를 붙여넣습니다.
# main.py @app.put("/api/v1/users/{id}") async def update_user(user_update: UpdateUser, id: UUID): for user in db: if user.id == id: if user_update.first_name is not None: user.first_name = user_update.first_name if user_update.last_name is not None: user.last_name = user_update.last_name if user_update.roles is not None: user.roles = user_update.roles return user.id raise HTTPException(status_code=404, detail=f"Could not find user with id: {id}")
위의 코드에서 다음을 수행했습니다.
- 업데이트 엔드포인트인
@app.put("/api/v1/users/{id}")
을 생성했습니다. 사용자id
에 해당하는 변수 매개변수 ID가 있습니다. -
UpdateUser
클래스와id
를 받는update_user
라는 메서드를 만들었습니다. - 전달된
id
와 연결된 사용자가 데이터베이스에 있는지 확인하기for
루프를 사용했습니다. - 사용자 매개변수가
is not None
(null 아님)이 아닌지 확인했습니다.first_name
,last_name
또는roles
와 같은 매개변수가 null이 아니면 업데이트됩니다. - 작업이 성공하면 사용자 ID가 반환됩니다.
- 사용자를 찾지 못한 경우 상태 코드가 404이고
Could not find user with id: {id}
라는 메시지와 함께HTTPException
예외가 발생합니다.
이 엔드포인트를 테스트하려면 Uvicorn 서버가 실행 중인지 확인하십시오. 실행 중이 아니면 다음 명령을 입력합니다.
uvicorn main:app --reload
아래는 테스트 스크린샷입니다.
요약
이 자습서에서는 Python용 FastAPI 프레임워크에 대해 배웠고 FastAPI 기반 애플리케이션을 얼마나 빨리 시작하고 실행할 수 있는지 직접 확인했습니다. 데이터베이스 레코드 생성, 읽기, 업데이트 및 삭제와 같은 프레임워크를 사용하여 CRUD API 엔드포인트를 구축하는 방법을 배웠습니다.
이제 웹 앱 개발을 한 단계 더 발전시키려면 애플리케이션 호스팅 및 데이터베이스 호스팅을 위한 Kinsta의 플랫폼을 확인하십시오. FastAPI와 마찬가지로 매우 간단합니다.