본문 바로가기
Back-end/Fastapi

#1. Fastapi 배우기 : 초기 설정

by hsloth 2023. 7. 2.

본 포스팅은 SKT FLY AI Challenge를 하면서 모델 서버 구축을 위해 혼자서 Fastapi에 대해 공부하는 포스팅입니다.

틀린 부분이 있거나, 이상한 부분이 있다면 지적해주시면 감사하겠습니다.

 

일단 먼저, 내가 생각하는 Fastapi의 장점은 이렇다.

  1. 빠른 속도(성능)
  2. 빠른 코드 작성 속도(express와 비슷하다)
  3. Swagger 문서의 자동 생성

이 정도가 있을 것 같은데, 여기서 node.js를 하는 사람의 입장에서 장점을 꼽자면, express.js와 비슷하기 때문에 express.js를 경험해본 사람이라면 금방 익숙해질 수 있을 것 같다는 점이다.

 

Fastapi 배우기 포스팅 시리즈는 내가 공부한 방법들을 되도록 같이 적으면서 해볼 생각이다.

 

혹시, Http Method에 대해서 모르시는 분이 있다면 다음 포스팅을 참고 바랍니다.

https://suloth.tistory.com/47

 

#2. 기초부터 따라하는 Nest.js : HTTP 메소드와 Nest.js 구조

해당 포스팅은 nest.js 9.0.0 버전을 기준으로 작성되었습니다. 모든 글은 작성자의 주관이 100% 담겨있기 때문에 부정확할 수 있습니다. HTTP 메소드 HTTP 메소드는 사용자가 백엔드 서버에게 무언가

suloth.tistory.com


시작


일단 뭐니뭐니해도 첫 시작은 공식문서를 보고 하는 것이다. Fastapi 공식문서 사이트를 봐보자.

https://fastapi.tiangolo.com/ko/

 

FastAPI

FastAPI framework, high performance, easy to learn, fast to code, ready for production

fastapi.tiangolo.com

친절하게도 처음 부분은 한글로 친절하게 번역이 되어 있다.

공식문서를 살펴보면,

  1. fastapi 설치
  2. uvicorn설치
  3. main.py 생성
  4. 서버 실행

위의 순서로 알려준다.

 

하지만, 나는 파이썬에서 패키지관리를 하기 위해서는 가상환경requirements.txt를 사용해야한다는 것을 알고 있기 때문에, 나만의 방식대로 구축을 할 것이다.

 


1. 가상환경 설정


먼저, 로컬로 가상환경을 설정해보자.

참고로, source 명령어는 mac, linux명령어이다. 윈도우는 그냥 activate.bat파일을 찾아서 실행시켜주면 된다.

아래 명령어를 써놓긴 할텐데, 안되면 구글링해보자.

# 가상환경 설치. venv라는 이름의 가상환경을 현재 폴더에 생성한다.
python3 -m venv venv

# 가상환경 접속(mac, linux)
source ./venv/bin/activate

# 가상환경 접속(window). 확실하지 않다.
./venv/Scripts/activate.bat

# 가상환경에서 탈출하는 방법
deactivate

 

 

윈도우 유저라면

powershell 말고 terminal을 사용하자. 그래야 잘된다. 그리고 파일,폴더구분시 / (슬래시) 말고 \ (역슬래시, 원화표시) 를 사용하도록 하자.

.\venv\Scripts\activate.bat

 

 

 

 

 

 


2. Fastapi관련 패키지 설치


가상환경을 설정했다면, fastapi와 uvicorn을 설치해보자.

pip install fastapi
pip install uvicorn

 

그리고 fastapi와 uvicorn을 설치했으면, 해당 패키지들을 관리하는 파일을 만들어야 한다.

requirements.txt 파일을 프로젝트 최상단 폴더에 만들어주자.

# 현재 가상환경에 설치되어있는 패키지들을 requirements.txt라는 파일에 버전과 함께 명시해준다.
pip freeze > requirements.txt

# 만약, requirements.txt에 명시된 패키지들을 설치하고 싶으면 다음 명령을 입력하면 된다.
pip install -r requirements.txt

 


3. 폴더 구조 


일단, 내가 생각하는 fastapi의 폴더 구조는 다음과 같다.

├── src #혹은 app폴더. 나의경우 src가 편해서 src폴더로 하였다
│	├── routers # router는 url 경로에 대한 파일들을 모아놓은 폴더라고 보면 된다.
│	│	└── user_router.py # /user 경로에 대한 라우터 파일. 
│	│    
│	├── services # 서비스를 모아놓은 폴더이다. router를 통해 사용자에게 전달된다.
│	│	└── user_service.py # 유저에 대한 서비스 함수들을 모아놓은 파일.
│	│
│	└── main.py  #fastapi를 실행시키는 메인파일
│
├── venv # 가상환경 폴더
│
└── .vscode
	└── settings.json # 코드 포맷터를 위한 파일

 

일단, 다른 건 다 배제하고 router만 고려해서 작성해봤다. 차차 업데이트 해보겠다.

다만, 우려가 되는건 fastapi는 class를 사용하지 않는 것 같은데 Mocking test를 어떻게 하려나 싶긴하다.

 

아래는 폴더 구조를 고려할 때 참고한 레포이다.

https://github.com/Buuntu/fastapi-react

 

GitHub - Buuntu/fastapi-react: 🚀 Cookiecutter Template for FastAPI + React Projects. Using PostgreSQL, SQLAlchemy, and Doc

🚀 Cookiecutter Template for FastAPI + React Projects. Using PostgreSQL, SQLAlchemy, and Docker - GitHub - Buuntu/fastapi-react: 🚀 Cookiecutter Template for FastAPI + React Projects. Using Pos...

github.com

 

참고로, 파이썬 3.3이하의 버전에서는 __init__.py 파일이 있어야 해당 폴더를 패키지로 인식을 한다고 하니, __init__.py파일도 폴더마다 넣어주는 것을 권장한다고 하는 것 같다.

 


4. main.py 작성


간단하게 main.py파일을 작성해보도록 하자.

from fastapi import FastAPI
import uvicorn
# from src.api.index import api_router

app = FastAPI(docs_url="/api-docs", openapi_url="/open-api-docs")

# 이 코드는 router를 붙이는 코드라서 지금은 굳이 안적어도 된다.
# app.include_router(api_router, prefix="/api")

@app.get("/user/{username}")
async def getUser(username: str):
	return {"username": username}

if __name__ == "__main__":
    uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)

나의 경우는 uvicorn말고, python명령을 사용해서 실행시키기 때문에 __main__ 을 설정해주었다.

 

위 코드는 사용하지 말자. python 명령을 사용해서 실행시키는 것보다 uvicorn 명령을 사용해서 실행시키면, 절대 경로 인식을 더 쉽게 할 수 있다.

 

아래와 같이 작성하자.

from fastapi import FastAPI

# swagger 문서는 /docs 경로로, openapi 문서는 /open-api-docs 경로로 설정한다.
app = FastAPI(docs_url="/docs", openapi_url="/open-api-docs")

@app.get("/")
async def getHello():
    return "Hello, World!"

 

 


5. 환경변수 설정


 

이 부분은 uvicorn 명령을 사용하여 서버를 실행시킬 경우 볼 필요 없다. 넘어가도록 하자.

 

파이썬에서 다른 폴더의 함수를 불러올 때, 절대 경로를 인식하지 못하는 경우가 발생했다. 그래서 환경 변수를 설정해주어야 한다.

터미널에서 다음 명령어를 입력하자.

PYTHONPATH=.

# 확인
echo $PYTHONPATH

PYTHONPATH를 설정해주어야 import 에러가 뜨지 않는다.

아니면 sys를 import해서 써도 되는데... 나는 코드가 더러워지는 것 같아서 이 방법을 선호한다.

그리고, PYTHONPATH같은 환경변수는 나중에 Docker에서 따로 설정도 가능하니까 말이다.

 


6. 서버 실행


Fastapi 공식문서에는 서버 실행을 다음과 같이 한다. (터미널에서)

uvicorn main:app --reload

# app dir을 설정해주려면 다음과 같이 하면 되는데, 별로 선호하지는 않는다.
uvicorn main:app --app-dir [폴더명] --reload

 

 

음... 그런데 나는 이 방법을 사용하니, 무조건 src폴더에서 실행을 해야하는 문제가 있었고 --app-dir 옵션을 사용하려고 하니, import가 제대로 되지 않는다는 문제가 있었다.

그래서 원래 Fastapi에서 제공하는 main.py파일 내용을 4번의 내용과 같이 uvicorn을 import해서 사용하는 것으로 수정하고, python 명령을 사용해서 실행시키기 시작했다.

python src/main.py

 

 

위의 방법 말고 해당 방법으로 실행시키자.

일단 터미널에서 프로젝트 최상위 폴더로 이동하자.

그리고 아래의 명령을 입력하면, 절대 경로 관련 에러가 뜨지 않는다.

# --host=0.0.0.0은 모든 ip에 대해서 요청을 허용하겠다는 의미이고
# --port=3000은 3000번 포트로 서버를 열겠다는 의미이다.
# --reload는 코드의 변경 사항을 저장하면 즉시 서버가 재실행되도록 하는 옵션이다.
uvicorn src.main:app --host=0.0.0.0 --port=3000 --reload

 

그냥 uvicorn main:app 으로 실행시키면, No module named 'src' 에러가 발생한다.

 


7. Code Formatter 설정


그리고 협업을 위해서는 Code Formatter가 필요하다. 나의 경우 black이라는 code formatter를 사용하기로 했다.

(파이선은 prettier가 안되나보다 ㅠ)

 

  1. vscode에 python extension 설치
  2. 현재 작업 환경(가상환경)에 black 패키지 설치 : pip install black
  3. vscode - setting(ctrl+,) - formatting provider검색 - autopep8을 black으로 변경
  4. 프로젝트 폴더 최상단에 .vscode 폴더 만들고 그 안에 settings.json파일 생성
# settings.json
{
	"[python]": {
		"editor.defaultFormatter": "ms-python.black-formatter"
	},
	"python.formatting.blackArgs": ["--line-length", "80"], # 최대 코드길이를 80으로 지정
	"python.formatting.provider": "black", # black으로 formatter 지정
	"editor.formatOnSave": true # 저장할 때마다 formatter 적용
}

다음과 같이 설정해주면 된다.

물론 이 작업은 각자 선택이다.

 

 

 

 

해당 프로젝트 관련 레포가 궁금하다면 아래 깃허브를 참고해주세요.

 

https://github.com/8471919/fastapi-tutorial-for-ai-engineer

 

GitHub - 8471919/fastapi-tutorial-for-ai-engineer

Contribute to 8471919/fastapi-tutorial-for-ai-engineer development by creating an account on GitHub.

github.com