robert-min / performance_go_python_api

Performance test : python HTTP vs Go HTTP vs Go HTTP + gRPC
0 stars 0 forks source link

Python Flask 서버 구축 #4

Open robert-min opened 1 year ago

robert-min commented 1 year ago

Python Flask 서버 구축

서버 코드 경로

요청을 받는 서버 1 : ./python_api DB 핸들링 서버 2 : ./python_api_db

📌 To do list

robert-min commented 1 year ago

python venv 가상환경 구축

python -m venv .venv

echo '.venv' >> .gitignore

# 가상환경 실행
. .venv/bin/activate

# Python version 확인
python -V
robert-min commented 1 year ago

Python 배포 준비

Python 배포를 위한 Dockerfile 작성

FROM ubuntu:20.04

ARG EXPOSE_PORT=8000
EXPOSE $EXPOSE_PORT/tcp
ARG PYTHON_VERSION=3.8
ARG CONDA_DIR=/opt/conda

USER root
RUN apt-get update -y && apt-get upgrade -y && \
apt-get install -y --no-install-recommends && \ 
apt-get install -y python3-dev python3-pip && apt install curl -y

# install python
SHELL ["/bin/bash", "-c"]
RUN curl -o ~/miniconda.sh https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh && \
    chmod +x ~/miniconda.sh && \
    bash ~/miniconda.sh -b -p ${CONDA_DIR} && \
    rm ~/miniconda.sh && \
    ${CONDA_DIR}/bin/conda install -y python=${PYTHON_VERSION} && \
    ${CONDA_DIR}/bin/conda clean -ya
ENV PATH ${CONDA_DIR}/bin:${PATH}

SHELL ["/bin/bash", "-c"]
RUN mkdir /home/user
ENV HOME_PATH=/home/user
ARG APP_NAME=python_api
ARG MODULE_PATH=${HOME_PATH}/${APP_NAME}
WORKDIR ${MODULE_PATH}

COPY app.py ${MODULE_PATH}/app.py
COPY backend ${MODULE_PATH}/backend
COPY requirements.txt ${MODULE_PATH}/requirements.txt

RUN pip install -r ${MODULE_PATH}/requirements.txt

EXPOSE ${EXPOSE_PORT}
RUN cd ${MODULE_PATH}

CMD ["gunicorn", "app:app", "--timeout", "15", "--bind", "0.0.0.0:8000"]

Dockerfile 빌드 및 실행

## Dockerfile이 있는 경로에서
docker build -t python_api .

## 실행
docker run -d -p 8000:8000 --name python_api python_api

## 종료
docker rm -f python_api
robert-min commented 1 year ago

SQLAlchemy 활용한 DB conneciton 추가

python_api_db/lib/model.py

from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
from sqlalchemy import VARCHAR

class Base(DeclarativeBase):
    pass

class Movies(Base):
    __tablename__ = "movies"

    seq: Mapped[int] = mapped_column(primary_key=True, autoincrement=True, nullable=False)
    name: Mapped[str] = mapped_column(VARCHAR(200), nullable=False)
    movie_id: Mapped[str] = mapped_column(VARCHAR(200), nullable=False)
    rating: Mapped[str] = mapped_column(VARCHAR(200), nullable=False)
    timestamp: Mapped[str] = mapped_column(VARCHAR(200), nullable=False)

    def __repr__(self) -> str:
        return f"User(name={self.name}"
python_api_db/lib/db_connect.py

from . import DB_CONNECTION
from sqlalchemy import create_engine, select
from sqlalchemy.orm import Session
from flask_restx import abort
from model import Movies

class MySQLManager:
    """
    Database Manager
    """

    def __init__(self, env) -> None:
        user = DB_CONNECTION[env]['user']
        passwd = DB_CONNECTION[env]['passwd']
        host = DB_CONNECTION[env]['host']
        port = DB_CONNECTION[env]['port']
        db = DB_CONNECTION[env]['db']
        charset = DB_CONNECTION[env]['charset']
        engine = create_engine(f"mysql+pymysql://{user}:{passwd}@{host}:{port}/{db}?{charset}",
                                echo=False)

        self.session = Session(engine)

    def insert_movie(self, name, movie_id, rating, timestamp):
        """
        Insert movie data to movies table on robertmin db.
        """
        try:
            with self.session as session:
                content = Movies(
                    name=name,
                    movie_id=movie_id,
                    rating=rating,
                    timestamp=timestamp
                )
                session.add(content)
                session.commit()

        except Exception as e:
            return abort(404, status="Fail", message="Problems to DB connection", result=e)

        return name

    def get_all_movies(self):
        """
        Get all movies from movies table on robertmin db
        """
        try:
            all_movies = list()
            with self.session as session:
                sql = select(Movies)
                for row in session.execute(sql):
                    all_movies.append({
                        "name": row.Movies.name,
                        "movie_id": row.Movies.movie_id,
                        "rating": row.Movies.rating,
                        "timestamp": row.Movies.timestamp
                    })

        except Exception as e:
            return abort(404, status="Fail", message="Problems to DB connection", result=e)

        return all_movies
robert-min commented 1 year ago

Dockerfile 빌드 및 실행

## 이미지 생성
sudo docker build -t python_api ./python_api
sudo docker build -t python_api_db ./python_api_db 

## network 생성
sudo docker network create --driver bridge python

## 실행
sudo docker run -d -p 8000:8000 --name python_api --network python python_api
sudo docker run -d -p 8080:8080 --name python_api_db --network python python_api_db

## 종료
sudo docker rm -f python_api