제수기 > fast API 프로젝트 만들기/튜토리얼 따라하기

Eunbi Jo·2025년 2월 14일
0

제수기

목록 보기
88/90
제수기  - 제발 수업내용을 기어해라 / 단순 수업정리 시리즈

FastAPI 프로젝트 만들기

fastapi는 flas framework보다 요즘 잘 쓰이고 있는 가볍고 빠른 프레임워크다.
동기적 방식, 비동기적 방식이라는 규격 중에 비동기 기반의 asgi 규격을 맞춘 프로젝트다. uvicon으로 실행된다.


모델 추론서버를 제공을 할 때

  • node.js 기반의 express도 자주 쓰이고
  • python 기반으로는 fastapi가 잘 쓰이고 있다.

fastapi는 한글화 잘 돼있고, 튜토리얼 따라가봤을 때 이해하기도 쉽다. 홈페이지 '배우기' 가서 배우면 충분.

프로젝트 생성

  1. 파이참에서 faist_env 가상환경 (안 만들어도 됨) 만들고 프로젝트 새로 만들기

  2. test_main.http는 일단 무시하고 main에서 객체화 한 다음에 @app.get() 이런 요청이 들어오면 이런 거 실행해 주세요 정도만 써주고 바로 실행할 수 있다.

  3. 셸에서 실행
    실제 실행할 모델 + 객체 : uvicorn main:qpp --port 9000
    기본적으로 포트는 8000으로 돼있는데, 강사님이 8000이 문제가 있어서 port를 적으신 거. 원래는 그 전까지 적어도 실행된다.

링크에 작성하는 내용대로 웹에 나오는 걸 확인할 수 있다. 이유는 모르겠다.

fast_api는 html 웹페이지로도 가능하긴 한데 보통은 restful api를 만들 때 사용한다. data로 응답을 주고 받는다.

restful의 특징

  • 조회 GET, 등록 Post, 수정 PUT, PATCH, 삭제 DELETE 요청 성격별로 메소드를 달리한다.
  • url을 작성할 때 자원의 계층구조를 잘 반영하자.
    그래서 단순 GET /products 이렇게 하면 products 전체 조회가 되는 거고
  • GET / products/123 이렇게 하면 한 건 조회
  • PATCH / products/123 수정해 달라는 거고
  • DELETE / prodcuts/123 123번 상품을 삭제해주세요 이런식으로 되는 거다.

얘네들에 대한 응답은 다 웹페이지가 아니라 데이터 자체를 준다. jason 형식으로 반환하거나 한다.

이거를 fastapi로 구축하는 것도 엄청 수월하다. 요청 메소드에 대한 것들이 여기 있는 .get이다. get 방식이면 이렇게 처리해주세요. 라고 써놓은 것.

실제 기능은 뭐가 있는가.

요청 처리 라우터 함수/ 사용자 입력값 검증 / form 데이터 처리

main.py에서 router 추가가 있다.

경로를 아래와 같이 3개로 쓰고 파일을 나눠봤다. 안 나눠도 상관은 없다.

  • 경로 변수
  • 쿼리 매개변수 (링크에서 ? 뒤에 주렁주렁 있는 거)
  • jason 데이터 넘어왔을 때 처리

라우터 함수는 따로 뺴놨음

경로매개변수는 이런식으로 쓴다.

같이 /user/에 있어도 저렇게 구분해서 뒤에 써줄 수 있다.

변수 이름 그리고 타입을 쓴다. model_name이 변수 이름, 그 옆에 ModelName이 타입.

타입을 쓰는 게 낯설텐데 이 타입만 들어올 수 있다고 선언한 거다. 요즘 코딩 추세가 일부러 타입 제한을 만들어서 쓰면서 프로젝트 의도를 분명히 한다. 파이썬에서도 문법적으로 지원은 하는데 강제하지는 않는다.

이것들을 실제로 돌려보자.

docs

링크에 docs를 붙여서 써주면 이런 창이 나온다. 이런 창을 스웨거 대화형이라고 한다.

어떤 라우터 있는지 요청 등을 볼 수 있다. 백엔드 후에 프로트엔드 개발자들에게 알려주기 위해서라도 문서가 필요한데 그걸 자동화해주는 거라고 보면 된다.

이런식으로 경로를 확인해볼 수 있다.

쿼리 스트링

경로변수가 없는 애는 다 쿼리 스트링이라고 보면 된다.

섞어서도 쓸 수 있다. 여기서는 경로가 없는 q가 쿼리인 걸 알 수 있다.

여기서 q를 123으로 바꿀 수도 있다. (왜 바꿔보는 거지..?) 여기서 product_id는 required라고 써있고 q는 그런 게 없다. 필수 입력이 아닌 건데, 이걸 설정할 수 있다.

q는 int=None으로 기본값을 없앴다. 그러면 이제 입력해보는 게 필수가 아니게 된다.

jason

from pydantic import BaseModel : 설명해주셨는데 놓쳤다.. 아무튼 jason으로 할 때 필요한 거 같다.


POSTMEN으로 강의내용을 정리해주셨다.

경로변수 - url에 쓰면 되고

쿼리변수 - params에 써주면되고 (query parmas라고 돼있는 표)

제이슨 - body raw json 형식으로 해두면, 이 형태만 라우터에 받아진다

경로변수의 검증은 path를 통해서 처리할 수 있다.
범위설정, 정규식 표현 등을 검증해놓을 수 있다.

form

form-urlencoded
Annotated 필요.

파일이 같이 있을 경우에 사용하는 form multipath 도 있음

파일이 섞여있으면 uploadfile로도 받을 수 있고 file로도 받을 수 있다. 라고 Annotated를 해놨다.


FAST API 튜토리얼 따라하기

  • 아나콘다 프롬프트에서 'fast_api' 가상환경 만들었음
  • 가상환경에서 파이참 실행

https://fastapi.tiangolo.com/tutorial/

  • fastapi 설치
    pip install "fastapi[standard]"

    "fastapi[standard]" 옵션을 사용하면 기본적인 필수 라이브러리(Uvicorn 포함)가 함께 설치된다. 기본 FastAPI만 설치하고 싶다면 pip install fastapi 도 가능

  • main.py를 만들고 튜토리얼에서 제공하는 FastAPI 코드 넣기

  • fastapi 개발 환경 실행
    fastapi dev main.py


서버를 확인할 수 있다.

/docs도 제공된다.

First Steps

https://fastapi.tiangolo.com/tutorial/first-steps/
메시지 내용을 바꿔보라고 한다.

  • FastAPI() → FastAPI 인스턴스를 생성.
  • @app.get("/") → GET / 요청을 처리하는 경로(path) 등록.
  • async def root() → 비동기 함수로 요청을 처리.
  • return {"message": "Hello World"} → JSON 응답을 반환.

끌 때 : ctrl + c

  • 끄고, fastapi dev main.py로 다시 열어보자.

  • Interactive API docs

  • Alternative API docs

  • OpenAPI and JSON Schema
    FastAPI는 자동으로 OpenAPI 스키마를 생성한다.
    OpenAPI는 API의 구조를 정의하는 표준 스키마.
    FastAPI는 이를 자동으로 생성하여 문서화해 줌.

HTTP 메서드 사용

@app.post("/items")
async def create_item():
    return {"message": "Item Created"}

@app.put("/items/{item_id}")
async def update_item(item_id: int):
    return {"message": f"Item {item_id} Updated"}

@app.delete("/items/{item_id}")
async def delete_item(item_id: int):
    return {"message": f"Item {item_id} Deleted"}
  • @app.post("/items") → 새로운 데이터를 생성.
  • @app.put("/items/{item_id}") → 특정 데이터를 업데이트.
  • @app.delete("/items/{item_id}") → 특정 데이터를 삭제.

동기, 비동기 이해하고 넘어가기

동기(Synchronous) 하나의 작업이 끝날 때까지 다음 작업을 진행할 수 없다.
비동기(Asynchronous) 한 작업을 기다리지 않고 동시에 여러 작업을 진행할 수 있다.

동기 코드

app = FastAPI()

def slow_task():
    time.sleep(5)  # 5초 동안 멈춤
    return "Task Done"

@app.get("/sync")
def sync_route():
    result = slow_task()
    return {"message": result}
  • slow_task() 함수가 실행될 때 5초 동안 기다려야 함.
  • 작업이 끝날 때까지 다른 요청을 처리하지 못함.

비동기 코드

app = FastAPI()

async def slow_task():
    await asyncio.sleep(5)  # 5초 동안 기다리지만 다른 작업 가능
    return "Task Done"

@app.get("/async")
async def async_route():
    result = await slow_task()
    return {"message": result}
  • async defawait을 사용하여 비동기 처리.
  • await asyncio.sleep(5) → 5초 동안 기다리지만 그동안 다른 요청도 처리 가능!
  • API 요청이 동시에 여러 개 들어와도 병렬적으로 처리됨.

그러면 챗봇은 동기를 써야 할까?

헷갈렸던 게, 챗봇에게 질문하고, 응답을 받아야 또 질문을 할 수 있으니까 이건 동기일까? 였다. 결론은 아니다. 비동기가 맞다.

0개의 댓글