๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐™‹๐™ฎ๐™ฉ๐™๐™ค๐™ฃ/๐™๐™–๐™จ๐™ฉ ๐˜ผ๐™‹๐™„

Fast API๋กœ ๋ฐฑ์—”๋“œ์„œ๋ฒ„ ๋งŒ๋“ค๊ธฐ [1]

by beomcoder 2023. 10. 26.
728x90
๋ฐ˜์‘ํ˜•

๊ฒŒ์‹œํŒ์„ ๋ณด๋‹ˆ 2์›”์— Fast API๋ฅผ ๊ณต๋ถ€ํ–ˆ๋˜ ํ”์ ์ด ์žˆ์—ˆ๋‹ค. ๊ทธ ๋‹น์‹œ์—๋Š” ์„œ๋ฒ„๋ฅผ ๋น ๋ฅด๊ฒŒ ๋งŒ๋“ค์–ด์•ผํ•˜๋‹ˆ ์ต์ˆ™ํ•˜์ง€ ์•Š์€ ํ”„๋ ˆ์ž„์›Œํฌ๋ณด๋‹ค flask๋กœ ๋งŒ๋“œ๋Š”๊ฒŒ ํŽธํ•ด์„œ ์ž ์‹œ ์ ‘์–ด๋‘์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ flask๋กœ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ผ์ •์‹œ๊ฐ„๋งˆ๋‹ค ์œ ์ €์ •๋ณด๋ฅผ ์ทจํ•ฉํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์—…๋ฐ์ดํŠธ๋ฅผ ํ•˜๋Š” ์„œ๋ฒ„๋ฅผ ๋งŒ๋“ค๊ณ  ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ์—ˆ๋‹ค. ์กฐ๊ธˆ์”ฉ ๋‚ด ์—…๋ฌด ์˜์—ญ์— ๋„“ํ˜€์ ธ์„œ ํ”„๋ก ํŠธ์™€ ํ†ต์‹ ํ•˜๋Š” ์„œ๋ฒ„๋‹จ์—์„œ ๋‚ด์ชฝ์œผ๋กœ ๊ฐ„๊ฐ„ํžˆ ๋ฐ์ดํ„ฐ๋ฅผ ๋„˜๊ฒจ ๋ฐ์ดํ„ฐ๋ฅผ ํ™œ์šฉํ•ด ๊ฒฐ๊ณผ๋ฌผ์„ ๋ฆฌํ„ดํ•ด์ฃผ๋Š” ์„œ๋ฒ„๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ–ˆ๋‹ค. ์ด๋ฒˆ์—๋„ flask๋กœ ๋งŒ๋“ค๊ณ  ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด๋ด์„œ ์ž˜๋˜์–ด ๋ฐฐํฌ๋ฅผ ํ–ˆ๋Š”๋ฐ ์—ฌ๊ธฐ์„œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒผ๋‹ค.

 

๋ฉ์ฒญํ•˜๊ฒŒ flask๋ฅผ ์‚ฌ์šฉํ• ๋•Œ๋Š” Flask + uWSGI + Nginx ์„ธํŠธ์™€ ๊ฐ™์ด ์™ธ๋ถ€ ์ž๋ฃŒ๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•ด์•ผ ํ–ˆ๋Š”๋ฐ flask์— ๋ฌด์ง€ํ–ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์—ด์‹ฌํžˆ ์ด๊ฒƒ์ €๊ฒƒ ๋งŒ์ ธ๋ณด๋Š”๋ฐ aws ๊ณ„์ •์—์„œ ๋ง‰ํžˆ๊ณ , ๋ฒ„์ „์—์„œ ๋ง‰ํžˆ๊ณ  ์Šค์ผ€์ค„๋Ÿฌ์—์„œ๋„ ๋ง‰ํžˆ๊ณ  ๋‹ต๋‹ตํ–ˆ๋‹ค. ์˜ˆ์ „์— FastAPI๋กœ ์‰ฝ๊ฒŒ ๋งŒ๋“ค์—ˆ๋˜ ๊ธฐ์–ต์ด ๋– ์˜ฌ๋ผ FastAPI๋กœ ๊ฐˆ์•„ํƒ€๊ฒŒ ๋˜์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์„œ๋ฒ„๋ฅผ ๋งŒ๋“ค์–ด๋‚˜๊ฐ€๋ฉฐ ์• ๋กœ์‚ฌํ•ญ์ด๋‚˜ ๋งŒ๋“ค์—ˆ๋˜ ๋ฐฉ์‹์— ๋Œ€ํ•ด ์ ์–ด๋ณผ๊นŒ ํ•œ๋‹ค.

 

์„œ๋ฒ„๋Š” ์šฐ์„  ์Šค์ผ€์ค„๋Ÿฌ๋กœ 10๋ถ„๋งˆ๋‹ค ํ•œ๋ฒˆ์”ฉ DB์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธ์–ด์™€์„œ ๋กœ์ปฌ์— ์ €์žฅํ•ด๋‘”๋‹ค. API์š”์ฒญ์ด ์˜ค๋ฉด ๋กœ์ปฌ์— ์ €์žฅํ•ด์ค€ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ’์„ ๋งŒ๋“ค์–ด๋‚ด์„œ ๋ฆฌํ„ดํ•ด์ค€๋‹ค. ๋“ค์œผ๋ฉด ๋˜๊ฒŒ ์‰ฌ์›Œ๋ณด์ด์ง€๋งŒ ๋‚˜๋Š” ๋งŒ๋“ค๋•Œ ์•„๋ฌด ๋„์›€์—†์ด ๋งจ๋•…์— ํ—ค๋”ฉ์œผ๋กœ ๋งŒ๋“ ๊ฑฐ๋ผ ์ƒ๋‹นํžˆ ์˜ค๋ž˜ ๊ณต๋ถ€ํ–ˆ๋‹ค. ๋งŽ์€ ๋ธ”๋กœ๊ทธ์™€ ๊ตฌ๊ธ€๋ง์„ ํ†ตํ•ด ์ด์ƒํ•˜๊ฒŒ ๋งŒ๋“ ๊ฒƒ์ด ๋งŽ์„ ๊ฒƒ์ด๋‹ค. ๊ทธ๋ž˜๋„ ์™„์„ฑํ˜•์˜ ๊น”๋”ํ•œ ์ฝ”๋”ฉ์„ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ๋„ ์ข‹์ง€๋งŒ ์ด๋ ‡๊ฒŒ ์งœ์ง‘๊ธฐ๋กœ ๋งŒ๋“ค์–ด๋ณธ ๊ฒƒ์„ ๊ณต์œ ํ•ด๋„ ์ข‹๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค. ์ฒซ๋‚ ์˜ ๊ณผ์ •๋ถ€ํ„ฐ ์ˆ˜์ •ํ•˜๋Š” ๊ณผ์ •์„ ์ฐจ๋ก€๋Œ€๋กœ ์ ์–ด๋ณผ ์˜ˆ์ •์ด๋‹ค. ์–ด๋””์„œ ๋ฐฐ์›Œ์„œ ํ•œ๊ฒŒ ์•„๋‹ˆ๋ผ ํ˜ผ์ž์„œ ๊ณต๋ถ€ํ•˜๋ฉฐ ํ•œ ๊ฒƒ์ด๋ผ '์™œ ์ €๋ ‡๊ฒŒ ํ•˜์ง€'๋ผ๊ณ  ์ƒ๊ฐํ•˜๋Š” ๋ถ€๋ถ„์ด ๋งŽ์•„๋„ ์ดํ•ดํ•ด์ฃผ์…จ์œผ๋ฉด ์ข‹๊ฒ ๋‹ค.

 

ํ™˜๊ฒฝ์€ ์•„๋งˆ์กด EC2์„œ๋ฒ„์—์„œ ๋ฆฌ๋ˆ…์Šคํ™˜๊ฒฝ์— ๋ฐฐํฌ๋˜์–ด ์žˆ๋Š” ์ƒํƒœ์ด๋‹ค. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” aws์— mariadb๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๊ณ , db๋Š” ๋‘๊ตฐ๋ฐ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์˜จ๋‹ค.

 

.
โ””โ”€โ”€ app
    โ”œโ”€โ”€ __init__.py
    โ”œโ”€โ”€ crud.py
    โ”œโ”€โ”€ database.py
    โ”œโ”€โ”€ main.py
    โ”œโ”€โ”€ models.py
    โ”œโ”€โ”€ settings.py
    โ””โ”€โ”€ schemas.py

 

ํด๋” ๊ตฌ์กฐ๋Š” ์œ„์˜ ๊ตฌ์กฐ์™€ ๊ฐ™์ด ๋งŒ๋“ค์–ด ์ฃผ์—ˆ๋‹ค. ๊ฒ€์ƒ‰์œผ๋กœ ์ฐพ์•„์„œ ๋˜‘๊ฐ™์ด ๋งŒ๋“ค์—ˆ๋Š”๋ฐ ๋‚˜๋Š” ๋ฐ์ดํ„ฐ ์ž…๋ ฅ๊ณผ ์ˆ˜์ • ์‚ญ์ œ๋ฅผ ํ•˜์ง€ ์•Š์•„์„œ crudํŒŒ์ผ์„ ๋‚˜์ค‘์—๋Š” ์‚ญ์ œํ•˜์˜€๋‹ค. ๊ทธ๋ž˜๋„ ์ฒซ๋‚ ๋ถ€ํ„ฐ์˜ ๊ณผ์ •์ด๋‹ˆ ๊ทธ๋ƒฅ ์ ๊ฒ ๋‹ค.

 

pip install sqlalchemy
pip install uvicorn
pip install fastapi

----------------------
pip install apscheduler

 

์œ„ 3๊ฐœ์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋จผ์ € ์„ค์น˜ํ•ด์ฃผ์—ˆ๋‹ค. ์Šค์ผ€์ค„๋Ÿฌ๋กœ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์‹คํ–‰์‹œํ‚ค์ง€ ์•Š์„๊ฑฐ๋ผ๋ฉด ์•„๋ž˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์„ค์น˜ํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

 

# crud.py

from sqlalchemy.orm import Session
import models, schemas

def get_users(db: Session):
    return db.query(models.Users).all()

crud.py ํŒŒ์ผ์€ ๊ฒŒ์‹œํŒ๋งŒ๋“ค๊ธฐ ํ• ๋•Œ ํ•ญ์ƒ ๋“ฃ๋Š” Create(์ƒ์„ฑ), Read(์ฝ๊ธฐ), Update(๊ฐฑ์‹ ), Delete(์‚ญ์ œ) ์ด๋‹ค.  ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด db์™€ ํ†ต์‹ ํ•˜๋Š” ํŒŒ์ผ์ด๋‹ค.

 

# database.py

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, Session

import settings


MAIN_DB_URL = f"mysql+pymysql://{settings.DB_ID}:{settings.DB_PW}@{settings.DB_IP}:{settings.DB_PORT}/{settings.DB_NAME}"
ACTION_DB_URL = f"mysql+pymysql://{settings.DB_ID}:{settings.DB_PW}@{settings.ACTION_DB_IP}:{settings.DB_PORT}/{settings.ACTION_DB_NAME}"

main_engine = create_engine(MAIN_DB_URL)
main_session_local = sessionmaker(autocommit=False, autoflush=False, bind=main_engine)
main_base = declarative_base()

action_engine = create_engine(ACTION_DB_URL)
action_session_local = sessionmaker(autocommit=False, autoflush=False, bind=action_engine)
action_base = declarative_base()

database.py ํŒŒ์ผ์—์„œ๋Š” database๋ฅผ ์—ฐ๊ฒฐ์‹œ์ผœ์„œ ์‚ฌ์šฉํ•˜๋Š” ํŒŒ์ผ์ด๋‹ค.

 

  • mysql+pymysql : mariadb๋ฅผ ์ง€์›ํ•˜๋Š” ๋ฒ„์ „์ผ ๊ฒฝ์šฐ
  • mariadb+pymysql : mariadb๋งŒ ์ง€์›ํ•˜๋Š” ๋ฒ„์ „์ผ ๊ฒฝ์šฐ
  • posgresql : postgreSQL์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ
MAIN_DB_URL = f"mysql+pymysql://{settings.DB_ID}:{settings.DB_PW}@{settings.DB_IP}:{settings.DB_PORT}/{settings.DB_NAME}"
์‚ฌ์šฉ์ž์ด๋ฆ„:์‚ฌ์šฉ์ž๋น„๋ฐ€๋ฒˆํ˜ธ@๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ฃผ์†Œ:๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์‚ฌ์šฉํ•˜๋Š” ํฌํŠธ๋ฒˆํ˜ธ/๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ด๋ฆ„

๋‚˜๋Š” mariaDB์™€ mysql ๋‘๊ฐœ๋ฅผ ์ง€์›ํ•ด์ฃผ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ผ์„œ ์œ„์™€ ๊ฐ™์ด ์ ์—ˆ๋‹ค. ์ž์„ธํžˆ ์•Œ๋ ค์ฃผ๋Š” ์‚ฌ๋žŒ์ด ์—†์–ด์„œ ๋Œ€์ถฉ ๋•Œ๋ ค ๋„ฃ์–ด๋ดค๋”๋‹ˆ ์ž˜๋˜์—ˆ๋‹ค. ์‚ฌ์šฉ์ž ์ด๋ฆ„๊ณผ ์•”ํ˜ธ๋Š” db์— ์ ‘์†ํ• ๋•Œ ์“ฐ๋Š” id์™€ pw๋ฅผ ์ ์œผ๋ฉด ๋œ๋‹ค. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ฃผ์†Œ๋Š” ๋กœ์ปฌ์ด๋ผ๋ฉด ๋กœ์ปฌ์ฃผ์†Œ๋ฅผ ์ ๊ณ , aws์—์„œ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด aws ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ IP๋ฅผ ์ ์œผ๋ฉด ๋œ๋‹ค. ํฌํŠธ๋ฒˆํ˜ธ๋Š” ๋”ฐ๋กœ ์„ค์ •ํ•ด์ฃผ์ง€ ์•Š์•˜๋‹ค๋ฉด 3306์ผ ๊ฒƒ์ด๋‹ค.

 

# main.py

from typing import List
import uvicorn

from fastapi import Depends, FastAPI, HTTPException
from sqlalchemy.orm import Session

import crud, models, schemas, settings
from database import main_session_local, main_engine, action_session_local, action_engine

models.main_base.metadata.create_all(bind=main_engine)

app = FastAPI()

# Dependency ์ด ํ•จ์ˆ˜๋กœ db๋ฅผ ์—ฐ๊ฒฐํ•˜๊ณ  ์ข…๋ฃŒํ•œ๋‹ค.
def get_main_db():
    db = main_session_local()
    try: yield db
    finally: db.close()

# api ํ˜ธ์ถœํ• ๋•Œ /get_users๋ฅผ ๋ถ™์ด๋ฉด ์—ฌ๊ธฐ๋กœ ์ฐพ์•„์™€์„œ ์•„๋ž˜ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰์‹œํ‚จ๋‹ค.
@app.get("/get_users")
def get_users(db: Session = Depends(get_main_db)):
    return crud.get_users(db)[:10]

if __name__ == '__main__':
    uvicorn.run(app, host='0.0.0.0', port=settings.PORT_NUMBER)

main.pyํŒŒ์ผ์—์„œ uvicorn์„ ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ๋˜๋Š”์ง€๋Š” ๋ชจ๋ฅด๊ฒ ๋‹ค. flask์—์„œ ์‚ฌ์šฉํ•˜์—ฌ ์“ฐ๋‹ค๋ณด๋‹ˆ ๊ทธ๋ƒฅ ๊ฐ€์ง€๊ณ  ์™”๋Š”๋ฐ ์กฐ๊ธˆ๋” ๊ณต๋ถ€ํ•ด๋ณด๊ณ  ์ˆ˜์ •ํ•ด๋ณด๋ ค ํ•œ๋‹ค.

 

 

 

728x90
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€