대표적인 python web framework이다.
fastapi 전에 django,flask가 유명했지만 fastapi가 나오면서 가장 대표적인 web framework이다.
지금까지는 pip install requirement.txt를 이용해서 패키지를 깔았었다.
지금 배우는 poetry는 pip를 대체할 수 있는 패키지 매니저이다.

아래의 그림과 같이 설치하거나 poetry 공식 홈페이지를 이용하면 된다.

project init
poetry init 명령 후,메타 정보들 입력
대화 형식으로 패키지 설치가 가능하다.
또한 개발환경(dev용인지 product용인지)에 따라 패키지를 분리할 수 있다.

init으로 설정한 것들을 pyproject.toml에 저장한다.
cat pyproject.toml
poetry shell 활성화
가상환경에 진입할 때 쓰는 코드
poetry shell
emulate bash -c '주소'
poetry install
가상환경 진입 후 pyproject.toml에 저장된 정보를 기반하여 의존성 라이브러리 설치를 한다.
poetry add
poetry install 후 이제 서버를 사용하다가 더 필요한 패키지가 생기는 경우 poetry add를 통해 설치가 가능하다.
poetry remove
poetry install 후 이제 서버를 사용하다가 패키지를 지우고 싶은 경우 poetry add를 통해 제거가 가능하다.
poetry.lock
이 파일이 존재하면 작성하고 있는 프로젝트 의존성을 어디에서든 동일한 의존성을 가질 수 있다.
때문에 git repository에 커밋을 해줘야한다!!
그 전에 HTTP method인 get과 post부터 알아보자
| 처리방식 | GET | POST |
|---|---|---|
| URL 데이터 노출 | O | X |
| 예시 | 웹페이지 접근시 | 웹페이지에 FORM 제출 |
| URL 예시 | localhost:8080/login?id=tory | localhost:8080/login |
| 데이터 위치 | header | body |
루트('/')로 접근하면 hello world가 출력되는 서버를 만들어보자
from fastapi import FastAPI
app=FastAPI()
@app.get("/")
def read_root():
return ("Hello" : "World")
이후에 uvicorn을 이용해서 웹을 실행하면 된다.
터미널 (혹은CLI)에서 uvicorn01_simple_webserver:app--reload명령
만약 터미널에서 uvicorn을 하기 귀찮다면 py파일내에 구현하자!
# poetry add uvicorn한 후에 실행하자
from fastapi import FastAPI
import uvicorn
app=FastAPI()
@app.get("/")
def read_root():
return ("Hello" : "World")
if __name__ = "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
# 이후 터미널에서 python3 01_simple_webserver.py로 실행
실행 후 localhost 8000에 접근하면 아래와 같은 결과를 볼 수 있다.

localhost:8000/docs로 이동하면 swagger 문서를 확인할 수 있다.
swagger문서란 우리가 어떤 함수를 실행하면 어떤 결과를 얻을 수 있는지 설명하는 문서이다.

우리가 만든 api를 클라이언트에서 호출하는 경우 설명서로 사용된다.
다른 개발팀과 협업할 때도 유용하며, 구축된 프로젝트를 유지보수 할 때도 사용된다.
웹에서 GET method를 사용하여 데이터를 전송할 수 있다.
https://search.naver.com/search.naver?where=nexearch&sm=top_hty&fbm=0&ie=utf8&query=광진구

url를 전송할 때 방식이 2가지로 나뉘어진다.
users에 id가 402인 데이터를 전송하고 싶을 때를 예시로 들어보자
path 파라미터 방식
서버에 값만 전달해 변수로 사용
/users/402
query 파라미터 방식
Query String은 Key, Value의 쌍으로 이루어지며 &로 연결해 여러 데이터를 넘길 수 있음
/users?id=402
언제 어떤 방식을 사용할까?
resource를 식별 해야 되는 경우 : path parameter가 적합하다.
즉 있는지 없는지 알고 싶을 때 사용
정렬, 필터링을 해야 하는 경우 : Query Parameter가 적합하다.
path parameter

query parameter
skip파라미터 값을 변경하고 싶으면 ?skip=20 이런식으로 하면 된다.

특정 파라미터는 Optional(선택적)으로 하고 싶은 경우 사용한다.


클라이언트에서 API에 데이터를 보낼 때, Request Body(=Payload)를 사용함
Request Body에 데이터가 항상 포함되어야 하는 것은 아니다!
Request Body에 데이터를 보내고 싶다면 POST Method를 사용!!
GET Method는 URL,Request Header로 데이터 전달

python305_request_body.py를 실행해 웹 서버 실행 후 localhost:8000/docs로 이동하여 확인하면 class에서 정의한 것들을 볼 수 있다.
또한 try it out을 통해 실행을 해볼수도 있다!!

API의 Response => 클라이언트 : Response Body
Output Data를 해당 정의에 맞게 변형시켜준다.
python306_response_body.py 웹 서버 실행한 후, docs 확인
Tryitout을 누르고 Execute를 실행해보면
Request 데이터와 Response 데이터가 다른 것을 알 수 있다.

form 형태로 데이터를 받고 싶은 경우 사용할 수 있다.
이 형태를 사용하려면 패키지를 설치해야한다.
pip install python-multipart
# 간단한 프론트 엔드도 만들어 줄려면
pip install Jinja2
웹 사이트에 접근 : GET 요청
사용자가 데이터를 제출하는 행위 : POST 요청

즉 get을 이용해 login사이트로 이동하고 form형식에 맞게 데이터를 제출하는 것이다.
File 업로드 하고 싶은 경우
File을 사용할 때도 python-multipart를 설치 해야한다.
from fastapi import UploadFile

file.py를 실행하면 아래와 같은 결과를 볼 수 있다.

FastAPI에서 기본적으로 Data Model클래스로 사용하고 있는 Pydantic사용법을 알아보자!
모델 class를 정의할 때 사용한다.
Type Hint를 런타임에서 강제해 안전하게 데이터 핸들링하게 한다.

Machine Learning Model Input Validation
즉, Online Serving에서 Input 데이터를 Validation(검증)하는 Case를 말한다.
예를 들어,
아래와 같이 입력 데이터가 들어오면 확인하고 싶은 것들을 정해서 체크하는 것이다.

일반 python class
data class 활용
pydantic 활용
이중에서 pydantic을 활용하면 훨씬 코드가 간결해지고, 편리하다!
앱을 기동하기 위해,사용자가 설정 해야 하는 일련의 정보를 의미한다.
-예) DB 정보
이런 Config들은 하나의 모듈이나 클래스로 관리 해서,사용자가 보기 쉽게 저장한다.
코드 내 상수로 관리
가장 간단하지만 개인 정보가 노출될 수 있다.
또한 정보 변경이 어려울 수 있다.

yaml등과 같은 파일로 관리
별도의 파일에서 관리 후,실행할 때 파일을 지정해서 Config 클래스에 주입 하는 방법
여전히 파일에서 보안 정보가 노출되기 때문에 관리가 필요하다.

환경 변수(+Pydantic.BaseSettings)로 관리
환경 변수에 설정 값을 저장한 뒤, 코드에서는 환경 변수를 읽어오는 방법이다.
.env 파일들을 환경 별로 만들어 두거나, 실행 환경에서 유연하게 오버라이딩이 가능하다.(보안 노출 걱정 no!)

Fast API앱을 실행할 때와 종료할 때, 로직을 넣고 싶은 경우에 사용한다.
예)
Fast API앱이 처음 실행될 때, 머신러닝 모델을 Load하고,
앱을 종료할 때 연결해 두었던 Database Connection을 정리
async def lifespan(app:FastAPI)로 정의되며,
yield를 기점으로 이전은 앱 시작전, 이후는 앱 종료 전을 의미한다.
Fast API 인스턴스 생성 시 lifespan 파라미터에 위 함수를 전달
FastAPI(lifespan=lifespan)

API 엔드 포인트가 점점 많아져서, @app.get, @app.post 와 같은 코드를 하나의 모듈에서 관리하기가 어려워질 수 있다.
이때 활용하는 것이 router이다!
API Router는 큰 애플리케이션들에서 많이 사용되는 기능으로 API Endpoint를 정의한다.
API Router는 Mini Fast API로 여러 API를 연결해서 활용
기존에 사용하던 @app.get, @app.post을 사용하지 않고, router 파일을 따로 설정하고 app에 import해서 사용한다.

user Router,order Router 2개 생성 후에 include_router를 통해 app에 연결한다.
그럼 아래와 같은 결과를 볼 수 있다.

코드가 점점 커짐에 따라 프로젝트 구조를 어떻게 잡는것이 좋을까?
각 역할에 맞게 묶어서 구조를 잡는것이 좋다!

error handling은 웹 서버를 안정적으로 운영하기 위해 반드시 필요하다!!
발생 하고 있는 오류를 빠르게 수정할 수 있도록 예외 처리를 잘 만들 필요가 있다.
어떤 에러가 난것이고, 클라이언트에서 그 정보를 전달해서 대응할 수 있도록 해야 한다.

위의 사진 처럼 클라이언트에게 더 자세한 에러 메세지를 보내는 것이다!
오래 걸리는 작업들을 background에서 실행하게 하는 것이다.
CPU 사용이 많은 작업들을 Background ask로 사용하면,
클라이언트는 작업 완료를 기다리지 않고 즉시 Response를 받아볼 수 있다!

작업 결과물을 조회할 때는 Task를 어딘가에 저장해 두고, GET 요청을 통해 Task가 완료됐는지 확인한다.