PyPIデビュー 2023

author:

Kazuya Takei / @attakei

date:

2023/10/27

event:

PyCon APAC 2023

hashtags:

#pyconapac , #pyconapac_4

はじめに

お前誰よ

Kazuya Takei

  • attakei (X, GitHub, etc)

  • 株式会社ニジボックス

  • 趣味系Pythonista <= こっち

著者近影

株式会社ニジボックス

../_images/logo-corporate.png

ニジボックス は「Grow all」をミッションに、企業やサービスの成長に向き合い続けるリクルートグループのデザイン会社。

お客様のビジネスの成長をUI UXのデザインプロセスから開発・運用・改善までワンストップでサポート。

興味が湧いた・問い合わせしたくなったら、 https://www.nijibox.jp へ。

株式会社ニジボックス

POSTD

  • https://postd.cc

  • エンジニアに向けたキュレーションメディア

  • 海外のテック記事を日本語に翻訳して配信

../_images/logo-postd.png

今日話す予定のこと

  • Pythonにおけるモジュール/パッケージと、PyPIの紹介

  • PyPI上へ自身の開発したパッケージをアップロードする流れ

  • 上記+αを、GitHubを有効活用していく手法

これらを、「発表者の体験を踏まえて」話します。

今日話さない予定のこと

  • パッケージングを「支える」側の技術

  • (後述する)各種ステップの各論

PythonパッケージとPyPI

とあるSphinx拡張(仮)

from sphinx.application import Sphinx


def setup(app: Sphinx):
    """拡張として読み込み時にprintをするだけ。
    """

    print("Let's build by Sphinx!")

Pythonにおけるモジュール/パッケージ

  • スクリプト = Pythonコードが記述されたファイル

  • モジュール = import による再利用を前提とした「スクリプト」

  • パッケージ = 1個以上の「モジュール」の集まり

…自分以外もパッケージを共有したい時がある

…PyPIへアップロードしたくなる

PyPI

../_images/pypi.png

PyPI

http://pypi.org/

  • Py thon P ackage I ndex

  • Pythonパッケージを公開するためのリポジトリサイト

  • pip install で特に指定がない場合に、パッケージを見に行く第一候補

  • PSF(Python Software Foundation) によって運用中

今日の目的

  • PyPIへ自作のライブラリをアップロードする道筋を知ること

今日の目的

  • PyPIへ自作のライブラリをアップロードする道筋を知ること

  • PyPIデビューをすること

今日の目的

  • PyPIへ自作のライブラリをアップロードする道筋を知ること

  • GitHubを使った 、楽なPyPIデビューをすること

巨人の肩に乗ってゆけ

../_images/octcat.png

Pythonパッケージを開発する

基本的な流れ

  • (想起する)

  • セットアップする

  • 開発する

  • テストをする

  • ドキュメントを書く

  • パッケージングする

  • アップロードする

セットアップする

パッケージに必要なファイルを準備する。

必要なもの:

  • Pythonパッケージ本体

  • pyproject.toml

以上(あくまで最小要件)

セットアップする

pyproject.toml (Pythonパッケージのメタデータなどを管理するファイル)

# Pythonパッケージの基本情報たち
[project]
name = "atsphinx-buildtime"
description = "Simple build-time logger for Sphinx."
requires-python = ">=3.7"
dependencies = ["Sphinx"]
dynamic = ["version"]

# sdist/bdistを作成する際のツール定義
[build-system]
requires = ["setuptools", "setuptools-scm"]
build-backend = "setuptools.build_meta"

# ビルドツールのオプション
[tool.setuptools.dynamic]
version = {attr = "atsphinx.buildtime.__version__"}

セットアップする

[project] の要素例

  • name ... パッケージ名

  • version ... バージョン情報

  • description ... パッケージの説明

  • scripts ... CLIコマンド

  • dependencies ... 依存パッケージの情報

  • optional-dependencies ... 直接依存しないパッケージの情報

セットアップする

[project] の要素例

  • requires-python ... 必要なPython実行環境のバージョン

  • license ... 配布時のライセンス

  • classifiers ... PyPIの分類情報( 詳細 )

  • urls ... パッケージの関連サイト

  • dynamic ... 外部ファイルから取り込む値

※より詳しくは PEP 621

セットアップする

必要なもの(再掲):

  • Pythonパッケージ本体

  • pyproject.toml

Q
これだけ?
A
一応、あれこれ考えずに最近のPython実行環境のみを前提にすれば、ビルドツールがよしなにやってくれる。

開発する

各自の環境でPythonパッケージの開発を進める。

  • Editable Install ( pip install -e . 等)を利用すると楽。

  • 「どのPythonバージョンまでサポートするか」「依存パッケージがどこまでサポートしているか」

    • 例:パターンマッチングを使うならPython 3.9を見捨てる。

    • 目安として、PythonのEOLを見ると良い。

    • Python 2.xは忘れましょう

開発する

なるべく早いうちに。

  • フォーマッターによる記述の統一 (PEP 8 , isort , 他 )

  • 静的解析ツールによる不要な記述の除去 ( pyflake , 他)

  • docstringの記述

テストする

「この呼び出しをしたら、この結果が返る」を担保する行為。

  • トレンド的にはpytestを推奨

  • ある意味、自分の不安との戦い

  • 個人的には、社内のプロダクト開発以上に重要

    • 他者(不特定多数)への動作保証のエビデンス

    • 周辺の変化に追従する指針になる

  • 「好きとか嫌いとかはいい、練習してテストを書けるようになるんだ」 [1]

ドキュメントを書く

他者が使うことを想定して、「利用法」などをまとめる。

  • テストより人に優しいので、ある方が良い。

  • ツールは様々

    • Sphinx

    • MKDoc

    • (etc)

パッケージングする

ソースコードをsdist(tar.gz)にしたり、bdist(wheel)を作成したり。

  • ツールは様々。 [2]

    • setuptools, flit, poetry, rye ...

    • pyprojectがちゃんとしているなら、pyproject-buildを使うと単一コマンドにできて楽...かもしれない。

  • PyPA に感謝を。

アップロードする

PyPIにsdist,bdistを登録する。

  • ビルドツール内の機能でそのままアップロードまでできるものが多い。

  • 個別に実施するときでも、 twine で十分。

pyproject-build
twine upload dist/*

アップロードする

この時点までに、PyPIのアカウントを作成する必要あり。

../_images/api-token-before.png
../_images/api-token-after.png

アップロードする


おめでとう!あなたはPyPIデビューできました!

…ひとまずは。

GitHubに乗りかかって開発する

基本的な流れ(おさらい)

  • (想起する)

  • セットアップする

  • 開発する

  • テストする

  • ドキュメントを書く

  • パッケージングする

  • アップロードする

基本的な流れ with GitHub

  • (想起する)

  • セットアップする with GitHub

  • 開発する with GitHub

  • テストする with GitHub

  • ドキュメントを書く with GitHub

  • パッケージングする with GitHub

  • アップロードする with GitHub

開発する with GitHub

開発する with GitHub

../_images/codespaces.png

開発する with GitHub

GitHub Codespaces

  • GitHubがホスティングしているクラウド開発環境

  • ブラウザ・端末を飛び越えて環境を共有できるのが強み

  • 中身はVisual Studio Code

開発する with GitHub

GitHub Copilot

  • AIによる、プログラミング支援サービス

  • (使ってないので、紹介だけ)

テストする with GitHub

テストする with GitHub

../_images/actions.png

テストする with GitHub

GitHub Actions

  • GitHub提供のワークフロー基盤

  • CI/CDなんでもござれ

  • マニュアルバッチに定期処理

テストする with GitHub

test:
  runs-on: ubuntu-latest
  strategy:
    max-parallel: 4
    matrix:
      python-version: [3.7, 3.8, 3.9, '3.10', '3.11']
      sphinx-version: ['>=3.0.0,<4.0.0', '>=4.0.0,<5.0.0', '>=5.0.0,<5.1.0', '>=5.1.0,<6.0.0', '==7.*']
      exclude:
        # Old major version does not support python>=3.10
        - python-version: '3.7'
          sphinx-version: '==7.*'
        - python-version: '3.10'
          sphinx-version: '>=3.0.0,<4.0.0'
        - python-version: '3.11'
          sphinx-version: '>=3.0.0,<4.0.0'
  • matrix を使って、組み合わせテストが出来て便利

  • exclude で特定条件の除外も可能

  • ( ref )

テストする with GitHub

on:
  push:
  pull_request:
  workflow_dispatch:
  schedule:
    - cron: '30 0 * * 1'
  • on.push でPushのたびにテスト実行するのが基本

  • on.schedule を登録しておくことで、未来に備えられる

    • 依存パッケージがいきなり後方互換を壊して登場する

    • 依存の依存パッケージが突然組み合わせ不全を起こす

  • on.workflow_dispatch はいざというときのマニュアル実行

ドキュメントを書く with GitHub

ドキュメントを書く with GitHub

../_images/actions.png

ドキュメントを書く with GitHub

GitHub Actions

  • GitHub提供のワークフロー基盤

  • CI/CDなんでもござれ

  • マニュアルバッチに定期処理

2度目の登場

↑ワークフロー処理として、ドキュメントのビルドが可能
※ビルドだけだが…?

ドキュメントを書く with GitHub

GitHub Pages

  • 静的サイト配信基盤

  • GitHub Actionsの過程で、楽にデプロイできるのが魅力

  • ライブラリが育ちそうならRead the docsへの切り替えを推奨

パッケージングする with GitHub

パッケージングする with GitHub

../_images/actions.png

パッケージングする with GitHub

GitHub Actions

  • GitHub提供のワークフロー基盤

  • CI/CDなんでもござれ

  • マニュアルバッチに定期処理

3度目の登場

↑ワークフロー処理として、sdist,bdistの作成が可能

パッケージングする with GitHub

GitHub Actions

on:
  push:
    tags:
      - 'v*.*.*'
  • 自分の場合は、タグPushをトリガーにしている

  • 実行環境にWindows,macOSも選択可能なため、bdist作成に便利

  • (余談)デスクトップアプリのビルドにも便利

パッケージングする with GitHub

GitHub Releases

  • タグ等を使ったリリース状態保全

  • PyPIがあれば基本的にそこまで強い出番がない

  • …が、bdistのミラーサイト扱いにはできる

  • GitHub Actionsの過程で、楽にデプロイできるのが魅力

アップロードする with GitHub

アップロードする with GitHub

../_images/actions.png

アップロードする with GitHub

GitHub Actions

  • GitHub提供のワークフロー基盤

  • CI/CDなんでもござれ

  • マニュアルバッチに定期処理

4度目の登場

↑ワークフロー処理として、作成済みsdist,bdistのアップロードが可能
※パッケージングと同じタイミング

GitHub Actionsの出番が多すぎる件

  • CLI処理なら割と何でもできるのが強い

  • OSバリエーションも豊富

  • MarketPlaceのアクションが便利

セットアップする with GitHub

セットアップする with GitHub

../_images/repository-template.png

セットアップする with GitHub

リポジトリテンプレート機能

  • 大雑把に言えば「新規リポジトリ作成用の雛形リポジトリ」

  • テンプレート側もリポジトリなので、メンテナンスしやすい

  • GitHub-CLIからも指定できるのでありがたい

  • ライブラリ作成をこなせばこなすほど意味を持ってくる

セットアップする with GitHub

(番外)cookiecutter

  • 同じくテンプレートから作成するCLIツール

  • プロンプト経由で変数を引き渡せるので、リポジトリテンプレートより柔軟性がある

  • (個人的には、こっちを使っている)

まとめ

これであなたもPyPIデビュー

  • 過去と比較して、単純にパッケージを開発してアップロードする行為がシンプルになっています。

  • 巨人の肩は非常に広いです。活用しまくりましょう。

  • これで、よりライブラリが増えると良いですね。

Thanks