๐Ÿ’ป ๋‚ด๊ฐ€ ๋ณด๋ ค๊ณ  ์ž‘์„ฑํ•œ UV ์™„๋ฒฝ ๊ฐ€์ด๋“œ

Posted by Euisuk's Dev Log on April 24, 2025

๐Ÿ’ป ๋‚ด๊ฐ€ ๋ณด๋ ค๊ณ  ์ž‘์„ฑํ•œ UV ์™„๋ฒฝ ๊ฐ€์ด๋“œ

UV: Rust ๊ธฐ๋ฐ˜ ์ดˆ๊ณ ์† Python ํ™˜๊ฒฝ ๊ด€๋ฆฌ ๋„๊ตฌ ์™„๋ฒฝ ๊ฐ€์ด๋“œ

UV๋Š” Rust๋กœ ๊ตฌํ˜„๋œ ์ดˆ๊ณ ์† Python ํ™˜๊ฒฝ ๊ด€๋ฆฌ ๋„๊ตฌ๋กœ, Python ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ๊ฐ€์žฅ ๋น ๋ฅด๊ณ  ๊ฐ„๋‹จํ•˜๋ฉฐ ๊ฐ•๋ ฅํ•˜๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด์˜ ์—ฌ๋Ÿฌ ๋„๊ตฌ๋“ค(pyenv, pip, pipenv, venv ๋“ฑ)์„ ํ•˜๋‚˜๋กœ ํ†ตํ•ฉํ–ˆ์Šต๋‹ˆ๋‹ค.

(๊นƒํ—ˆ๋ธŒ) https://github.com/astral-sh/uv/blob/main/README.md

์ด ๊ฐ€์ด๋“œ์—์„œ๋Š” UV์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ๊ณผ ์‹ค๋ฌด ์ ์šฉ ๋ฐฉ๋ฒ•์„ ์ƒ์„ธํžˆ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  1. UV์˜ ๊ฐœ๋…๊ณผ ํŠน์ง•

https://docs.astral.sh/uv/getting-started/

UV๋ž€ ๋ฌด์—‡์ธ๊ฐ€?

UV๋Š” Astral์—์„œ ๊ฐœ๋ฐœํ•œ Rust ๊ธฐ๋ฐ˜์˜ Python ํ™˜๊ฒฝ ๊ด€๋ฆฌ ๋„๊ตฌ๋กœ, Python ์ƒํƒœ๊ณ„์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋‹ค์–‘ํ•œ ๋„๊ตฌ๋“ค์„ ํ•˜๋‚˜์˜ ํ†ตํ•ฉ๋œ CLI๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

  • ๊ธฐ์กด์— ์‚ฌ์šฉํ•˜๋˜ pip, pip-tools, pipx, poetry, pyenv, twine, virtualenv ๋“ฑ์„ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ํŠน์ง•

https://docs.astral.sh/uv/

  • ์ดˆ๊ณ ์† ์„ฑ๋Šฅ: Rust ์–ธ์–ด๋กœ ์ž‘์„ฑ๋˜์–ด ๊ธฐ์กด ๋„๊ตฌ๋ณด๋‹ค 10~100๋ฐฐ ๋น ๋ฅธ ์†๋„ ์ œ๊ณต
  • ํ†ตํ•ฉ๋œ ์›Œํฌํ”Œ๋กœ์šฐ: Python ๋ฒ„์ „ ๊ด€๋ฆฌ๋ถ€ํ„ฐ ํŒจํ‚ค์ง€ ์„ค์น˜, ๊ฐ€์ƒํ™˜๊ฒฝ ์ƒ์„ฑ, ํ”„๋กœ์ ํŠธ ๋ฐฐํฌ๊นŒ์ง€ ์ผ๊ด€๋œ ์ธํ„ฐํŽ˜์ด์Šค ์ œ๊ณต
  • ๋””์Šคํฌ ๊ณต๊ฐ„ ์ตœ์ ํ™”: ํ•˜๋“œ ๋งํฌ๋ฅผ ํ™œ์šฉํ•ด ์ค‘๋ณต ํŒจํ‚ค์ง€ ์„ค์น˜ ๋ฐฉ์ง€
  • ์žฌํ˜„ ๊ฐ€๋Šฅํ•œ ๋นŒ๋“œ: ์ •ํ™•ํ•œ ์˜์กด์„ฑ ์ž ๊ธˆ๊ณผ ํ•ด๊ฒฐ ๋ฉ”์ปค๋‹ˆ์ฆ˜
  • ๋ชจ๋˜ํ•œ ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ: pyproject.toml์„ ํ‘œ์ค€์œผ๋กœ ์‚ฌ์šฉํ•˜์—ฌ PEP 621 ์ค€์ˆ˜
  1. UV ์„ค์น˜ ๋ฐฉ๋ฒ•

https://docs.astral.sh/uv/getting-started/installation/#standalone-installer

์šด์˜์ฒด์ œ๋ณ„ ์„ค์น˜ ๊ฐ€์ด๋“œ

Windows

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

macOS/Linux

1
curl -LsSf https://astral.sh/uv/install.sh | sh

PyPI๋ฅผ ํ†ตํ•œ ์„ค์น˜

1
pip install uv

์„ค์น˜ ํ™•์ธ

1
uv --version

๐Ÿ’ก ์ฐธ๊ณ : UV๋ฅผ ์ „์—ญ์œผ๋กœ ์„ค์น˜ํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. pip install uv๋กœ ์„ค์น˜ํ•  ๊ฒฝ์šฐ ํŠน์ • ํ™˜๊ฒฝ์— ์ข…์†๋˜๊ธฐ ๋•Œ๋ฌธ์—, ์œ„์˜ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ†ตํ•œ ์„ค์น˜ ๋ฐฉ๋ฒ•์ด ๋” ํšจ๊ณผ์ ์ž…๋‹ˆ๋‹ค.

  1. UV ํ•ต์‹ฌ ๊ธฐ๋Šฅ ์ƒ์„ธ ๊ฐ€์ด๋“œ

3.1 Python ์„ค์น˜ ๋ฐ ๋ฒ„์ „ ๊ด€๋ฆฌ

UV๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ธฐ์กด pyenv์™€ ์œ ์‚ฌํ•˜๊ฒŒ ๋‹ค์–‘ํ•œ Python ๋ฒ„์ „์„ ์„ค์น˜ํ•˜๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Python ์„ค์น˜ํ•˜๊ธฐ

์ตœ์‹  ํŒŒ์ด์ฌ ์„ค์น˜:

1
uv python install

ํŠน์ • ๋ฒ„์ „ ํŒŒ์ด์ฌ ์„ค์น˜:

1
uv python install 3.12

๋ณต์ˆ˜๊ฐœ ํŠน์ • ๋ฒ„์ „ ํŒŒ์ด์ฌ ์„ค์น˜:

1
uv python install 3.11 3.12

์„ค์น˜ ์‹œ ์—๋Ÿฌ, ๋˜๋Š” ๋‹ค์‹œ ์„ค์น˜๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ

1
uv python install --reinstall

Python ๋ฒ„์ „ ๊ด€๋ฆฌ ๋ช…๋ น์–ด

๋ช…๋ น์–ด ์„ค๋ช…
uv python install <๋ฒ„์ „> ์ง€์ •ํ•œ Python ๋ฒ„์ „ ์„ค์น˜ (uv python install 3.12)
uv python list ์„ค์น˜ ๊ฐ€๋Šฅํ•œ Python ๋ฒ„์ „ ๋ชฉ๋ก ํ‘œ์‹œ
uv use <๋ฒ„์ „> ํ˜„์žฌ ๋””๋ ‰ํ† ๋ฆฌ์— .python-version ํŒŒ์ผ ์ƒ์„ฑํ•˜์—ฌ ๊ธฐ๋ณธ Python ๋ฒ„์ „ ์ง€์ •

๐Ÿ’ก ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ: uv python install --with-patches <ํŒจ์น˜๋ช…> <๋ฒ„์ „>๊ณผ ๊ฐ™์ด ํŠน์ • ํŒจ์น˜๊ฐ€ ์ ์šฉ๋œ Python ๋ฒ„์ „์„ ์„ค์น˜ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

Python ์„ค์น˜ ์‹œ, UV๋Š” python-build-standalone ํ”„๋กœ์ ํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•„์š”ํ•œ ์ตœ์†Œํ•œ์˜ ๊ตฌ์„ฑ์š”์†Œ๋งŒ ๋‹ค์šด๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค.

  • ์ด๋Š” ๋น ๋ฅธ ์„ค์น˜๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜์ง€๋งŒ, IDLE์ด๋‚˜ ๊ธฐํƒ€ ํ‘œ์ค€ ๋„๊ตฌ๊ฐ€ ํฌํ•จ๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

3.2 ํ”„๋กœ์ ํŠธ ์ดˆ๊ธฐํ™” ๋ฐ ๊ตฌ์„ฑ

UV๋Š” ํ”„๋กœ์ ํŠธ ์ดˆ๊ธฐํ™”๋ฅผ ์œ„ํ•œ ๊ฐ„๋‹จํ•œ ๋ช…๋ น์–ด๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๋ช…๋ น์–ด ์„ค๋ช… ์ƒ์„ฑ๋˜๋Š” ํŒŒ์ผ/๋””๋ ‰ํ† ๋ฆฌ
uv init ๊ธฐ๋ณธ ํ”„๋กœ์ ํŠธ ์ดˆ๊ธฐํ™” pyproject.toml, .python-version
uv init --package ํŒจํ‚ค์ง€ ํ˜•ํƒœ ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ pyproject.toml, .python-version, src/ ๋””๋ ‰ํ† ๋ฆฌ
uv init --lib ๋ฐฐํฌ์šฉ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ตฌ์กฐ์˜ pyproject.toml, ํ…Œ์ŠคํŠธ ๋””๋ ‰ํ† ๋ฆฌ ๋“ฑ

๐Ÿ’ผ pyproject.toml ์˜ˆ์‹œ:

1
2
3
4
5
6
7
8
9
10
[project]
name = "my-project"
version = "0.1.0"
description = "A sample Python project"
requires-python = ">=3.8"
dependencies = []

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

๐Ÿ’ก ์ฐธ๊ณ : uv init ๋ช…๋ น์–ด๋Š” .venv ๊ฐ€์ƒํ™˜๊ฒฝ์„ ์ฆ‰์‹œ ์ƒ์„ฑํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  • ํ•˜์ง€๋งŒ ์ดํ›„ uv add, uv run, uv sync ๋“ฑ์˜ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

3.3 ๊ฐ€์ƒํ™˜๊ฒฝ ์ƒ์„ฑ ๋ฐ ๊ด€๋ฆฌ

UV๋Š” ๊ฐ€์ƒํ™˜๊ฒฝ์„ ํšจ์œจ์ ์œผ๋กœ ์ƒ์„ฑํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๋ช…๋ น์–ด ์„ค๋ช… ์‚ฌ์šฉ ์ƒํ™ฉ
uv venv [๊ฒฝ๋กœ] ๊ฐ€์ƒํ™˜๊ฒฝ ์ƒ์„ฑ ํ”„๋กœ์ ํŠธ์™€ ๋ณ„๊ฐœ๋กœ ๋น ๋ฅด๊ฒŒ ๊ฐ€์ƒํ™˜๊ฒฝ ํ•„์š” ์‹œ
uv venv -p 3.11 [๊ฒฝ๋กœ] ํŠน์ • Python ๋ฒ„์ „์œผ๋กœ ๊ฐ€์ƒํ™˜๊ฒฝ ์ƒ์„ฑ ์‹œ์Šคํ…œ Python๊ณผ ๋‹ค๋ฅธ ๋ฒ„์ „์œผ๋กœ ์ž‘์—… ํ•„์š” ์‹œ
uv sync pyproject.toml๊ณผ uv.lock ๊ธฐ๋ฐ˜์œผ๋กœ .venv ๋™๊ธฐํ™” ํ”„๋กœ์ ํŠธ ํด๋ก  ํ›„ ํ™˜๊ฒฝ ์žฌํ˜„ ์‹œ

๐Ÿ’ผ venv ์˜ˆ์‹œ:

1
2
3
4
5
# ํŠน์ • Python ๋ฒ„์ „์œผ๋กœ ๊ฐ€์ƒํ™˜๊ฒฝ ์ƒ์„ฑ
uv venv -p 3.10 .venv-310

# ํ˜„์žฌ ํ”„๋กœ์ ํŠธ ์„ค์ •์œผ๋กœ ๊ฐ€์ƒํ™˜๊ฒฝ ๋™๊ธฐํ™”
uv sync

ํ˜„์žฌ ํ”„๋กœ์ ํŠธ ์„ค์ •์œผ๋กœ ๊ฐ€์ƒํ™˜๊ฒฝ ๋™๊ธฐํ™”๋ž€?

  • uv sync ๋ช…๋ น์–ด์˜ ์˜๋ฏธ๋Š” ๋‹จ์ˆœํžˆ โ€œํ˜„์žฌ ๊ฒฝ๋กœ์˜ .venv์™€ ๋™๊ธฐํ™”ํ•œ๋‹คโ€๋Š” ์˜๋ฏธ๊ฐ€ ์•„๋‹ˆ๋ผ, ํ˜„์žฌ ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ† ๋ฆฌ์— ์กด์žฌํ•˜๋Š” pyproject.toml ๋ฐ uv.lock ํŒŒ์ผ์„ ๊ธฐ์ค€์œผ๋กœ ๊ฐ€์ƒํ™˜๊ฒฝ์„ ๊ตฌ์„ฑ(์žฌํ˜„)ํ•œ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค.
  • ์ฆ‰, ์ด๋Ÿฐ ํ๋ฆ„์ด ๋ฉ๋‹ˆ๋‹ค:
    1. uv init ํ˜น์€ ์ˆ˜๋™์œผ๋กœ pyproject.toml ์ž‘์„ฑ
    2. ์˜์กด์„ฑ ์ถ”๊ฐ€ โ†’ uv add ...
    3. uv lock ์‹คํ–‰ โ†’ uv.lock ์ƒ์„ฑ๋จ
    4. ์ดํ›„์—:
      • .venv๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ or ์ƒˆ๋กœ์šด ํ™˜๊ฒฝ์„ ๋งŒ๋“ค์—ˆ์„ ๊ฒฝ์šฐ
      • โ†’ uv sync๋Š” pyproject.toml๊ณผ uv.lock์„ ๊ธฐ์ค€์œผ๋กœ ํ•„์š”ํ•œ ํŒจํ‚ค์ง€๋ฅผ .venv (ํ˜น์€ ๋‹ค๋ฅธ ์ง€์ •๋œ ๊ฐ€์ƒํ™˜๊ฒฝ) ์— ์„ค์น˜ํ•˜์—ฌ ํ™˜๊ฒฝ์„ ์ผ๊ด€์„ฑ ์žˆ๊ฒŒ ์žฌํ˜„ํ•˜๋Š” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ’ก ์„ฑ๋Šฅ ์ด์ : UV๋กœ ์ƒ์„ฑํ•œ ๊ฐ€์ƒํ™˜๊ฒฝ์€ ํ‘œ์ค€ venv ๋ชจ๋“ˆ๋กœ ์ƒ์„ฑํ•œ ๊ฒƒ๊ณผ ํ˜ธํ™˜๋˜์ง€๋งŒ, ์ƒ์„ฑ ์†๋„๊ฐ€ ํ›จ์”ฌ ๋น ๋ฆ…๋‹ˆ๋‹ค.

์ฐธ๊ณ : UV venv์™€ UV init์˜ ์ฐจ์ด์ 

uv venv์™€ uv init์€ ๋ชฉ์ ๊ณผ ์‚ฌ์šฉ ์‹œ๋‚˜๋ฆฌ์˜ค๊ฐ€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค:

uv venv

  • ๋ชฉ์ : ์ˆœ์ˆ˜ํ•˜๊ฒŒ ๊ฐ€์ƒํ™˜๊ฒฝ๋งŒ ์ƒ์„ฑ
  • ๊ฒฐ๊ณผ๋ฌผ: Python ์ธํ„ฐํ”„๋ฆฌํ„ฐ์™€ ๊ธฐ๋ณธ ํŒจํ‚ค์ง€๋ฅผ ํฌํ•จํ•œ ๊ฐ€์ƒํ™˜๊ฒฝ(.venv ๋””๋ ‰ํ† ๋ฆฌ)
  • ์‚ฌ์šฉ ์‹œ๊ธฐ: ๋น ๋ฅด๊ฒŒ ๊ฒฉ๋ฆฌ๋œ Python ํ™˜๊ฒฝ์ด ํ•„์š”ํ•  ๋•Œ, ํ”„๋กœ์ ํŠธ ์„ค์ • ์—†์ด ๋‹จ์ˆœ ์‹คํ—˜ํ•  ๋•Œ
  • ํŠน์ง•: ํ”„๋กœ์ ํŠธ ํŒŒ์ผ(pyproject.toml) ์ƒ์„ฑํ•˜์ง€ ์•Š์Œ

uv init

  • ๋ชฉ์ : ํ”„๋กœ์ ํŠธ ์ดˆ๊ธฐํ™” ๋ฐ ๊ตฌ์กฐ ์„ค์ •
  • ๊ฒฐ๊ณผ๋ฌผ: pyproject.toml, .python-version ๋ฐ ๊ธฐํƒ€ ํ”„๋กœ์ ํŠธ ํŒŒ์ผ
  • ์‚ฌ์šฉ ์‹œ๊ธฐ: ์ƒˆ Python ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•  ๋•Œ, ์˜์กด์„ฑ ๊ด€๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ ์ฒด๊ณ„์ ์ธ ๊ฐœ๋ฐœ ์‹œ
  • ํŠน์ง•: ์ฆ‰์‹œ ๊ฐ€์ƒํ™˜๊ฒฝ์„ ์ƒ์„ฑํ•˜์ง€ ์•Š์ง€๋งŒ, ์ถ”ํ›„ ๋ช…๋ น์–ด(uv sync, uv add ๋“ฑ) ์‹คํ–‰ ์‹œ ์ž๋™์œผ๋กœ ์ƒ์„ฑ

๊ฐ€์ƒํ™˜๊ฒฝ ํ™œ์„ฑํ™” ๋ฐฉ๋ฒ•

UV์˜ ํฐ ์žฅ์  ์ค‘ ํ•˜๋‚˜๋Š” ์ „ํ†ต์ ์ธ ๊ฐ€์ƒํ™˜๊ฒฝ ํ™œ์„ฑํ™”(activate) ๊ณผ์ •์ด ํ•„์š” ์—†๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค.

  • ํ•˜์ง€๋งŒ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

1. UV ๋ช…๋ น์–ด๋กœ ์ง์ ‘ ์‹คํ–‰ (ํ™œ์„ฑํ™” ๋ถˆํ•„์š”)

1
2
3
uv run python script.py
uv add requests
uv run -- python -c "import sys; print(sys.prefix)"

2. ์ „ํ†ต์ ์ธ ๊ฐ€์ƒํ™˜๊ฒฝ ํ™œ์„ฑํ™” ๋ฐฉ๋ฒ•

Windows:

1
2
.\.venv\Scripts\Activate.ps1
.\.venv\Scripts\activate.bat

macOS/Linux:

1
source .venv/bin/activate

3. ๊ฐ€์ƒํ™˜๊ฒฝ Python ์ง์ ‘ ์ฐธ์กฐ

Windows:

1
.\.venv\Scripts\python script.py

macOS/Linux:

1
./.venv/bin/python script.py

3.4 ์˜์กด์„ฑ ๊ด€๋ฆฌ

UV๋Š” ํ”„๋กœ์ ํŠธ์˜ ์˜์กด์„ฑ์„ pyproject.toml ํŒŒ์ผ์— ๊ธฐ๋กํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๋Š” ํ˜„๋Œ€์ ์ธ ๋ฐฉ์‹์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. uv add ๋ช…๋ น์–ด๋Š” ๋‹จ์ˆœํžˆ ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•˜๋Š” ๊ฒƒ์„ ๋„˜์–ด, ํ”„๋กœ์ ํŠธ ์„ค์ • ํŒŒ์ผ์— ์˜์กด์„ฑ์„ ์ž๋™์œผ๋กœ ์ถ”๊ฐ€ํ•˜๊ณ  ๋ฝํŒŒ์ผ์„ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.

uv add์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ

uv add๋Š” ํ”„๋กœ์ ํŠธ ๋ ˆ๋ฒจ์˜ ์˜์กด์„ฑ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ ๋ช…๋ น์–ด์ž…๋‹ˆ๋‹ค. ์ด ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด:

  1. ํŒจํ‚ค์ง€ ์„ค์น˜: ์ง€์ •ํ•œ ํŒจํ‚ค์ง€๋ฅผ ํ˜„์žฌ ํ”„๋กœ์ ํŠธ์˜ ๊ฐ€์ƒํ™˜๊ฒฝ์— ์„ค์น˜
  2. pyproject.toml ์—…๋ฐ์ดํŠธ: ์˜์กด์„ฑ ์ •๋ณด๋ฅผ ํ”„๋กœ์ ํŠธ ์„ค์ • ํŒŒ์ผ์— ์ž๋™ ๊ธฐ๋ก
  3. ๋ฝํŒŒ์ผ ๊ฐฑ์‹ : uv.lock ํŒŒ์ผ์„ ์—…๋ฐ์ดํŠธํ•˜์—ฌ ์ •ํ™•ํ•œ ๋ฒ„์ „ ๊ณ ์ •
  4. ๊ฐ€์ƒํ™˜๊ฒฝ ์ž๋™ ์ƒ์„ฑ: .venv๊ฐ€ ์—†์œผ๋ฉด ์ž๋™์œผ๋กœ ์ƒ์„ฑ

๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•

๋ช…๋ น์–ด ์„ค๋ช… pyproject.toml ๋ฐ˜์˜
uv add <ํŒจํ‚ค์ง€> ํ”„๋กœ๋•์…˜ ์˜์กด์„ฑ ์ถ”๊ฐ€ โœ… [project.dependencies]
uv add --dev <ํŒจํ‚ค์ง€> ๊ฐœ๋ฐœ ์˜์กด์„ฑ ์ถ”๊ฐ€ โœ… [dependency-groups.dev]
uv add --optional <๊ทธ๋ฃน> <ํŒจํ‚ค์ง€> ์„ ํƒ์  ์˜์กด์„ฑ ์ถ”๊ฐ€ โœ… [project.optional-dependencies.<๊ทธ๋ฃน>]
uv remove <ํŒจํ‚ค์ง€> ์˜์กด์„ฑ ์ œ๊ฑฐ โœ… ํ•ด๋‹น ์„น์…˜์—์„œ ์ œ๊ฑฐ
uv lock ๋ฝํŒŒ์ผ ์ƒ์„ฑ/๊ฐฑ์‹  uv.lock ํŒŒ์ผ ์—…๋ฐ์ดํŠธ

์‹ค์ „ ์˜ˆ์ œ

1. ๊ธฐ๋ณธ ์˜์กด์„ฑ ์ถ”๊ฐ€

1
2
3
4
5
6
7
8
9
# ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ถ”๊ฐ€
uv add pandas numpy

# ๊ฒฐ๊ณผ: pyproject.toml
[project]
dependencies = [
    "pandas>=2.1.0",
    "numpy>=1.26.0",
]

2. ํŠน์ • ๋ฒ„์ „ ์ง€์ •

1
2
3
4
5
6
7
8
# ์ •ํ™•ํ•œ ๋ฒ„์ „ ์ง€์ •
uv add "requests==2.31.0"

# ๋ฒ„์ „ ๋ฒ”์œ„ ์ง€์ •
uv add "fastapi>=0.104.0,<1.0.0"

# ์ตœ์†Œ ๋ฒ„์ „๋งŒ ์ง€์ •
uv add "scikit-learn>=1.3.0"

3. ๊ฐœ๋ฐœ ์˜์กด์„ฑ ๊ด€๋ฆฌ

1
2
3
4
5
6
7
8
9
10
11
# ํ…Œ์ŠคํŠธ ๋ฐ ๋ฆฐํŒ… ๋„๊ตฌ ์ถ”๊ฐ€
uv add --dev pytest black ruff mypy

# ๊ฒฐ๊ณผ: pyproject.toml
[dependency-groups]
dev = [
    "pytest>=7.4.0",
    "black>=23.10.0",
    "ruff>=0.1.0",
    "mypy>=1.6.0",
]

4. ์„ ํƒ์  ์˜์กด์„ฑ ๊ทธ๋ฃน

1
2
3
4
5
6
7
8
9
10
# ๋ฌธ์„œํ™” ๋„๊ตฌ๋ฅผ ์„ ํƒ์  ๊ทธ๋ฃน์œผ๋กœ ์ถ”๊ฐ€
uv add --optional docs sphinx sphinx-rtd-theme

# ML ๊ด€๋ จ ํŒจํ‚ค์ง€๋ฅผ ๋ณ„๋„ ๊ทธ๋ฃน์œผ๋กœ ๊ด€๋ฆฌ
uv add --optional ml tensorflow torch

# ๊ฒฐ๊ณผ: pyproject.toml
[project.optional-dependencies]
docs = ["sphinx>=7.0.0", "sphinx-rtd-theme>=1.3.0"]
ml = ["tensorflow>=2.14.0", "torch>=2.1.0"]

5. Git ์ €์žฅ์†Œ์—์„œ ์ง์ ‘ ์„ค์น˜

1
2
3
# ํŠน์ • ๋ธŒ๋žœ์น˜๋‚˜ ํƒœ๊ทธ์—์„œ ์„ค์น˜
uv add "git+https://github.com/user/repo.git@main"
uv add "git+https://github.com/user/repo.git@v1.0.0"

uv add์˜ ๋™์ž‘ ์›๋ฆฌ

uv add pandas๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ณผ์ •์ด ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค:

  1. ์˜์กด์„ฑ ๋ถ„์„: pandas์™€ ๊ทธ ํ•˜์œ„ ์˜์กด์„ฑ ํ™•์ธ
  2. ๋ฒ„์ „ ํ•ด์„: ํ˜ธํ™˜ ๊ฐ€๋Šฅํ•œ ์ตœ์‹  ๋ฒ„์ „ ๊ฒฐ์ •
  3. pyproject.toml ์ˆ˜์ •: [project.dependencies]์— ํŒจํ‚ค์ง€ ์ถ”๊ฐ€
  4. ๋ฝํŒŒ์ผ ์—…๋ฐ์ดํŠธ: uv.lock์— ์ •ํ™•ํ•œ ๋ฒ„์ „ ์ •๋ณด ๊ธฐ๋ก
  5. ํŒจํ‚ค์ง€ ์„ค์น˜: .venv์— ์‹ค์ œ ํŒจํ‚ค์ง€ ์„ค์น˜

์ด ๋ชจ๋“  ๊ณผ์ •์ด ์ž๋™ํ™”๋˜์–ด ์žˆ์–ด, ๊ฐœ๋ฐœ์ž๋Š” ๋‹จ์ˆœํžˆ uv add ๋ช…๋ น๋งŒ ์‹คํ–‰ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

๐Ÿ’ก ํ•˜๋“œ ๋งํฌ์˜ ์ด์ : UV๋Š” ํŒจํ‚ค์ง€ ์„ค์น˜ ์‹œ ํ•˜๋“œ ๋งํฌ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋™์ผํ•œ ํŒจํ‚ค์ง€๊ฐ€ ์—ฌ๋Ÿฌ ํ™˜๊ฒฝ์— ์„ค์น˜๋˜๋”๋ผ๋„ ๋””์Šคํฌ ๊ณต๊ฐ„์„ ์ ˆ์•ฝํ•ฉ๋‹ˆ๋‹ค.

  • ํ•˜๋“œ ๋งํฌ(Hard link)๋Š” ๋™์ผํ•œ ํŒŒ์ผ ๋ฐ์ดํ„ฐ๋ฅผ ์—ฌ๋Ÿฌ ์œ„์น˜์—์„œ ๊ณต์œ ํ•˜๋„๋ก ํ•˜๋Š” ํŒŒ์ผ ์‹œ์Šคํ…œ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.
  • UV๋Š” ์ด๋ฏธ ์„ค์น˜๋œ ํŒจํ‚ค์ง€์˜ ๋ฐ”์ด๋„ˆ๋ฆฌ ํŒŒ์ผ์„ ๋ณต์‚ฌํ•˜์ง€ ์•Š๊ณ , ๋‹ค๋ฅธ ๊ฐ€์ƒํ™˜๊ฒฝ์—์„œ ํ•ด๋‹น ํŒŒ์ผ์— ๋Œ€ํ•œ ํ•˜๋“œ ๋งํฌ๋งŒ ์ƒ์„ฑํ•˜์—ฌ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.
  • ์ด ๋ฐฉ์‹์€ ์—ฌ๋Ÿฌ ๊ฐ€์ƒํ™˜๊ฒฝ์ด ๋™์ผํ•œ ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์—๋„ ๋””์Šคํฌ ๊ณต๊ฐ„์„ ์ถ”๊ฐ€๋กœ ์†Œ๋ชจํ•˜์ง€ ์•Š์œผ๋ฉฐ, ์„ค์น˜ ์†๋„๋„ ๋น„์•ฝ์ ์œผ๋กœ ํ–ฅ์ƒ๋ฉ๋‹ˆ๋‹ค.
    • ์˜ˆ๋ฅผ ๋“ค์–ด numpy์™€ ๊ฐ™์€ ๋Œ€ํ˜• ํŒจํ‚ค์ง€๋ฅผ ์—ฌ๋Ÿฌ ํ”„๋กœ์ ํŠธ์—์„œ ์‚ฌ์šฉํ•˜๋”๋ผ๋„ ์‹ค์ œ ๋””์Šคํฌ์—๋Š” ํ•˜๋‚˜๋งŒ ์กด์žฌํ•˜๋ฉฐ, ๊ฐ .venv๋Š” ํ•ด๋‹น ํŒŒ์ผ์— ๋Œ€ํ•œ ์ฐธ์กฐ๋งŒ ๊ฐ€์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

3.5 ์‹คํ–‰ ๋ฐ ์Šคํฌ๋ฆฝํŠธ ๊ด€๋ฆฌ

UV๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ€์ƒํ™˜๊ฒฝ ๋‚ด์—์„œ ๋ช…๋ น์–ด์™€ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ช…๋ น์–ด ์„ค๋ช… ์˜ˆ์‹œ
uv run <๋ช…๋ น์–ด> ๊ฐ€์ƒํ™˜๊ฒฝ์—์„œ ๋ช…๋ น์–ด ์‹คํ–‰ uv run python script.py
uv run --with <ํŒจํ‚ค์ง€> <๋ช…๋ น์–ด> ์ถ”๊ฐ€ ํŒจํ‚ค์ง€์™€ ํ•จ๊ป˜ ์‹คํ–‰ uv run --with rich script.py
uv pip freeze ์„ค์น˜๋œ ํŒจํ‚ค์ง€ ๋ชฉ๋ก ์ถœ๋ ฅ uv pip freeze > requirements.txt

๐Ÿ’ผ ์˜ˆ์‹œ - ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ๋ช…๋ น์–ด:

1
2
3
4
5
# Jupyter Lab ์‹คํ–‰
uv run jupyter lab

# ํ…Œ์ŠคํŠธ ์‹คํ–‰
uv run pytest

๐Ÿ’ก ์ž๋™ ๊ฐ€์ƒํ™˜๊ฒฝ ์ƒ์„ฑ: .venv๊ฐ€ ์—†๋Š” ์ƒํƒœ์—์„œ uv run์„ ์‹คํ–‰ํ•˜๋ฉด, UV๋Š” ์ž๋™์œผ๋กœ ๊ฐ€์ƒํ™˜๊ฒฝ์„ ์ƒ์„ฑํ•˜๊ณ  ์˜์กด์„ฑ์„ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

3.6 ๋„๊ตฌ ๊ด€๋ฆฌ (uvx์™€ uv tool)

UV๋Š” Python ๊ธฐ๋ฐ˜ CLI ๋„๊ตฌ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

uv tool - ์˜๊ตฌ ์„ค์น˜

๋ช…๋ น์–ด ์„ค๋ช… ์˜ˆ์‹œ
uv tool install <๋„๊ตฌ> CLI ๋„๊ตฌ ์˜๊ตฌ ์„ค์น˜ uv tool install black
uv tool uninstall <๋„๊ตฌ> ์„ค์น˜๋œ ๋„๊ตฌ ์ œ๊ฑฐ uv tool uninstall black
uv tool list ์„ค์น˜๋œ ๋„๊ตฌ ๋ชฉ๋ก ํ‘œ์‹œ uv tool list

uvx - ์ผํšŒ์„ฑ ์‹คํ–‰

uvx๋Š” CLI ๋„๊ตฌ๋ฅผ ์ž„์‹œ ํ™˜๊ฒฝ์—์„œ ์‹คํ–‰ํ•˜๋Š” ๋ช…๋ น์–ด๋กœ, uv tool run์˜ ๋ณ„์นญ์ž…๋‹ˆ๋‹ค.

๋ช…๋ น์–ด ์„ค๋ช… ์˜ˆ์‹œ
uvx <๋„๊ตฌ> [์ธ์ž] ๋„๊ตฌ ์ž„์‹œ ์„ค์น˜ ๋ฐ ์‹คํ–‰ uvx black .
uvx --from '<ํŒจํ‚ค์ง€>' <๋ช…๋ น์–ด> ํŠน์ • ํŒจํ‚ค์ง€ ๋ฒ„์ „์œผ๋กœ ์‹คํ–‰ uvx --from 'ruff==0.3.0' ruff check .

๐Ÿ’ก ์„ฑ๋Šฅ ์ตœ์ ํ™”: uvx๋Š” ์บ์‹ฑ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ™์€ ๋„๊ตฌ๋ฅผ ๋ฐ˜๋ณต ์‹คํ–‰ํ•  ๋•Œ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•ฉ๋‹ˆ๋‹ค.

3.7 ํ”„๋กœ์ ํŠธ ์˜์กด์„ฑ vs ๋„๊ตฌ ๊ด€๋ฆฌ: uv add vs uv tool์˜ ์ฐจ์ด

๋งŽ์€ ๊ฐœ๋ฐœ์ž๋“ค์ด uv add์™€ uv tool์„ ํ˜ผ๋™ํ•ฉ๋‹ˆ๋‹ค. ๋‘ ๋ช…๋ น์–ด๋Š” ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•œ๋‹ค๋Š” ๊ณตํ†ต์ ์ด ์žˆ์ง€๋งŒ, ๋ชฉ์ ๊ณผ ๋ฒ”์œ„, ์‚ฌ์šฉ ์‹œ๋‚˜๋ฆฌ์˜ค๊ฐ€ ์™„์ „ํžˆ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ์ฐจ์ด์  ์š”์•ฝ

๊ตฌ๋ถ„ uv add uv tool
๋ชฉ์  ํ”„๋กœ์ ํŠธ ์˜์กด์„ฑ ๊ด€๋ฆฌ CLI ๋„๊ตฌ ์ „์—ญ ์„ค์น˜
๋ฒ”์œ„ ํ˜„์žฌ ํ”„๋กœ์ ํŠธ๋งŒ ์‹œ์Šคํ…œ ์ „์—ญ(์‚ฌ์šฉ์ž ๋ ˆ๋ฒจ)
์„ค์น˜ ์œ„์น˜ .venv/ (ํ”„๋กœ์ ํŠธ๋ณ„ ๊ฐ€์ƒํ™˜๊ฒฝ) ~/.local/bin/ (์ „์—ญ ๊ฒฝ๋กœ)
pyproject.toml โœ… ๊ธฐ๋ก๋จ โŒ ๊ธฐ๋ก ์•ˆ ๋จ
uv.lock โœ… ๋ฒ„์ „ ๊ณ ์ •๋จ โŒ ๋…๋ฆฝ ๊ด€๋ฆฌ
์‚ฌ์šฉ ๋Œ€์ƒ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ, ํ”„๋ ˆ์ž„์›Œํฌ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ CLI ๋„๊ตฌ
์˜ˆ์‹œ pandas, fastapi, requests black, ruff, pytest

์–ธ์ œ uv add๋ฅผ ์‚ฌ์šฉํ•˜๋‚˜?

uv add๋Š” ํ˜„์žฌ ์ž‘์—… ์ค‘์ธ ํ”„๋กœ์ ํŠธ์—์„œ ์ฝ”๋“œ ๋‚ด์—์„œ importํ•˜์—ฌ ์‚ฌ์šฉํ•  ํŒจํ‚ค์ง€๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์‚ฌ์šฉ ์‹œ๋‚˜๋ฆฌ์˜ค:

1
2
3
4
5
6
7
8
9
10
11
# โœ… ๋ฐ์ดํ„ฐ ๋ถ„์„ ํ”„๋กœ์ ํŠธ
uv add pandas numpy matplotlib

# โœ… ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ
uv add fastapi uvicorn sqlalchemy

# โœ… ๋จธ์‹ ๋Ÿฌ๋‹ ํ”„๋กœ์ ํŠธ
uv add scikit-learn tensorflow

# โœ… ํ…Œ์ŠคํŠธ ์ž‘์„ฑ (๊ฐœ๋ฐœ ์˜์กด์„ฑ)
uv add --dev pytest pytest-cov

ํŠน์ง•:

  • ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ† ๋ฆฌ ๋‚ด .venv์— ์„ค์น˜
  • pyproject.toml์— ์˜์กด์„ฑ ๊ธฐ๋ก
  • ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๊ฐ€ uv sync๋กœ ๋™์ผ ํ™˜๊ฒฝ ์žฌํ˜„ ๊ฐ€๋Šฅ
  • ํ”„๋กœ์ ํŠธ ๊ฐ„ ๋…๋ฆฝ์  ๊ด€๋ฆฌ

์–ธ์ œ uv tool์„ ์‚ฌ์šฉํ•˜๋‚˜?

uv tool์€ ํ”„๋กœ์ ํŠธ์™€ ๋ฌด๊ด€ํ•˜๊ฒŒ ๋ช…๋ น์ค„์—์„œ ์ง์ ‘ ์‹คํ–‰ํ•˜๋Š” CLI ๋„๊ตฌ๋ฅผ ์‹œ์Šคํ…œ ์ „์—ญ์— ์„ค์น˜ํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์‚ฌ์šฉ ์‹œ๋‚˜๋ฆฌ์˜ค:

1
2
3
4
5
6
7
8
9
10
11
# โœ… ์ฝ”๋“œ ํฌ๋งทํ„ฐ ์ „์—ญ ์„ค์น˜
uv tool install black

# โœ… ๋ฆฐํ„ฐ ์ „์—ญ ์„ค์น˜  
uv tool install ruff

# โœ… HTTP ํด๋ผ์ด์–ธํŠธ ๋„๊ตฌ
uv tool install httpie

# โœ… ํ”„๋กœ์ ํŠธ ์Šค์บํด๋”ฉ ๋„๊ตฌ
uv tool install cookiecutter

ํŠน์ง•:

  • ์‚ฌ์šฉ์ž ํ™ˆ ๋””๋ ‰ํ† ๋ฆฌ (~/.local/bin/)์— ์„ค์น˜
  • ์–ด๋–ค ๋””๋ ‰ํ† ๋ฆฌ์—์„œ๋“  ์‹คํ–‰ ๊ฐ€๋Šฅ
  • ํ”„๋กœ์ ํŠธ๋ณ„ ์„ค์ •๊ณผ ๋ฌด๊ด€
  • pyproject.toml์— ๊ธฐ๋ก๋˜์ง€ ์•Š์Œ

์‹ค์ „ ๋น„๊ต ์˜ˆ์‹œ

์‹œ๋‚˜๋ฆฌ์˜ค 1: Black ํฌ๋งทํ„ฐ

1
2
3
4
5
6
7
8
9
# โŒ ์ž˜๋ชป๋œ ์‚ฌ์šฉ - ํ”„๋กœ์ ํŠธ ์˜์กด์„ฑ์œผ๋กœ ์ถ”๊ฐ€
uv add black
# โ†’ .venv์—๋งŒ ์„ค์น˜๋จ, ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ์—์„œ ์‚ฌ์šฉ ๋ถˆ๊ฐ€
# โ†’ ๋งค ํ”„๋กœ์ ํŠธ๋งˆ๋‹ค ์„ค์น˜ ํ•„์š”

# โœ… ์˜ฌ๋ฐ”๋ฅธ ์‚ฌ์šฉ - ์ „์—ญ ๋„๊ตฌ๋กœ ์„ค์น˜
uv tool install black
# โ†’ ์‹œ์Šคํ…œ ์–ด๋””์„œ๋“  `black` ๋ช…๋ น์–ด ์‚ฌ์šฉ ๊ฐ€๋Šฅ
# โ†’ ๋ชจ๋“  ํ”„๋กœ์ ํŠธ์—์„œ ๋™์ผํ•œ ๋ฒ„์ „ ์‚ฌ์šฉ

์‹œ๋‚˜๋ฆฌ์˜ค 2: Pytest

์ผ€์ด์Šค A - ํ”„๋กœ์ ํŠธ ์˜์กด์„ฑ์œผ๋กœ ๊ด€๋ฆฌ:

1
2
3
uv add --dev pytest
# โ†’ ํŒ€์›๋“ค๊ณผ ๋™์ผํ•œ pytest ๋ฒ„์ „ ๊ณต์œ 
# โ†’ CI/CD ํŒŒ์ดํ”„๋ผ์ธ์—์„œ๋„ ๋™์ผ ๋ฒ„์ „ ๋ณด์žฅ

์ผ€์ด์Šค B - ์ „์—ญ ๋„๊ตฌ๋กœ ์„ค์น˜:

1
2
3
uv tool install pytest
# โ†’ ๋น ๋ฅธ ํ…Œ์ŠคํŠธ ์‹คํ–‰์„ ์œ„ํ•œ ๊ฐœ์ธ ํ™˜๊ฒฝ ๊ตฌ์„ฑ
# โ†’ ํ”„๋กœ์ ํŠธ๋ณ„ ๋ฒ„์ „ ์ฐจ์ด ๊ฐ€๋Šฅ์„ฑ ์กด์žฌ

์‹œ๋‚˜๋ฆฌ์˜ค 3: ๋ฐ์ดํ„ฐ ๋ถ„์„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

1
2
3
4
5
6
7
8
# โœ… ์˜ฌ๋ฐ”๋ฅธ ์‚ฌ์šฉ - ํ”„๋กœ์ ํŠธ ์˜์กด์„ฑ
uv add pandas numpy matplotlib
# โ†’ import pandas๋กœ ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉ
# โ†’ pyproject.toml์— ๊ธฐ๋ก๋˜์–ด ์žฌํ˜„ ๊ฐ€๋Šฅ

# โŒ ์ž˜๋ชป๋œ ์‚ฌ์šฉ - ์ „์—ญ ๋„๊ตฌ๋กœ ์„ค์น˜ํ•˜๋ฉด ์•ˆ ๋จ
uv tool install pandas  # ๋ถˆ๊ฐ€๋Šฅํ•˜๊ณ  ์˜๋ฏธ ์—†์Œ
# โ†’ pandas๋Š” CLI ๋„๊ตฌ๊ฐ€ ์•„๋‹ˆ๋ฏ€๋กœ tool๋กœ ์„ค์น˜ ๋ถˆ๊ฐ€

uvx: ์ผํšŒ์„ฑ ๋„๊ตฌ ์‹คํ–‰

uvx๋Š” uv tool run์˜ ๋ณ„์นญ์œผ๋กœ, ์„ค์น˜ ์—†์ด ๋„๊ตฌ๋ฅผ ์ž„์‹œ๋กœ ์‹คํ–‰ํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

1
2
3
4
5
6
7
8
# ์ž„์‹œ๋กœ black ์‹คํ–‰ (์„ค์น˜ํ•˜์ง€ ์•Š์Œ)
uvx black .

# ์ž„์‹œ๋กœ cookiecutter ์‹คํ–‰
uvx cookiecutter gh:user/template

# ํŠน์ • ๋ฒ„์ „์œผ๋กœ ์‹คํ–‰
uvx --from 'ruff==0.1.6' ruff check .

uvx์˜ ์žฅ์ :

  • ๋„๊ตฌ ์„ค์น˜ ์—†์ด ์ฆ‰์‹œ ์‚ฌ์šฉ
  • ๋ฒ„์ „๋ณ„ ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅ
  • ๋””์Šคํฌ ๊ณต๊ฐ„ ์ ˆ์•ฝ (์บ์‹ฑ ํ™œ์šฉ)

์˜์‚ฌ๊ฒฐ์ • ํ”Œ๋กœ์šฐ์ฐจํŠธ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ํŒจํ‚ค์ง€๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค๋ฉด?
โ”‚
โ”œโ”€ ์ฝ”๋“œ์—์„œ importํ•ด์„œ ์‚ฌ์šฉํ•˜๋‚˜? (pandas, requests, fastapi)
โ”‚  โ””โ”€ YES โ†’ `uv add <ํŒจํ‚ค์ง€>`
โ”‚
โ”œโ”€ ๋ช…๋ น์ค„์—์„œ ์‹คํ–‰ํ•˜๋Š” ๋„๊ตฌ์ธ๊ฐ€? (black, ruff, httpie)
โ”‚  โ”œโ”€ ์ž์ฃผ ์‚ฌ์šฉํ•˜๋‚˜?
โ”‚  โ”‚  โ”œโ”€ YES โ†’ `uv tool install <๋„๊ตฌ>`
โ”‚  โ”‚  โ””โ”€ NO โ†’ `uvx <๋„๊ตฌ>`
โ”‚  โ””โ”€ ํ”„๋กœ์ ํŠธํŒ€๊ณผ ๋ฒ„์ „ ๊ณต์œ  ํ•„์š”?
โ”‚     โ””โ”€ YES โ†’ `uv add --dev <๋„๊ตฌ>`
โ”‚
โ””โ”€ ํ…Œ์ŠคํŠธ/๋ฆฐํŠธ ๋„๊ตฌ์ธ๊ฐ€? (pytest, mypy)
   โ”œโ”€ ํŒ€๊ณผ ๋ฒ„์ „ ํ†ต์ผ ํ•„์š”? โ†’ `uv add --dev`
   โ””โ”€ ๊ฐœ์ธ ํ™˜๊ฒฝ ๊ตฌ์„ฑ์šฉ? โ†’ `uv tool install`

์‹ค๋ฌด ๊ถŒ์žฅ ์‚ฌํ•ญ

ํ”„๋กœ์ ํŠธ ์˜์กด์„ฑ์œผ๋กœ ๊ด€๋ฆฌ (uv add):

  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋Ÿฐํƒ€์ž„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
  • ์›น ํ”„๋ ˆ์ž„์›Œํฌ (FastAPI, Django, Flask)
  • ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ (pandas, numpy)
  • ํŒ€๊ณผ ๋ฒ„์ „ ๊ณต์œ ๊ฐ€ ํ•„์š”ํ•œ ๊ฐœ๋ฐœ ๋„๊ตฌ

์ „์—ญ ๋„๊ตฌ๋กœ ๊ด€๋ฆฌ (uv tool):

  • ์ฝ”๋“œ ํฌ๋งทํ„ฐ (black, autopep8)
  • ๋ฆฐํ„ฐ (ruff, pylint, flake8)
  • ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ ๋„๊ตฌ (cookiecutter)
  • HTTP ํด๋ผ์ด์–ธํŠธ (httpie)
  • ๊ฐœ์ธ ์ƒ์‚ฐ์„ฑ ๋„๊ตฌ

์ผํšŒ์„ฑ ์‹คํ–‰ (uvx):

  • ํ•œ ๋ฒˆ๋งŒ ์‚ฌ์šฉํ•  ๋„๊ตฌ
  • ๋ฒ„์ „๋ณ„ ํ…Œ์ŠคํŠธ
  • ๋„๊ตฌ ํ‰๊ฐ€ ๋ฐ ์‹คํ—˜

3.8 UV - ๊ธฐ๋Šฅ๋ณ„ ๋ช…๋ น์–ด ์š”์•ฝ

์•ž์—์„œ ์†Œ๊ฐœํ•œ ๋‚ด์šฉ๋“ค๊ณผ UV์˜ ์ฃผ์š” ๊ธฐ๋Šฅ๋ณ„ ๋ช…๋ น์–ด๋ฅผ ์ •๋ฆฌํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค.

Python ๋ฒ„์ „ ๊ด€๋ฆฌ

  • uv python install: Python ๋ฒ„์ „ ์„ค์น˜
  • uv python list: ์„ค์น˜ ๊ฐ€๋Šฅํ•œ ๋ฒ„์ „ ๋ชฉ๋ก ํ‘œ์‹œ
  • uv python find: ํ˜„์žฌ ์‹œ์Šคํ…œ์—์„œ ์„ค์น˜๋œ Python ํƒ์ƒ‰
  • uv python pin: ํ˜„์žฌ ํ”„๋กœ์ ํŠธ์— ํŠน์ • ๋ฒ„์ „ ๊ณ ์ •
  • uv python uninstall: ์„ค์น˜๋œ ๋ฒ„์ „ ์ œ๊ฑฐ

์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰

  • uv run: ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰ (๊ฐ€์ƒํ™˜๊ฒฝ ์ž๋™ ์ ์šฉ)
  • uv add --script: ์Šคํฌ๋ฆฝํŠธ ์ „์šฉ ์˜์กด์„ฑ ์ถ”๊ฐ€
  • uv remove --script: ์Šคํฌ๋ฆฝํŠธ ์˜์กด์„ฑ ์ œ๊ฑฐ

ํ”„๋กœ์ ํŠธ ๊ด€๋ฆฌ

  • uv init: ํ”„๋กœ์ ํŠธ ์ดˆ๊ธฐํ™” (pyproject.toml ์ƒ์„ฑ)
  • uv add: ํ”„๋กœ์ ํŠธ ์˜์กด์„ฑ ์ถ”๊ฐ€
  • uv remove: ํ”„๋กœ์ ํŠธ ์˜์กด์„ฑ ์ œ๊ฑฐ
  • uv sync: ํ™˜๊ฒฝ ๋™๊ธฐํ™” (uv.lock ๊ธฐ๋ฐ˜)
  • uv lock: ๋ฝํŒŒ์ผ ์ƒ์„ฑ ๋ฐ ์—…๋ฐ์ดํŠธ
  • uv run: ํ”„๋กœ์ ํŠธ ํ™˜๊ฒฝ ๋‚ด ๋ช…๋ น์–ด ์‹คํ–‰
  • uv tree: ์˜์กด์„ฑ ํŠธ๋ฆฌ ์‹œ๊ฐํ™”
  • uv build: ํ”„๋กœ์ ํŠธ ๋นŒ๋“œ
  • uv publish: ํŒจํ‚ค์ง€ ๋ฐฐํฌ

๋„๊ตฌ ์‹คํ–‰ ๋ฐ ๊ด€๋ฆฌ

  • uvx ๋˜๋Š” uv tool run: ์ž„์‹œ ํ™˜๊ฒฝ์—์„œ ๋„๊ตฌ ์‹คํ–‰
  • uv tool install: ์‚ฌ์šฉ์ž ์ „์—ญ ๋„๊ตฌ ์„ค์น˜
  • uv tool uninstall: ์ „์—ญ ๋„๊ตฌ ์ œ๊ฑฐ
  • uv tool list: ์„ค์น˜๋œ ๋„๊ตฌ ๋ชฉ๋ก
  • uv tool update-shell: PATH ๋ฐ˜์˜ ๋“ฑ ์‰˜ ์—…๋ฐ์ดํŠธ

ํŒจํ‚ค์ง€ ๋ฐ ํ™˜๊ฒฝ ๊ด€๋ฆฌ (pip ํ˜ธํ™˜ ๋ ˆ๋ฒจ)

  • uv venv: ๊ฐ€์ƒํ™˜๊ฒฝ ์ƒ์„ฑ (venv ๋Œ€์ฒด)
  • uv pip install: ํŒจํ‚ค์ง€ ์„ค์น˜
  • uv pip uninstall: ํŒจํ‚ค์ง€ ์ œ๊ฑฐ
  • uv pip freeze: ํŒจํ‚ค์ง€ ๋ชฉ๋ก ์ถœ๋ ฅ (๋ฒ„์ „ ํฌํ•จ)
  • uv pip show: ์„ค์น˜๋œ ํŒจํ‚ค์ง€ ์ƒ์„ธ ์ •๋ณด
  • uv pip check: ํŒจํ‚ค์ง€ ํ˜ธํ™˜์„ฑ ๊ฒ€์‚ฌ
  • uv pip list: ์„ค์น˜๋œ ํŒจํ‚ค์ง€ ๋‚˜์—ด
  • uv pip tree: ์˜์กด์„ฑ ํŠธ๋ฆฌ ํ™•์ธ

๊ณ ๊ธ‰ ํ™˜๊ฒฝ ๊ด€๋ฆฌ (pip-tools ํ˜ธํ™˜ ๋ ˆ๋ฒจ)

  • uv pip compile: requirements.txt์—์„œ ๋ฝํŒŒ์ผ ์ƒ์„ฑ
  • uv pip sync: ๋ฝํŒŒ์ผ ๊ธฐ๋ฐ˜ ํ™˜๊ฒฝ ๊ตฌ์„ฑ ๋™๊ธฐํ™”

๊ฐ๊ฐ์˜ ๋ช…๋ น์–ด๋Š” ๋…๋ฆฝ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์œผ๋ฉฐ, ์กฐํ•ฉํ•˜์—ฌ ์™„์ „ํ•œ Python ๊ฐœ๋ฐœ ํŒŒ์ดํ”„๋ผ์ธ์„ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ์‹ค๋ฌด ์ ์šฉ ์›Œํฌํ”Œ๋กœ์šฐ

๋ฐ์ดํ„ฐ ์‚ฌ์ด์–ธ์Šค ํ”„๋กœ์ ํŠธ ํ…œํ”Œ๋ฆฟ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 1. ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑ
mkdir ds-project
cd ds-project

# 2. ํ”„๋กœ์ ํŠธ ์ดˆ๊ธฐํ™” ๋ฐ Python ๋ฒ„์ „ ์„ค์ •
uv init --package
uv python install 3.11
uv use 3.11

# 3. ๋ฐ์ดํ„ฐ ์‚ฌ์ด์–ธ์Šค ํ•ต์‹ฌ ํŒจํ‚ค์ง€ ์„ค์น˜
uv add numpy pandas matplotlib scikit-learn

# 4. ๊ฐœ๋ฐœ ๋„๊ตฌ ์„ค์น˜
uv add --dev ipython jupyterlab black ruff

# 5. ํ™˜๊ฒฝ ์ž ๊ธˆ ๋ฐ ๋™๊ธฐํ™”
uv lock
uv sync

# 6. Jupyter Lab ์‹คํ–‰
uv run jupyter lab

์ด ํ…œํ”Œ๋ฆฟ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ผ๊ด€๋œ ๋ฐ์ดํ„ฐ ์‚ฌ์ด์–ธ์Šค ํ™˜๊ฒฝ์„ ์‰ฝ๊ฒŒ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์›น ๊ฐœ๋ฐœ ํ”„๋กœ์ ํŠธ ํ…œํ”Œ๋ฆฟ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 1. ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ
mkdir web-project
cd web-project

# 2. ํ”„๋กœ์ ํŠธ ์ดˆ๊ธฐํ™”
uv init --package
uv python install 3.12
uv use 3.12

# 3. ์›น ํ”„๋ ˆ์ž„์›Œํฌ ๋ฐ ๊ด€๋ จ ํŒจํ‚ค์ง€ ์„ค์น˜
uv add "fastapi>=0.104.0" "uvicorn[standard]" sqlalchemy pydantic

# 4. ๊ฐœ๋ฐœ ๋„๊ตฌ ์„ค์น˜
uv add --dev pytest pytest-cov black ruff

# 5. ํ™˜๊ฒฝ ์ž ๊ธˆ ๋ฐ ๋™๊ธฐํ™”
uv lock
uv sync

# 6. ๊ฐœ๋ฐœ ์„œ๋ฒ„ ์‹คํ–‰
uv run uvicorn src.main:app --reload

๊ธฐ์กด ํ”„๋กœ์ ํŠธ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜

๊ธฐ์กด์˜ requirements.txt ๋˜๋Š” Pipfile ๊ธฐ๋ฐ˜ ํ”„๋กœ์ ํŠธ๋ฅผ UV๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๋Š” ๋ฐฉ๋ฒ•:

1
2
3
4
5
6
7
8
9
10
11
12
# 1. ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ† ๋ฆฌ๋กœ ์ด๋™
cd existing-project

# 2. UV ํ”„๋กœ์ ํŠธ ์ดˆ๊ธฐํ™”
uv init

# 3. requirements.txt๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์˜์กด์„ฑ ๊ฐ€์ ธ์˜ค๊ธฐ
cat requirements.txt | xargs uv add

# 4. ํ™˜๊ฒฝ ์ž ๊ธˆ ๋ฐ ๋™๊ธฐํ™”
uv lock
uv sync

๐Ÿ’ก ํŒ€ ํ˜‘์—… ํŒ: uv.lock ํŒŒ์ผ์„ ๋ฒ„์ „ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ์— ํฌํ•จํ•˜์—ฌ ๋ชจ๋“  ํŒ€์›์ด ๋™์ผํ•œ ํ™˜๊ฒฝ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

  1. UV vs ๊ธฐ์กด ๋„๊ตฌ ๋น„๊ต

๊ธฐ๋Šฅ ๊ธฐ์กด ๋„๊ตฌ UV UV์˜ ์žฅ์ 
Python ์„ค์น˜ pyenv install 3.11 uv python install 3.11 ๋น ๋ฅธ ์„ค์น˜, ์ž๋™ ํ™˜๊ฒฝ ์„ค์ •
๊ฐ€์ƒํ™˜๊ฒฝ ์ƒ์„ฑ python -m venv .venv uv venv .venv 10๋ฐฐ ์ด์ƒ ๋น ๋ฅธ ์†๋„
ํŒจํ‚ค์ง€ ์„ค์น˜ pip install requests uv add requests ์˜์กด์„ฑ ์ž๋™ ๊ด€๋ฆฌ, ํ•˜๋“œ ๋งํฌ ํ™œ์šฉ
์˜์กด์„ฑ ๊ณ ์ • pip freeze > requirements.txt uv lock ์ •ํ™•ํ•œ ์˜์กด์„ฑ ํ•ด๊ฒฐ, ํ”Œ๋žซํผ๋ณ„ ์ตœ์ ํ™”
ํ™˜๊ฒฝ ๋™๊ธฐํ™” pip install -r requirements.txt uv sync ๋น ๋ฅธ ์„ค์น˜, ํ™•์‹คํ•œ ์žฌํ˜„์„ฑ
๋„๊ตฌ ์‹คํ–‰ pipx run black . uvx black . ์บ์‹ฑ ํ™œ์šฉ, ๋น ๋ฅธ ์‹คํ–‰

์„ฑ๋Šฅ ๋น„๊ต

๋‹ค์Œ์€ ๋™์ผํ•œ ํ™˜๊ฒฝ์—์„œ ๊ฐ ๋„๊ตฌ์˜ ์„ฑ๋Šฅ์„ ๋น„๊ตํ•œ ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค:

์ž‘์—… ๊ธฐ์กด ๋„๊ตฌ UV ์†๋„ ํ–ฅ์ƒ
๊ฐ€์ƒํ™˜๊ฒฝ ์ƒ์„ฑ 2-3์ดˆ 0.2-0.3์ดˆ ~10๋ฐฐ
pandas ์„ค์น˜ 15-20์ดˆ 2-3์ดˆ ~7๋ฐฐ
ํ”„๋กœ์ ํŠธ ํ™˜๊ฒฝ ๋™๊ธฐํ™” 30-60์ดˆ 3-6์ดˆ ~10๋ฐฐ
  1. ๊ณ ๊ธ‰ ์‚ฌ์šฉ๋ฒ• ๋ฐ ํŒ

์ปค์Šคํ…€ ์ธ๋ฑ์Šค ์‚ฌ์šฉ

ํŠน์ • ํŒจํ‚ค์ง€ ์ธ๋ฑ์Šค(PyPI ์™ธ์˜ ์†Œ์Šค)๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•:

1
2
3
4
5
6
# ํŠน์ • ์ธ๋ฑ์Šค์—์„œ ํŒจํ‚ค์ง€ ์„ค์น˜
uv pip install --index-url https://my-custom-index.org/simple some-package

# pyproject.toml์— ์ธ๋ฑ์Šค ์ถ”๊ฐ€
# [tool.uv]
# index-url = "https://my-custom-index.org/simple"

๋นŒ๋“œ ๋ฐ ๋ฐฐํฌ

UV๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŒจํ‚ค์ง€๋ฅผ ๋นŒ๋“œํ•˜๊ณ  ๋ฐฐํฌํ•˜๋Š” ๋ฐฉ๋ฒ•:

1
2
3
4
5
# ํŒจํ‚ค์ง€ ๋นŒ๋“œ
uv build

# PyPI์— ๋ฐฐํฌ
uv publish

ํ™˜๊ฒฝ ๋‚ด๋ณด๋‚ด๊ธฐ ๋ฐ ๊ฐ€์ ธ์˜ค๊ธฐ

๋‹ค๋ฅธ ๋„๊ตฌ์™€์˜ ํ˜ธํ™˜์„ฑ์„ ์œ„ํ•œ ํ™˜๊ฒฝ ๋‚ด๋ณด๋‚ด๊ธฐ:

1
2
3
4
5
# requirements.txt๋กœ ๋‚ด๋ณด๋‚ด๊ธฐ
uv pip freeze > requirements.txt

# Poetry ํ˜•์‹์œผ๋กœ ๋‚ด๋ณด๋‚ด๊ธฐ
uv export -f poetry > pyproject.toml

๋””๋ฒ„๊น… ๋ฐ ๋ฌธ์ œ ํ•ด๊ฒฐ

UV ์‚ฌ์šฉ ์‹œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ํŒ:

1
2
3
4
5
6
7
8
# ์ž์„ธํ•œ ๋กœ๊ทธ ์ถœ๋ ฅ
uv --verbose add requests

# ์บ์‹œ ์ •๋ฆฌ
uv cache clean

# ์˜์กด์„ฑ ํŠธ๋ฆฌ ํ™•์ธ
uv pip show --tree pandas
  1. ์‹ค๋ฌด ์ ์šฉ ์‚ฌ๋ก€

๋Œ€๊ทœ๋ชจ ML ํ”„๋กœ์ ํŠธ

๋Œ€๊ทœ๋ชจ ๋จธ์‹ ๋Ÿฌ๋‹ ํ”„๋กœ์ ํŠธ์—์„œ UV๋ฅผ ์‚ฌ์šฉํ•œ ๊ฒฝ์šฐ, ์˜์กด์„ฑ ํ•ด๊ฒฐ ๋ฐ ํ™˜๊ฒฝ ์„ค์ • ์‹œ๊ฐ„์ด ๊ธฐ์กด ๋Œ€๋น„ 85% ๊ฐ์†Œํ–ˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ GPU ๋“œ๋ผ์ด๋ฒ„์™€ ํ˜ธํ™˜๋˜๋Š” ์ •ํ™•ํ•œ ํŒจํ‚ค์ง€ ๋ฒ„์ „์„ ๋น ๋ฅด๊ฒŒ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ์–ด ์ƒ์‚ฐ์„ฑ์ด ํฌ๊ฒŒ ํ–ฅ์ƒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

CI/CD ํŒŒ์ดํ”„๋ผ์ธ

CI/CD ํŒŒ์ดํ”„๋ผ์ธ์—์„œ UV๋ฅผ ํ™œ์šฉํ•œ ๊ฒฝ์šฐ, ๋นŒ๋“œ ์‹œ๊ฐ„์ด ํ‰๊ท  72% ๋‹จ์ถ•๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํ•˜๋“œ ๋งํฌ๋ฅผ ํ™œ์šฉํ•œ ๋””์Šคํฌ ๊ณต๊ฐ„ ์ตœ์ ํ™”๋กœ ํด๋ผ์šฐ๋“œ ํ™˜๊ฒฝ์—์„œ์˜ ๋ฆฌ์†Œ์Šค ํ™œ์šฉ๋„ ๊ฐœ์„ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ๊ฐœ๋ฐœ

์—ฌ๋Ÿฌ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค๋กœ ๊ตฌ์„ฑ๋œ ํ”„๋กœ์ ํŠธ์—์„œ UV๋ฅผ ํ†ตํ•ด ์ผ๊ด€๋œ ํ™˜๊ฒฝ์„ ์œ ์ง€ํ•˜๋ฉด์„œ๋„ ๊ฐ ์„œ๋น„์Šค๋ณ„ ์˜์กด์„ฑ์„ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ uvx๋ฅผ ํ†ตํ•œ ๋„๊ตฌ ์‹คํ–‰์œผ๋กœ ๊ฐœ๋ฐœ์ž ๊ฐ„ ์ผ๊ด€๋œ ์ฝ”๋“œ ํ’ˆ์งˆ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

  1. ๊ฒฐ๋ก 

UV๋Š” Python ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ ์ƒˆ๋กœ์šด ํ‘œ์ค€์„ ์ œ์‹œํ•ฉ๋‹ˆ๋‹ค. Rust ๊ธฐ๋ฐ˜์˜ ๋›ฐ์–ด๋‚œ ์„ฑ๋Šฅ๊ณผ ์ง๊ด€์ ์ธ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ๊ธฐ์กด ๋„๊ตฌ๋“ค์˜ ๋ณต์žก์„ฑ์„ ํ•ด์†Œํ•˜๊ณ , ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ๋ถ€ํ„ฐ ๋ฐฐํฌ๊นŒ์ง€ ์ผ๊ด€๋œ ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๐ŸŒˆ ์ฃผ์š” ์žฅ์ :

  • ๋‹จ์ผ ๋„๊ตฌ: ์—ฌ๋Ÿฌ ๋„๊ตฌ๋ฅผ ๋Œ€์ฒดํ•˜๋Š” ํ†ตํ•ฉ๋œ ์ธํ„ฐํŽ˜์ด์Šค
  • ์†๋„: ๊ธฐ์กด ๋„๊ตฌ ๋Œ€๋น„ 10๋ฐฐ ์ด์ƒ ๋น ๋ฅธ ์„ฑ๋Šฅ
  • ๊ณต๊ฐ„ ํšจ์œจ์„ฑ: ํ•˜๋“œ ๋งํฌ๋ฅผ ํ†ตํ•œ ๋””์Šคํฌ ๊ณต๊ฐ„ ์ตœ์ ํ™”
  • ์žฌํ˜„์„ฑ: ์ •ํ™•ํ•œ ์˜์กด์„ฑ ํ•ด๊ฒฐ๊ณผ ์ž ๊ธˆ ๊ธฐ๋Šฅ
  • ํ˜„๋Œ€์ : PEP 621 ๊ธฐ๋ฐ˜์˜ pyproject.toml ์ง€์›

UV๋ฅผ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ Python ๊ฐœ๋ฐœ์ž๋Š” ํ™˜๊ฒฝ ์„ค์ •์— ์†Œ์š”๋˜๋Š” ์‹œ๊ฐ„์„ ์ค„์ด๊ณ , ์‹ค์ œ ๊ฐœ๋ฐœ์— ๋” ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋น ๋ฅด๊ณ  ๊ฐ„๊ฒฐํ•œ ํ™˜๊ฒฝ ๊ด€๋ฆฌ๋ฅผ ํ†ตํ•ด ๋” ๋‚˜์€ Python ๊ฐœ๋ฐœ ๊ฒฝํ—˜์„ ์ œ๊ณตํ•˜๋Š” UV๋กœ์˜ ์ „ํ™˜์„ ๊ณ ๋ คํ•ด๋ณด์„ธ์š”!!

์ฝ์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค ๐Ÿ˜Ž

(์ฐธ๊ณ ) ํ˜‘์—… ์‹œ ๊ถŒ์žฅ ์›Œํฌํ”Œ๋กœ์šฐ

๐Ÿ’ก pyproject.toml + uv lock ๊ธฐ๋ฐ˜ ๊ด€๋ฆฌ

1. ์˜์กด์„ฑ ์ถ”๊ฐ€ ์‹œ:

1
2
uv pip install numpy pandas
uv pip freeze > requirements.lock.txt

2. ๋˜๋Š” pyproject.toml์— ์ง์ ‘ ๊ธฐ์ž… ํ›„:

1
2
3
[tool.uv.dependencies]
numpy = "*"
pandas = "*"

๊ทธ๋‹ค์Œ, ๋ฝํŒŒ์ผ ์ƒ์„ฑ:

1
uv pip compile > requirements.lock.txt

3. ํ˜‘์—…์ž ํ™˜๊ฒฝ ๊ตฌ์ถ•:

  1. Git ๋“ฑ์„ ํ†ตํ•ด ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ† ๋ฆฌ(์˜ˆ: my_project/)๋ฅผ ํด๋ก 
  2. ๋””๋ ‰ํ† ๋ฆฌ ์ง„์ž… ํ›„:
1
cd my_project
  1. ์•„๋ž˜ ๋ช…๋ น์œผ๋กœ .venv ๊ฐ€์ƒํ™˜๊ฒฝ ์ƒ์„ฑ ๋ฐ ์ž ๊ฒจ์ง„ ํŒจํ‚ค์ง€ ์„ค์น˜:
1
2
uv sync
uv pip install -r requirements.lock.txt