기술/웹 개발

[FastAPI/python] 파이썬 FastAPI로 정말 간단하게 API 만들기(CORS)

하기싫지만어떡해해야지 2024. 8. 31. 17:04

이번에 외주 작업하고 있는 프로젝트에서

사이드 개발을 FastAPI로 하고있는걸 봤다

 

FastAPI는 들어봤었는데

정확히 뭔지도 몰랐고

파이썬으로 하는건지도 몰랐는데

이번에 작업을 진행하면서

정말 이렇게 간단하게도

백엔드 작업을 할 수가 있구나 싶었서

글을 작성해보려한다

 

백엔드 입문을

spring으로 한 나에게는

정말 신세계 그 자체,,

 

https://fastapi.tiangolo.com/ko/#typer-fastapi-cli

 

FastAPI

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

fastapi.tiangolo.com

 

공식문서에도 굉장히 설명이 잘돼있어서

참고하면 좋을 것 같다


FastAPI 설치

pip3 install fastapi

 

파이썬을 이용해서 fastapi를 설치해준다

 

 

main.py 작성

1. CORS 적용하기

FastAPI를 웹사이트 백엔드 프레임워크로 사용할거면

거의 필수라고 볼 수 있는 CORS를 적용해줘야한다

 

CORS는Cross Origin Resource Share의 약자로

자원의 교차 공유를 허용해주는 것이다

 

이게 뭔지 이해가 잘 안갈텐데

간단하게 말하면

frontend는 localhost:3000에 띄우고

backend는 localhost:8000에 띄우는데

원칙적으로는 3000포트에서 8000포트로의

자원 요청이 안된다

 

왜냐면 도메인이 다르기 때문이다

보안 등의 이유로 다른 도메인으로의

요청은 원칙적으로는 불가능하다

 

CORS는 이를 특정 도메인에 한해서는

허용하게 해주는 것이다

 

그래야 frontend에서 backend로

데이터를 가져올 수 있다

 

FastAPI에서

CORS 설정은 다음과 같다

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:3000"],  # Adjust this to your frontend URL
    allow_credentials=True,
    allow_methods=["*"],  # Allow all HTTP methods
    allow_headers=["*"],  # Allow all headers
)

 

2. root API 만들기

이제 API가 잘 작동하는지 알기 위해서

root를 만들어보면 된다

@app.get("/")
def read_root():
    return {"message": "Hello, World!"}

 

이렇게하면 endpoint없이

요청을 날렸을때

return값의 json이 날라온다

 

 

main.py 전체코드

# backend/main.py
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:3000"],  # Adjust this to your frontend URL
    allow_credentials=True,
    allow_methods=["*"],  # Allow all HTTP methods
    allow_headers=["*"],  # Allow all headers
)

@app.get("/")
def read_root():
    return {"message": "Hello, World!"}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="127.0.0.1", port=8000)

 

 

router 설정

이제 root가 잘 작동하는걸 확인했다면

우리가 필요한 데이터를 주고받을 API를 생성해야한다

 

그다음 prefix endpoint 설정해주기위해서

router까지 설정해주기로했다

 

나같은 경우는 backend작업을 할 때

같은 페이지에서 사용되는 API들 끼리

주로 파일을 따로 만들어서 관리해주는 편이다

 

그래서 내가 작업하고 있는 부분의

py파일을 따로 만들었다

 

1. router 생성

# backend/routers/part1_pharagraphs_router.py
from fastapi import APIRouter

router = APIRouter()

이렇게 하면 router가 생성되고

 

router가 설정된 endpoint로

API를 생성해줬다

@router.get("/get-part1-pharagraph")
async def get_part1_pharagraph():
    pharagraph = random.choice(pharagraphs["pharagraphs"])
    return {"pharagraph": pharagraph}

 

전체코드

# backend/routers/part1_pharagraphs_router.py
from fastapi import APIRouter
import random
import json
import os

router = APIRouter()

# 데이터 가져오는 부분
# Define the path to the part_pharagraphs.json file
pharagraphs_file_path = os.path.join(os.path.dirname(__file__), '../models/part1_pharagraphs.json')

# Load image annotations
with open(pharagraphs_file_path, 'r') as f:
    pharagraphs = json.load(f)
 
# api 생성
@router.get("/get-part1-pharagraph")
async def get_part1_pharagraph():
    pharagraph = random.choice(pharagraphs["pharagraphs"])
    return {"pharagraph": pharagraph}

 

 

이제 다시 main.py로 돌아와서

# backend/main.py
from fastapi import FastAPI
from routers import tts_router, stt_router, image_router, part1_pharagraphs_router

app = FastAPI()

# Include the routers
app.include_router(part1_pharagraphs_router.router, prefix="/api")

 

이렇게 해서 prefix를 추가해주면 완성

 

이렇게 생성한 api를 통해서

해당 데이터가 잘 주고받아지는 것을

확인할 수 있다