241219 TIL #567 AI Tech #100 FastAPI - 1

김춘복·2024년 12월 19일
0

TIL : Today I Learned

목록 보기
569/575

Today I Learned

오늘 배운 내용은 python의 웹 프레임워크인 FastAPI


Requirements.txt 관리

  • 초기 세팅 : pipreqs
    서브 디렉토리도 모두 탐색해서 프로젝트에서 실제로 사용하는 패키지만 기록한다.
# pipreqs 설치
pip install pipreqs
# requirements.txt 생성. 현재경로면 경로에 . 을 사용
pipreqs 생성경로
  • 이후 관리 : Poetry
    pip를 대체하는 의존성 관리 및 패키징 도구
    가상환경을 자동으로 관리하고 의존성 충돌을 방지한다.
    개발 환경(dev)과 프로덕션 환경(prod) 의존성을 분리할 수 있다.
# Poetry 설치 방법
curl -sSL https://install.python-poetry.org | python3 -
# 프로젝트 내 가상환경 생성 설정
poetry config virtualenvs.in-project true
# 시작
poetry init
# 지정된 모든 라이브러리 설치
poetry install
# 가상환경 활성화
poetry shell

FastAPI

Python 3.6+ 기반 웹 프레임워크

파이썬 웹 프레임워크 비교

  • Django
    파이썬기반 풀스택 프레임워크. 학습곡선이 가파르고 초기 개발속도가 빠름.
    대규모 웹 애플리케이션 개발용도

  • Flask
    파이썬기반 마이크로 프레임워크. 최소한의 기능만 제공하며 유연성이 높아 개발자가 필요한 기능을 구현. 소규모 웹 애플리케이션 및 마이크로 서비스 개발 용도

  • FastAPI
    파이썬 기반 현대적이고 빠른 API 개발에 특화된 프레임워크. 비동기 프로그래밍 지원
    타입힌트 같은 현대적인 python 기능을 쓸 수 있고 자동 문서화 기능으로 API 개발이 편함
    고성능 API 개발이나 머신러닝 모델 서빙, 실시간 애플리케이션 개발 용도


  • 기본 프로젝트 구조
    app(or src) 모듈 안에 엔트리 역할인 __main.py__,
    main.py(or app.py)에서 애플리케이션과 Router 설정
    model.py에서 ML 모델 클래스와 함수 정의
  • API 명세서를 자동으로 만들어준다. swagger 지원(localhost:8000/docs)

  • Redoc(localhost:8000/redoc)


Fast API 구현

  • 간단한 구현(GET 요청)
    python3 파일명.py로 웹서버 실행가능(uvicorn을 코드 안에서 구현 했다면)
from typing import Optional
from fastapi import FastAPI
import uvicorn

# FastAPI 객체 생성
app = FastAPI()


# "/"로 접근하면 return을 보여줌
@app.get("/")
def read_root():
    return {"Hello": "World"}

# GET요청 Path Parameter 방식
@app.get("/users/{user_id}")
def get_user(user_id):
    return {"user_id": user_id}
    
# 임시로 db 구현
fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]

# GET요청 Query String 방식. Optional을 사용해 파라미터 옵셔널로 줌
@app.get("/items/{item_id}")
def read_item(item_id: str, q: Optional[str] = None):
    if q:
        return {"item_id": item_id, "q": q}
    return {"item_id": item_id}

# unicorn으로 웹서버 실행
if __name__ == '__main__':
    uvicorn.run(app, host="0.0.0.0", port=8000)
  • POST 요청 : requestbody(파라미터)를 받아서 resposebody(decorator의 response_model)로 반환
    pydantic.BaseModel을 사용해서 class 생성
from typing import Optional
from fastapi import FastAPI
import uvicorn

from pydantic import BaseModel


class ItemIn(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None


class ItemOut(BaseModel):
    name: str
    price: float
    tax: Optional[float] = None


app = FastAPI()


@app.post("/items/", response_model=ItemOut)
def create_item(item: ItemIn):
    return item


if __name__ == '__main__':
    uvicorn.run(app, host="0.0.0.0", port=8000)
  • Form 형태로 데이터를 받고싶으면 python-multipart를 설치해야 한다.
from fastapi import FastAPI, Form, Request
from fastapi.templating import Jinja2Templates

import uvicorn

app = FastAPI()
# html 템플릿으로 진자2 사용
templates = Jinja2Templates(directory='./')


@app.get("/login/")
def get_login_form(request: Request):
    return templates.TemplateResponse('login_form.html', context={'request': request})


# Form(...)에 ...은 필수(required)를 의미
@app.post("/login/")
def login(username: str = Form(...), password: str = Form(...)):
    return {"username": username}


if __name__ == '__main__':
    uvicorn.run(app, host="0.0.0.0", port=8000)
  • files
from typing import List

from fastapi import FastAPI, File, UploadFile
from fastapi.responses import HTMLResponse

import uvicorn

app = FastAPI()

# file을 바이너리데이터로 받으므로 bytes 사용
@app.post("/files/")
def create_files(files: List[bytes] = File(...)):
    return {"file_sizes": [len(file) for file in files]}


@app.post("/uploadfiles/")
def create_upload_files(files: List[UploadFile] = File(...)):
    return {"filenames": [file.filename for file in files]}
profile
Backend Dev / Data Engineer

0개의 댓글