예외 처리와 로깅으로 안정성을 확보했다면, 이제 실행 환경을 통제해야 팀과 서버 어디서든 같은 결과를 얻을 수 있습니다. 이번 글에서는 "가상환경 만들기 → pyproject에 적기 → uv로 설치하기"라는 핵심 루트를 먼저 잡고, 필요하면 CI나 pre-commit까지 단계적으로 확장하는 방식을 안내합니다.
이번 글에서 새로 나오는 용어
- pyproject.toml: 패키지 정보와 의존성을 선언하는 표준 설정 파일
- uv.lock:
uv가 만든 잠금 파일로 의존성 버전을 정확히 기록해 재현성을 높임 - 환경 변수: 실행 시점에 주입하는 키-값으로 API 키나 경로 같은 비밀 설정을 관리
핵심 개념
학습 메모
- 소요 시간: 50~60분
- 준비물: 가상환경·uv 설치 경험, requests 기반 스크립트
- 학습 목표:
pyproject.toml과uv명령으로 의존성과 환경 변수를 통제하기
가상환경은 프로젝트 전용 실행 공간을 만들고, pyproject.toml은 의존성을 한 문서에서 관리하게 해 줍니다. 이름이 낯설더라도 "폴더 하나 모아 두기" 정도의 개념으로 출발하세요.
코드로 따라하기
가상환경이 필요한 이유 (Core)
시스템 Python에 라이브러리를 전역 설치하면 버전 충돌이 일어나고, 서버/로컬 환경을 맞추기 어렵습니다. 가상환경(virtualenv)은 프로젝트별 독립적인 site-packages 디렉터리를 만들어 패키지 충돌을 막아 줍니다. 복잡하게 느껴지면, "프로젝트마다 전용 폴더를 만들어 거기서만 패키지를 쓰는 것"으로 이해하면 충분합니다.
uv venv .venv
source .venv/bin/activate
python --version
CI나 서버에서는 source .venv/bin/activate 대신 uv run python app.py처럼 실행할 수 있어 스크립트에서 경로 걱정을 덜 수 있습니다.
pyproject.toml 구성 (Core)
[project]
name = "mealbot"
version = "0.1.0"
description = "급식 알림 봇"
requires-python = ">=3.12"
[project.dependencies]
requests = "^2.31.0"
python-dotenv = "^1.0.1"
[tool.uv]
dev-dependencies = ["pytest", "ruff"]
pyproject.toml은 패키지 메타데이터와 의존성을 선언하는 표준 문서입니다. 버전 범위를 명시해 호환 가능한 업데이트를 허용하거나 고정할 수 있습니다. 처음에는 name, version, dependencies 세 줄만 채워도 괜찮으니 겁먹지 마세요.
📦 pyproject.toml은? 빌드 도구, 패키지 정보, 의존성을 한곳에 적는 Python 표준 설정 파일입니다.
setup.py대신 이 파일 하나만 관리하면 됩니다.
uv로 의존성 관리 (Core)
uv add requests typer
uv add --dev pytest
uv pip list
uv add는 pyproject와 잠금 파일을 동시에 갱신합니다. 처음에는 uv add <패키지명> → uv run python main.py 정도만 익히면 됩니다. 그 후에 uv lock이나 uv sync --frozen처럼 재현성을 강화하는 명령을 추가로 배우면 됩니다.
환경 변수 관리 (Core → Plus)
cp .env.example .env
.env.example에는 키 이름과 형식을 남기고 비밀 값은 비워둡니다. 실행 시에는
uv run --env-file .env python scripts/send_meal.py
처럼 명시적으로 파일을 지정합니다. 이 패턴을 익히면 학교 계정, 개인 계정 같은 서로 다른 설정을 간단히 바꿔 사용할 수 있습니다.
프로젝트 구조 제안 (Optional)
mealbot/
├── pyproject.toml
├── uv.lock
├── src/mealbot/__init__.py
├── tests/
├── scripts/
└── README.md
src 레이아웃을 사용하면 패키지가 설치되지 않은 상태에서 잘못된 import를 조기에 발견할 수 있습니다. 폴더 구조가 아직 부담스럽다면, pyproject와 uv.lock만 먼저 관리하다가 필요할 때 이 구성을 옮겨 와도 됩니다.
CI와 pre-commit 연동 (Optional)
- GitHub Actions에서
uv setup-python으로 캐시된 가상환경을 재사용 - pre-commit 훅에
uv run ruff check와uv run pytest를 등록해 local/CI 일관성 확보
이 섹션은 협업 프로젝트를 진행할 때만 필요한 확장 단계입니다. 개인 학습이라면 제목만 기억하고 넘어가도 괜찮습니다.
왜 중요한가
프로젝트 위생이 갖춰져야 동아리 노트북과 학교 서버 어디서든 같은 실행 결과를 얻을 수 있습니다. pyproject와 uv.lock을 관리하면 버전 충돌을 예방하고, .env 파일을 통해 민감한 값을 안전하게 주고받을 수 있습니다.
실습
- 따라 하기: 빈 폴더에서
uv init,uv add requests,uv add --dev pytest까지 진행하고pyproject.toml변화를 확인합니다. - 확장하기:
.env.example를 만들고uv run --env-file로 환경 변수를 적용한 실행 로그를 남깁니다. - 디버깅:
uv sync --frozen상태에서pyproject를 바꿔 오류를 만든 뒤 잠금 파일을 갱신하거나 변경을 되돌려 문제를 해결합니다. - 완료 기준:
pyproject,uv.lock,.env.example이 갖춰진 폴더 구조에서 명령어 하나로 동일한 환경을 재현할 수 있을 때입니다.
마무리
가상환경과 pyproject를 제대로 관리하면 패키지 충돌이나 "내 컴퓨터에서는 되는데" 같은 불신을 크게 줄일 수 있습니다. 다음 편에서는 이 환경 위에서 테스트를 자동화해 신뢰도를 한 단계 더 끌어올립니다.
💬 댓글
이 글에 대한 의견을 남겨주세요