본문 바로가기
프로젝트 개발 기록/[개발] trouble shooting

파이썬 가상 환경(virtualenv)과 Flask 서버 구축, pip freeze vs pipreqs

by HelloJudy 2022. 6. 18.

파이썬을 사용하여 프로젝트를 진행할 때엔 가상 환경을 구축한 뒤 개발을 권장하고 있다.

가상 환경을 구축하여 프로젝트를 하는 이유는 프로젝트 마다 라이브러리의 버전이 다를 수 있기 때문에 프로젝트 내에 버전을 일치시켜 독립적으로 개발하기 위해서이다.

 

출처: 코딩도장

 

1. 설치

 

$ pip install virtualenv

 

 

2. 프로젝트 폴더 생성

 

$ virtualenv "프로젝트폴더명"

 

나는 프로젝트 이름을 app 으로 했다.

 

 

이렇게 폴더가 생성된다.

 

 

3. 가상환경 시작

 

위에서 생성한 app 폴더로 cd app 해서 다음 명령어를 실행한다.

그러면 가상환경이 시작된다.

가상환경 명이 (app) 처럼 뜬다면 정상적으로 실행된 것이다.

 

$ source ./Scripts/activate

 

 

이제 여기서 원하는 패키지를 설치하면 된다.

 

$ pip install Flask

 

 

4. 파이썬 Flask 기본 어플리케이션

 

가상환경을 접속한 상태에서 Flask 서버를 구축해보자.

 

먼저 파이썬 파일을 만들어 보자!

위에서 생성한 app 폴더 내에서 생성하면 안되고, 프로젝트 폴더 기준 root 경로에 만들어야한다.

 

 

👉 공식 문서

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello World!'

if __name__ == '__main__':
    app.run()

 

코드를 작성한 뒤 아래 명령어로 실행하면 서버 구축이 완료된다.

 

$ python app.py

 

 

5. 패키지 목록 관리하기

내가 구축한 flask 환경과 코드 실행을 위한 다양한 패키지들을 다른 팀원이 새로운 환경에서 동일한 버전으로 실행했으면 했다.

개발을 하다보면 패키지 버전 업데이트에 따른 오류가 발생하기도 한다.

이는 운영의 안정성을 떨어뜨리고, 예상치 못한 상황을 발생시킬 수 있기 때문에 특정 버전으로 패키지를 고정하여 개발자들과 개발하는 것이 필요하다.

 

그래서 패키지 목록을 관리하는 requirements.txt 파일을 만든다. 그리고 Git Hub에는 requirements.txt 파일과 코드 실행 파일만 공유한다.

 

그래서 팀원이 코드를 pull 해온 다음 가상환경을 세팅한 다음 requirements.txt에 있는 패키지를 설치하여 동일한 버전으로 프로젝트를 개발할 수 있다.

 

(node 개발에서 package.json 관리해주는 것 같다.)

 

# 다음과 같이 requirements.txt로 패키지를 모두 깔아줍니다.
$ pip install -r requirements.txt

 

그럼 requirements.txt은 어떻게 만들까.

 

✔️ (방법1) freeze - 추천하지 않는다.

 

# freeze를 통해 설정파일의 버전 정보 리스트를 확인
$ pip freeze
# 확인하는 방법2
$ pip list
# 해당 내용을 requirements.txt에 넣어 생성해줍니다. 
$ pip freeze > requirements.txt

 

가장 많이 사용하는 pip는 node에서 npm 패키지 매니저와 동일한 역할을 한다. 

마지막 명령어를 실행하면 requirements.txt 파일이 만들어진다. 이 파일로 사용하는 패키지를 한 번에 설치할 수 있다.

 

  • requirements.txt
certifi==2022.5.18.1
cffi==1.15.0
charset-normalizer==2.0.12
click==8.1.3
colorama==0.4.5
cryptography==37.0.2
docopt==0.6.2
Flask==2.1.2
Flask-Cors==3.0.10
gunicorn==20.1.0
idna==3.3
importlib-metadata==4.11.4
itsdangerous==2.1.2
Jinja2==3.1.2
joblib==1.1.0
JPype1==1.4.0
konlpy==0.6.0
lxml==4.9.0
MarkupSafe==2.1.1
numpy==1.22.4
pandas==1.4.2
pipreqs==0.4.11
pycparser==2.21
PyJWT==2.4.0
PyMySQL==1.0.2
python-dateutil==2.8.2
python-dotenv==0.20.0
pytz==2022.1
requests==2.28.0
scikit-learn==1.1.1
scipy==1.8.1
six==1.16.0
sklearn==0.0
threadpoolctl==3.1.0
urllib3==1.26.9
Werkzeug==2.1.2
wincertstore==0.2
yarg==0.1.9
zipp==3.8.0

 

freeze 명령어로 간편하게 파일을 만들었다. 그런데 뚜둥...!

내가 이렇게 많은 패키지를 썼던가?? 🤔

 

역시 현재 프로젝트에서 사용하지 않는 패키지까지 들어와 있다.

그래서 이 파일을 본 다른 개발자는 어떤 패키지가 프로젝트에서 사용되는지 한 눈에 확인하기 어렵다.

 

[ freeze의 단점 ]

 

위와 같이 많은 패키지가 나온 이유는 한 패키지를 설치할 때 그에 의존하고 있는 패키지가 함께 설치되기 때문이다.

 

예를 들어 현재 flask를 설치한다고 생각해보자.

 

$ pip install flask

다음과 같이 입력하면 flask만 설치되는 것이 아니라 flask가 의존하고 있는 Jinja2 , MarkupSafe 등 다른 패키지도 함께 설치된다.

그럼 자연스럽게 현재 프로젝트에서 사용하지 않을 위 두 패키지도 requirements.txt에 포함된다.

 

그런데 이것만으로 문제를 아니다.

 

예를 들어 내가 해당 패키지의 버전을 업데이트한다.

 

$ pip install -U flask

 

그럼 여기에 종속되는 패키지들의 버전 또한 변한다. 

그리고 다시 requirements.txt를 만들면 의존 패키지가 이전에 버전과 새로운 버전 모두 가지고 있다.

 

출처: 조마다 케이타 (https://towardsdatascience.com/goodbye-pip-freeze-welcome-pipreqs-258d2e7a5a62)

 

이것은 종속성 관리가 효율적으로 보이지 않는다.

또한 가상환경을 사용하지 않는 경우 다른 프로젝트 환경의 패키지까지 가지고 온다.

 

 

정리

  • 현재 프로젝트에서 사용하지 않는 패키지를 포함하여 python에 의존걸린 모든 패키지들을 넘겨줘서 저장된다.
  • pip install을 사용하지 않고 설치한 패키지는 포함되지 않는다.
  • (가상 환경을 사용하지 않는 경우) 다른 프로젝트 환경의 패키지까지 가지고 온다.

 

 

✔️ (방법2) pipreqs - 추천

그래서 pipreqs로 위 문제를 해결할 수 있다.

pipreqs는 프로젝트의 모든 Python 파일(.py)을 스캔하여 import 기반으로 requirements.txt 파일을 생성한다.

 

👉 문서 확인하기

 

  • Installation
$ pip install pipreqs

 

  • Usage
$ pipreqs /home/project/location
Successfully saved requirements file in /home/project/location/requirements.txt

기본은 현재 디렉토리이다.

 

  • Conda에서 
conda list -e > requirements.txt

 

[ 잠시 window에서 생길 수 있는 오류 ]

 

UnicodeDecodeError: 'cp949' codec can't decode byte 0xec in position 237: illegal multibyte sequence

 

이때는 아래 명령어로 실행해주면 된다.

 

pipreqs --encoding=utf8 <project-root-path>

 

결과

 

아래 사진과 같이 필요한 패키지만 간결하게 입력된 것을 확인할 수 있다.

 

 

 

패키지 설치

# 다음과 같이 requirements.txt로 패키지를 모두 깔아줍니다.
$ pip install -r requirements.txt

 

 


📌 Reference

반응형

댓글