본문 바로가기

AI Agent

uv + Ruff 완전 가이드 — OpenAI가 인수한 Python 툴링의 새 표준

반응형

pip install 10초, flake8 + black + isort 따로 실행, 가상환경 관리는 또 따로. Python 개발자가 매일 하던 일들입니다. Astral이 이걸 전부 Rust로 다시 만들었고, OpenAI가 3월 19일 인수했습니다. 이제 Python 생태계의 기본 툴링이 바뀝니다.

[핵심 요약]
→ Astral: uv + Ruff + ty를 Rust로 만든 스타트업 (2023년 창업)
→ OpenAI 인수: 2026년 3월 19일 발표, Codex 팀에 합류
→ 규모: uv 월간 다운로드 1억 2,600만회 / Ruff GitHub 34,000+ 스타
→ uv: pip + virtualenv + pyenv + pipx + pip-tools 전부 대체 — 10~100배 빠름
→ Ruff: flake8 + black + isort + pyupgrade 전부 대체 — 10~100배 빠름
→ ty: mypy/pyright 대체 예정 타입 체커 (개발 중)
→ 라이선스: MIT — 오픈소스 유지 약속
→ 이유: AI 에이전트(Codex)가 Python 전체 개발 라이프사이클 처리 위해

 


기존 Python 툴체인의 문제

기존 방식 (지옥의 조합):
→ pip: 패키지 설치
→ virtualenv / venv: 가상환경
→ pyenv: Python 버전 관리
→ pipx: CLI 도구 설치
→ pip-tools: 의존성 고정
→ poetry / pdm: 통합 관리 시도 (느림)

→ flake8: 린팅
→ black: 포매팅
→ isort: import 정렬
→ pyupgrade: 문법 업그레이드
→ bandit: 보안 검사

총합: 도구 10개 이상, 설정 파일 여러 개, 실행 시간 수십 초

Astral 이후:
→ uv: 위 5개 전부 대체 (패키지+환경+버전 통합)
→ Ruff: 위 4개 전부 대체 (린팅+포매팅 통합)
→ ty: mypy/pyright 대체 (개발 중)
→ 총합: 도구 2개, 설정 pyproject.toml 하나, 실행 시간 밀리초

실전 1 — uv 완전 설치 및 프로젝트 세팅

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

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

# 버전 확인
uv --version  # uv 0.6.x

새 프로젝트 시작

# 프로젝트 생성 (pyproject.toml 자동 생성)
uv init my-ai-agent
cd my-ai-agent

# Python 버전 지정 (pyenv 불필요)
uv python install 3.12
uv python pin 3.12

# 의존성 추가 (pip install 대체)
uv add anthropic fastapi "uvicorn[standard]"
uv add --dev pytest ruff

# 의존성 설치 (requirements.txt 대신 uv.lock 사용)
uv sync

생성된 pyproject.toml:

[project]
name = "my-ai-agent"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
    "anthropic>=0.49.0",
    "fastapi>=0.115.0",
    "uvicorn[standard]>=0.32.0",
]

[dependency-groups]
dev = [
    "pytest>=8.3.0",
    "ruff>=0.9.0",
]

pip과 비교

# pip (기존)
python -m venv .venv
source .venv/bin/activate
pip install anthropic fastapi uvicorn  # 30~60초

# uv (신규)
uv add anthropic fastapi uvicorn  # 1~3초 (10~100배 빠름)
# 가상환경 자동 생성, 활성화 불필요
[uv 핵심 개념]
→ uv.lock: 재현 가능한 의존성 고정 파일 (git 커밋 권장)
→ uv sync: lock 파일 기반 정확한 환경 재현
→ uv run: 가상환경 활성화 없이 명령 실행
→ uv tool install: pipx 대체 (전역 CLI 도구 설치)
→ uvx: 임시 실행 (npx 같은 개념)
→ workspace: 모노레포 멀티 패키지 지원

실전 2 — uv 실전 커맨드 완전 정리

# ── 의존성 관리 ──────────────────────────────

# 패키지 추가
uv add requests
uv add "django>=5.0"
uv add --dev pytest-asyncio  # 개발 의존성

# 패키지 제거
uv remove requests

# 의존성 업데이트
uv lock --upgrade          # 전체 업데이트
uv lock --upgrade-package django  # 특정 패키지만

# 의존성 트리 확인
uv tree

# ── 실행 ─────────────────────────────────────

# 스크립트 실행 (가상환경 활성화 불필요)
uv run python main.py
uv run pytest
uv run uvicorn app:app --reload

# 임시 실행 (설치 없이)
uvx ruff check .
uvx black --check .
uvx cowsay "hello"

# ── Python 버전 관리 (pyenv 대체) ────────────

# Python 버전 목록
uv python list

# 특정 버전 설치
uv python install 3.11 3.12 3.13

# 프로젝트에 버전 고정
uv python pin 3.12  # .python-version 파일 생성

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

# ── 전역 CLI 도구 (pipx 대체) ────────────────

# CLI 도구 설치
uv tool install ruff
uv tool install httpie
uv tool install claude-code  # 예시

# 설치된 도구 목록
uv tool list

# 도구 업데이트
uv tool upgrade ruff

# ── 기존 프로젝트 마이그레이션 ────────────────

# requirements.txt → uv
uv add $(cat requirements.txt)

# poetry → uv (pyproject.toml 자동 인식)
uv sync  # poetry.lock 무시하고 uv.lock 생성

실전 3 — Ruff 완전 설정

Ruff는 flake8 + black + isort + pyupgrade를 하나로 통합합니다.

# Ruff 설치 (uv로)
uv add --dev ruff

# 또는 전역 설치
uv tool install ruff

pyproject.toml 설정

[tool.ruff]
# 적용 경로
src = ["src", "tests"]
# Python 버전
target-version = "py312"
# 라인 길이 (black 기본값과 동일)
line-length = 88
# 무시할 파일/디렉토리
exclude = [
    ".git",
    ".venv",
    "__pycache__",
    "migrations",
]

[tool.ruff.lint]
# 활성화할 규칙 (기존 flake8 + 추가)
select = [
    "E",    # pycodestyle errors
    "W",    # pycodestyle warnings
    "F",    # Pyflakes (미사용 import 등)
    "I",    # isort (import 정렬)
    "N",    # pep8-naming
    "UP",   # pyupgrade (최신 문법으로 자동 업그레이드)
    "B",    # flake8-bugbear (흔한 버그 패턴)
    "S",    # flake8-bandit (보안)
    "ANN",  # 타입 어노테이션 강제
]
# 무시할 규칙
ignore = [
    "ANN101",  # self 어노테이션 불필요
    "S101",    # assert 허용 (테스트 코드)
]

[tool.ruff.lint.per-file-ignores]
# 테스트 파일은 일부 규칙 무시
"tests/**" = ["S101", "ANN"]

[tool.ruff.format]
# black 호환 포매터
quote-style = "double"
indent-style = "space"

실전 사용

# 린트 검사
ruff check .

# 자동 수정 (--fix)
ruff check --fix .

# 포매팅 (black 대체)
ruff format .

# 포매팅 체크만 (CI용)
ruff format --check .

# 특정 파일만
ruff check src/main.py
ruff format src/

# 규칙 설명 보기
ruff rule E501
# 속도 비교 (대형 프로젝트 기준)
# flake8 + black + isort (기존)
time flake8 .        # ~8초
time black --check . # ~5초
time isort --check . # ~3초
# 합계: ~16초

# Ruff (신규)
time ruff check .    # ~0.15초
time ruff format --check .  # ~0.1초
# 합계: ~0.25초 → 64배 빠름

실전 4 — CI/CD 통합

# .github/workflows/quality.yml
name: Code Quality

on: [push, pull_request]

jobs:
  quality:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      # uv 설치 (공식 액션)
      - name: Install uv
        uses: astral-sh/setup-uv@v5
        with:
          version: "latest"
          enable-cache: true  # 의존성 캐시

      # Python 설치 (pyenv 불필요)
      - name: Set up Python
        run: uv python install

      # 의존성 설치 (uv.lock 기반 재현)
      - name: Install dependencies
        run: uv sync --all-extras --dev

      # Ruff 린트
      - name: Lint with Ruff
        run: uv run ruff check .

      # Ruff 포맷 체크
      - name: Format check with Ruff
        run: uv run ruff format --check .

      # 테스트 실행
      - name: Run tests
        run: uv run pytest --cov=src tests/
# Makefile — 자주 쓰는 커맨드 단축
.PHONY: install lint format test clean

install:
	uv sync --all-extras --dev

lint:
	uv run ruff check .
	uv run ruff format --check .

format:
	uv run ruff check --fix .
	uv run ruff format .

test:
	uv run pytest -v

clean:
	find . -type d -name __pycache__ -exec rm -rf {} +
	find . -type f -name "*.pyc" -delete
	rm -rf .venv

# 전체 품질 체크 (CI와 동일)
check: lint test
[OpenAI 인수 이후 전망]
→ 단기 (6개월): 변화 없음. MIT 라이선스, 오픈소스 유지
→ 중기 (1년): Codex와 uv/Ruff 더 깊은 통합 예상
→ 우려: Codex 전용 기능 우선 개발, Claude Code 등 경쟁사에 불이익 가능성
→ 대응: MIT 라이선스라 포크 가능. 지금 당장은 계속 사용 권장
→ 모니터링: 거버넌스 변화, Codex 전용 기능 추가 여부 주시

마무리

✅ 지금 당장 uv + Ruff로 전환해야 하는 경우
→ 새 Python 프로젝트 시작하는 경우 (처음부터 uv로)
→ CI/CD 빌드가 느려서 답답한 팀
→ 린팅 도구 여러 개 관리가 귀찮은 경우
→ AI 에이전트(Codex, Claude Code)와 Python 개발 병행하는 경우
→ 재현 가능한 환경이 중요한 프로덕션 팀

❌ 당장 전환 안 해도 되는 경우
→ poetry/pdm으로 이미 완벽히 잘 돌아가는 기존 프로젝트
→ 팀 전체 마이그레이션 비용이 큰 대형 레거시 프로젝트
→ OpenAI 인수 이후 방향 지켜보고 싶은 경우
→ conda 생태계 의존성이 많은 데이터 사이언스 팀

관련 글

관련글 제목 확인할게요.관련 글

 

반응형