28
43

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonパッケージ開発チュートリアル

Last updated at Posted at 2025-03-11

個人的なパッケージ開発チュートリアルです。ここに書いてあるのは一例なので、ググったり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の開発環境においてはまず

を使えるようになりましょう。一括でこれらをインストールしたい場合は、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というファイルを作成し、以下のような内容を書いてください。

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ディレクトリに作成します。

pack_test/test1.py
#!/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関数は、input1input2という2つの引数を取り、switch1switch2という2つのスイッチを取ります。switch1Trueの場合、input1を表示します。switch2Trueの場合、input2を表示します。test1.pyは、コマンドライン引数として-i-j-s-tを取り、それぞれinput1input2switch1switch2に対応します。-iは必須の引数です。-jは任意の引数です。-s-tはスイッチです。-sがある場合、switch1Trueになります。-tがある場合、switch2Trueになります。

ここまでの操作で、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に追記します。

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を有効にしてください。

8IhyCuV.png

さらに、VSCode上でGitHub Copilotを使うには、VSCodeでアカウントを連携する必要があります。VSCodeの左下のアイコンをクリックして、GitHubアカウントを連携してください。また、拡張機能からGitHub Copilotを検索し、これをインストールしてください

使えるようになると、VSCodeの右下に「Copilot」というアイコンが表示されます。

GitHubでリポジトリを作成する

GitHubと連携して自身のリポジトリを作成する方法を説明します。本来gitはローカル(自身のパソコン)で管理するものですが、GitHubを使うことで、リモート(インターネット上)にも保存することができます。また、GitHubを使うことで、他の人との共同作業も可能になります。

gitはもともとコマンドラインベースなので、すべての操作はターミナルのコマンドから行うことができます。それらのコマンドをしっかりと覚えたい方は慶應義塾大学の渡辺先生のGitHub演習のウェブサイトを参考にするとよいでしょう。しかし、これらのコマンドを完全に覚えるのは大変ですし、今ではVScodeまたはGitHubのウェブサイト上からのGUI操作でおおよそ最低限必要な操作は行うことができます。この章では、GUI操作でリポジトリを作成する方法を説明します。

GitHubのトップ画面に新しくリポジトリを作成するためのボタンがあります。このボタンをクリックすると、リポジトリの作成画面に移動します。

adfadf.png

Create a new repositoryの画面で、プロジェクトファイルを保存するためのリポジトリを作成します。リポジトリ名は、プロジェクト名と同じにしておくとよいでしょう。

jXOOhxS.png

この画面では、リポジトリの説明を書くことができます。また、リポジトリの公開範囲を設定することができます。ここでは、Publicにしておきます。Publicにすると、他の人がこのリポジトリを見ることができます。Privateにすると、自分以外は見ることができません。PrivateはGitHub Educationに加入していれば選択できますが、基本的には有料サービスです。

Add a README fileにはチェックを入れておきましょう。

.gitignoreは、作成したいプロジェクトで主に使われることになる言語を設定する事が多いです。ここでは、Pythonを選択します。
Choose a licenseのところではそのプロジェクトのライセンスを設定します。この効力は大きく、ユーザーおよび営利目的とする企業はGitHub上のソフトウェアのライセンスの仕様に必ず従わなければなりません。最も制限がゆるいライセンスはMIT Licenseと言われます。ここでは例としてMIT Licenseを選択します。

リポジトリを作成するとこのような画面になります。

リポジトリメイン1

ここに向けて、先ほど作成した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ブランチに.gitignoreREADME.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が現れます。

Webブラウザ上でのVSCode

このように、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の中身は以下のようになっています。

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.tomlrequires-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

長いヘルプメニューを使用する場合、uvlessまたはを使用して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の値が随時変化します。

pyproject.toml
[project]
name = "newcomer-practice"
version = "0.1.0"
...
...
dependencies = []

[tool.uv]
dev-dependencies = ["mypy", "notebook", "pandas", "pytest", "ruff", "pandas"]

スクリプトの実行

uvを使用してスクリプトを実行すると、環境を手動で管理しなくてもスクリプトの依存関係が管理されます。

依存関係のないスクリプトの実行

スクリプトにdependenciesがない場合(または標準ライブラリモジュールのみに依存している場合)は、uv runで実行できます。

example.py
import os
print(os.path.expanduser("~"))
$ uv run example.py
/Users/YoshitakaM

スクリプトには引数を指定できます:

example.py
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パッケージを使った以下のスクリプト

example.py
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

と同じです。uvxuv 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
28
43
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
43

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?