43
68

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

ターミナルは以下のメニューの"新しいターミナル"から開けます(ショートカットキーを覚えると楽)。
2025-04-03 11.05.56.png

下にターミナルが開きました。

2025-04-03 11.06.07.png

このターミナルに以下のコマンドをまとめて打ちます。

code --install-extension charliermarsh.ruff
code --install-extension davidanson.vscode-markdownlint
code --install-extension ms-ceintl.vscode-language-pack-ja
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
code --install-extension shd101wyy.markdown-preview-enhanced
code --install-extension tamasfe.even-better-toml
code --install-extension vscode-icons-team.vscode-icons
code --install-extension yzhang.markdown-all-in-one

これによって便利プラグインがまとめてインストールされます。

また、日本語環境の方が良い場合は、いま導入したms-ceintl.vscode-language-pack-jaによって日本語環境に変更することができます。

Shift+Ctrl+PまたはShft+Command+PでConfigure Display Languageから言語を選択します。

2025-04-03 10.59.28.png

2025-04-03 10.59.39.png

これで日本語を選び、再起動すると、表示が日本語に変化します。

パッケージ開発チュートリアル:newcomer-practice

ここからはuvを使って実際にnewcomer-practiceディレクトリを作成して公開するところまでやってみます。

uvのインストール

まずはuvの公式ドキュメントを参照のこと。macOSまたはLinuxの場合は、以下でインストールします。

$ curl -LsSf https://astral.sh/uv/install.sh | sh
downloading uv 0.6.12 x86_64-apple-darwin
no checksums to verify
installing to /Users/bilab/.local/bin
  uv
  uvx
everything's installed!

To add $HOME/.local/bin to your PATH, either restart your shell or run:

    source $HOME/.local/bin/env (sh, bash, zsh)
    source $HOME/.local/bin/env.fish (fish)
WARNING: The following commands are shadowed by other commands in your PATH: uv uvx

インストール後にターミナルを再起動するとuvコマンドが使えるようになっているはずです。

$ uv --version
uv 0.6.12 (e4e03833f 2025-04-02)

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

echo "3.12" > .python-version

また、後ほどパッケージをビルドするためのディレクトリ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ファイル設定に書き換えてください。

2025/4/3 tool.ruff周りについてアップデート

[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]
indent-width = 4
line-length = 88 # Same as Black.
exclude = [".ruff_cache", ".ruff.toml", ".ruff.lock"]
target-version = "py312"

[tool.ruff.lint]
select = [
    "F", # Flake8
    "B", # Black
    "I", # isort
    "E", # error
    "W", # warning
]
ignore = ["F401", "E501"]
fixable = ["ALL"]
unfixable = []

[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"]

2025-04-03 12.06.28.png

これに書き換えた後、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を実行した時点で仮想環境の作成が検知され、「これをワークスペースフォルダに選択しますか?」と表示されるのでそれを許可してください。
2025-04-03 11.11.08.png

ここで許可しなかった場合で後に切り替えたい場合は、新たに作業ディレクトリ内でPythonファイルを開いた時に、右下のPythonのバージョンをクリックして、仮想環境へのPATH/path/to/newcomer-practice/.venv/bin/python3.12を選択してください。
2025-04-03 11.11.20.png

2025-04-03 11.11.45.png

コードの作成

コードはpack_testディレクトリに配置します。ここでは、pack_testディレクトリにhello.pyというファイルを作成し、以下のような内容を書いてください。

2025-04-03 11.10.00.png

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

VSCodeとRuffを使ってPythonコードの自動フォーマットを導入する

Pythonファイルを作ってみましたが、なんかhello.pyの方では表示が赤くなっています。

2025-04-03 12.21.37.png
2025-04-03 11.15.55.png

画像の上の方に赤い下波線が、一番下の行に黄色の下波線が現れています。近くにマウスをホバーさせるとその理由が表示されます。

これはPython文法チェッカーのflake8が、正しい文法になるように自動チェックを働かせてくれている状態です。その指示に従うことでErrorやWarningを解決できます。が、これって面倒ですよね。自動で修正してほしいですよね。
これをVSCodeである程度自動で行ってくれるようにするために、以下の設定を追加します。
Ctrl+,またはCommand+,で、設定画面を開きます。画像の赤枠の部分を押すとsettings.jsonが開きます。

2025-04-03 11.19.20.png

settings.jsonを開いて、以下の内容を入力します。すでに他の設定値がある場合は、,で間を区切ることを忘れないようにしながら設定値を追記します。

settings.json
{
    "files.autoSave": "onWindowChange",
    "[python]": {
        "editor.formatOnSave": true,
        "editor.defaultFormatter": "charliermarsh.ruff",
        "editor.codeActionsOnSave": {
            "source.organizeImports": "explicit",
            "source.fixAll": "explicit"
        },
    },
    "[markdown]": {
        "editor.formatOnSave": true,
        "editor.formatOnPaste": true,
        "editor.defaultFormatter": "DavidAnson.vscode-markdownlint",
    },
    "flake8.enabled": false,
}

この設定追記によって、ウィンドウが変わると自動でファイル保存が実行されるようになり、かつpythonのファイルを編集しているときはRuffによる自動フォーマットが実行されるようになります(ついでにmarkdownも)。また、"flake8.enabled": falseを用いて、flake8による文法チェッカーを無効化しています。このへんの設定は好みによるので好きな値に設定してください。

settings.jsonの編集時に、下波線が現れている場合、またはハイライトが消えている場合は、その設定が有効でないことを表しています。画像では、editor.defaultFormatterに下波線が、ruff.lineLength: 88のハイライトが消えています。
2025-04-03 11.30.33.png
,を忘れてしまっているために設定が有効化されていないこともありますが、Ruffについては、拡張機能:マーケットプレースから手動でインストールする必要があるかもしれません。この場合、画像左の赤枠から拡張機能を選び、ruffと入力して現れるRuffを手動でインストールしてください。その後、settings.jsonの表示に異常がなくなればOKです。
2025-04-03 11.23.45.png

これを用いてhello.pytest1.pyに変更を加え、ウィンドウを変えたり保存したりすると、自動である程度フォーマッターが働いて整形してくれるようになるはずです。

パッケージの動作

実際にこの自作の関数が期待通りに動作するかを試してみましょう。ターミナルから以下のコマンドを入力し、仮のディレクトリを作成してその中で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()と指定してあるためです。これで、自作のパッケージが正常に動作することが確認できました。

依存パッケージの追加

プロジェクト内でnumpy, matplotlibなどのパッケージを使いたい場合、ターミナルからuv addコマンドで追加することができます。

uv add numpy matplotlib

uv addを行うと、pyproject.tomlファイルの[project.dependencies]に追加されます。

pyproject.toml
[project]
name = "newcomer-practice"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = ["numpy", "matplotlib"]

バージョン指定や、githubからのgitでのインストールも可能です。

# バージョン指定
uv add "requests==2.31.0"
# git dependency
uv add git+https://github.com/psf/requests

uv removeでパッケージを取り除くことも可能です。

uv remove numpy matplotlib

パッケージを追加した後は、uv syncを実行して依存パッケージをインストールします。

uv sync

uv lock --upgrade-packageでパッケージをアップグレードすることもできます。

uv lock --upgrade-package numpy matplotlib requests

--upgrade-packageフラグは、指定されたパッケージを最新の互換バージョンに更新しようとしますが、lockファイルの他の部分はそのままにします。

また、--devで開発用の依存パッケージとしてインストールすることも可能です。開発用依存パッケージは、実際のパッケージには含まれず、開発時のみに必要なパッケージです。主にjupyter notebook, mypy, ruffなどの開発支援ツールを入れておくとよいでしょう。

uv add notebook mypy ruff --dev

GitHub連携

Gitとはプログラムのソースコードなどの変更履歴を記録・追跡するための分散型バージョン管理システムです。Linuxカーネルのソースコード管理に用いるためLinuxの生みの親であるLinus Torvaldsによって開発され、それ以降ほかの多くのプロジェクトで採用されています。

GitHubはソフトウェア開発のプラットフォームであり、ソースコードをホスティングすることで複数人のソフトウエア開発者と協働してコードをレビューしたり、プロジェクトを管理しつつ開発を行うことができます。コードのバージョン管理システムにはGitを使用しています。2008年4月にサービス開始され、2010年にGitHub社が設立されました。2018年にはMicrosoftに買収されています。

現在では研究者もGitHubなどのプラットフォームを使って研究に使ったコードを公開することが推奨されています。これによって他のユーザーもその人の実験を再現することができるようになります。

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
43
68
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
43
68

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?