Pyhton/python

UV 파이썬 패키지 관리의 새로운 표준

으뜸아빠 2026. 1. 6. 11:03
728x90
반응형

파이썬 생태계의 패키지 관리는 오랫동안 복잡하고 파편화된 상태였습니다. 가상환경을 만들려면 virtualenv나 venv, 패키지를 설치하려면 pip, 의존성을 잠그려면 pip-tools, Python 버전을 관리하려면 pyenv, CLI 도구를 격리 설치하려면 pipx를 써야 했습니다. 프로젝트 하나를 시작하는 데 5개의 도구를 조합해야 하는 상황이었죠. uv는 이 모든 것을 단 하나의 도구로 통합하며, Rust로 작성되어 기존 도구들보다 10~100배 빠른 속도를 자랑합니다. 이 글에서는 uv의 모든 기능을 실무에서 바로 활용할 수 있도록 자세히 다룹니다.

 

 

1부: uv 소개 및 설치


 

1. uv란 무엇인가?

 

한 줄 요약: pip, pyenv, virtualenv, poetry, pipx를 모두 대체하는 초고속 올인원 파이썬 패키지 매니저

 

uv는 Astral이라는 회사에서 개발한 파이썬 패키지 및 프로젝트 관리 도구입니다. Astral은 Ruff라는 초고속 파이썬 린터/포매터를 만든 회사로, Rust 언어의 성능을 파이썬 생태계에 가져오는 데 집중하고 있습니다. 2024년 초에 uv가 처음 출시되었고, 같은 해에 Flask 창시자 Armin Ronacher가 만든 Rye 프로젝트를 인수하여 uv에 통합했습니다.

 

uv가 해결하는 문제는 명확합니다. 기존에는 파이썬 프로젝트를 시작하려면 pyenv로 Python 버전을 설치하고, virtualenv로 가상환경을 만들고, pip로 패키지를 설치하고, pip-tools로 의존성을 잠가야 했습니다. 각 도구마다 다른 명령어와 설정 파일을 익혀야 했고, 도구들 간의 호환성 문제도 발생했습니다. uv는 이 모든 기능을 하나의 바이너리로 제공합니다.

 

성능 면에서 uv는 압도적입니다. pip로 Django를 설치하면 수 초가 걸리지만, uv는 밀리초 단위로 완료합니다. 이는 Rust로 작성되어 있고, 병렬 다운로드와 글로벌 캐시를 활용하기 때문입니다. 한 번 다운로드한 패키지는 모든 프로젝트에서 재사용되어 디스크 공간도 절약됩니다.

 

uv의 비전은 "Cargo for Python"입니다. Rust의 Cargo가 패키지 관리, 빌드, 테스트를 하나로 통합한 것처럼, uv도 파이썬 개발의 모든 단계를 하나의 도구로 처리하려 합니다. PEP 621(pyproject.toml), PEP 723(인라인 스크립트 메타데이터) 등 파이썬 표준을 철저히 준수하면서도, 개발자 경험을 크게 개선했습니다.

 

🔗 공식 사이트: https://astral.sh/

 

Astral: High-performance Python tooling

Astral builds high-performance developer tools for the Python ecosystem: Ruff, ty, and uv, an extremely fast Python package manager, written in Rust.

astral.sh

 

 

 

 

2. 왜 uv인가? (기존 도구와의 비교)

 

한 줄 요약: pip보다 100배 빠르고, poetry보다 심플하며, pyenv+virtualenv+pip-tools를 하나로 통합

 

파이썬 패키지 관리 도구는 크게 세 세대로 나눌 수 있습니다. 1세대는 pip, virtualenv, pip-tools 같은 기본 도구들입니다. 각각 한 가지 일만 잘하지만, 조합해서 사용해야 해서 복잡합니다. 2세대는 poetry, pdm, hatch 같은 통합 도구들입니다. 프로젝트 관리를 하나로 묶었지만, Python 버전 관리는 여전히 pyenv에 의존하고, 속도가 느린 편입니다. uv는 3세대로, Python 버전 관리까지 포함한 완전한 통합과 극단적인 속도를 모두 갖췄습니다.

 

pip과 비교하면 uv의 속도 차이는 충격적입니다. 대규모 프로젝트에서 pip install이 1분 걸리는 상황에서 uv는 1~2초면 끝납니다. 이는 캐시 시스템 덕분이기도 합니다. pip은 각 프로젝트마다 패키지를 새로 다운로드하지만, uv는 글로벌 캐시에서 하드링크로 연결해서 디스크 I/O를 최소화합니다.

 

poetry와 비교하면 uv가 더 심플합니다. poetry는 자체적인 의존성 해결 알고리즘과 pyproject.toml 확장을 사용하는데, 이것이 때로는 표준과 충돌하거나 복잡성을 야기합니다. uv는 PEP 표준을 엄격히 따르면서도 더 빠르고 직관적인 명령어를 제공합니다. poetry에서 uv로 마이그레이션하는 프로젝트가 늘어나는 이유입니다.

 

pyenv와 비교하면 uv가 Python 설치도 처리합니다. pyenv는 Python 소스를 컴파일해서 설치하기 때문에 시간이 오래 걸리고 빌드 의존성이 필요합니다. uv는 사전 빌드된 Python 바이너리를 다운로드해서 몇 초 만에 설치를 완료합니다. 더 이상 Python 버전 관리를 위해 별도 도구를 설치할 필요가 없습니다.

 

🔗 벤치마크: https://docs.astral.sh/uv/#highlights

 

uv

An extremely fast Python package and project manager, written in Rust. Installing Trio's dependencies with a warm cache. 🚀 A single tool to replace pip, pip-tools, pipx, poetry, pyenv, twine, virtualenv, and more. ⚡️ 10-100x faster than pip. 🗂️

docs.astral.sh

 

 

 

 

3. 설치하기

한 줄 요약: curl 한 줄이면 끝, 또는 brew/pip/cargo로도 설치 가능

 

uv 설치는 놀라울 정도로 간단합니다. 공식 설치 스크립트를 사용하면 운영체제를 자동 감지하고 적절한 바이너리를 다운로드합니다. macOS나 Linux에서는 터미널에서 curl 명령 한 줄이면 됩니다. Windows에서는 PowerShell에서 비슷한 명령을 실행합니다. 설치 후 쉘을 재시작하거나 source 명령으로 PATH를 갱신하면 바로 사용할 수 있습니다.

 

패키지 관리자를 선호한다면 Homebrew, pip, pipx, Cargo 등으로도 설치할 수 있습니다. Homebrew는 macOS와 Linux 모두에서 동작하고, pip는 기존 Python 환경이 있을 때 유용합니다. Rust 개발자라면 Cargo로 소스에서 직접 빌드할 수도 있습니다. 설치 후에는 uv self update 명령으로 언제든 최신 버전으로 업데이트할 수 있습니다. uv는 빠르게 발전하고 있어서 정기적인 업데이트를 권장합니다. 쉘 자동완성도 지원하는데, bash, zsh, fish, PowerShell 모두에서 탭 완성이 가능해져서 명령어를 외울 필요가 줄어듭니다.

# macOS / Linux 공식 설치 (권장)
curl -LsSf https://astral.sh/uv/install.sh | sh

# Windows PowerShell
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

# Homebrew
brew install uv

# pip (기존 Python 환경이 있을 때)
pip install uv

# 설치 확인
uv version

# 자동 업데이트
uv self update

# 쉘 자동완성 (Zsh 예시)
echo 'eval "$(uv generate-shell-completion zsh)"' >> ~/.zshrc

 

🔗 설치 가이드: https://docs.astral.sh/uv/getting-started/installation/

 

Installation | uv

Use curl to download the script and execute it with sh: $ curl -LsSf https://astral.sh/uv/install.sh | sh If your system doesn't have curl, you can use wget: $ wget -qO- https://astral.sh/uv/install.sh | sh Request a specific version by including it in the

docs.astral.sh

 

 

 

 

2부: 프로젝트 관리


4. 프로젝트 초기화

한 줄 요약: uv init 한 번으로 pyproject.toml, .venv, .gitignore까지 모두 생성

 

새로운 파이썬 프로젝트를 시작할 때 uv init 명령을 사용합니다. 이 명령은 프로젝트에 필요한 모든 파일을 자동으로 생성합니다. pyproject.toml은 프로젝트 메타데이터와 의존성을 정의하고, .python-version은 사용할 Python 버전을 지정하며, .gitignore는 버전 관리에서 제외할 파일들을 설정합니다. Git 저장소도 자동으로 초기화됩니다.

 

프로젝트 타입에 따라 다른 템플릿을 선택할 수 있습니다. 기본값인 --app은 실행 가능한 애플리케이션용이고, --lib은 다른 프로젝트에서 임포트할 라이브러리용입니다. --package는 PyPI에 배포할 패키지를 만들 때 사용하고, --bare는 최소한의 설정만 생성합니다. 대부분의 경우 기본값으로 충분합니다.

 

생성된 pyproject.toml은 PEP 621 표준을 따릅니다. [project] 섹션에 패키지 이름, 버전, Python 버전 요구사항, 의존성이 들어가고, [tool.uv] 섹션에 uv 전용 설정이 들어갑니다. 개발 의존성은 dev-dependencies에 별도로 관리되어 프로덕션 배포 시 제외할 수 있습니다.

# 새 프로젝트 생성
uv init my-project
cd my-project

# 현재 디렉토리에서 초기화
uv init

# 라이브러리 프로젝트
uv init --lib my-library

# 생성되는 구조
# my-project/
# ├── .git/
# ├── .gitignore
# ├── .python-version
# ├── README.md
# ├── pyproject.toml
# └── main.py
# pyproject.toml 예시
[project]
name = "my-project"
version = "0.1.0"
description = "프로젝트 설명"
requires-python = ">=3.12"
dependencies = []

[tool.uv]
dev-dependencies = [
    "pytest>=8.0.0",
    "ruff>=0.5.0",
]

 

🔗 프로젝트 가이드: https://docs.astral.sh/uv/guides/projects/

 

Working on projects | uv

Introduction Guides uv supports managing Python projects, which define their dependencies in a pyproject.toml file. You can create a new Python project using the uv init command: $ uv init hello-world $ cd hello-world Alternatively, you can initialize a pr

docs.astral.sh

 

 

 

 

5. 의존성 관리

한 줄 요약: uv add로 추가, uv remove로 제거, uv.lock으로 정확한 버전 잠금

 

uv에서 패키지를 추가하는 것은 매우 직관적입니다. uv add requests 한 줄이면 requests 패키지가 설치되고, pyproject.toml의 dependencies에 자동으로 추가되며, uv.lock에 정확한 버전이 기록됩니다. 이 모든 것이 1초 안에 완료됩니다. 버전을 지정하고 싶으면 uv add "requests>=2.28.0"처럼 따옴표로 감싸서 버전 조건을 명시합니다.

 

개발용 의존성은 --dev 플래그로 분리합니다. pytest, ruff, mypy 같은 도구는 개발 시에만 필요하고 프로덕션에는 포함되지 않아야 하므로, uv add --dev pytest로 추가합니다. 더 세밀하게 그룹을 나누고 싶으면 --group 플래그를 사용해서 test, lint, docs 등으로 분류할 수 있습니다.

 

uv.lock 파일은 uv의 핵심 기능 중 하나입니다. 이 파일에는 모든 의존성의 정확한 버전, 해시, 다운로드 URL이 기록됩니다. 다른 개발자가 같은 프로젝트를 클론해서 uv sync를 실행하면 정확히 동일한 환경이 재현됩니다. 크로스 플랫폼 락파일이라서 macOS에서 생성한 락파일로 Linux에서도 동일한 환경을 만들 수 있습니다. 이 파일은 반드시 Git에 커밋해야 합니다.

의존성을 업데이트하고 싶으면 uv lock --upgrade를 실행합니다. 이 명령은 pyproject.toml의 버전 조건을 만족하는 범위 내에서 모든 패키지를 최신 버전으로 올립니다. 특정 패키지만 업데이트하려면 uv lock --upgrade-package requests처럼 패키지 이름을 지정합니다.

# 패키지 추가
uv add requests
uv add "django>=4.0,<5.0"
uv add pandas numpy matplotlib

# 개발 의존성 추가
uv add --dev pytest ruff mypy

# 그룹별 의존성
uv add --group test pytest pytest-cov
uv add --group docs sphinx

# extras 포함
uv add "fastapi[standard]"

# 패키지 제거
uv remove requests

# 의존성 트리 확인
uv tree

# 락파일 업데이트
uv lock --upgrade

# 환경 동기화
uv sync

 

🔗 의존성 가이드: https://docs.astral.sh/uv/concepts/dependencies/

 

Redirecting...

 

docs.astral.sh

 

 

 

 

6. Python 버전 관리

한 줄 요약: pyenv 없이 uv python install로 여러 Python 버전 설치 및 전환

uv는 Python 인터프리터 자체도 관리합니다. uv python install 3.12를 실행하면 사전 빌드된 Python 3.12 바이너리가 다운로드되어 설치됩니다. pyenv처럼 소스를 컴파일할 필요가 없어서 몇 초면 완료됩니다. 여러 버전을 동시에 설치해두고 프로젝트마다 다른 버전을 사용할 수 있습니다.

 

프로젝트에서 사용할 Python 버전은 uv python pin으로 고정합니다. 이 명령은 .python-version 파일을 생성하고, 이후 uv run이나 uv sync 실행 시 이 버전이 자동으로 사용됩니다. 해당 버전이 설치되어 있지 않으면 uv가 자동으로 다운로드합니다. 팀원들이 같은 버전을 사용하도록 .python-version 파일을 Git에 커밋하는 것이 좋습니다.

 

설치된 Python 버전을 확인하려면 uv python list를 실행합니다. 설치된 버전만 보려면 --only-installed 플래그를 추가합니다. 더 이상 필요 없는 버전은 uv python uninstall로 제거할 수 있습니다.

# 설치 가능한 버전 확인
uv python list

# Python 설치
uv python install 3.12
uv python install 3.11 3.12 3.13

# 프로젝트 버전 고정
uv python pin 3.12

# 설치된 버전만 표시
uv python list --only-installed

# Python 제거
uv python uninstall 3.11

 

🔗 Python 버전 가이드: https://docs.astral.sh/uv/guides/install-python/

 

Installing and managing Python | uv

Introduction Guides If Python is already installed on your system, uv will detect and use it without configuration. However, uv can also install and manage Python versions. uv automatically installs missing Python versions as needed — you don't need to i

docs.astral.sh

 

 

 

 

 

7. 가상환경과 uv run

한 줄 요약: uv run으로 가상환경 활성화 없이 바로 스크립트 실행, 의존성도 자동 동기화

 

전통적인 파이썬 개발에서는 가상환경을 만들고 활성화한 후 스크립트를 실행해야 했습니다. source .venv/bin/activate를 매번 실행하는 것은 번거롭고, 활성화를 잊으면 시스템 Python이 사용되어 의존성 문제가 발생하기도 합니다. uv는 이 문제를 uv run으로 해결합니다.

 

uv run python script.py를 실행하면 uv가 자동으로 .venv 가상환경을 감지하고, 필요하면 생성하며, 의존성을 동기화한 후 스크립트를 실행합니다. 가상환경을 명시적으로 활성화할 필요가 없습니다. 이 방식은 CI/CD 환경에서도 유용합니다. 활성화 스크립트를 호출하는 복잡한 쉘 명령 대신 uv run으로 일관되게 실행할 수 있습니다.

물론 전통적인 방식으로 가상환경을 직접 다룰 수도 있습니다. uv venv로 가상환경을 생성하고, source .venv/bin/activate로 활성화하면 됩니다. 특정 Python 버전으로 가상환경을 만들고 싶으면 uv venv --python 3.11처럼 버전을 지정합니다.

# 가상환경 활성화 없이 실행 (권장)
uv run python script.py
uv run pytest
uv run flask run

# 특정 Python 버전으로 실행
uv run --python 3.11 python script.py

# 전통적인 방식: 가상환경 직접 관리
uv venv
source .venv/bin/activate
python script.py

# 특정 버전으로 가상환경 생성
uv venv --python 3.11

# 환경 동기화
uv sync
uv sync --no-dev  # 개발 의존성 제외

 

🔗 실행 가이드: https://docs.astral.sh/uv/guides/scripts/

 

Running scripts | uv

Introduction Guides A Python script is a file intended for standalone execution, e.g., with python .py. Using uv to execute scripts ensures that script dependencies are managed without manually managing environments. Note If you are not familiar with Pytho

docs.astral.sh

 

 

 

 

3부: 고급 기능


 

8. 인라인 스크립트 의존성 (PEP 723)

 

한 줄 요약: 스크립트 파일 안에 의존성을 선언하면 uv run이 자동으로 설치하고 실행

 

PEP 723은 파이썬 3.12에서 도입된 표준으로, 단일 파일 스크립트에 의존성 메타데이터를 인라인으로 포함할 수 있게 합니다. 예를 들어 requests와 pandas를 사용하는 데이터 수집 스크립트가 있다면, 스크립트 상단에 특별한 주석 블록으로 이 의존성들을 선언합니다. uv run으로 이 스크립트를 실행하면 uv가 주석을 파싱하고, 필요한 패키지를 설치한 후 실행합니다.

 

이 기능은 독립적인 유틸리티 스크립트를 공유할 때 특히 유용합니다. requirements.txt나 pyproject.toml 없이 .py 파일 하나만 전달하면 됩니다. 받은 사람은 uv run script.py 한 줄로 의존성 설치와 실행을 동시에 처리합니다.

uv add --script 명령으로 기존 스크립트에 인라인 메타데이터를 쉽게 추가할 수 있습니다. 이 명령은 스크립트 상단에 적절한 주석 블록을 자동으로 삽입합니다.

# fetch_data.py
# /// script
# requires-python = ">=3.12"
# dependencies = [
#     "requests",
#     "pandas>=2.0",
# ]
# ///

import requests
import pandas as pd

response = requests.get("https://api.example.com/data")
df = pd.DataFrame(response.json())
print(df.head())
# 인라인 의존성 스크립트 실행
uv run fetch_data.py

# 기존 스크립트에 의존성 추가
uv add --script script.py requests pandas

 

🔗 PEP 723 가이드: https://docs.astral.sh/uv/guides/scripts/#declaring-script-dependencies

 

Running scripts | uv

Introduction Guides A Python script is a file intended for standalone execution, e.g., with python .py. Using uv to execute scripts ensures that script dependencies are managed without manually managing environments. Note If you are not familiar with Pytho

docs.astral.sh

 

 

 

9. CLI 도구 관리 (uvx)

한 줄 요약: pipx 대체, 격리된 환경에서 CLI 도구를 설치 없이 바로 실행

 

uvx는 pipx의 uv 버전입니다. ruff, black, httpie 같은 CLI 도구를 현재 프로젝트와 격리된 환경에서 실행합니다. uvx ruff check .를 실행하면 ruff가 임시 환경에 설치되고 즉시 실행됩니다. 프로젝트의 의존성에 영향을 주지 않으면서 도구를 사용할 수 있습니다.

자주 사용하는 도구는 uv tool install로 영구 설치할 수 있습니다. 설치된 도구는 ~/.local/bin에 링크되어 일반 명령처럼 사용할 수 있습니다. uv tool list로 설치된 도구 목록을 확인하고, uv tool upgrade로 업데이트합니다.

uvx는 버전 지정도 지원합니다. uvx ruff@0.5.0처럼 특정 버전을 실행하거나, uvx --from ruff@latest ruff로 최신 버전을 사용할 수 있습니다.

# 도구를 설치 없이 바로 실행
uvx ruff check .
uvx black --check .
uvx httpie GET https://api.example.com

# 특정 버전 실행
uvx ruff@0.5.0 check .

# 영구 설치
uv tool install ruff
uv tool install black

# 설치된 도구 목록
uv tool list

# 도구 업데이트
uv tool upgrade ruff
uv tool upgrade --all

 

🔗 도구 가이드: https://docs.astral.sh/uv/guides/tools/

 

Using tools | uv

Introduction Guides Many Python packages provide applications that can be used as tools. uv has specialized support for easily invoking and installing tools. The uvx command invokes a tool without installing it. For example, to run ruff: Note This is exact

docs.astral.sh

 

 

 

10. 워크스페이스 (모노레포)

한 줄 요약: 하나의 저장소에서 여러 관련 패키지를 함께 관리하고 로컬 의존성으로 연결

 

대규모 프로젝트에서는 여러 개의 관련 패키지를 하나의 저장소에서 관리하는 모노레포 구조가 유용합니다. uv의 워크스페이스 기능은 이를 지원합니다. 루트 pyproject.toml에 [tool.uv.workspace] 섹션을 정의하고, 각 하위 패키지의 경로를 members로 지정합니다. 이렇게 하면 하위 패키지들이 서로를 로컬 의존성으로 참조할 수 있고, 락파일도 공유됩니다.

 

워크스페이스의 장점은 의존성 일관성입니다. 모든 패키지가 같은 uv.lock을 사용하므로, 서로 다른 패키지가 같은 라이브러리의 다른 버전을 요구하는 버전 충돌을 방지할 수 있습니다. 또한 한 패키지를 수정하면 의존하는 다른 패키지에서 즉시 반영됩니다.

# 워크스페이스 구조
my-monorepo/
├── pyproject.toml          # 워크스페이스 루트
├── uv.lock                  # 공유 락파일
├── packages/
│   ├── core/
│   │   ├── pyproject.toml
│   │   └── src/
│   ├── api/
│   │   ├── pyproject.toml
│   │   └── src/
│   └── cli/
│       ├── pyproject.toml
│       └── src/
# 루트 pyproject.toml
[tool.uv.workspace]
members = ["packages/*"]
# packages/api/pyproject.toml
[project]
name = "my-api"
dependencies = [
    "my-core",  # 로컬 패키지 참조
    "fastapi",
]

[tool.uv.sources]
my-core = { workspace = true }

 

🔗 워크스페이스 가이드: https://docs.astral.sh/uv/concepts/workspaces/

 

Redirecting...

 

docs.astral.sh

 

 

 

11. Docker 통합

한 줄 요약: 멀티스테이지 빌드로 uv 캐시를 활용한 빠른 Docker 이미지 생성

 

Docker 환경에서 uv를 사용하면 이미지 빌드 시간을 크게 줄일 수 있습니다. uv의 캐시 시스템은 Docker 빌드 캐시와 잘 어울립니다. Dockerfile에서 uv.lock과 pyproject.toml을 먼저 복사하고 uv sync를 실행한 후, 소스 코드를 복사하면 의존성이 변경되지 않은 경우 캐시된 레이어를 재사용합니다.

 

멀티스테이지 빌드를 사용하면 최종 이미지에 uv 바이너리를 포함할 필요 없이 가상환경만 복사할 수 있습니다. 빌드 스테이지에서 uv로 의존성을 설치하고, 런타임 스테이지에서 .venv 디렉토리만 가져오면 됩니다. 이렇게 하면 이미지 크기도 줄일 수 있습니다.

uv는 --no-cache 옵션도 제공해서 CI 환경에서 캐시 없이 깨끗한 설치를 할 수 있습니다.

# Dockerfile
FROM python:3.12-slim AS builder

COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv

WORKDIR /app

COPY pyproject.toml uv.lock ./

RUN uv sync --frozen --no-dev

COPY . .

FROM python:3.12-slim

WORKDIR /app

COPY --from=builder /app/.venv /app/.venv
COPY --from=builder /app .

ENV PATH="/app/.venv/bin:$PATH"

CMD ["python", "main.py"]

 

🔗 Docker 가이드: https://docs.astral.sh/uv/guides/integration/docker/

 

Using uv in Docker | uv

Introduction Guides Integrations Tip Check out the uv-docker-example project for an example of best practices when using uv to build an application in Docker. uv provides both distroless Docker images, which are useful for copying uv binaries into your own

docs.astral.sh

 

 

 

 

12. pip 호환 인터페이스

한 줄 요약: 기존 pip 명령어를 uv pip으로 대체하면 동일한 동작을 100배 빠르게

 

uv는 pip의 거의 모든 명령어를 호환 인터페이스로 제공합니다. pip install이 익숙하다면 uv pip install로 바꾸기만 하면 됩니다. requirements.txt도 그대로 사용할 수 있습니다. 이 방식은 기존 프로젝트를 점진적으로 uv로 마이그레이션할 때 유용합니다.

uv pip compile은 pip-tools의 pip-compile을 대체합니다. requirements.in에서 requirements.txt를 생성하는 워크플로우를 그대로 사용하면서 속도만 개선됩니다. uv pip sync는 requirements.txt 기준으로 환경을 정확히 동기화합니다.

 

다만 장기적으로는 uv의 네이티브 명령어(uv add, uv sync)를 사용하는 것이 권장됩니다. pyproject.toml 기반의 현대적인 워크플로우가 더 강력하고 유지보수하기 쉽습니다.

# pip 호환 명령어
uv pip install requests
uv pip install -r requirements.txt
uv pip uninstall requests
uv pip list
uv pip freeze

# pip-tools 대체
uv pip compile requirements.in -o requirements.txt
uv pip sync requirements.txt

# 가상환경 없이 시스템에 설치 (권장하지 않음)
uv pip install --system requests

 

🔗 pip 인터페이스 가이드: https://docs.astral.sh/uv/pip/

 

Index | uv

uv provides a drop-in replacement for common pip, pip-tools, and virtualenv commands. These commands work directly with the virtual environment, in contrast to uv's primary interfaces where the virtual environment is managed automatically. The uv pip inter

docs.astral.sh

 

 

 

 

13. 패키지 빌드 및 배포

한 줄 요약: uv build로 wheel/sdist 생성, uv publish로 PyPI에 배포

 

파이썬 패키지를 PyPI에 배포하려면 먼저 배포 가능한 형식으로 빌드해야 합니다. uv build 명령은 wheel(.whl)과 source distribution(.tar.gz)을 생성합니다. 빌드 결과물은 dist/ 디렉토리에 저장됩니다.

 

빌드된 패키지를 PyPI에 업로드하려면 uv publish를 사용합니다. PyPI API 토큰이 필요하며, 환경변수나 명령행 옵션으로 전달할 수 있습니다. TestPyPI에 먼저 테스트하고 싶으면 --publish-url 옵션으로 URL을 지정합니다.

uv는 twine을 대체하므로, 빌드부터 배포까지 별도 도구 없이 uv 하나로 완료할 수 있습니다.

# 패키지 빌드
uv build

# wheel만 빌드
uv build --wheel

# 결과물 확인
ls dist/
# my_package-0.1.0-py3-none-any.whl
# my_package-0.1.0.tar.gz

# PyPI에 배포
uv publish

# TestPyPI에 배포
uv publish --publish-url https://test.pypi.org/legacy/

# 토큰 환경변수 설정
export UV_PUBLISH_TOKEN=pypi-xxxxx
uv publish

 

🔗 배포 가이드: https://docs.astral.sh/uv/guides/publish/

 

Redirecting...

 

docs.astral.sh

 

 

 

 

4부: 실전 활용


 

 

14. 설정 및 환경변수

 

한 줄 요약: pyproject.toml의 [tool.uv] 섹션 또는 환경변수로 uv 동작 커스터마이징

 

uv의 동작은 여러 방법으로 커스터마이징할 수 있습니다. 프로젝트별 설정은 pyproject.toml의 [tool.uv] 섹션에, 전역 설정은 ~/.config/uv/uv.toml에 작성합니다. 환경변수로도 대부분의 설정을 오버라이드할 수 있습니다.

자주 사용하는 설정으로는 인덱스 URL 변경(프라이빗 PyPI 사용), 캐시 디렉토리 위치, Python 버전 기본값 등이 있습니다. 기업 환경에서 프라이빗 패키지 저장소를 사용한다면 index-url 설정이 필수입니다.

# pyproject.toml
[tool.uv]
dev-dependencies = ["pytest", "ruff"]
python-preference = "managed"

[[tool.uv.index]]
url = "https://private.pypi.company.com/simple/"
name = "private"
# 환경변수
export UV_CACHE_DIR="/path/to/cache"
export UV_PYTHON_PREFERENCE="managed"
export UV_INDEX_URL="https://private.pypi.company.com/simple/"

# 캐시 관리
uv cache dir    # 캐시 위치 확인
uv cache clean  # 캐시 정리

 

🔗 설정 레퍼런스: https://docs.astral.sh/uv/reference/settings/

 

Settings | uv

Introduction Reference Settings Constraints to apply when solving build dependencies. Build constraints are used to restrict the versions of build dependencies that are selected when building a package during resolution or installation. Including a package

docs.astral.sh

 

 

 

 

 

15. 마이그레이션 가이드

한 줄 요약: poetry에서는 uv init + uv add, requirements.txt에서는 uv pip compile

 

기존 프로젝트를 uv로 마이그레이션하는 방법은 현재 사용 중인 도구에 따라 다릅니다. poetry나 pdm을 사용하고 있다면, 기존 pyproject.toml을 uv가 이해할 수 있는 형식으로 변환해야 합니다. 대부분의 경우 [project] 섹션은 그대로 사용할 수 있고, [tool.poetry] 같은 도구별 섹션만 [tool.uv]로 재작성하면 됩니다.

 

requirements.txt만 사용하던 프로젝트라면 더 간단합니다. uv init으로 pyproject.toml을 생성하고, requirements.txt의 패키지들을 uv add로 추가합니다. 또는 uv pip install -r requirements.txt로 기존 방식을 유지하면서 속도만 개선할 수도 있습니다.

pyenv를 사용하고 있었다면 uv python install로 대체합니다. .python-version 파일은 uv도 인식하므로 그대로 유지해도 됩니다.

# poetry에서 마이그레이션
# 1. poetry.lock 삭제
rm poetry.lock

# 2. pyproject.toml의 [tool.poetry] 섹션을 [tool.uv]로 변환
# 3. uv sync 실행
uv sync

# requirements.txt에서 마이그레이션
uv init
uv add $(cat requirements.txt | tr '\n' ' ')

# 또는 점진적 마이그레이션
uv pip install -r requirements.txt

# pyenv에서 마이그레이션
uv python install 3.12
uv python pin 3.12

 

🔗 마이그레이션 가이드: https://docs.astral.sh/uv/guides/integration/

 

Index | uv

Introduction Guides Integrations Learn how to integrate uv with other software: Or, explore the concept documentation for comprehensive breakdown of each feature. September 12, 2025

docs.astral.sh

 

 

 

 

 

16. CI/CD 통합

한 줄 요약: GitHub Actions에서 uv 캐시로 빌드 시간 대폭 단축

 

CI/CD 환경에서 uv를 사용하면 빌드 시간을 크게 줄일 수 있습니다. GitHub Actions의 경우 astral-sh/setup-uv 액션으로 uv를 설치하고, 캐시를 활성화하면 의존성 설치 시간이 수 초로 단축됩니다. uv의 캐시는 크로스 플랫폼이라서 한 번 캐시된 패키지를 다른 OS에서도 재사용할 수 있습니다. 다만 wheel이 플랫폼별로 다를 수 있으므로, 복잡한 C 확장이 있는 패키지는 주의가 필요합니다.

GitLab CI, CircleCI 등 다른 CI 시스템에서도 curl로 uv를 설치하고 캐시 디렉토리를 지정하면 비슷한 효과를 얻을 수 있습니다.

# .github/workflows/test.yml
name: Test

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Install uv
        uses: astral-sh/setup-uv@v4
        with:
          enable-cache: true
      
      - name: Install dependencies
        run: uv sync
      
      - name: Run tests
        run: uv run pytest
      
      - name: Run linting
        run: uv run ruff check .

 

🔗 GitHub Actions 가이드: https://docs.astral.sh/uv/guides/integration/github/

 

Using uv in GitHub Actions | uv

For use with GitHub Actions, we recommend the official astral-sh/setup-uv action, which installs uv, adds it to PATH, (optionally) persists the cache, and more, with support for all uv-supported platforms. To install the latest version of uv: example.ymlna

docs.astral.sh

 

 

 

 

 

 

17. 팁과 베스트 프랙티스

한 줄 요약: uv.lock은 반드시 커밋, uv run으로 통일, 정기적으로 uv lock --upgrade

락파일 관리: uv.lock 파일은 반드시 Git에 커밋합니다. 이 파일이 있어야 모든 개발자와 CI 환경에서 동일한 의존성 버전을 사용할 수 있습니다. .gitignore에 uv.lock을 추가하지 마세요.

uv run 사용 습관: 가상환경을 직접 활성화하는 대신 항상 uv run을 사용하세요. 활성화를 잊어서 시스템 Python을 사용하는 실수를 방지하고, 의존성이 자동으로 동기화됩니다. IDE에서도 uv run python으로 인터프리터를 지정할 수 있습니다.

정기적 업데이트: 보안과 버그 수정을 위해 정기적으로 uv lock --upgrade를 실행합니다. CI에서 주간 스케줄로 자동화하는 것도 좋은 방법입니다. 업데이트 후에는 테스트를 실행해서 문제가 없는지 확인합니다.

개발 의존성 분리: pytest, ruff 같은 개발 도구는 --dev로 추가합니다. 프로덕션 배포 시 uv sync --no-dev로 불필요한 패키지를 제외할 수 있습니다.

캐시 관리: 디스크 공간이 부족하면 uv cache clean으로 캐시를 정리합니다. 캐시 위치는 uv cache dir로 확인할 수 있습니다.

 

 

 

 

마무리

uv는 파이썬 패키지 관리의 새로운 표준이 되어가고 있습니다. pip보다 100배 빠른 속도, pyenv+virtualenv+pip-tools의 통합, 현대적인 락파일 시스템까지, 기존 도구들의 장점을 모두 가져오면서 불편함은 제거했습니다. Rust 기반의 견고한 구현과 Astral의 적극적인 개발 덕분에 빠르게 성숙해지고 있습니다. 새 프로젝트를 시작한다면 처음부터 uv를 사용하는 것을 강력히 권장합니다. 기존 프로젝트도 점진적으로 마이그레이션하면 개발 경험이 크게 개선됩니다. "Cargo for Python"이라는 비전대로, uv가 파이썬 개발의 필수 도구로 자리 잡을 날이 머지않았습니다.

🔗 uv 시작하기: https://docs.astral.sh/uv/

🔗 GitHub: https://github.com/astral-sh/uv

🔗 Discord 커뮤니티: https://discord.gg/astral-sh

 

 

 

 

 

 

728x90
반응형