Python

poetry 1편 : poetry란? 의존성 관리하는 방법, 기본 사용법 및 설정 방법

vipDeveloper 2023. 12. 7. 14:15
반응형

안녕하세요, 오늘은 poetry 를 사용해서 

파이썬 프로젝트를 관리하는 방법에 관하여 글을 작성해볼까 합니다!

 

저도 사실 poetry 라는 것을 이번에 처음 써보게 되어 공부할 겸! 글을 작성하는 것이다 보니 부족한 부분이 많을 수 있습니다.

틀린 부분이나 추가적인 부분은 댓글로 남겨주시면 감사하겠습니다! 

1. poetry란?

Introduction
Poetry is a tool for dependency management and packaging in Python. 
It allows you to declare the libraries your project 
depends on and it will manage (install/update) them for you.
Poetry offers a lockfile to ensure repeatable installs, and can build
your project for distribution.

 

poetry 공식 사이트의 소개입니다! 

번역하자면 poetry는 python의 종속성 관리 및 패키징을 위한 도구로 이를 통해 프로젝트가 의존하는 라이브러리를 선언할 수 있으며 이를 관리(설치/업데이트)합니다. poetry는 반복 가능한 설치를 보장하기 위해 잠금 파일을 제공하고 배포용 프로젝트를 구축할 수 있습니다! 로 나와있습니다.ㅎ

 

중요한 포인트가 잘 소개되어 있네욥! 

종속성 관리도구 입니다! 

 

2. poetry 설치 및 사용 방법

1) poetry 설치

poetry 설치 pip로 설치하셔도 되고 brew 로 설치하셔도 됩니다. 그런데 일부의 경우 brew로 설치하였을때 문제가 발생하는 경우가 있어서 저는 pipx 로 설치하였습니다!

#pip로 설치
pip install poetry

#pipx로 설치
pipx install poetry

#brew로 설치
brew install poetry

 

2) poetry로 신규 프로젝트 생성하기

# poetry로 프로젝트 생성하기
poetry new poetry-project

그러면 다음과 같은 구조의 프로젝트 폴더가 생성됩니다.

poetry-project
├── pyproject.toml 
├── README.rst 
├── poetry_demo 
│   └── __init__.py 
└── tests 
	├── __init__.py 
    └── test_poetry_demo.py

 

3) 기존 프로젝트 폴더에서 pyproject.toml 파일 생성하기

# pyproject.toml 생성하기
poetry init

poetry init이란 명령어를 통해 가능합니다. 위 명령어를 치시면 해당 프로젝트에 맞는 pyproject.toml 파일을 작성할 수 있습니다. 

 

저의 진행 예시 입니다.

leehosung@LeeHosungui-MacBookPro  ~/PycharmProjects/test  poetry init

This command will guide you through creating your pyproject.toml config.

Package name [test]:  test
Version [0.1.0]:
Description []:
Author [test <test@test.com>, n to skip]:  -
License []:
Compatible Python versions [^3.11]:

Would you like to define your main dependencies interactively? (yes/no) [yes]
You can specify a package in the following forms:
  - A single name (requests): this will search for matches on PyPI
  - A name and a constraint (requests@^2.23.0)
  - A git url (git+https://github.com/python-poetry/poetry.git)
  - A git url with a revision (git+https://github.com/python-poetry/poetry.git#develop)
  - A file path (../my-package/my-package.whl)
  - A directory (../my-package/)
  - A url (https://example.com/packages/my-package-0.1.0.tar.gz)

Package to add or search for (leave blank to skip):

Would you like to define your development dependencies interactively? (yes/no) [yes]
Package to add or search for (leave blank to skip):

Generated file

[tool.poetry]
name = "test"
version = "0.1.0"
description = ""
authors = ["-"]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.11"


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


Do you confirm generation? (yes/no) [yes]

 

그러면 패키지는 어찌 추가할까요?

 

3. 패키지 추가하기 

# 패키지 추가 명령어
poetry add 패키지명

 

4. poetry로 의존성 관리하기

requirements.txt 파일로 관리하면 되지 않나..?

보통 개발을 하다보면 패키지들을 설치하게 되는데 이때 많은 분들이 pip로 설치하고

pip freeze > requirements.txt

위와 같은 명령어로 requirements.txt file을 만들어서 관리합니다. 그런데 이러한 방식은 여러가지 불편한 점을 가져오게 합니다. 그 중에 제가 느끼는 가장 큰 불편한 점은 실제 사용되는 라이브러리와 의존성으로 인해 설치된 라이브러리들이 불명확해 진다는 것 입니다.

 

예를 들어 pip 로 fastapi를 설치하고 이 설치 패키지 목록을 requierments.txt로 생성하면 아래와 같은 내용으로 생성될 것입니다.

 

패키지 설치

pip install fastapi
 ✘ leehosung@LeeHosungui-MacBookPro  ~/PycharmProjects/test  pip install fastapi
Collecting fastapi
  Downloading fastapi-0.104.1-py3-none-any.whl.metadata (24 kB)
Collecting anyio<4.0.0,>=3.7.1 (from fastapi)
  Downloading anyio-3.7.1-py3-none-any.whl.metadata (4.7 kB)
Collecting pydantic!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0,>=1.7.4 (from fastapi)
  Downloading pydantic-2.5.2-py3-none-any.whl.metadata (65 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 65.2/65.2 kB 5.8 MB/s eta 0:00:00
Collecting starlette<0.28.0,>=0.27.0 (from fastapi)
  Downloading starlette-0.27.0-py3-none-any.whl.metadata (5.8 kB)
Collecting typing-extensions>=4.8.0 (from fastapi)
  Downloading typing_extensions-4.8.0-py3-none-any.whl.metadata (3.0 kB)
Collecting idna>=2.8 (from anyio<4.0.0,>=3.7.1->fastapi)
  Using cached idna-3.6-py3-none-any.whl.metadata (9.9 kB)
Collecting sniffio>=1.1 (from anyio<4.0.0,>=3.7.1->fastapi)
  Downloading sniffio-1.3.0-py3-none-any.whl (10 kB)
Collecting annotated-types>=0.4.0 (from pydantic!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0,>=1.7.4->fastapi)
  Downloading annotated_types-0.6.0-py3-none-any.whl.metadata (12 kB)
Collecting pydantic-core==2.14.5 (from pydantic!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0,>=1.7.4->fastapi)
  Downloading pydantic_core-2.14.5-cp311-cp311-macosx_11_0_arm64.whl.metadata (6.5 kB)
Downloading fastapi-0.104.1-py3-none-any.whl (92 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 92.9/92.9 kB 11.7 MB/s eta 0:00:00
Downloading anyio-3.7.1-py3-none-any.whl (80 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 80.9/80.9 kB 13.1 MB/s eta 0:00:00
Downloading pydantic-2.5.2-py3-none-any.whl (381 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 381.9/381.9 kB 23.5 MB/s eta 0:00:00
Downloading pydantic_core-2.14.5-cp311-cp311-macosx_11_0_arm64.whl (1.7 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.7/1.7 MB 46.5 MB/s eta 0:00:00
Downloading starlette-0.27.0-py3-none-any.whl (66 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 67.0/67.0 kB 9.2 MB/s eta 0:00:00
Downloading typing_extensions-4.8.0-py3-none-any.whl (31 kB)
Downloading annotated_types-0.6.0-py3-none-any.whl (12 kB)
Using cached idna-3.6-py3-none-any.whl (61 kB)
Installing collected packages: typing-extensions, sniffio, idna, annotated-types, pydantic-core, anyio, starlette, pydantic, fastapi
Successfully installed annotated-types-0.6.0 anyio-3.7.1 fastapi-0.104.1 idna-3.6 pydantic-2.5.2 pydantic-core-2.14.5 sniffio-1.3.0 starlette-0.27.0 typing-extensions-4.8.0

 

추출된 목록

 leehosung@LeeHosungui-MacBookPro  ~/PycharmProjects/test  cat requirements.txt
annotated-types==0.6.0
anyio==3.7.1
fastapi==0.104.1
idna==3.6
pydantic==2.5.2
pydantic_core==2.14.5
sniffio==1.3.0
starlette==0.27.0
typing_extensions==4.8.0

 

fastapi하나 설치했을 뿐인데 많은 의존하고 있는 많은 패키지들이 같이 설치되고 있습니다. 이 프로젝트를 배포할 경우 어떤것이 사용하려 설치한 패키지이고 어떤것이 의존성에 의해 설치된 패키지인지 뚜렷하게 구분이 가지 않습니다. 만약 poetry를 사용한다면?

 ✘leehosung@LeeHosungui-MacBookPro  ~/PycharmProjects/test  poetry add fastapi
Using version ^0.104.1 for fastapi

Updating dependencies
Resolving dependencies... (0.3s)

Package operations: 9 installs, 0 updates, 0 removals

  • Installing idna (3.6)
  • Installing sniffio (1.3.0)
  • Installing typing-extensions (4.8.0)
  • Installing annotated-types (0.6.0)
  • Installing anyio (3.7.1)
  • Installing pydantic-core (2.14.5)
  • Installing pydantic (2.5.2)
  • Installing starlette (0.27.0)
  • Installing fastapi (0.104.1)

Writing lock file

 

Writing lock file, lock(poetry.lock) 파일이 생성 된 것을 확인 할 수 있습니다.

 

pyproject.toml 을 보게되면 실제로 poetry를 통해 명시적으로 설치한 패키지 목록이 정리되어 있습니다. 그럼 해당 패키지의 의존성으로 인해 설치된 패키지의 정보는 어디있을까요? 바로 poetry.lock파일 입니다! 

 leehosung@LeeHosungui-MacBookPro  ~/PycharmProjects/test  cat pyproject.toml
[tool.poetry]
name = "test"
version = "0.1.0"
description = ""
authors = ["-"]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.11"
fastapi = "^0.104.1"


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

 

poetry.lock 파일의 일부를 보면 아래와 같습니다.

[[package]]
name = "fastapi"
version = "0.104.1"
description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
optional = false
python-versions = ">=3.8"
files = [
    {file = "fastapi-0.104.1-py3-none-any.whl", hash = "sha256:752dc31160cdbd0436bb93bad51560b57e525cbb1d4bbf6f4904ceee75548241"},
    {file = "fastapi-0.104.1.tar.gz", hash = "sha256:e5e4540a7c5e1dcfbbcf5b903c234feddcdcd881f191977a1c5dfd917487e7ae"},
]

[package.dependencies]
anyio = ">=3.7.1,<4.0.0"
pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0"
starlette = ">=0.27.0,<0.28.0"
typing-extensions = ">=4.8.0"

 

이런식으로 의존성으로 인해 설치된 패키지들을 알수있습니다.

poetry에서는 poetry.lock 파일을 통해 패키지의 의존성을 관리하며 이 lock file만 공유하면 poetry가 설치되어 있는 환경에서 모든 패키지를 동일한 버전으로 설치할 수 있게 됩니다.

 

추가적으로 poetry는 dev, 즉 개발용 패키지를 별도로 관리할 수 있습니다! 이는 개발 환경 -D 옵션을 붙이면 됩니다.

- poetry -D add 패키지_명

leehosung@LeeHosungui-MacBookPro  poetry -D add flask

The --dev option is deprecated, use the `--group dev` notation instead.
Using version ^3.0.0 for flask

Updating dependencies
Resolving dependencies... (0.2s)

Package operations: 7 installs, 0 updates, 0 removals

  • Installing markupsafe (2.1.3)
  • Installing blinker (1.7.0)
  • Installing click (8.1.7)
  • Installing itsdangerous (2.1.2)
  • Installing jinja2 (3.1.2)
  • Installing werkzeug (3.0.1)
  • Installing flask (3.0.0)

Writing lock file

leehosung@LeeHosungui-MacBookPro  cat pyproject.toml

[tool.poetry]
name = "test"
version = "0.1.0"
description = ""
authors = ["-"]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.11"
fastapi = "^0.104.1"


[tool.poetry.group.dev.dependencies]
flask = "^3.0.0"

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

 

보시는 것과 같이 tool.poetry.group.dev.dependencies에 별도로 관리 됩니다! 이전에 프로젝트를 진행 할 때 개발환경에선 퍼포먼스 테스트와 측정을 위해 몇몇 패키지들을 사용했는데 사실 실 서비스시 사용할 패키지들은 아니였습니다. ㅎ 이런 경우 사용하면 좋았을 것 같다는 생각이 들었습니다!

 

오늘은 여기까지 작성하고 2편에서는 poetry 로 가상환경을 사용하는 방법을 적어볼까 합니다. 감사합니다 뿅..~

반응형