Python uv 일반적인 패턴: 의존성·uvx·스크립트 실행

3 min read

이 글은 일상 개발에서 가장 자주 하는 5가지 작업에 집중하며, 바로 쓸 수 있는 작업 템플릿을 제공합니다. 이 패턴들을 익히면 8할의 상황을 처리할 수 있습니다 — 나머지 2할은 고급편에서 다룹니다.

패턴 1: 의존성 추가와 제거

# 의존성 추가
uv add requests
uv add "requests>=2.31,<3"   # 버전 제약 포함
 
# 개발 의존성 (테스트·lint·타입 체크)
uv add --dev pytest ruff mypy
 
# 제거
uv remove requests

uv addpyproject.toml·uv.lock·.venv를 동시에 업데이트 — 한 명령어로 완결.

패턴 2: uv run으로 프로젝트 내 명령 실행

프로젝트 내 스크립트·CLI·테스트는 항상 uv run 사용:

uv run python main.py
uv run pytest
uv run ruff check .
uv run mypy src/

activate 불필요, 잘못된 Python 걱정 없음.

패턴 3: uvx로 독립 CLI 도구 실행

도구를 임시로 실행하고 싶고 프로젝트에 추가하기 싫다면? uvx (uv tool run과 동등) 사용:

# 즉시 실행, 일회용
uvx ruff check .
uvx pycowsay "hello uv"
 
# 버전 지정
uvx ruff@0.5.0 check
 
# 패키지 이름과 명령어가 다를 때
uvx --from httpie http https://httpbin.org/get

uvx는 프로젝트를 오염시키지 않는 임시 환경을 만들어 실행합니다 — 시식만 하고 전체 패키지는 안 사는 느낌. "그냥 한 번 써보고 싶다"는 상황에 딱입니다.

패턴 4: 스크립트 인라인 의존성 (PEP 723)

단일 스크립트, 프로젝트 만들기 귀찮다면? 인라인 스크립트 메타데이터 사용:

# /// script
# dependencies = ["requests", "rich"]
# ///
 
import requests
from rich.pretty import pprint
 
r = requests.get("https://api.github.com/zen")
pprint(r.text)
uv add --script fetch.py requests rich
uv run fetch.py

또는 한 줄로:

uv run --with requests --with rich fetch.py

패턴 5: requirements.txt에서 마이그레이션

기존 프로젝트에 requirements.txt가 있다면? 바로 받아들이기:

uv add -r requirements.txt

또는 잠금 파일로 컴파일 후 동기화:

uv pip compile requirements.in -o requirements.txt
uv pip sync requirements.txt

마이그레이션 후 pyproject.toml을 주 소스로 사용하고, requirements.txt는 내보내기 형식으로 사용.

다음 단계

일상 패턴을 익혔다면 Python 버전 전환·pip 인터페이스·monorepo를 시도해 보세요: 👉 고급 사용법