Poetry) poetry를 사용하여 외부/내부 repository의 의존성을 고려하여 패키지 목록 관리 및 다운로드 하기

2024. 6. 22. 15:24분석 Python/Packages

패키지 개발을 할 때 잘 안 되는 점 중에서 하나는 다른 환경에서 동일하게 설치할 경우 설치가 잘 안 되는 경우가 있다.

항상 패키지를 설치하다보면 내 환경에서는 되지만 다른 사람에게 해당하는 경우를 전달해도, 다른 의존성으로 인해 설치가 안 되는 경우를 자주 경험했다.

 

그리고 내부 레포지토리가 있고 외부 레포지토리 2개가 있을 경우에도 우선적으로는 내부 레포지토리를 기반으로 의존성이 나오면 좋겠으면 고민했다가 해당 방식으로 하면 괜찮을 것 같아서 공유한다.

 

괜찮을 것 같다고 한 것은 실제로 테스트를 많이 해보지 않아서 다른 사람들에게는 안될 수 있기 때문이다.

개선 사항이 있다면 댓글에 남겨주시면 반영해보겠다!

 

참고로 필자는 poetry를 많이 사용하지 않아서 다른 디테일한 설정을 잘 몰라서... 알려주시면 공부하겠습니다.

 

나의 환경 

os : linux (ubuntu)

python : 3.8.10

requirements.txt 파일 존재

click==7.1.2
polyaxon==1.8.4
Jinja2==3.1.2
Markdown==3.4.3
numpy==1.23.5
pandas==1.4.4
Pillow==10.3.0
PyYAML==6.0.1
tritonclient==2.33.0
termcolor
temp-api # 내부 레포지토리에만 있는 패키지
joblib==1.2.0
python-gitlab==3.14.0
  • 위의 requirements.txt 에 보면 내부에서 가져올 것과 외부에서 가져올 것이 존재한다.

 

1. 기본 index_url이 내부 레포지토리로 되어있어서 poetry가 설치 안 되는 경우

아마 보통 다들 이렇게 설치할 텐데 이때 poetry를 설치하는데 만약 내부 레포지토리에 없다면 에러가 날 것이다.

curl -sSL https://install.python-poetry.org | python3
sudo apt install python3-poetry

 

그때는 다음과 같이 해결하면 된다.

 

1. 설치 파일을 우선 다운로드

curl -sSL https://install.python-poetry.org -o install-poetry.py

 

2. 안에서 index-url 추가

 

기존에 install_poetry 부분에서 다음과 같이 url을 추가해 주는 작업을 한다.

    def install_poetry(self, version: str, env: VirtualEnvironment) -> None:
        self._install_comment(version, "Installing Poetry")

        if self._git:
            specification = "git+" + version
        elif self._path:
            specification = version
        else:
            specification = f"poetry=={version}"

        # env.pip("install", specification)
            # pip 명령어에 --index-url 옵션 추가
        index_url = "https://pypi.org/simple"
        env.pip("install", specification, "--index-url", index_url)

3. 설치

python3 install-poetry.py

 

2. Poetry 설정

 

1. poetry 초기화

poetry init

 

이건 알아서 따다닥 누르면 pyproject.toml 이 나올 것이다.

[tool.poetry]
name = "support"
version = "0.1.0"
description = ""
authors = ["srlee <x@xx>"]
readme = "README.md"

[tool.poetry.dependencies]
python = "3.8.10"  # Python 3.8로 제한


[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

2. source 경로 추가 (pyproject.toml)

  • "http://xx/xx/pypi-hosted/simple"
    • 해당 url이 내부 레포지토리 
    • primary
  • "https://pypi.org/simple"
    • 해당 url이 외부 레포지토리
    • secondary

 

이런 식으로 우선순위를 정할 수 있다.

 

[[tool.poetry.source]]
name = "devainexus"
url = "http://xx/xx/pypi-hosted/simple"
priority = "primary"  # 기존 default를 primary로 변경

[[tool.poetry.source]]
name = "custom-repo"
url = "https://pypi.org/simple"
priority = "secondary"

 

chatgpt에 물어보니 다음과 같다.

결국에는 우선순위를 정해서 탐색할 수 있다는 소리를 하는 것 같다.

priority 설정의 작동 방식
pyproject.toml 파일에서 저장소 우선순위를 설정하면, Poetry는 패키지를 검색하고 설치할 때 각 저장소의 우선순위를 고려합니다. priority 설정은 다음과 같은 값들을 가질 수 있습니다:

default: 기본 우선순위.
primary: 가장 높은 우선순위. 이 설정이 적용된 저장소는 가장 먼저 패키지를 검색합니다.
secondary: 중간 우선순위. primary 저장소에서 패키지를 찾지 못한 경우에만 사용됩니다.
supplemental: 보조 우선순위. 주로 특정 패키지를 보완하기 위해 사용됩니다.
explicit: 명시적 우선순위. 명시적으로 지정된 경우에만 사용됩니다.

3. requirements.txt 추가하기 

이걸 하면 의존성을 맞춰서 쭈르륵 설치가 된다.

poetry add $(cat ./requirements.txt)

만약 requirements.txt 에 내용이 추가된다면?

이런 식으로 할 수도 있다고 한다 참고만!

poetry remove $(cat ./requirements.txt)
poetry add $(cat ./requirements.txt)

 

 

4. requirements.txt 에 의존성을 추가해서 다시 requirements.txt 만들기

이런 식으로 기존에 requirements.txt를 이용해서 새롭게 requirements.txt 를 만드는데, 이때 의존성은 나의 다른 환경 정보를 참고해서 더 구체적으로 만들어진다.

여기까지만 작업해도 내가 원하는 패키지 목록을 의존성을 고려해서 다시 만들 수 있다
poetry export -f requirements.txt --output requirements_new.txt

 

상단에 보면 이런 식으로 나오게 된다.

여기에는 내가 쓰는 환경을 3.8.10으로 고정해서 저렇게 고정해서 얻게 된다.

 

--trusted-host xxx
--index-url http://xxx/xx/pypi-hosted/simple
--extra-index-url https://pypi.org/simple

appnope==0.1.4 ; sys_platform == "darwin" and python_full_version == "3.8.10" \
    --hash=sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee \
    --hash=sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c

 

5. 새로운 requirements.txt를 이용해서 패키지 목록 다운로드 하기

그러면 이 패키지 목록이 내가 사용하는 내부 레포지토리에도 옮겨줘야 내부 레포지토리만 이용해서 패키지를 설치할 수 있게 된다.

그래서 패키지 설치를 작업하면 다음과 같다.

mkdir ./packages
pip download -r ./requirements.txt -d ./packages/

 

 

6, 패키지 설치 (로컬)

패키지 설치를 로컬만 할 경우 다음과 같다.

pip install --no-index --find-links=./packages -r requirements.txt

 

결론

만약 내가 패키지를 추가할 때 다음과 같이 작업을 하면 애가 의존성을 고려한다.

 poetry add pycaret[full]@3.1.0

 

가장 좋은 점을 설치를 하기 전에 미리 체크를 하기 때문에 마구잡이로 설치하다가 발생하는 꼬임 현상은 방지할 수 있는 것 같고 관리도 용이해 보인다.

이렇게 정리하다 보니 패키지 의존성 관련해서는 잘 해결해 줄 것 같다는 생각이 든다.

 

728x90