Python 초보자를 위한 FastAPI(1) 1
소개
저자는 오랫동안 다른 프로그래밍 언어를 배울까 고민해왔다. 그는 프론트엔드 개발자인데, Javascript는 매우 다재다능한 언어이기 때문에 그에게 축복이자 저주였다. Node의 강력한 기능 덕분에 거의 모든 것을 할 수 있다. 그는 무언가를 시작할 때마다 다음과 같이 시작하는 상황을 잘 알고 있었다.
"이 Javascript 라이브러리로 해결하면 되겠네." 또는 "간단한 스크립트를 작성하고 노드로 실행하면 되겠네."라고 생각했다.
이것은 마치 "망치만 있으면 모든 것이 못처럼 보인다"라는 말을 완벽하게 정의한 것과 같다.
저자가 배우고 싶은 언어가 꽤 많았다. Python도 그중 하나이다. 머신 러닝, AI, 웹 스크래핑 등에서 Python이 정말 빛을 발한다는 것을 알고 있다. 하지만 새로운 언어를 배우면서 사전 지식이 없는 모든 기술에 압도당하는 것이 싫었다. 그래서 그는 웹 서비스를 구축하기로 결정했다. 그리고 온라인에서 몇 가지 조사를 한 후 단순성 때문에 FastAPI를 선택했다. 이 프레임워크는 모든 기능을 갖춘 웹 API 서비스를 구축할 수 있는 많은 도구를 제공하는 높은 수준의 프레임워크이다. 그러면 밤새도록 머리를 긁적거리며 어떻게 작동할지 고민할 필요가 없죠. 그의 우선순위는 Python 그 자체이지 그 반대가 아니기 때문이다.
고지
- 이 포스트는 Python과 FastAPI에 대해 이미 모든 것을 알고 있는 사람이 제공하는 튜토리얼이 아니고, 학습 과정이다.
- FastAPI는 아직 Python 웹 개발에서 새로운 영역이다. 이는 이 프레임워크를 홍보하기 위한 것이 아니다. 사용하기 전에 성능과 기능을 제대로 평가한 후 사용하시기 바란다.
환경 설정
비록 런타임 버전 관리자를 사용하지만(현재 asdf는 선택해야 할 사항이다). 하지만 이번에는 컨테이너를 한번 사용해보기로 결정했다. 그것이 정말로 필요한 것이 무엇인지 확신하지 못하기 때문에 컴퓨터를 망치지 않고 코딩을 시작하고 싶은 사람에게 잘 맞는다고 생각한다.
컨테이너를 실행하고 설정하기 위해 Docker를 사용하고 있다. 컴퓨터에 도커가 설치되어 있지 않고 혼자 팔로우하고 싶은 사람이 있다면, https://www.docker.com/ 에 가서 설치할 수 있다. 설치 단계는 꽤 간단하고 사용자 친화적이어야 한다.
컨테이너를 개발 환경으로 사용할 것이기 때문이다. 첫 번째는 모든 종속성이 설치된 Python 이미지를 만드는 것이다.
Python 의존성을 관리하는 기존의 방법은 requirements.txt
파일을 사용하는 것이다.
fastapi==0.103.1
pydantic==2.3.0
uvicorn==0.23.2
이것들이 현재로서는 최소한의 종속성 요건이다.
이제 해야 할 일은 이 파일을 이미지에 복사하고 pip install
을 실행하여 이러한 종속성을 설치하는 것이다.
FROM python:3.11
WORKDIR /usr/src/app
COPY ./requirements.txt /usr/src/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /usr/src/requirements.txt
여기서 프로젝트 루트에 도커 파일을 만들었다. 도커 파일 안에서 공식 Python 3.11 이미지를 기본 이미지로 사용한다. 최신 Python 3.12 이미지를 사용하려고 하지 않았다. 며칠 전에 출시되었기 때문에 호환성에 대해 잘 모르기 때문이다.
그리고 다음은 도커에게 로컬 프로젝트 루트에서 requirements.txt
파일을 컨테이너 내부의 /usr/src
에 복사하라고 지시한 다음 pip install --no-cache-dir --upgrade -r /usr/src/requirements.txt
를 실행하여 종속성을 설치한다.
이제 이 컨테이너의 다른 측면을 지정하려면 compose 파일이 필요하다. 이제 프로젝트 루트 디렉터리에 docker-compose.yml
파일을 생성해야 할 때이다.
version: "3.9"
services:
fastapi:
container_name: fastapi
build: .
working_dir: /usr/src/app
command: uvicorn main:app --host=0.0.0.0 --port=8000 --reload
environment:
DEBUG: 1
volumes:
- ./app:/usr/src/app
ports:
- "80:8000"
restart: on-failure
이 시점에서 아직도 무엇을 만들지 확실하지 않아 서비스 이름과 컨테이너 이름을 FastAPI
로 유지한다.
다른 모든 설정들은 꽤 간단하다. 나는 도커에게 현재 디렉터리에 있는 dockerfile
로부터 이미지를 빌드하라고 말한다. 그리고 uvicorn main:app --host=0.0.0.0 --port=8000 --reload
명령을 실행하여 main
모듈 안에서 uvicorn
이 앱을 실행하고 이 앱을 0.0.0:8000
에서 호스팅을 시작한다. --reload
플래그는 코드가 변경될 때마다 uvicorn
이 다시 로드되도록 만든다. 그리고 앱 디렉터리를 컨테이너의 /usr/src/app
에 마운트한다. 마지막으로, 내 로컬 80
포트를 컨테이너의 8000
포트에 매핑한다. 그래서 앱이 작동하기 시작하면 브라우저에서 http://localhost
로 가서 서버의 응답을 볼 수 있다.
그리고 이제 기본적으로 작업 디렉토리가 될 앱 폴더를 만든다. 그리고 앱 디렉토리 아래에 __init__.py
와 main.py
파일을 만든다.
Python에서 각 폴더는 패키지이고 .py
파일은 각각 모듈이다. __init__.py
는 필수 사항은 아니지만 모듈을 가져오는 더 간단한 방법을 사용할 수 있게 해준다. 다른 용도로도 쓰이지만 지금은 비워두기로 한다.
모든 단계를 거친 후, 이제 프로젝트 폴더는 아래처럼 보여야 한다.
app
├── __init__.py
├── main.py
dockerfile
docker-compose.yml
requirements.txt
"Hello World"
모든 설정이 정확하다면 docker-compose up
명령으로 앱을 시작할 수 있다. 도커가 기본 Python 이미지를 끌어와 모든 설치 명령을 실행하는 데 시간이 좀 걸릴 수 있다.
설치가 완료되면 모듈 main
에서 app
에 대한 불만을 제기하는 로그를 볼 수 있을 것이다.
fastapi | ERROR: Error loading ASGI app. Attribute "app" not found in module "main".
그것은 완벽하게 정상이다. 왜냐하면 우리 main.py
에는 아직 앱이 없기 때문이다.
FastAPI 서버를 초기화하려면 먼저 main.py 에서 모듈을 가져와야 한다.
from fastapi import FastAPI
프론트엔드 개발자로서, 이 구문은 나를 약간 괴롭힌다. Javascript가 y에서 x를 가져오는 것과는 완전히 반대이다.
그럼 우리는 앱을 신고하고 방금 import한 FastAPI를 호출해서 사용해야 한다.
app = FastAPI()
이 단계 이후에 우리 앱은 요청을 받아서 클라이언트에게 응답을 보낼 수 있어야 한다. 브라우저를 열고 http://localhost
로 이동하면 404 상태 코드를 가진 {"detail": "Not Found"}
을 볼 수 있을 것이다.
이제, 악명 높은 "Hello World"를 말할 시간이다.
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"Hello": "World!"}
다음 비동기 함수 root
에 /
의 모든 get
요청을 가져가라고 FastAPI에 알린다. 그러면 JSON {"Hello": "World!"}
이(가) 반환된다.
그것은 단순하다. 그리고 이것이 기본적으로 Python의 첫 번째 맛으로 FastAPI 프레임워크를 선택하는 이유이다. 이미 다른 언어로 API 서비스를 만든 경험이 있다면 모든 것이 자연스럽게 느껴진다.
1편은 여기까지.
모든 소스 코드는 여기에서 찾을 수 있다.
1: 이 페이지는 FastAPI by A Python Beginner (1)을 편역한 것임.