pyproject.toml이 Python 프로젝트의 설정 파일이라면, Poetry는 이 파일을 기반으로 프로젝트의 의존성을 관리하고, 가상 환경을 구축하며, 패키지를 빌드하고 게시하는 모든 과정을 통합적으로 처리해주는 도구이다. 복잡한 프로젝트 설정과 의존성 지옥에서 벗어나 깔끔하고 효율적인 개발 환경을 만들고 싶다면 Poetry가 훌륭한 해답이 될 것이다.
1. Poetry 설치
Poetry는 Python 패키지이지만, 시스템에 독립적으로 설치하는 것을 권장한다. 왜냐하면 Poetry 자체의 의존성이 다른 프로젝트의 의존성과 충돌하는 것을 방지하기 위해서이다.
macOS / Linux / WSL:
curl -sSL https://install.python-poetry.org | python3 -
Windows (PowerShell):
(Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | python -
설치 후, Poetry의 실행 경로를 시스템 PATH에 추가해야 할 수 있다. 설치 스크립트가 안내하는 메시지를 참고하여 PATH를 설정한다. 설치가 완료되었는지 확인하려면 다음 명령어를 실행하면 된다.
poetry --version
2. 새 프로젝트 생성
Poetry를 사용하여 새로운 프로젝트를 시작하는 것은 매우 간단하다.
poetry new my-new-app
이 명령어는 my-new-app이라는 이름의 새로운 디렉토리를 생성하고, 그 안에 기본적인 프로젝트 구조를 만들어준다.
my-new-app/
├── my_new_app/
│ └── __init__.py
└── pyproject.toml
자동으로 생성된 pyproject.toml 파일은 다음과 같은 내용을 포함한다.
# my-new-app/pyproject.toml
[tool.poetry]
name = "my-new-app"
version = "0.1.0"
description = ""
authors = ["Your Name <you@example.com>"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.10" # 현재 시스템의 Python 버전에 따라 다를 수 있습니다.
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
새 프로젝트 디렉토리로 이동합니다.
cd my-new-app
3. 의존성 관리
Poetry는 강력한 의존성 관리 기능을 제공한다.
의존성 추가 (poetry add)
프로젝트에 새로운 라이브러리를 추가하고 싶다면 poetry add 명령어를 사용한다. 예를 들어, requests 라이브러리를 추가해 보자.
poetry add requests
이 명령어는 다음을 수행한다.
- 프로젝트의 가상 환경(없으면 자동 생성)에 requests를 설치한다.
- pyproject.toml 파일의 [tool.poetry.dependencies] 섹션에 requests를 추가한다.
- poetry.lock 파일을 업데이트한다. 이 파일은 프로젝트의 모든 의존성(직접 의존성 및 하위 의존성)의 정확한 버전을 기록하여, 다른 환경에서도 동일한 의존성 구성을 보장한다.
개발 전용 의존성(예: pytest, black)은 --group dev 옵션을 사용하여 추가할 수 있다.
poetry add pytest --group dev
poetry add black --group dev
pyproject.toml은 다음과 같이 업데이트된다.
# ... (생략) ...
[tool.poetry.dependencies]
python = "^3.10"
requests = "^2.31.0" # 추가된 requests
[tool.poetry.group.dev.dependencies] # dev 그룹 추가
pytest = "^7.4.0"
black = "^23.11.0"
의존성 설치 (poetry install)
프로젝트를 클론했거나 pyproject.toml에 새로운 의존성이 추가되었을 때, poetry.lock 파일에 명시된 정확한 버전의 의존성들을 설치하려면 다음 명령어를 사용한다.
poetry install
이 명령어는 pyproject.toml을 기반으로 가상 환경을 설정하고, poetry.lock 파일에 명시된 정확한 버전의 모든 의존성을 설치한다.
의존성 제거 (poetry remove)
프로젝트에서 더 이상 필요 없는 의존성은 poetry remove로 쉽게 제거할 수 있다.
poetry remove requests
poetry remove pytest --group dev
가상 환경
Poetry는 기본적으로 프로젝트별로 독립적인 가상 환경을 자동으로 생성하고 관리한다. 별도로 venv를 활성화할 필요 없이, Poetry 명령어(poetry run, poetry add 등)를 사용하면 해당 프로젝트의 가상 환경 내에서 작동한다.
가상 환경이 어디에 위치하는지 확인하려면:
poetry env info
특정 Python 버전을 가진 가상 환경을 사용하고 싶다면, 해당 Python 버전을 설치한 후 Poetry에 등록할 수 있다.
poetry env use python3.11
4. 스크립트 실행
Poetry 가상 환경 내에서 파이썬 스크립트를 실행하려면 poetry run 명령어를 사용한다.
poetry run python my_new_app/__init__.py
pyproject.toml에 커스텀 스크립트를 정의하여 더 편리하게 사용할 수도 있다. `[tool.poetry.scripts]` 섹션을 추가한다.
# pyproject.toml
# ... (생략) ...
[tool.poetry.scripts]
start = "my_new_app:main" # 'my_new_app' 모듈의 'main' 함수 실행
이제 poetry run start 명령어로 해당 스크립트를 실행할 수 있다.
poetry run start
위와 같이 [tool.poetry.scripts]를 설정하고 poetry run start를 실행할 때, ModuleNotFoundError나 "not installed as a script" 경고가 발생한다면, 다음 사항을 확인해야 한다.
- poetry install 실행 확인: pyproject.toml에 새로운 스크립트를 정의했거나, 프로젝트의 모듈 구조(예: src 디렉토리 추가/제거)를 변경했다면, 반드시 poetry install을 다시 실행하여 변경 사항을 Poetry 환경에 반영해야 한다. 이 과정에서 Poetry는 프로젝트의 자체 패키지를 가상 환경에 "설치"하여 Python이 해당 모듈을 찾을 수 있도록 한다.
- 진입점 (main 함수) 정의: my_new_app:main으로 설정했다면, my_new_app 패키지 내부(예: my_new_app/__init__.py 또는 src/my_new_app/__init__.py)에 main 함수가 정의되어 있거나, 다른 모듈에서 해당 함수를 임포트하여 노출시켜야 한다. 예를 들어, src/my_new_app/hello_world.py에 main 함수가 있다면:
# src/my_new_app/hello_world.py
def main():
print("Hello World!")
# ... (필요하다면 if __name__ == '__main__': main() 추가)
그리고 src/my_new_app/__init__.py에서 이 함수를 임포트하여 노출시킨다.
# src/my_new_app/__init__.py
from .hello_world import main
위의 해결 방법을 적용하고 poetry install을 다시 실행한 후 poetry run start를 시도해보면 해결될 것이다.
5. poetry install 이 필요한 이유
실제 main 함수 자체는 외부 패키지에 의존하지 않더라도, poetry install은 프로젝트 자체를 Poetry 가상 환경에 "설치"하는 역할을 한다.
- 프로젝트도 하나의 패키지이다: pyproject.toml의 [tool.poetry] 섹션에 name과 packages를 정의하는 순간, Poetry는 프로젝트(my_new_app)를 외부 패키지처럼 가상 환경에 "설치" 가능한 형태로 인식한다.
- Python의 모듈 탐색 경로 (sys.path): Python이 어떤 모듈(예: my_new_app)을 임포트하려면, 해당 모듈의 위치가 sys.path라는 모듈 탐색 경로에 포함되어 있어야 한다.
poetry install의 역할:
- poetry install 명령을 실행하면, Poetry는 pyproject.toml에 명시된 외부 의존성들(예: requests, pytest)을 설치한다.
- 가장 중요한 점은, 이 과정에서 Poetry는 프로젝트(my_new_app) 자체도 가상 환경의 site-packages 디렉토리(또는 그와 유사한 위치)에 "편집 가능(editable)" 모드로 설치한다. 이렇게 해야 Python 인터프리터가 my_new_app을 유효한 패키지로 인식하고 임포트할 수 있게 된다.
poetry run start의 작동 방식:
- pyproject.toml의 [tool.poetry.scripts] 섹션에 start = "my_new_app:main"이라고 정의하면, poetry run start는 Poetry가 활성화한 가상 환경 내에서 my_new_app 패키지를 임포트하고 그 안에 정의된 main 함수를 실행하라는 의미이다.
- 만약 poetry install을 하지 않았다면, my_new_app 패키지가 가상 환경에 "설치"되지 않았기 때문에 Python은 my_new_app이라는 모듈을 찾지 못하여 ModuleNotFoundError를 발생시킨다.
main 함수 내부에 외부 의존성이 없더라도, Poetry를 통해 프로젝트의 스크립트 진입점(my_new_app:main)을 실행하려면 Poetry가 프로젝트 자체를 가상 환경에 "임포트 가능한" 형태로 준비하는 과정인 poetry install 과정이 필요하다. 이 과정이 없으면 Python이 프로젝트의 모듈을 찾을 수 없게 된다.
6. 결론
Poetry는 pyproject.toml을 중심으로 Python 프로젝트의 의존성 관리, 가상 환경 구축, 빌드 및 스크립트 실행에 이르는 전반적인 과정을 통합하고 자동화하여 개발자의 생산성을 크게 향상시킨다.
단순한 스크립트를 넘어 체계적인 프로젝트 개발을 시작하길 원한다면, Poetry를 통해 깔끔하고 효율적인 개발 환경을 구축하고 pyproject.toml의 진정한 힘을 느껴보자.
'잡(job)기술' 카테고리의 다른 글
CMake --preset: 더 이상 길고 복잡한 빌드 명령어에 시달리지 말자 (1) | 2025.06.28 |
---|---|
pyproject.toml 시작하기: Python 프로젝트의 현대적 설정 파일 (2) | 2025.06.24 |
Node.js child_process의 exec와 spawn 차이 정리 (0) | 2025.06.20 |
pickle 모듈을 이용한 캐싱 관리 기법 (2) | 2025.06.18 |
TypeORM 마이그레이션 사용하기: 안전한 데이터베이스 관리를 위한 단계별 가이드 (0) | 2025.05.30 |