uvでPythonアプリをポータブルにしてオフラインPCへインストール

# 可搬性を持ったPythonアプリを作成して生産設備のPCで実行する

### はじめに
生産設備で物体検出や画像認識を行いたいときなど、PythonとYOLO, Open-CVなどを使ってシステムを作ったりすると思います。作るまでは簡単で良いのですが、これを生産設備のオフラインPCにインストールして実行したいのです。

今回は、OSはWindows、VSCode等の環境で自由気ままに作成したPythonプログラムを、外部パッケージや実行環境一式と共に一つのディレクトリに詰め込んでzipで固めた後、目的のPCで展開して実行できるようにします。

---

### 1. Pythonプログラムを用意する

VSCode等のお気に入りの環境で自由気ままにPythonプログラムを作成し、動作確認までしておきます。仮想環境とか気にしません(venv？何ですかそれ？)
例えば以下のような画面を出すコードをtest.pyという名前で作ります。UIフレームワークはpyxelを使ってみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6824/8a0b0b11-9a12-48f0-b81f-513b5fb51560.png)

```python
import os
import pyxel
import cv2
os.chdir(os.path.dirname(os.path.abspath(__file__)))
class App:
    def __init__(self):
        pyxel.init(200, 60, title = u"検査", fps = 30, display_scale = 2)
        pyxel.mouse(True)
        pyxel.run(self.update, self.draw)
    def update(self):
        if pyxel.btnp(pyxel.KEY_Q):
            pyxel.quit()
    def draw(self):
        pyxel.cls(5)
        pyxel.text(40, 20, "Hello, Pyxel!", pyxel.frame_count % 16)
App()
```
---
### 2. インストール資材を集める
ディレクトリを作り、そこにインストールするファイル一式を集めていきます

#### 1 ディレクトリ作成・Pythonプログラムを入れる
product_checkというフォルダを作り、test.pyを入れました。外部フォントなどを使っていたらそれも入れます
```
D:\work\product_check> dir
2025/05/06  13:21               534 test.py
```
#### 2 uvを入れる
下記サイトからuvのzipをダウンロードしてきて解凍します。先ほどのフォルダ直下にuv.exeを入れます
https://github.com/astral-sh/uv/releases

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6824/cf09b77c-fa7f-46e0-8ed0-27bb76946334.png)
```
2025/05/06  13:21               534 test.py
2025/05/06  10:01        51,505,664 uv.exe
```
#### 3 Pythonを入れる
下記サイトからPythonの「embeddable package」のzipをダウンロードしてきて先ほどのフォルダ直下に解凍します( 例: python-3.8.10-embed-amd64.zip )
または、通常のインストーラーパッケージでインストール場所をフォルダ直下に指定する方法でも良いです
https://www.python.org/downloads/release/python-3810/
```
2025/05/06  14:02    <DIR>          python-3.8.10-embed-amd64
2025/05/06  13:21               534 test.py
2025/05/06  10:01        51,505,664 uv.exe
```
#### 4 コマンドプロンプト起動、カレントディレクトリ移動
以降、コマンドプロンプトでの操作となります。まずはフォルダ内にcdします
```
cd D:\work\product_check
```
#### 5 uv init ＜初期化＞
使用するPythonのフォルダを指定してinit
```
uv init --bare --python python-3.8.10-embed-amd64
```
#### 6 uv venv ＜仮想環境作成＞
使用するPythonのフォルダを指定してvenv
```
uv venv --python python-3.8.10-embed-amd64
```
.venv/pyenv.cfg のhomeは絶対パスで設定される。ここは可搬性のため相対パスにエディタで書き換える
```
(( .venv/pyenv.cfg 変更前 ))
home = D:\work\product_check\python-3.8.10-embed-amd64

　　　　↓↓↓
    
(( .venv/pyenv.cfg 変更後 ))
home = python-3.8.10-embed-amd64
```

#### 7 uv add　＜パッケージ追加＞
```
uv add --link-mode=copy opencv-python
uv add --link-mode=copy pyxel


uv tree                       (( treeで確認してみる ))
Resolved 6 packages in 1ms
product-check v0.1.0
├── opencv-python v4.11.0.86
│   └── numpy v1.24.4
└── pyxel v2.3.18
```
#### 8 uv run ＜アプリ実行＞
実行
```
uv run test.py
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6824/8a0b0b11-9a12-48f0-b81f-513b5fb51560.png)

---
### 3. オフラインPCへのインストール
ここまでの作業で、フォルダ product_checkの中は以下のようにいくつか自動生成されたファイルが追加されています。
```
D:\work\product_check> dir
2025/05/06  14:44    <DIR>          .venv
2025/05/06  14:46               212 pyproject.toml
2025/05/06  14:02    <DIR>          python-3.8.10-embed-amd64
2025/05/06  15:02               462 test.py
2025/05/06  10:01        51,505,664 uv.exe
2025/05/06  14:46            50,677 uv.lock
```
これをzip等でアーカイブ、USBメモリ等で目的のPCで展開すればインストール完了です
目的のPCにおいても実行はuv runで行います
```
cd C:\product_check
uv run test.py
```
以上

---
### 参考 
pyxel - https://github.com/kitao/pyxel/blob/main/docs/README.ja.md
uv    -  https://docs.astral.sh/uv/