본문 바로가기

프로그래밍/language

setup.py vs requirements.txt

python을 통해 개발을 하기 시작했다면, 대부분 setup.py 와 requirements.txt가 존재하는 것을 알고 있을 것이다.

pypi 에서 확인해보면 라이브러리마다 setup.py와 requirements.txt 둘 중 하나만 사용하거나 둘 다 사용하는 경우가 존재한다.

이 포스트에서는 setup.py 와 requirements.txt의 역할의 차이를 살펴보고 흔히 알려져있는 오해에 대해서 다뤄보고자 한다.

 

필자는 처음 setup.py와 requirements.txt를 처음 사용할 때 이 두 매니저가 사실상 동일한 역할을 하고, 개발자의 취향에 따라 선택하는 정도인줄 알았다. 

 

requirements.txt 

requirements.txt 는 순수한 text 파일로 일반적으로 개발하고 있는 파이썬 어플리케이션에 의존성을 부여하는 라이브러리를 관리하는 역할을 한다. 예를 들어 python 어플리케이션 "A"를 개발하는데 필요한 라이브러리가 requests, beautifulsoap, flask 라고 가정했을 때 requirements.txt는 아래와 같이 작성될 수 있다.

requests==2.7.0
beautifulsoup==4.8.1
flask==1.1.1

 

이 후 pip install -r requirements.txt  명령어를 통해서 개발에 필요한 의존성 라이브러리를 설치하게 된다. 그래서 이 파일을 사용할 때 따라오는 이득은 매우 직관적인데 사용자가 일일히 필요한 라이브러리들을 pip install 명령어를 반복적으로 입력하며 사용할 수고를 덜어준다. 가령 특정 어플리케이션을 개발하는데 10개의 모듈이 필요하다고 가정했을 때 pip install -r requirements.txt 한 번으로 해결할 수 있음을 알려준다. 또한 모듈 옆에 버전을 명시할 수 있어서 한 번 버전 호환성을 맞춰놓으면 나중에 각 라이브러리들의 버전 때문에 고생할 일이 없어진다. 그리고 그것이 끝이다. requirements.txt는 단순히 사용자가 어플리케이션을 개발하는데 필요한 라이브러리를 설치하는 기능만 제공하기 때문에 프로젝트 내에서 현재 개발되고 있는 어플리케이션은 설치하지 못한다.

 

setup.py

하지만 setup.py는 좀 더 다양한 기능을 제공한다.

통상적으로 개발이 완료된 라이브러리를 배포할 때 필요한 몇 가지 메타데이터를 포함해야하는 경우가 있다. 예를 들어 이름, 버전, 의존성 모듈 등이 있는데 setup.py 는 이러한 메타데이터를 포함하는 기능을 제공한다.

from setuptools import setup

setup(
    name="jadehan",
    version="1.0",
    author="HanMinSoo"
    install_requires=[
        'requests==2.2.7',
        'beautifulsoup==4.8.1',
        'flask==1.1.1'
    ]
)

 

그러면 여기서 의문점이 생기는데 '어짜피 라이브러리 설치는 requirements.txt 뿐만 아니라 setup.py에서도 할 수 있는 기능인데 더 많은 기능을 제공하는 setup.py 로 통일 시키는게 낫지 않은가?' 라고 생각할 수 있겠지만 setup.py에는 한가지 문제 사항이 있다. install_requires 에 적혀있는 라이브러리들의 목록은 '어디에 있는 라이브러리'를 다운받을 것인가? 에 대한 문제를 해결해주지 않는다. 기본적으로 대부분의 python 라이브러리들은 pypi에 존재하겠지만, 다른 주소에 존재하는 라이브러리들을 다운받고 싶을 때는 달리 방도가 없다.

 

--index-url https://pypi.python.org/simple/

-e .

다시 requirements.txt로 넘어와서 보면 첫 행의 --index-url 은 라이브러리를 어느 경로에서 다운받을 것은 가를 결정해주는 역할을 한다. 일반적으로 -e . 명령어는 '.' 경로에 존재하는 라이브러리를 모두 설치하고 나서 --index-url에 명시된 주소를 활용하여 나머지 라이브러리들을 설치한다. 이 방식은 매우 효과적인데 예를 들어 jadehan이라는 어플리케이션을 만드는데 필요한 3개의 라이브러리 중에서 requests, falsk를 다른 경로에서 다운받기를 원한다고 가정해보자.

 

--index-url https://pypi.python.org/simple/

-e https://private.pypi.co.kr/requests
-e https://test-server.co.kr/flask
-e .

이렇게 지정할 경우, 먼저 지정된 경로에서 requests 와 flask 라이브러리를 설치한 이후 나머지 라이브러리를 --index-url에서 설치할 수 있게 된다.

 

참고

https://www.idkrtm.com/what-is-the-python-requirements-txt/

https://caremad.io/posts/2013/07/setup-vs-requirement/

https://stackoverflow.com/questions/43658870/requirements-txt-vs-setup-py