個人的なパッケージ開発チュートリアルです。ここに書いてあるのは一例なので、ググったりChatGPTに聞くなりして、より良い方法を見つけるなどして各自レベルアップしてください。
最近作成したAlphaFold3のインプット支援・アウトプット解析ツールであるalphafold3_toolsもこの流れで作っています。
使うツール
ソフトウェア・パッケージ群
- uv: Pythonパッケージ開発ツール。2024年8月頃にRyeでできる操作を統合し始めた。
-
Visual Studio Code (VSCode): Integrated Development Environment/統合開発環境とそのプラグイン
- Pythonプラグイン
- Ruff (Rustで書かれた自動フォーマット)
- mypy (型チェッカ)
- GitHub Copilot (GitHubが開発したAIによるコード補完, 要GitHub EducationまたはGitHub Pro)
- デバッグ機能
VSCodeとの連携
Windows, macOS, Linux、いずれのOSでも動作するように用意されているVisual Code Studio (VSCode)というIDE(統合開発環境)と連携するのがわかりやすいので、これを使っていきます。特にGitHubとVSCodeはともにMicrosoftによって開発が行われていることもあり、両者の連携が図られています。
VSCodeは様々なソフトウェア開発に向いていますが、Pythonの開発環境においてはまず
- Pythonプラグイン
-
Ruff (linter)
- RuffのVSCode拡張機能設定
- isort, black, flake8などのツールを統合したもの。
- mypy (型チェッカ)
- GitHub Copilot (AIが先読みして入力したいコードを先に提示してくれる。要GitHub Global Campusへの登録)
- デバッグ機能
を使えるようになりましょう。一括でこれらをインストールしたい場合は、VSCodeのターミナルで以下のコマンドを入力してください。参考:https://zenn.dev/karaage0703/books/80b6999d429abc8051bb/viewer/349524
code --install-extension charliermarsh.ruff
code --install-extension ms-vscode-remote.remote-containers
code --install-extension ms-vscode-remote.remote-ssh
code --install-extension ms-vscode-remote.remote-ssh-edit
code --install-extension ms-vscode-remote.remote-wsl
code --install-extension ms-vscode-remote.vscode-remote-extensionpack
code --install-extension ms-vscode.remote-explorer
code --install-extension ms-vscode.remote-server
code --install-extension ms-vscode.test-adapter-converter
code --install-extension ms-python.debugpy
code --install-extension ms-python.python
code --install-extension ms-python.vscode-pylance
code --install-extension github.copilot
code --install-extension github.copilot-chat
code --install-extension github.github-vscode-theme
code --install-extension github.vscode-github-actions
code --install-extension github.vscode-pull-request-github
code --install-extension ms-toolsai.jupyter
code --install-extension ms-toolsai.jupyter-keymap
code --install-extension ms-toolsai.vscode-jupyter-slideshow
パッケージ開発チュートリアル:newcomer-practice
ここからはuvを使って実際にnewcomer-practice
ディレクトリを作成して公開するところまでやってみます。
uvのインストール
まずはuvの公式ドキュメントを参照のこと。macOSまたはLinuxの場合は、以下でインストールします。
$ curl -LsSf https://astral.sh/uv/install.sh | sh
downloading uv 0.6.5 aarch64-apple-darwin
installing to /Users/YoshitakaM/.cargo/bin
uv
uvx
everything's installed!
インストール後にexec $SHELL -l
などでshellを再読み込みを行うとuvを起動できます。今回用いるuvのバージョンは以下です。
$ uv --version
uv 0.6.5 (bcbcd0a1e 2025-03-06)
uv
は現在も精力的に機能が更新され続けていますので、定期的に更新しましょう。uv self update
で更新できます。
pythonのインストール
今回はpython3.12を使います。macOSであればHomebrewからインストールすることができます。Ubuntu 22.04だとデフォルトは3.10です。
brew install python@3.12
なお、デモの範囲ではPython 3.6〜3.13であれば問題なく動きますので、その範囲のPythonが入っていれば適宜読み替えて進めて結構です。
作業ディレクトリの作成
uvをインストールし終わったら、まずは、作業ディレクトリを作成しましょう。以下のコマンドを実行してください。
mkdir -p ~/Desktop/work/newcomer-practice
cd ~/Desktop/work/newcomer-practice
newcomer-practice
ディレクトリで、uvを使ってパッケージ開発を行います。
$ uv init
Initialized project `newcomer-practice`
newcomer-practice
ディレクトリには、隠しを含めて5つのファイルと1つの隠しディレクトリが作成されます。
$ ls -a
. .git .python-version main.py
.. .gitignore README.md pyproject.toml
.python-version
はuvでのPythonのバージョンを指定するファイルです。中には3.13と書かれていますが、これを3.12や3.11とすることで、開発のためのPythonバージョンを下げることができます。まずはこのファイルをVSCodeなどで開いて3.12
にしておいてください。
また、後ほどパッケージをビルドするためのディレクトリpack_test
をこの中に作成しておきます。
# ~/Desktop/work/newcomer-practiceディレクトリで実行する。
mkdir -p pack_test
pyproject.toml
はuvの設定ファイルです。Pythonのパッケージ開発に必要な情報が書かれています。
[project]
name = "newcomer-practice"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = []
ここに書ける設定は非常に幅広く、また他の開発ツールとの連携を行うために必要な設定を書く必要があるため、詳細はuv - Projectsを読んでください。ここでは以下のようなtomlファイル設定に書き換えてください。
[project]
name = "newcomer-practice"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = []
[tool.uv]
dev-dependencies = ["mypy", "notebook", "pandas", "pytest", "ruff", "pandas"]
[tool.ruff]
select = [
"F", # Flake8
"B", # Black
"I", # isort
"E", # error
"W", # warning
]
ignore = ["F401"]
exclude = [".ruff_cache", ".ruff.toml", ".ruff.lock"]
indent-width = 4
line-length = 88 # Same as Black.
target-version = "py312"
[tool.ruff.isort]
combine-as-imports = true
section-order = ["future", "standard-library", "third-party", "first-party", "local-folder"]
split-on-trailing-comma = true
[tool.ruff.format]
quote-style = "double"
[tool.ruff.lint.isort]
known-third-party = ["fastapi", "pydantic", "starlette"]
[tool.pytest.ini_options]
filterwarnings = [
"ignore:.*Jupyter is migrating.*:DeprecationWarning",
]
addopts = "-vv --color=yes"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.metadata]
dynamic = ["name", "version"]
[tool.hatch.build.targets.wheel]
packages = ["pack_test"]
これに書き換えた後、uv sync
を実行すると、開発環境が整います。
$ uv sync
Resolved 107 packages in 6ms
Built newcomer-practice @ file:///Users/YoshitakaM/Desktop/work/newcomer-practice
Prepared 16 packages in 1.77s
Installed 104 packages in 383ms
+ anyio==4.8.0
+ appnope==0.1.4
+ attrs==25.1.0
...
...
+ webcolors==24.11.1
+ webencodings==0.5.1
+ websocket-client==1.8.0
これによって.venv
ディレクトリに仮想環境が構築され、同時にその仮想環境に必要なパッケージがインストールされます。
uvで構築されたpyproject.toml
は複数人で同じ開発環境を共有できるというメリットもあります。後ほどGitHubでパッケージが公開されるとき、このファイルがあれば、他の人がこのパッケージをgit clone
でダウンロードしてきたあと、uv sync
で開発者と同じ環境をすぐに構築することができます。そして変更を加えてGitHubにpull requestを送ることができ、開発者はその変更をレビューしてマージすることができます。この仕組みによって、ユーザーがすぐに開発者になることができ、安定したパッケージ開発が可能になります。
仮想環境はnewcomer-practice
ディレクトリにて. .venv/bin/activate
を実行することで有効になります。また、deactivate
を実行することで無効になります。
# 仮想環境の有効化
. .venv/bin/activate
# 仮想環境の無効化
deactivate
VSCodeを使っている場合、VSCodeのターミナルからuv sync
を実行した時点で仮想環境の作成が検知され、「仮想環境に切り替えますか?」と表示されるのでそれを許可してください。ここで許可しなかった場合で後に切り替えたい場合は、新たに作業ディレクトリ内でPythonファイルを開いた時に、右下のPythonのバージョンをクリックして、仮想環境へのPATH/path/to/newcomer-practice/.venv/bin/python3.12
を選択してください。
コードの作成
コードはpack_test
ディレクトリに配置します。ここでは、pack_test
ディレクトリにhello.py
というファイルを作成し、以下のような内容を書いてください。
def hello_test1(input1: str, input2: str, switch1: bool, switch2: bool) -> None:
"""uvパッケージングのデモ用挨拶関数。
指定されたスイッチの状態に応じて、入力された名前で挨拶メッセージを表示します。
Args:
input1: 最初の挨拶で使用する名前
input2: 2番目の挨拶で使用する名前
switch1: Trueの場合、input1を使った挨拶を表示
switch2: Trueの場合、input2を使った挨拶を表示
Returns:
None
Example:
>>> hello_test1("太郎", "花子", True, False)
Hello uv packaging!. I'm 太郎.
>>> hello_test1("太郎", "花子", False, True)
I'm 花子. Nice to meet you.
"""
if switch1:
print(f"Hello uv packaging!. I'm {input1}.")
if switch2:
print(f"I'm {input2}. Nice to meet you.")
次に、これを呼び出すtest1.py
を同pack_test
ディレクトリに作成します。
#!/usr/bin/env python3
from argparse import ArgumentDefaultsHelpFormatter, ArgumentParser
from pack_test.hello import hello_test1
def main():
parser = ArgumentParser(
formatter_class=ArgumentDefaultsHelpFormatter,
description="Test script for uv packaging.",
)
group = parser.add_mutually_exclusive_group()
parser.add_argument(
"-i",
"--input1",
help="argument for input1",
type=str,
required=True,
)
parser.add_argument(
"-j",
"--input2",
help="argument for input2",
type=str,
)
group.add_argument(
"-s",
"--switch1",
help="Turn on switch1. Switch1 and Switch2 are mutually exclusive.",
action="store_true",
)
group.add_argument(
"-t",
"--switch2",
help="Turn on switch2. Switch1 and Switch2 are mutually exclusive.",
action="store_true",
)
args = parser.parse_args()
hello_test1(args.input1, args.input2, args.switch1, args.switch2)
if __name__ == "__main__":
main()
簡単な解説ですが、このtest1.py
では、pack_test/hello.py
に書き込んだhello_test1
関数を呼び出しています。hello_test1
関数は、input1
とinput2
という2つの引数を取り、switch1
とswitch2
という2つのスイッチを取ります。switch1
がTrue
の場合、input1
を表示します。switch2
がTrue
の場合、input2
を表示します。test1.py
は、コマンドライン引数として-i
と-j
と-s
と-t
を取り、それぞれinput1
とinput2
とswitch1
とswitch2
に対応します。-i
は必須の引数です。-j
は任意の引数です。-s
と-t
はスイッチです。-s
がある場合、switch1
がTrue
になります。-t
がある場合、switch2
がTrue
になります。
ここまでの操作で、newcomer-practice
内のディレクトリ構成は以下のようになります。
newcomer-practice
├── LICENSE
├── README.md
├── main.py
├── pack_test
│ ├── hello.py
│ └── test1.py
├── pyproject.toml
└── uv.lock
パッケージの動作
実際にこの自作の関数が期待通りに動作するかを試してみましょう。ターミナルから以下のコマンドを入力し、仮のディレクトリを作成してその中でpython3.12の仮想環境を有効化します。
# mktemp -dで一時的なディレクトリを作成し、その中で仮想環境を有効化する。
cd "$(mktemp -d)"
python3.12 -m venv .venv
. .venv/bin/activate
次に、この中でpipを用いてnewcomer-practice
パッケージをインストールします。このとき-e
をつけることでeditableモードでインストールします。これにより、~/Desktop/work/newcomer-practice
パッケージの中身を変更しても、再度インストールしなくても変更が反映されます。
$ python3.12 -m pip install -e ~/Desktop/work/newcomer-practice
...
...
Successfully built newcomer-practice
Installing collected packages: newcomer-practice
Successfully installed newcomer-practice-0.1.0
[notice] A new release of pip is available: 25.0 -> 25.0.1
[notice] To update, run: pip install --upgrade pip
これを実行して、python3.12をインタラクティブに起動し、以下のような動作が確認できれば成功です。
$ python3.12
Python 3.12.9 (main, Feb 4 2025, 14:38:38) [Clang 16.0.0 (clang-1600.0.26.6)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from pack_test import hello
>>> hello.hello_test1("AAA", "BBB", True, False)
Hello uv packaging!. I'm AAA.
>>> hello.hello_test1("AAA", "BBB", False, True)
I'm BBB. Nice to meet you.
>>> #(Ctrl-Dを押すとPythonインタラクティブモードを抜けられる)
さらに、このコマンドをターミナルのコマンドラインから実行するために、以下の設定をpyproject.toml
に追記します。
[project.scripts]
kadai_test1 = "pack_test.test1:main"
これを実行した状態で再度pip install
を実行すると、今度はkadai_test1
というコマンドが使えるようになります。
$ python3.12 -m pip install -e ~/Desktop/work/newcomer-practice
Obtaining file:///Users/YoshitakaM/Desktop/work/newcomer-practice
Installing build dependencies ... done
Checking if build backend supports build_editable ... done
...
...
Attempting uninstall: newcomer-practice
Found existing installation: newcomer-practice 0.1.0
Uninstalling newcomer-practice-0.1.0:
Successfully uninstalled newcomer-practice-0.1.0
Successfully installed newcomer-practice-0.1.0
[notice] A new release of pip is available: 25.0 -> 25.0.1
[notice] To update, run: pip install --upgrade pip
$ kadai_test1 -h
usage: kadai_test1 [-h] -i INPUT1 [-j INPUT2] [-s | -t]
Test script for uv packaging.
options:
-h, --help show this help message and exit
-i INPUT1, --input1 INPUT1
argument for input1 (default: None)
-j INPUT2, --input2 INPUT2
argument for input2 (default: None)
-s, --switch1 Turn on switch1. Switch1 and Switch2 are mutually exclusive. (default: False)
-t, --switch2 Turn on switch2. Switch1 and Switch2 are mutually exclusive. (default: False)
これで、kadai_test1
というコマンドが使えるようになりました。引数を指定して実行してみましょう。
$ kadai_test1 -i AAA -j BBB -s
Hello uv packaging!. I'm AAA.
$ kadai_test1 -i AAA -j BBB -t
I'm BBB. Nice to meet you.
$ kadai_test1 -i AAA -j BBB -s -t
usage: kadai_test1 [-h] -i INPUT1 [-j INPUT2] [-s | -t]
kadai_test1: error: argument -t/--switch2: not allowed with argument -s/--switch1
最後のコマンドkadai_test1 -i AAA -j BBB -s -t
は、-s
と-t
が同時に指定されているためエラーが出ます。これはgroup = parser.add_mutually_exclusive_group()
と指定してあるためです。これで、自作のパッケージが正常に動作することが確認できました。
GitHub連携
Gitとはプログラムのソースコードなどの変更履歴を記録・追跡するための分散型バージョン管理システムです。Linuxカーネルのソースコード管理に用いるためLinuxの生みの親であるLinus Torvaldsによって開発され、それ以降ほかの多くのプロジェクトで採用されています。
GitHubはソフトウェア開発のプラットフォームであり、ソースコードをホスティングすることで複数人のソフトウエア開発者と協働してコードをレビューしたり、プロジェクトを管理しつつ開発を行うことができます。コードのバージョン管理システムにはGitを使用しています。2008年4月にサービス開始され、2010年にGitHub社が設立されました。2018年にはMicrosoftに買収されています。
現在では研究者もGitHubなどのプラットフォームを使って研究に使ったコードを公開することが推奨されています。これによって他のユーザーもその人の実験を再現することができるようになります。
GitHubは無料で使えますが、プライベートリポジトリを作るには有料プランに加入する必要があります。研究者はGitHub Educationに登録することで、無料でプライベートリポジトリを作成することができます。
GitHubのアカウント作成
アカウント作成など基本的なところは省略します。また、学生や大学の学生証・職員証を持っている人はGitHub Educationに登録することでGitHub Proアカウントになることができ、GitHub Copilotが使えるようになるので、この手続きをしておくことをおすすめします。
登録には学生証・職員証が必要です。申請から承認までには2週間ほどかかります(と言われますが多くの場合は割とすぐに承認されます)。承認されたら、GitHubのアカウントの設定から「Education」の項目に「GitHub Education」が表示されていることを確認してください。
GitHub Copilotを使う
https://github.com/settings/copilot にアクセスして、GitHub Copilotを有効にしてください。
さらに、VSCode上でGitHub Copilotを使うには、VSCodeでアカウントを連携する必要があります。VSCodeの左下のアイコンをクリックして、GitHubアカウントを連携してください。また、拡張機能からGitHub Copilotを検索し、これをインストールしてください。
使えるようになると、VSCodeの右下に「Copilot」というアイコンが表示されます。
GitHubでリポジトリを作成する
GitHubと連携して自身のリポジトリを作成する方法を説明します。本来gitはローカル(自身のパソコン)で管理するものですが、GitHubを使うことで、リモート(インターネット上)にも保存することができます。また、GitHubを使うことで、他の人との共同作業も可能になります。
gitはもともとコマンドラインベースなので、すべての操作はターミナルのコマンドから行うことができます。それらのコマンドをしっかりと覚えたい方は慶應義塾大学の渡辺先生のGitHub演習のウェブサイトを参考にするとよいでしょう。しかし、これらのコマンドを完全に覚えるのは大変ですし、今ではVScodeまたはGitHubのウェブサイト上からのGUI操作でおおよそ最低限必要な操作は行うことができます。この章では、GUI操作でリポジトリを作成する方法を説明します。
GitHubのトップ画面に新しくリポジトリを作成するためのボタンがあります。このボタンをクリックすると、リポジトリの作成画面に移動します。
Create a new repositoryの画面で、プロジェクトファイルを保存するためのリポジトリを作成します。リポジトリ名は、プロジェクト名と同じにしておくとよいでしょう。
この画面では、リポジトリの説明を書くことができます。また、リポジトリの公開範囲を設定することができます。ここでは、Publicにしておきます。Publicにすると、他の人がこのリポジトリを見ることができます。Privateにすると、自分以外は見ることができません。PrivateはGitHub Educationに加入していれば選択できますが、基本的には有料サービスです。
Add a README fileにはチェックを入れておきましょう。
.gitignore
は、作成したいプロジェクトで主に使われることになる言語を設定する事が多いです。ここでは、Pythonを選択します。
Choose a licenseのところではそのプロジェクトのライセンスを設定します。この効力は大きく、ユーザーおよび営利目的とする企業はGitHub上のソフトウェアのライセンスの仕様に必ず従わなければなりません。最も制限がゆるいライセンスはMIT Licenseと言われます。ここでは例としてMIT Licenseを選択します。
リポジトリを作成するとこのような画面になります。
ここに向けて、先ほど作成したnewcomer-practice
パッケージを、GitHubのリポジトリnewcomer-practiceに紐づけます。以下にその手順を示します。
ターミナルを開き、すでに作成済みのローカルのnewcomer-practiceディレクトリへ移動します。
cd ~/Desktop/work/newcomer-practice
まだGitを初期化していない場合は、git init
を実行してリポジトリを作成します。(uv init
を使ってローカルにパッケージを先に作成した場合は、このコマンドは不要です。)
次に、このローカルリポジトリをGitHubのリポジトリ(https://github.com/YoshitakaMo/newcomer-practice.git)と紐づけます。
git remote add origin https://github.com/YoshitakaMo/newcomer-practice.git
リモートリポジトリの設定を確認するには、以下を実行します。
$ git remote -v
origin https://github.com/YoshitakaMo/newcomer-practice.git (fetch)
origin https://github.com/YoshitakaMo/newcomer-practice.git (push)
git branch -M main
でブランチをmainに変更します。GitHubのデフォルトブランチ名がmainの場合は、以下を実行します。
git branch -M main
リモート(https://github.com/YoshitakaMo/newcomer-practice.git)のmainブランチの内容をまずローカルにコピーします。
$ git pull origin main
From https://github.com/YoshitakaMo/newcomer-practice
* branch main -> FETCH_HEAD
error: The following untracked working tree files would be overwritten by merge:
.gitignore
README.md
Please move or remove them before you merge.
Aborting
ここでエラーが出ました。この原因は、すでにリモートのmainブランチに.gitignore
とREADME.md
が存在しているためです。今回はまだこれらのファイルに手を付けていませんので、ローカルのnewcomer-practice
にあるこれらのファイルを削除してから、再度git pull origin main
を実行します。
$ rm .gitignore README.md
$ git pull origin main
From https://github.com/YoshitakaMo/newcomer-practice
* branch main -> FETCH_HEAD
これでリモートのmainブランチの内容がローカルにコピーされました。次に、ローカルの変更をステージングしてコミットします。
$ git add .
$ git commit -m "initial commit"
[main (root-commit) 29b1d0e] initial commit
6 files changed, 1671 insertions(+)
create mode 100644 .python-version
create mode 100644 main.py
create mode 100644 pack_test/hello.py
create mode 100644 pack_test/test1.py
create mode 100644 pyproject.toml
create mode 100644 uv.lock
最後に、ローカルのmainブランチの内容をリモートのmainブランチにプッシュします。
$ git push origin main
Enumerating objects: 10, done.
Counting objects: 100% (10/10), done.
Delta compression using up to 20 threads
Compressing objects: 100% (8/8), done.
Writing objects: 100% (9/9), 50.25 KiB | 3.59 MiB/s, done.
Total 9 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
To https://github.com/YoshitakaMo/newcomer-practice.git
674d97d..d246ec1 main -> main
なお、このgitコマンドを使った一連の手順は、VSCodeのGitHub拡張機能を使うことでGUIで行うこともできます。VSCodeの左側にあるGitアイコンをクリックすると、リポジトリの変更をステージングしたり、コミットしたり、プッシュしたりすることができます。詳しくはVSCodeの公式ドキュメントを参照してください。
GitHubのリポジトリページ(https://github.com/YoshitakaMo/newcomer-practice)を開き、ファイルが正しくアップロードされているか確認します。これでローカルのnewcomer-practiceとGitHubのリポジトリが紐づきました! 🚀
今回はローカルにパッケージを開発してからGitHubに同名のリポジトリを作るという流れで行いましたが、先にGitHubリポジトリを作成してそれをローカルPCにgit clone
しておき、その中でuv init
してからパッケージ開発を進めるという順番でも可能です。
ちなみに、このリポジトリの画面で.
キーを押すと、GitHubのウェブサイト上でVSCodeのGUIを開いているかのようにファイルを編集することもできます。github.devというアドレスにアクセスすることができ、VSCodeライクなGUIが現れます。
このように、GitHubとVSCodeを連携させることで、ローカルでの作業とリモートでの作業をシームレスに行うことができます。
GitHubに置いたPythonパッケージをpipでインストールできることを確認する
作成したPythonパッケージをGitHubにアップロードしておくと、pip install
で取り込むことが可能になります。具体的には
コマンドライン | 説明 |
---|---|
pip install pkg_name@git+https://github.com/username/repo_name.git |
リポジトリ名とパッケージ名が異なる場合は「パッケージ名@」を「git+https://…….git」の前に付加 |
pip install git+https://github.com/username/pkg_name.git |
リポジトリ名とパッケージ名が同じならこう書ける |
pip install git+https://github.com/username/pkg_name.git@v1.0 |
「@v1.0」のように末尾にバージョンやタグを付加できる |
という形でインストールできます。これを試してみましょう。適当なディレクトリを作り、その中で仮想環境を起動してからpip
を行います。
$ cd"(mktemp -d)"
$ python3.12 -m venv .venv
$ source .venv/bin/activate
$ which python3.12
# /private/var/folders/xxxxxxxxxxxx/.venv/bin/python3.12 # なんか適当なtempディレクトリの中のpython3.12になっていることを確認
$ python3.12 -m pip install git+https://github.com/YoshitakaMo/newcomer-practice.git
Collecting git+https://github.com/YoshitakaMo/newcomer-practice.git
Cloning https://github.com/YoshitakaMo/newcomer-practice.git to /private/var/folders/2x/
......
Successfully built newcomer-practice
Installing collected packages: newcomer-practice
Successfully installed newcomer-practice-0.1.0
[notice] A new release of pip is available: 25.0 -> 25.0.1
[notice] To update, run: pip install --upgrade pip
$ kadai_test1 -h
usage: kadai_test1 [-h] -i INPUT1 [-j INPUT2] [-s | -t]
ということで、GitHubに置いた自作Pythonパッケージをpipでインストールでき、自作のkadai_test1
が使えるようになっていることを確認できました。
あとはこのリポジトリをどんどん改良していくだけです。また、他の人にもgit clone
してもらうことで、他の人との共同作業も可能になります。
Pythonパッケージ開発ツール"uv"の使い方
uvのインストール
まずはuvの公式ドキュメントを参照のこと。macOSまたはLinuxの場合は、以下でインストールします。
$ curl -LsSf https://astral.sh/uv/install.sh | sh
downloading uv 0.6.5 aarch64-apple-darwin
installing to /Users/YoshitakaM/.cargo/bin
uv
uvx
everything's installed!
インストール後にexec $SHELL -l
などでshellを再読み込みを行うとuvを起動できます。今回用いるuvのバージョンは以下です。
$ uv --version
uv 0.6.5 (bcbcd0a1e 2025-03-06)
uv
は現在も精力的に機能が更新され続けていますので、定期的に更新しましょう。uv self update
で更新できます。
新規プロジェクトの初期化
init
で新規プロジェクトを作成することができます。my-project
は任意のプロジェクト名です。既に作成したいプロジェクト下にいる場合はuv init
だけで作成できます。
$ uv init my-project
Initialized project `my-project` at `/Users/YoshitakaM/Desktop/my-project`
$ cd my-project
すると以下のディレクトリ構造が作成されて、pyproject.toml
も自動で生成されます。
.
├── README.md
├── main.py
└── pyproject.toml
pyproject.toml
の中身は以下のようになっています。
[project]
name = "my-project"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = []
パッケージの同期
pyproject.toml
をもとにパッケージをインストールします。以下のコマンドを実行できます。
uv sync
Rye同様に仮想環境として.venv
が作成されて、また、uv.lock
というlockファイルが生成されます。また、全てのパッケージを再インストールする場合はuv sync --reinstall
で可能です。
仮想環境のアクティベート
以下のコマンドで仮想環境を有効化できます。
. .venv/bin/activate
Python3のパスとバージョンが仮想環境のものになっていることを確認します。
$ which python3
/Users/YoshitakaM/Desktop/my-project/.venv/bin/python3
$ python3 --version
Python 3.12.6
無効化する場合は以下を実行します。
deactivate
Pythonのバージョン変更
pin
コマンドでPythonのバージョンを変更することが可能です。.python-version
ファイルも生成されます。
# 目的に応じて3.12の代わりに3.10, 3.11を指定する
uv python pin 3.12
また、プロジェクトを初期化する際にuv init
の引数に--python
または-p
にバージョンを指定することでも可能です。
uv init my-project-3.10 -p 3.10
または、直接pyproject.toml
のrequires-python = ">=3.10,<3.11"
のように書き換えてuv sync
で更新することも可能です。
詳細な情報は公式のuv - Python versionsを参照してください。
helpコマンド
--help
を使うとコマンドのヘルプメニューを表示できます。
uv --help
特定のコマンドのヘルプメニューを表示するには、次のようにします(例:uv init
)。
uv init --help
--help
フラグを使った場合、簡略化されたヘルプメニューを表示します。コマンドのより長いヘルプ メニューを表示するには、uv help
を使用します。
uv help
特定のコマンドの長いヘルプメニューを表示するには、次のようにしますuv init。
uv help init
長いヘルプメニューを使用する場合、uv
はless
またはを使用してmore
出力を「ページング」しようとするため、一度にすべてが表示されることはありません。ページャーを終了するには、q
を押します。
バージョンの表示
uvは現在も精力的に開発を続けているため、ヘルプを見たい場合は使用しているuv
のバージョンを知ることが重要です。新しいバージョンでは問題がすでに解決されている場合もあります。
インストールされているバージョンを確認するには:
uv version
以下も有効です:
uv --version # Same output as `uv version`
uv -V # Will not include the build commit and date
uv pip --version # Can be used with a subcommand
依存するパッケージ(開発時を含む)の追加と削除
uv add
をつけることで、依存パッケージの追加が可能です。
uv add numpy biopython matplotlib pandas
バージョンを指定することも可能です。
uv add "numpy==1.26.4"
既にPythonファイルのrequirements.txt
が存在する場合はuv add -r
からインストールすることも可能です。
uv add -r requirements.txt
削除するときはuv remove
です。
uv remove numpy biopython matplotlib pandas
--dev
オプションをつけることで、開発用パッケージとして追加することも可能です。こちらはGitHubを使って仲間内で開発環境を統一するときに使います。こちらに追加したパッケージは、パッケージリリース時に一般ユーザーに対してはインストールされません。
uv add --dev pytest notebook ruff mypy
実行したら、uv sync
を実行して設定を反映させる必要があります。これを忘れずに。
uv sync
依存パッケージを追加・削除すると、以下で紹介するpyproject.toml
ファイルのproject.dependencies, tool.uv.dev-dependencies
の値が随時変化します。
[project]
name = "newcomer-practice"
version = "0.1.0"
...
...
dependencies = []
[tool.uv]
dev-dependencies = ["mypy", "notebook", "pandas", "pytest", "ruff", "pandas"]
スクリプトの実行
uvを使用してスクリプトを実行すると、環境を手動で管理しなくてもスクリプトの依存関係が管理されます。
依存関係のないスクリプトの実行
スクリプトにdependenciesがない場合(または標準ライブラリモジュールのみに依存している場合)は、uv run
で実行できます。
import os
print(os.path.expanduser("~"))
$ uv run example.py
/Users/YoshitakaM
スクリプトには引数を指定できます:
import sys
print(" ".join(sys.argv[1:]))
$ uv run example.py test
test
$ uv run example.py hello world!
hello world!
さらに、スクリプトはstdinから直接読み取ることもできます。
$ echo 'print("hello world!")' | uv run -
hello world!
または、シェルがヒアドキュメントをサポートしている場合は、次のようにしても同じ結果が得られます。
uv run - <<EOF
print("hello world!")
EOF
project.toml
を含むディレクトリでuv run
を使用する場合、スクリプトを実行する前に現在のプロジェクトがインストールされることに注意してください。スクリプトがプロジェクトに依存しない場合、フラグ--no-project
を使用してこれをスキップします。
# Note, it is important that the flag comes _before_ the script
uv run --no-project example.py
プロジェクトでの作業の詳細については、uv project guideを参照してください。
依存関係のあるスクリプトの実行
スクリプトが他のパッケージに依存する場合(※多くは依存します)、それらのパッケージがスクリプトが実行される環境にインストールされておく必要があります。uvは、手動で管理された依存関係を持つ長期の仮想環境を使用するのではなく、オンデマンドでこれらの環境を作成することを好みます。これには、スクリプトに必要な依存関係の明示的な宣言が必要です。通常、依存関係の宣言にはprojectまたはinline metadataを使用することをお勧めしますが、uvは呼び出しごとに依存関係を要求することもサポートしています。
例としてrich
パッケージを使った以下のスクリプト
import time
from rich.progress import track
for i in track(range(20), description="For example:"):
time.sleep(0.05)
これは--no-project
フラグを使って依存関係を指定しない場合は失敗します。
$ uv run --no-project example.py
# ModuleNotFoundError: No module named 'rich'
--with
オプションを使うと、依存関係を要求できます。複数の依存がある場合は、--with
を繰り返して指定します。
$ uv run --with rich example.py
# Success
特定のバージョンが必要な場合は、要求された依存関係に制約を追加することができます。
uv run --with "rich>=12.0.0,<13" example.py
uv run
がプロジェクトで使用されている場合、これらの依存関係はプロジェクトの依存関係に加えて含まれることに注意してください。この動作を無効にするには、--no-project
フラグを使用します。
ツールを使う
多くのPythonパッケージはtoolとして使えるアプリケーションを提供しています。
ツールの実行
uvx
コマンドを使ってインストールすることなくツールを呼び出すことができます。例えばruff
を実行する場合は以下のようにします。
uvx ruff
これは
uv tool run ruff
と同じです。uvx
はuv tool run
が便利に使えるようにしてあるエイリアスです。
引数はtoolの名前の後に続けて指定します。
$ uvx pycowsay hello from uv
-------------
< hello from uv >
-------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
uvx
を使用する場合、toolは一時的に隔離された環境にインストールされます。
例えば、pytestやmypyを使用する場合など、プロジェクト内でツールを実行し、そのツールがプロジェクトをインストールする必要がある場合は、uvx
の代わりにuv run
を使用します。そうしないと、ツールはプロジェクトから隔離された仮想環境で実行されます。
プロジェクトがフラットな構造になっている場合、例えば、モジュール用にsrc
ディレクトリを使う代わりとしての時などは、プロジェクト自体をインストールする必要はなく、uvx
でも問題ありません。この場合、プロジェクトの依存関係にツールのバージョンを固定したい場合にのみ、uv run
を使用するのが効果的です。
異なるパッケージ名でのコマンド
uvx ruff
を呼び出した時、uvはruff
コマンドを提供するruff
パッケージをインストールします。しかし、パッケージ名とコマンド名が異なる場合があります。例えば httpie
が提供するhttp
の場合などでは、--from
オプションを使用すると、特定のパッケージからコマンドを呼び出すことができます。
uvx --from httpie http
--from
はgitをソースにしている場合にも使えます。
uvx --from git+https://github.com/httpie/cli httpie
特定のバージョンを指定する
特定のバージョンでツールを実行するには、command@<version>
を使用します。
uvx ruff@0.3.0 check
ツールを最新バージョンで実行するには、command@latest
を使います。
uvx ruff@latest check
上記のように、--from
オプションを使用してパッケージのバージョンを指定することもできます:
uvx --from 'ruff==0.3.0' ruff check
または、バージョン範囲を制限する場合は
uvx --from 'ruff>0.2.0,<0.3.0' ruff check
@
構文はあるバージョンを正確に指定する場合のみ使用可能で、それ以外には使えないことに注意。
ツールのアップグレード
ツールをアップグレードするには、uv tool upgrade
を使います:
uv tool upgrade ruff
ツールのアップグレードは、ツールのインストール時に指定されたバージョン制約に従います。例えば、uv tool install ruff >=0.3,<0.4
をしたあとでuv tool upgrade ruff
を実行すると、ruff は>=0.3,<0.4
の範囲の最新バージョンにアップグレードされます。
バージョン制約を置き換えるには、uv tool install
でツールを再インストールします。
uv tool install ruff>=0.4
すべてのツールをアップグレードするには
uv tool upgrade --all
でOKです。
uvの仮想環境に入る
uvはvenvでプロジェクト直下の.venv
ディレクトリに仮想環境を作成しています。仮想環境に入るには通常通り. <myproject>/.venv/bin/activate
を実行します。
. .venv/bin/activate
仮想環境に正しく入った場合、which python3
の結果がそのmyprojectディレクトリ以下の.venv/bin/python3
になります。
$ which python3
/path/to/myproject/.venv/bin/python3
仮想環境を終了したい場合は、deactivate
を実行します。
deactivate