[Python] requirements.txt 작성하기
협업을 하다보면 requirements.txt 를 통해 본인이 실험하고 있는 환경에 대한 정보를 전달할 때가 존재한다. 가장 확실한 방법은 Dockerfile을 공유하여 docker image를 pull해서 서로 같은 가상환경 내에서 작업을 하는 것이다. 그러나, 가상환경을 잡고 하는 부분은 처음 시작하는 사용자에게는 어려울 수 있고, 해당 언어에 대한 내용을 알아야 사용할 수 있기 때문에 requirements.txt를 사용하게 된다. (추가로 poetry를 사용하여 버전 freeze를 할 수도 있다.)
그렇다면 requirements.txt를 어떻게 작성하는지에 대해서 알아보자. 예를 들어 pandas 를 설치하게 된다면 아래와 같은 코드를 사용하여 설치할 것이다.
!pip install pandas
단순히 버전 명시 없이 pandas를 설치하게 되면 가장 최신 버전(latest)의 pandas가 설치될 것이다. 그러나, 같이 협업하는 사람은 옛날 버전의 pandas를 사용해서 현재 버전에 추가가 된 함수나 명령어에 차이가 존재할 수 있다. 그렇기 때문에 pandas의 버전이 어떻게 되는지를 명시해야 한다.
각 package의 버전을 확인하는 방법은 간단하다.
import pandas as pd
pd.__version__
# 2.3.1
위 코드로 쉽게 pandas의 버전을 확인할 수 있다. 지금까지 pandas의 버전을 확인하는 법을 다루었다. 그렇다면 requirements.txt는 어떻게 작성하는 것일까? 매우 간단하다. 같은 경로에 requirements.txt라는 파일을 생성하고 하기 내용 처럼 작성하기만 하면 된다.
# requirements.txt
pandas==2.3.1
추가하고 싶은 package가 있다면 아래에 계속해서 작성해주면 된다. 그러나 package를 하나하나 버전을 확인하고 requirements.txt를 작성하는 것은 매우 번거로운 작업이다. 따라서, 아래와 같은 코드를 작성하면 package 이름만 넣어서 바로 requirements.txt를 작성할 수 있다.
import os
from pandas as pd, numpy as np
BASE_DIR = os.path.dirname(__file__)
def package_version_check(packs, requirements=False, base_path=None) -> None:
versions = dict()
if isinstance(packs, list):
for pack in packs:
print(f'{pack.__name__} version: {pack.__version__}')
versions[pack.__name__] = pack.__version__
else:
print(f'{packs.__name__} version: {packs.__version__}')
versions[pack.__name__] = pack.__version__
if requirements:
base_path = os.path.dirname(__file__) if not base_path else base_path
with open(os.path.join(BASE_DIR, 'requirements.txt'), 'w') as f:
for pack, ver in versions.items():
f.write(f'{pack}=={ver}\n')
package_version_check([pd, np], requirments=True)
자동으로 requirements.txt를 생성하고, 적재한 위치에 package별 version을 명시해서 작성한다. 만약 모든 package에 대해서 한꺼번에 requirements.txt를 작성하는 것은 매우 번거로운 작업이다. 이를 해결하는 방법은 cmd 창에서 코드 한줄로 가능하다.
pip3 freeze > requirements.txt
가상환경 내에 접근해서 위 명령어를 작성하게 되면 해당 경로에 requirements.txt가 바로 작성된다. 만약 특정 패키지에 대해서 명시하고 주석을 작성하면서 만들고 싶은 경우에는 위 함수를 사용해서 적용이 가능하지만, 일괄 적용하고 싶은 경우에는 freeze를 사용하는 것이 유용할 수 있다.