패키지 인덱스¶
기본적으로 uv는 의존성 해결과 패키지 설치를 위해 Python Package Index (PyPI)를 사용한다. 하지만 [[tool.uv.index]]
설정 옵션(또는 동일한 커맨드라인 옵션인 --index
)을 통해 프라이빗 인덱스를 포함한 다른 패키지 인덱스를 사용하도록 uv를 설정할 수 있다.
인덱스 정의하기¶
의존성을 해결할 때 추가 인덱스를 포함하려면 pyproject.toml
파일에 [[tool.uv.index]]
항목을 추가한다.
[[tool.uv.index]]
# 인덱스의 선택적 이름
name = "pytorch"
# 인덱스의 필수 URL
url = "https://download.pytorch.org/whl/cpu"
인덱스는 정의된 순서대로 우선순위가 부여된다. 즉, 설정 파일에 나열된 첫 번째 인덱스가 의존성을 해결할 때 가장 먼저 참조된다. 단, 커맨드라인을 통해 제공된 인덱스는 설정 파일의 인덱스보다 우선순위가 높다.
기본적으로 uv는 Python Package Index(PyPI)를 "기본" 인덱스로 포함한다. 이는 다른 인덱스에서 패키지를 찾을 수 없을 때 사용된다. PyPI를 인덱스 목록에서 제외하려면 다른 인덱스 항목에 default = true
를 설정하거나 --default-index
커맨드라인 옵션을 사용한다.
[[tool.uv.index]]
name = "pytorch"
url = "https://download.pytorch.org/whl/cpu"
default = true
기본 인덱스는 목록에서의 위치와 상관없이 항상 가장 낮은 우선순위로 간주된다.
인덱스 이름은 알파벳, 숫자, 대시, 언더스코어, 마침표만 포함할 수 있으며 유효한 ASCII 문자여야 한다.
커맨드라인에서 --index
또는 --default-index
를 통해 인덱스를 제공하거나 환경 변수(UV_INDEX
또는 UV_DEFAULT_INDEX
)를 통해 제공할 때 이름은 선택 사항이지만 <name>=<url>
구문을 사용해 포함할 수 있다.
# 커맨드라인에서
$ uv lock --index pytorch=https://download.pytorch.org/whl/cpu
# 환경 변수를 통해
$ UV_INDEX=pytorch=https://download.pytorch.org/whl/cpu uv lock
패키지를 특정 인덱스에 고정하기¶
tool.uv.sources
항목에서 인덱스를 지정하면 특정 패키지를 특정 인덱스에 고정할 수 있다. 예를 들어, torch
를 항상 pytorch
인덱스에서 설치하도록 하려면 pyproject.toml
파일에 다음과 같이 추가한다:
[tool.uv.sources]
torch = { index = "pytorch" }
[[tool.uv.index]]
name = "pytorch"
url = "https://download.pytorch.org/whl/cpu"
마찬가지로, 플랫폼에 따라 다른 인덱스에서 패키지를 가져오려면 환경 마커를 사용해 소스 목록을 제공할 수 있다:
[project]
dependencies = ["torch"]
[tool.uv.sources]
torch = [
{ index = "pytorch-cu118", marker = "sys_platform == 'darwin'"},
{ index = "pytorch-cu124", marker = "sys_platform != 'darwin'"},
]
[[tool.uv.index]]
name = "pytorch-cu118"
url = "https://download.pytorch.org/whl/cu118"
[[tool.uv.index]]
name = "pytorch-cu124"
url = "https://download.pytorch.org/whl/cu124"
인덱스를 explicit = true
로 표시하면 해당 인덱스에 명시적으로 고정된 패키지가 아니면 설치되지 않는다. 예를 들어, torch
는 pytorch
인덱스에서 설치하고, 다른 모든 패키지는 PyPI에서 설치하도록 하려면 pyproject.toml
파일에 다음과 같이 추가한다:
[tool.uv.sources]
torch = { index = "pytorch" }
[[tool.uv.index]]
name = "pytorch"
url = "https://download.pytorch.org/whl/cpu"
explicit = true
tool.uv.sources
를 통해 참조되는 이름이 지정된 인덱스는 프로젝트의 pyproject.toml
파일 내에서 정의되어야 한다. 커맨드라인, 환경 변수, 사용자 수준 설정을 통해 제공된 인덱스는 인식되지 않는다.
인덱스가 default = true
와 explicit = true
로 모두 표시된 경우, 해당 인덱스는 명시적 인덱스로 취급되며(즉, tool.uv.sources
를 통해서만 사용 가능), 동시에 PyPI를 기본 인덱스에서 제거한다.
여러 인덱스에서 검색하기¶
기본적으로 uv는 특정 패키지를 찾을 수 있는 첫 번째 인덱스에서 검색을 멈추고, 해당 인덱스에 있는 버전만을 해결 대상으로 삼는다(first-index
).
예를 들어, [[tool.uv.index]]
를 통해 내부 인덱스를 지정하면, uv는 해당 내부 인덱스에 패키지가 존재할 경우 항상 그 인덱스에서 패키지를 설치하고 PyPI에서는 절대 설치하지 않는다. 이는 "의존성 혼동" 공격을 방지하기 위한 의도다. 공격자가 내부 패키지와 동일한 이름으로 악성 패키지를 PyPI에 게시하면, 내부 패키지 대신 악성 패키지가 설치될 수 있다. 예를 들어, 2022년 12월 발생한 torchtriton
공격이 대표적이다.
사용자는 --index-strategy
커맨드라인 옵션이나 UV_INDEX_STRATEGY
환경 변수를 통해 다른 인덱스 동작을 선택할 수 있다. 이 옵션은 다음과 같은 값을 지원한다:
first-index
(기본값): 모든 인덱스에서 각 패키지를 검색하되, 패키지가 포함된 첫 번째 인덱스의 후보 버전만을 고려한다.unsafe-first-match
: 모든 인덱스에서 각 패키지를 검색하되, 호환 가능한 버전이 있는 첫 번째 인덱스를 우선한다. 다른 인덱스에 더 새로운 버전이 있어도 무시한다.unsafe-best-match
: 모든 인덱스에서 각 패키지를 검색하고, 후보 버전 전체에서 가장 적합한 버전을 선택한다.
unsafe-best-match
는 pip의 동작과 가장 유사하지만, "의존성 혼동" 공격의 위험에 노출될 수 있다.
인증 정보 제공¶
대부분의 프라이빗 레지스트리는 패키지에 접근하기 위해 인증을 요구한다. 일반적으로 사용자 이름과 비밀번호(또는 액세스 토큰)를 통해 인증한다.
인덱스와 인증하려면 환경 변수를 통해 인증 정보를 제공하거나 URL에 직접 포함시킬 수 있다.
예를 들어, 사용자 이름(public
)과 비밀번호(koala
)가 필요한 internal-proxy
라는 인덱스가 있다고 가정하자. 먼저 pyproject.toml
파일에 인증 정보 없이 인덱스를 정의한다:
[[tool.uv.index]]
name = "internal-proxy"
url = "https://example.com/simple"
그런 다음 UV_INDEX_INTERNAL_PROXY_USERNAME
과 UV_INDEX_INTERNAL_PROXY_PASSWORD
환경 변수를 설정한다. 여기서 INTERNAL_PROXY
는 인덱스 이름을 대문자로 변환하고, 영숫자가 아닌 문자를 밑줄(_)로 대체한 것이다:
export UV_INDEX_INTERNAL_PROXY_USERNAME=public
export UV_INDEX_INTERNAL_PROXY_PASSWORD=koala
환경 변수를 통해 인증 정보를 제공하면 pyproject.toml
파일에 민감한 정보를 평문으로 저장하지 않아도 된다.
또는 인덱스 정의에 인증 정보를 직접 포함시킬 수도 있다:
[[tool.uv.index]]
name = "internal"
url = "https://public:koala@pypi-proxy.corp.dev/simple"
보안상의 이유로 인증 정보는 uv.lock
파일에 절대 저장되지 않는다. 따라서 uv는 설치 시 인증된 URL에 반드시 접근할 수 있어야 한다.
--index-url
와 --extra-index-url
¶
[[tool.uv.index]]
설정 옵션 외에도, uv는 호환성을 위해 pip 스타일의 --index-url
와 --extra-index-url
커맨드라인 옵션을 지원한다. 여기서 --index-url
는 기본 인덱스를 정의하고, --extra-index-url
는 추가 인덱스를 정의한다.
이 옵션들은 [[tool.uv.index]]
설정 옵션과 함께 사용할 수 있으며, 동일한 우선순위 규칙을 따른다:
- 기본 인덱스는 항상 가장 낮은 우선순위로 처리된다. 이는 레거시
--index-url
인자, 권장되는--default-index
인자, 또는default = true
로 설정된[[tool.uv.index]]
항목을 통해 정의되었는지 여부와 무관하다. - 인덱스는 정의된 순서대로 참조된다. 이는 레거시
--extra-index-url
인자, 권장되는--index
인자, 또는[[tool.uv.index]]
항목을 통해 정의되었는지 여부와 무관하다.
실질적으로, --index-url
와 --extra-index-url
는 이름이 없는 [[tool.uv.index]]
항목으로 간주할 수 있다. 여기서 --index-url
는 default = true
가 활성화된 상태이며, 이 맥락에서 --index-url
는 --default-index
에 매핑되고, --extra-index-url
는 --index
에 매핑된다.