본문 바로가기
개발/파이썬 백엔드 프레임워크

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
반응형

댓글