byteforce

CPN 한국어 자습서 · 외부 문서 한국어 미러

UV 문서 · Concepts

패키지 인덱스

Package indexes · 원문: docs.astral.sh/uv/concepts/indexes/

아래는 원문을 한국어로 옮긴 미러입니다. 코드·명령은 원문 그대로이며, 가장 최신 정보는 하단 원문 링크에서 확인하세요.

기본적으로 uv는 의존성 해석 및 패키지 설치에 Python Package Index (PyPI)를 사용합니다. 그러나 uv는 [[tool.uv.index]] 설정 옵션(및 이에 상응하는 명령줄 옵션 --index)을 통해 프라이빗 인덱스를 포함한 다른 패키지 인덱스를 사용하도록 설정할 수 있습니다.

인덱스 정의

의존성 해석 시 추가 인덱스를 포함하려면 pyproject.toml[[tool.uv.index]] 항목을 추가합니다:

코드 · 명령
[[tool.uv.index]]
# Optional name for the index.
name = "pytorch"
# Required URL for the index.
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> 구문을 사용하여 포함할 수 있습니다:

코드 · 명령
# On the command line.
$ uv lock --index pytorch=https://download.pytorch.org/whl/cpu
# Via an environment variable.
$ 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-cpu", marker = "sys_platform == 'darwin'"},
  { index = "pytorch-cu130", marker = "sys_platform != 'darwin'"},
]

[[tool.uv.index]]
name = "pytorch-cpu"
url = "https://download.pytorch.org/whl/cpu"

[[tool.uv.index]]
name = "pytorch-cu130"
url = "https://download.pytorch.org/whl/cu130"

인덱스를 explicit = true로 표시하면 해당 인덱스에 명시적으로 고정된 경우에만 패키지가 그 인덱스에서 설치됩니다. 예를 들어, torchpytorch 인덱스에서 설치하고 다른 모든 패키지는 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 = trueexplicit = true 모두로 표시된 경우, 명시적 인덱스(즉, tool.uv.sources를 통해서만 사용 가능)로 취급되는 동시에 PyPI가 기본 인덱스에서 제거됩니다.

여러 인덱스에서 검색

기본적으로 uv는 주어진 패키지가 사용 가능한 첫 번째 인덱스에서 멈추고, 해석을 해당 첫 번째 인덱스에 있는 버전으로 제한합니다(first-index).

예를 들어, [[tool.uv.index]]를 통해 내부 인덱스가 지정된 경우, 패키지가 해당 내부 인덱스에 존재하면 항상 내부 인덱스에서 설치되고 PyPI에서는 절대 설치되지 않습니다. 이는 공격자가 내부 패키지와 동일한 이름으로 악성 패키지를 PyPI에 게시하여 악성 패키지가 설치되도록 하는 "의존성 혼동" 공격을 방지하기 위한 것입니다. 예를 들어 2022년 12월의 torchtriton 공격을 참고하세요.

대체 인덱스 동작을 선택하려면 --index-strategy 명령줄 옵션이나 UV_INDEX_STRATEGY 환경 변수를 사용합니다. 지원 값:

unsafe-best-match는 pip의 동작에 가장 가깝지만 사용자를 "의존성 혼동" 공격의 위험에 노출시킵니다.

인증

대부분의 프라이빗 패키지 인덱스는 패키지에 접근하기 위해 일반적으로 사용자 이름과 비밀번호(또는 액세스 토큰)를 통한 인증이 필요합니다.

특정 프라이빗 인덱스 공급자와의 인증에 대한 전용 가이드를 참고하세요: Azure Artifacts, Google Artifact Registry, AWS CodeArtifact, JFrog Artifactory.

자격증명 직접 제공

환경 변수를 통해 또는 URL에 포함시켜 자격증명을 직접 제공할 수 있습니다.

예를 들어, 사용자 이름(public)과 비밀번호(koala)가 필요한 internal-proxy라는 인덱스의 경우, pyproject.toml에 인덱스를 정의합니다(자격증명 제외):

코드 · 명령
[[tool.uv.index]]
name = "internal-proxy"
url = "https://example.com/simple"

그런 다음 UV_INDEX_INTERNAL_PROXY_USERNAMEUV_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@example.com/simple"

보안상 자격증명은 uv.lock 파일에 절대 저장되지 않습니다. 따라서 uv는 설치 시점에 인증된 URL에 접근할 수 있어야 합니다.

자격증명 공급자 사용

자격증명을 직접 제공하는 것 외에도 uv는 netrc 및 keyring에서 자격증명 탐색을 지원합니다. 특정 자격증명 공급자 설정에 대한 자세한 내용은 HTTP 인증 문서를 참고하세요.

기본적으로 uv는 공급자를 조회하기 전에 인증되지 않은 요청을 시도합니다. 요청이 실패하면 자격증명을 검색합니다. 자격증명을 찾으면 인증된 요청을 시도합니다.

사용자 이름이 설정된 경우 uv는 인증되지 않은 요청을 보내기 전에 자격증명을 검색합니다.

일부 인덱스(예: GitLab)는 인증되지 않은 요청을 PyPI와 같은 공개 인덱스로 전달합니다. 이 경우 uv는 자격증명을 검색하지 않습니다. 이 동작은 authenticate 설정을 사용하여 인덱스별로 변경할 수 있습니다. 예를 들어, 항상 자격증명을 검색하려면:

코드 · 명령
[[tool.uv.index]]
name = "example"
url = "https://example.com/simple"
authenticate = "always"

authenticatealways로 설정되면 uv는 적극적으로 자격증명을 검색하고, 자격증명을 찾지 못하면 오류를 반환합니다.

여러 인덱스 검색 시 오류 코드 무시

first-index 전략을 사용할 때, HTTP 401 Unauthorized 또는 HTTP 403 Forbidden 상태 코드가 발생하면 uv는 인덱스 검색을 중단합니다. 단, pytorch 인덱스 검색 시 403은 무시합니다(이 인덱스는 패키지가 없을 때 403을 반환하기 때문입니다).

인덱스에 대해 무시할 오류 코드를 설정하려면 ignored-error-codes 설정을 사용합니다. 예를 들어, 프라이빗 인덱스에서 403(401 제외)을 무시하려면:

코드 · 명령
[[tool.uv.index]]
name = "private-index"
url = "https://private-index.com/simple"
authenticate = "always"
ignore-error-codes = [403]

uv는 404 Not Found를 만나면 항상 인덱스 검색을 계속합니다. 이는 재정의할 수 없습니다.

인증 비활성화

자격증명 유출을 방지하기 위해 인덱스에 대한 인증을 비활성화할 수 있습니다:

코드 · 명령
[[tool.uv.index]]
name = "example"
url = "https://example.com/simple"
authenticate = "never"

authenticatenever로 설정되면 uv는 해당 인덱스에 대한 자격증명을 절대 검색하지 않으며, 자격증명이 직접 제공되면 오류를 반환합니다.

캐시 제어 헤더 커스터마이즈

기본적으로 uv는 인덱스가 제공하는 캐시 제어 헤더를 준수합니다. 예를 들어, PyPI는 패키지 메타데이터를 max-age=600 헤더와 함께 제공하여 uv가 10분 동안 패키지 메타데이터를 캐시할 수 있게 합니다. 휠 및 소스 배포판은 max-age=365000000, immutable 헤더와 함께 제공되어 아티팩트를 무기한 캐시할 수 있습니다.

인덱스의 캐시 제어 헤더를 재정의하려면 cache-control 설정을 사용합니다:

코드 · 명령
[[tool.uv.index]]
name = "example"
url = "https://example.com/simple"
cache-control = { api = "max-age=600", files = "max-age=365000000, immutable" }

cache-control 설정은 두 개의 선택적 키를 가진 객체를 허용합니다:

이 키의 값은 HTTP Cache-Control 구문을 따르는 문자열입니다. 예를 들어, uv가 항상 패키지 메타데이터를 재검증하도록 강제하려면 api = "no-cache"로 설정합니다:

코드 · 명령
[[tool.uv.index]]
name = "example"
url = "https://example.com/simple"
cache-control = { api = "no-cache" }

이 설정은 캐싱을 비활성화하는(종종 의도치 않게) 프라이빗 인덱스의 기본 캐시 제어 헤더를 재정의할 때 가장 많이 사용됩니다. 일반적으로 PyPI의 캐싱 헤더 방식을 따르는 것을 권장합니다. 즉, api = "max-age=600"files = "max-age=365000000, immutable"을 설정합니다.

인덱스에 대한 exclude-newer 설정

exclude-newer를 사용하는 경우 특정 인덱스에 대해 다른 컷오프를 설정할 수 있습니다:

코드 · 명령
[[tool.uv.index]]
name = "internal"
url = "https://internal.example.com/simple"
exclude-newer = "7 days"

인덱스별 값은 해당 인덱스에서 제공하는 패키지에만 영향을 미칩니다. 패키지별 exclude-newer-package 재정의가 여전히 우선합니다.

인덱스가 upload-time 메타데이터를 제공하지 않는 경우 해당 인덱스에 대한 컷오프를 완전히 비활성화할 수 있습니다:

코드 · 명령
[[tool.uv.index]]
name = "internal"
url = "https://internal.example.com/simple"
exclude-newer = false

"플랫" 인덱스

기본적으로 [[tool.uv.index]] 항목은 PEP 503 Simple Repository API를 구현하는 PyPI 스타일 레지스트리(registry)로 간주됩니다. 그러나 uv는 휠 및 소스 배포판의 플랫 목록을 포함하는 로컬 디렉터리나 HTML 페이지인 "플랫" 인덱스도 지원합니다. pip에서는 이러한 인덱스를 --find-links 옵션으로 지정합니다.

pyproject.toml에서 플랫 인덱스를 정의하려면 format = "flat" 옵션을 사용합니다:

코드 · 명령
[[tool.uv.index]]
name = "example"
url = "/path/to/directory"
format = "flat"

플랫 인덱스는 Simple Repository API 인덱스와 동일한 기능 집합을 지원합니다(예: explicit = true). tool.uv.sources를 사용하여 패키지를 플랫 인덱스에 고정할 수도 있습니다.

--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--extra-index-url은 이름 없는 [[tool.uv.index]] 항목으로 생각할 수 있으며, 전자는 default = true가 활성화되어 있습니다. 이 맥락에서 --index-url--default-index에, --extra-index-url--index에 매핑됩니다.

원문(영어): https://docs.astral.sh/uv/concepts/indexes/ · 본 문서는 학습용 한국어 번역이며 원본의 권리는 원저작자(Astral)에게 있습니다.

원문(영어): https://docs.astral.sh/uv/concepts/indexes/