UV

UV

An extremely fast Python package and project manager, written in Rust.

Rust 로 제작된 파이썬 패키지 매니저이자 프로젝트 매니저.

특징

  • pip, pip-tools, poetry, pyenv, twine, virtualenv 를 대체할 수 있는 단일 도구
  • pip 보다 10 ~ 100배 빠른 속도
  • universal lockfile 로 포괄적인 프로젝트 관리 가능
  • inline dependency metadata 를 지원해 스크립트를 실행 가능
  • Python 버전을 설치하고 관리할 수 있음
  • Python 패키지로 등록되어있는 도구들을 설치하고 실행할 수 있음
  • pip 호환 인터페이스 제공으로, 친숙한 CLI 환경 제공
  • Cargo-style workspace 를 제공해 확장 가능한 프로젝트의 환경 제공
  • 종속성 중복 제거를 위한 global cache를 사용해 디스크 공간 효울성 확보
  • curl 또는 pip 로 설치 가능
  • macOS, Linux, Windows 지원

UV 설치와 사용

설치

1
2
# mac, Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
1
2
# windows
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
1
2
3
4
5
# pip
pip install uv

# pipx
pipx install uv

프로젝트 init

  • 가장 먼저 init 을 통해 프로젝트(작업공간=workspace)를 초기화해준다.
1
2
3
4
5
# 현재 디렉터리에 초기화를 진행할 경우
uv init .

# 현재 디렉터리 하위에 디렉터리를 만들면서 그곳에 초기화를 진행할 경우
uv init example
  • 초기화한 내용을 삭제하려면 프로젝트 루트에서 파일들을 삭제하고, uv clean cache 를 해준다.
1
2
3
4
5
6
7
8
# 파일 삭제
- .python-verion
- main.py
- pyproject.toml
- README.md

# cache clean
uv cache clean

초기화한 프로젝트 디렉터리 살펴보기

파일명 설명
.python-version - 용도: 프로젝트에서 사용할 Python 버전을 명시한다.
- 예시: 3.11.9처럼 작성되어 있음.
- 사용 도구: pyenv, uv, direnv 등이 이 파일을 참고함
main.py - 용도: 기본 실행 스크립트로, Python 프로젝트의 진입점 역할을 한다.
- 내용: 일반적으로 “Hello, world!” 같은 간단한 예제 코드가 들어있음.
- 실행: python main.py 또는 uv run main.py로 실행 가능.
pyproject.toml - 용도: Python 프로젝트의 설정 파일.
- 포함 내용: 프로젝트 이름, 버전, 의존성, 빌드 시스템 설정 등.
- 표준: PEP 518에 따라 Python 생태계에서 공식 표준으로 채택된 형식.
README.md - 용도: 프로젝트에 대한 설명을 적는 문서.
- 형식: Markdown(.md) 포맷.
- 보통 포함 내용: 프로젝트 개요, 설치 방법, 사용 방법, 예제 코드 등.
uv.lock - 용도: 프로젝트의 의존성 잠금(lock) 파일
- 패키지 버전과 해시를 고정해 재현 가능한 환경을 보장
- 의존성 라이브러리나 파이썬 버전 등을 버전과 함께 기록
- 재현성: 같은 uv.lock 파일을 사용하면 항상 동일한 환경 확보 가능

Python 설치하기

  • 해당 프로젝트 디렉터리(workspace)에 파이썬을 설치한다.
  • 파이썬이 이미 시스템에 있다면, 별도의 설정 없이도 uv가 이를 감지하여 사용한다.
  • 그러나 uv는 파이썬 버전을 설치하고 관리할 수도 있다.
1
2
3
4
5
# 파이썬 설치
uv python install

# 버전 명시
uv python install 3.12

설치된 파이썬의 버전 및 경로는 uv python list 명령어를 통해 조회할 수 있다. 이 명령어는 시스템에 기존에 설치된 파이썬도 탐지하여 출력한다.

1
uv python list

uv 로 python script 실행하기

예시를 위한 example.py은 아래와 같다.

1
2
import datetime
print(f"it's uv! now is {datetime.datetime.now().strftime('%Y-%m-%d')}")
1
2
3
uv run example.py

>> it's uv! now is 2025-05-13

의존성

UV에서 의존성 관리

  • UV 에서는 uv.lock 파일에 의존성을 명세한다.
  • 이 파일에는 파이썬의 버전이나 의존성 라이브러리의 종류와 버전을 명세한다.
  • 이를 통해 동일 uv.lock 파일로 실행할 경우 재현성을 보장할 수 있게 된다.

의존성 추가

  • uv add 명령어로 프로젝트의 의존성을 추가할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
uv add pandas

Resolved 7 packages in 655ms
Prepared 6 packages in 3.49s
Installed 6 packages in 1.25s
 + numpy==2.2.5
 + pandas==2.2.3
 + python-dateutil==2.9.0.post0
 + pytz==2025.2
 + six==1.17.0
 + tzdata==2025.2

이렇게 추가한 의존성은 프로젝트 디렉터리의 .venv 디렉터리에 저장된다.

또한 의존성이 uv.lockpyproject.toml 에 명세된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# uv.lock
version = 1
revision = 2
requires-python = ">=3.11"
resolution-markers = [
    "python_full_version >= '3.12.4'",
    "python_full_version < '3.12.4'",
]

[[package]]
name = "annotated-types"
version = "0.7.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" }
wheels = [
    { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" },
]

[[package]]
name = "anyio"
version = "4.9.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
    { name = "idna" },
    { name = "sniffio" },
    { name = "typing-extensions", marker = "python_full_version < '3.13'" },
]
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# pyproject.toml
[project]
name = "workspace"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.11"
dependencies = [
    "ipykernel>=6.29.5",
    "langchain>=0.3.25",
    "langchain-cli>=0.0.36",
    "langserve[all]>=0.3.1",
    "python-dotenv>=1.1.0",
]

[dependency-groups]
dev = [
    "ipykernel>=6.29.5",
]

개발용 의존성 설치

개발용 의존성 실치시에는 uv add 명령어에 --dev 옵션을 추가하면 된다.

1
uv add [패키지명] --dev

의존성 제거

의존성 제거시에는 uv remove 명령어를 사용할 수 있다.

1
uv remove [패키지명]

의존성 라이브러리 업그레이드

의존성 라이브러리를 업그레이드 할 때에는 uv lock --upgrade-package 명령어를 사용할 수 있다.

1
uv lock --upgrade-package [패키지명]

uv.lock 파일로 의존성 설치

uv.lock 파일만 있다면 충돌 없이 의존성 설치가 가능하다. uv run 혹은 uv sync 명령어를 사용하면 된다.

1
2
3
4
5
# uv run 후 아무 인자도 주지 않으면 패키지 설치가 진행된다.
uv run

# uv sync 를 사용하면 환경을 수동으로 업데이트할 수 있다.
uv sync

의존성 추출

uv 에서는 uv export 명령어를 통해 의존성 라이브러리 리스트를 추출할 수 있다. pip의 pip freeze 와 같은 기능이다.

1
2
3
4
5
6
7
8
# 의존성 라이브러리 추출
uv export -o requirements.txt

# 의존성 라이브러리 추출, 개발용 의존성 제외
uv export -o requirements.txt --no-dev

# 의존성 라이브러리 추출, 해시값 제외
uv export -o requirements.txt --no-hashes

기타

UV 로 Jupyter 실행하기

1
2
3
4
5
# jupyter 의존성 설치
uv add jupyter jupyterlab ipykernel

# jupyterlab 실행
uv run --with jupyter jupyter lab --allow-root --ip=0.0.0.0 --port=8888 --NotebookApp.token=''

Reference

https://github.com/astral-sh/uv
https://chaechae.life/blog/python-uv

Comments