python的uv包管理器国内安装指南

2,288 阅读4分钟

python的uv包管理器国内安装指南

1. 前言

本篇文章最终结论是对于普通人来说最适合国内uv安装方式是pip install uv

如果想继续折腾可以看一下的本人拙劣方案与思路

本文是我折腾uv包管理在国内安装的遇到问题的总结,分享遇到问题的解决办法,与解决思路,如果各路大神有更好的解决方法与方法,也可以指点一下小弟

本文目前仅折腾uv脚本安装,安装完成之后发现uv安装python也是个坑,目前正在研究,本质也是通过github进行安装,一般也是采用本地镜像库的方式解决

附带uv官网文档

2. uv安装方式总结

使用独立安装

# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
wget -qO- https://astral.sh/uv/install.sh | sh
curl -LsSf https://astral.sh/uv/0.6.17/install.sh | sh
# windows
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
# 如果通过独立安装程序安装,uv 可以更新到最新版本:
uv self update

Pypi 安装

# pip
pip install uv

# pipx
pipx install uv

winget安装(也是通过github下载实现)

winget install --id=astral-sh.uv  -e

3. 安装过程

通过直接执行安装脚本出现报错

报错内容如下:

PS C:\Users\Administrator> powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
irm : 请求被中止: 未能创建 SSL/TLS 安全通道。
所在位置 行:1 字符: 1
+ irm https://astral.sh/uv/install.ps1 | iex
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod],We
    ption
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

通过对于报错与脚本内容的研究,uv的脚本安装是通过访问github就行实现下载二进制文件进行实现的

下载地址为:https://github.com/astral-sh/uv/releases/download/ + <版本> + <适合本地的二进制文件名称>

然而报错主要是访问不到github或者下载文件失败导致的

4. 解决方案

解决安装的方案核心就是解决github下载二进制文件的问题

4.1. 方案一:梯子大法

通过魔法方式直接访问,解决一切妖魔鬼怪

4.2. 方案二:加速github的访问

  1. 常见方面是通过查询github现在国内解析修改hosts文件,解决github的访问问题解决下载问题
  2. 使用github第三方加速网站(反代、镜像等)进行加速

★阅读uv的安装脚本,发现脚本留有通过读取本地环境变量获取二进制文件的方式

注意:windows的基本与linux的脚本变量名称不一样

powershell脚本内:

if ($env:INSTALLER_DOWNLOAD_URL) {
  $ArtifactDownloadUrl = $env:INSTALLER_DOWNLOAD_URL
} else {
  $ArtifactDownloadUrl = "$installer_base_url/astral-sh/uv/releases/download/0.6.14"
}

sh脚本

if [ -n "${INSTALLER_DOWNLOAD_URL:-}" ]; then
    ARTIFACT_DOWNLOAD_URL="$INSTALLER_DOWNLOAD_URL"
else
    ARTIFACT_DOWNLOAD_URL="${INSTALLER_BASE_URL}/astral-sh/uv/releases/download/0.6.14"
fi

windows下执行脚本前的操作:

$env:INSTALLER_DOWNLOAD_URL='<这里是加速之后的网址>'
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

linux执行脚本前的操作

export INSTALLER_DOWNLOAD_URL='<这里是加速之后的网址>'
curl -LsSf https://astral.sh/uv/install.sh | sh

4.3. 搭建本地镜像库

知道脚本如何添加环境变量的方式下载其他地址的二进制文件,便可利用这一点进行搭建本地的镜像库

需要下载脚本,当然也可以不需要,通过修改环境变量实现,但既然都搭建了本地镜像库,就要一步到位(在线用的脚本也抽风)

不需要下载方式:

$env:INSTALLER_DOWNLOAD_URL='<本地镜像库>'
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

脚本可以直接访问执行的url进行下载

4.3.1. 修改下载好的脚本

通过修改脚本内的环境变量将下载地址从github指向为本地镜像库

脚本内添加定义环境变量的赋值

  • windows脚本
...

$env:INSTALLER_DOWNLOAD_URL = '本地镜像库地址'

...
  • linux类脚本修改
...

INSTALLER_DOWNLOAD_URL="本地镜像库地址"

...

文件放在web文件服务器的目录下即可,需要注意uv的版本

本次我这使用的是v0.6.17版本的uv,需要下载github上的二进制,可以全下也可以下自己能用的到的,放在相同目录下

二进制文件下载地址:github.com/astral-sh/u…

4.4. 本地脚本安装

此方法比较邪道,一般不会用到,这边想到的能用的地方也就非内网远程安装uv

这里只介绍windows下本地脚本安装,linux下同理,我这边能想到一般也就windows下用的比较多

原理:修改脚本,通过重写下载函数,从下载变为拷贝的方式实现本地脚本安装

原本的脚本内的下载函数:

function Download($download_url, $platforms) {
  $arch = Get-TargetTriple $platforms

  if (-not $platforms.ContainsKey($arch)) {
    $platforms_json = ConvertTo-Json $platforms
    throw "ERROR: could not find binaries for this platform. Last platform tried: $arch platform info: $platforms_json"
  }

  # Lookup what we expect this platform to look like
  $info = $platforms[$arch]
  $zip_ext = $info["zip_ext"]
  $bin_names = $info["bins"]
  $lib_names = $info["libs"]
  $staticlib_names = $info["staticlibs"]
  $artifact_name = $info["artifact_name"]

  # Make a new temp dir to unpack things to
  $tmp = New-Temp-Dir
  $dir_path = "$tmp\$app_name$zip_ext"

  # Download and unpack!
  $url = "$download_url/$artifact_name"
  Write-Information "Downloading $app_name $app_version ($arch)"
  Write-Verbose "  from $url"
  Write-Verbose "  to $dir_path"
  $wc = New-Object Net.Webclient
  if ($auth_token) {
    $wc.Headers["Authorization"] = "Bearer $auth_token"
  }
  $wc.downloadFile($url, $dir_path)

  Write-Verbose "Unpacking to $tmp"

  # Select the tool to unpack the files with.
  #
  # As of windows 10(?), powershell comes with tar preinstalled, but in practice
  # it only seems to support .tar.gz, and not xz/zstd. Still, we should try to
  # forward all tars to it in case the user has a machine that can handle it!
  switch -Wildcard ($zip_ext) {
    ".zip" {
      Expand-Archive -Path $dir_path -DestinationPath "$tmp";
      Break
    }
    ".tar.*" {
      tar xf $dir_path --strip-components 1 -C "$tmp";
      Break
    }
    Default {
      throw "ERROR: unknown archive format $zip_ext"
    }
  }

  # Let the next step know what to copy
  $bin_paths = @()
  foreach ($bin_name in $bin_names) {
    Write-Verbose "  Unpacked $bin_name"
    $bin_paths += "$tmp\$bin_name"
  }
  $lib_paths = @()
  foreach ($lib_name in $lib_names) {
    Write-Verbose "  Unpacked $lib_name"
    $lib_paths += "$tmp\$lib_name"
  }
  $staticlib_paths = @()
  foreach ($lib_name in $staticlib_names) {
    Write-Verbose "  Unpacked $lib_name"
    $staticlib_paths += "$tmp\$lib_name"
  }

  if (($null -ne $info["updater"]) -and $install_updater) {
    $updater_id = $info["updater"]["artifact_name"]
    $updater_url = "$download_url/$updater_id"
    $out_name = "$tmp\uv-update.exe"

    $wc.downloadFile($updater_url, $out_name)
    $bin_paths += $out_name
  }

  return @{
    "bin_paths" = $bin_paths
    "lib_paths" = $lib_paths
    "staticlib_paths" = $staticlib_paths
  }
}

修改之后的脚本函数:

function Download($download_url, $platforms) {
  $arch = Get-TargetTriple $platforms

  if (-not $platforms.ContainsKey($arch)) {
    $platforms_json = ConvertTo-Json $platforms
    throw "ERROR: could not find binaries for this platform. Last platform tried: $arch platform info: $platforms_json"
  }

  # Lookup what we expect this platform to look like
  $info = $platforms[$arch]
  $zip_ext = $info["zip_ext"]
  $bin_names = $info["bins"]
  $lib_names = $info["libs"]
  $staticlib_names = $info["staticlibs"]
  $artifact_name = $info["artifact_name"]
  #
  # Make a new temp dir to unpack things to
  $tmp = New-Temp-Dir
  $dir_path = "$tmp\$app_name$zip_ext"
  #
  # Download and unpack!
  # $url = "$download_url/$artifact_name"
  # Write-Information "Downloading $app_name $app_version ($arch)"
  # Write-Verbose "  from $url"
  # Write-Verbose "  to $dir_path"
  # $wc = New-Object Net.Webclient
  # if ($auth_token) {
  #   $wc.Headers["Authorization"] = "Bearer $auth_token"
  # }

  # $wc.downloadFile($url, $dir_path)
  # > 这里注释掉下载函数改为拷贝函数
  Copy-Item -Path ./$artifact_name -Destination $dir_path
  Write-Verbose "Unpacking to $tmp"

  # Select the tool to unpack the files with.
  #
  # As of windows 10(?), powershell comes with tar preinstalled, but in practice
  # it only seems to support .tar.gz, and not xz/zstd. Still, we should try to
  # forward all tars to it in case the user has a machine that can handle it!
  switch -Wildcard ($zip_ext) {
    ".zip" {
      Expand-Archive -Path $dir_path -DestinationPath "$tmp";
      Break
    }
    ".tar.*" {
      tar xf $dir_path --strip-components 1 -C "$tmp";
      Break
    }
    Default {
      throw "ERROR: unknown archive format $zip_ext"
    }
  }

  # Let the next step know what to copy
  $bin_paths = @()
  foreach ($bin_name in $bin_names) {
    Write-Verbose "  Unpacked $bin_name"
    $bin_paths += "$tmp\$bin_name"
  }
  $lib_paths = @()
  foreach ($lib_name in $lib_names) {
    Write-Verbose "  Unpacked $lib_name"
    $lib_paths += "$tmp\$lib_name"
  }
  $staticlib_paths = @()
  foreach ($lib_name in $staticlib_names) {
    Write-Verbose "  Unpacked $lib_name"
    $staticlib_paths += "$tmp\$lib_name"
  }

  if (($null -ne $info["updater"]) -and $install_updater) {
    $updater_id = $info["updater"]["artifact_name"]
    $updater_url = "$download_url/$updater_id"
    $out_name = "$tmp\uv-update.exe"

    $wc.downloadFile($updater_url, $out_name)
    $bin_paths += $out_name
  }

  return @{
    "bin_paths" = $bin_paths
    "lib_paths" = $lib_paths
    "staticlib_paths" = $staticlib_paths
  }
}

通过注释$wc.downloadFile($url, $dir_path),添加Copy-Item -Path ./$artifact_name -Destination $dir_path进行实现

可以直接替换,当然你也可以顺便注释掉创建下载客户端的内容

5. 总结

本人常用的是:通过python -m http.server临时搭建本地镜像库,然后再通过使用修改之后的脚本方式进行安装 如果经常需要安装uv的情况下可以使用nignx、AList之类的搭建本地文件服务器进行搭建本地镜像库,这种一般是自动化测试或者docker、k8s弹性部署项目时会用的到,缺点是如果需要更新要自己手动进行修改