【2020年新人研修資料】 ナウでヤングなPython開発入門
〜2020年 新人研修資料〜ナウでヤングなPython開発入門 株式会社FORCAS 分析チーム1
View Slide
簡単な経歴2000 ~ 20062007 ~ 20202020/03 ~ 現在ちゃんぽん屋時代の私 現在の私慶応大学理学部物理学科 → 名古屋工業大学大学院(情報工学修了)いろんなジョブをホッピング(広告/ちゃんぽん屋など)株式会社FORCAS(UZABASEグループ) よしなにおじさん※寒ブリの里・金沢からフルリモート勤務中※その他、博士(統計科学)・修士(経営工学)なども保有研修講師(論理)2
目次● この研修は何なの?● 開発の基盤を整えよう○ poetryを使ってみよう○ pytestで単体テストをしよう○ black/autoflake8/isortでフォーマッティングしよう○ mypyでType Hintsを徹底活用しよう○ 退屈なことはGithub Actionsにやらせよう● 開発を進めていこう!3
この研修は何なの?4
● この研修はなんなの?○ FORCAS Product Division Analysis Teamの“標準的”なPython開発を紹介するよ○ 今回はCLI Applicationの開発が題材だよ■ 法人番号を引数に実行すると会社名と住所を返却するような簡易ツール● なんでCLI開発なの?○ 我々の業務としてクローラを書くことが多数あるのでWeb ApplicationというよりもCLIに焦点を当てたかったからだよ○ 機械学習モデル用のAPIサーバ開発(fastapi編かな?)はまた今度○ 資料の大部分は”開発基盤をどう整えるか”がメインだからツール自体については深く考えなくてもいいよ● 誰に向けて書いているの?○ まだ見ぬ未来の我々の同僚のためだよこの研修は何なの?5
この研修は何なの?● なんで“標準的な”開発なんて定義するの?○ UZABASEの7つのルール「自由主義で行こう」が行き過ぎることが多々あって、保守管理不可能なスクリプトが量産された歴史があるからだよ○ 経験ではなく歴史から学んでいるので講師は賢者だよ♂○ 不自由さがあってこそ自由が際立つんや!!!● “標準的”ってどのくらい業界の標準なの?○ 正直、よくわからない■ Pythonは良い意味でOSS(Rの一強Tidyverse的概念がない)なので…○ 「ググった感じモダンな奴のみ取り込んでるし大丈夫だろ、ワハハ!」のノリ6
開発の基盤を整えよう7
poetryを使ってみよう8
poetry● コレはなんなの?○ PythonのPackage Managerだよ○ メリット■ みんなのパッケージのバージョン/開発環境が揃って嬉しいよ○ デメリット■ 使い方を覚えるのが面倒(くらいかな?)■ poetry installした時の依存性解決待ちが結構長い● XXXでいいんじゃないの?○ Dockerでいいんじゃないの?■ Dockerfile内に pip install hoge==1.1.2 みたいなコード乱発はちょっと…■ requirements.txt で管理するのもなくはないがどのみち外側にPackage Manager欲しい9
poetryとりあえず- poetry new gbizinfoを実行してみよう。既に既存のディレクトリ位がある場合は- poetry initで適当にダイアログに出てくる質問に答えるといいよREADME.rstはREADME.mdにrenameしてもよいかも10※最終的なディレクトリ構造
poetry● 次に開発に必要となるライブラリをインストールしよう!○ 実際は何が必要になるのかは開発初期段階で全て把握するのは無理なので都度都度実行● とりあえず○ 開発に絶対必要なもの(--dev)○ 配布する際に必要となるもの(--devなし)をインストールしておこう(ライブラリの内容は後述)● poetry add black isort autoflake mock mypy responses --dev● poetry add click requests● インストールされるライブラリのversionはpyproject.tomlで管理○ バージョン指定方法は https://python-poetry.org/docs/versions/ を見ると良いよ!■ Minorバージョンは変更しても良い、などの書き方が載っている11※インストールの様子
poetry● 作成すると勝手に __version__ が定義されるよ● しかし、pyproject.tomlにもversion番号があって二重管理しんどい…● この管理のベストプラクティスについては諸説あってまだやりとりしてるみたいだよ○ importlib.metadataで書いておくのが楽そうだよ■ https://github.com/python-poetry/poetry/issues/14412
poetry● ローカルにあるライブラリをeditable/developなモードでインストールしたい場合は画像の用に書いてからpoetry install すると良いよ!○ editableモード:コードの変更が自動で反映されるようになり、いちいちpoetry remove/addして更新しなくてもよくなるモード○ 1.1.0からこの仕様になっているよ!○ https://python-poetry.org/blog/announcing-poetry-1-1-0.html● 使いどころ○ 例:社内ライブラリAの開発版を、他のレポジトリBで使いながらBの開発をしたい■ Aの機能をBで使う際に整合的にしたいとか、BのためにAで機能開発するとか● poetry add --editable でイケるためのPRが出ているけどまだMergeされていないみたいだよ!○ https://github.com/python-poetry/poetry/pull/325013
● 画像の2ファイルを作成してコードを書くと↓のように実行できるよ!○ poetry run はpoetryの作成する仮想環境で実行するおまじないだよ!○ 法人番号に対応した会社名と住所が返ってくる❯ poetry run python -m gbizinfo.main --corporate_number 7010401075212('株式会社ユーザベース', '東京都港区六本木7丁目7番7号')とりあえず動くコードを書く14※写経が面倒な人は https://github.com/forcas/analysis-example-app-gbizinfo をCloneしてしまおう!
● ちょっとだけコードの解説をするよとりあえず動くコードを書く15・clickを使うと引数の処理がめっちゃらくになるよ!・引数のValidationもできるよ!(桁数のみチェック、本当はCheckDigitとかもやる)・ #type: ignore はmypyを無視するおまじない・https://info.gbiz.go.jp/ が提供するAPIを呼ぶだけ・SPARQLという言語が必要!(詳しくない)・POST部分を切り出して書いておくと単体テストしやすくなるよ!(豆知識)※写経が面倒な人は https://github.com/forcas/analysis-example-app-gbizinfo をCloneしてしまおう!
pytestで単体テストをしよう16
テストがない=プロの仕事ではない● テストがないとそもそも動作として”何が正しいのか”が何もわからない…○ ここでは「正しさ」について議論することはやめておくよ!皆それぞれの正義があるので…● 機械学習だって統計学の知見があればテストが書ける!○ 推定値のバラツキ(標準誤差とか)を考えるんや&ここではやらない17
テストを書くよ!● こんな感じ● clickにはCliRunnerクラスがあって、実際にTerminalから呼び出した状態をテスト出来て便利だよ!● test_main()は単体ではなく結合テストになっている(Mockなしに全モジュールを使用してCLIとして実際に実行してるので)18
テストを書くよ!● SPARQLが所望のものになっているか確認したり、POSTした結果がちゃんと捌けるか確認したり● 実際にPOSTする代わりにPOST結果のMockをresponses で作成して、結果が正しくParseされるかを確認19
テストを動かすよ!poetry run pytestでおしまい。個別のテストはpoetry run pytest tests/test_basic.pyなどで実行できるよ!20
black/isort/autoflakeでフォーマッティングしよう21
Codeフォーマットについて● フォーマットに関する指摘がCodeレビューにしばしば出てきた○ おじさんが若い頃には、ね。○ e.g. 「フォーマットが崩れています、自戒を込めてUnapproveです」○ でもこれ時間の無駄じゃね?(1円も売上にならない)■ < そもそも高価な人間のやるべきことでもない○ 我々のやるべきこと=売上を上げること■ SaaSビジネス a.s. ≒ ユーザの期待に応え“続ける” ⇒ SaaS最高!● 保存 / git commitするたびに自動的にフォーマッター書けたい!○ 「git hook」や「保存時 整形」とかで検索するといいよ!○ PyCon JP 2020のYuuki Nakajimaさんの「チーム開発時にやっておいたほうが良いこと」が大変良いです(このトピックだけでなく全体的に良い)■ https://gitpitch.com/darakudou/pyconjp_2020○ 最後に弊チームでのやり方を紹介22
弊チームが採用しているコードフォーマッターpoetry run black . --check● --checkを外すとファイルを修正するよ● https://github.com/psf/black● フォーマットの形式は pyproject.toml で指定できるよ!(このレポジトリでもそうしている)○ https://black.readthedocs.io/en/stable/pyproject_toml.html#configuration-formatblack23
autoflake未使用変数、 未使用importを自動で検知/削除したいよpoetry run autoflake -r --check \--remove-all-unused-imports\--ignore-init-module-imports\--remove-unused-variables .● --ignore-init-module-imports : exclude __init__.py when removing unused imports● --checkを--in-placeに書き換えるとファイルの修正を行う● https://github.com/myint/autoflake● pyproject.toml対応したらオプション記述を移動したい24
isortライブラリのimportする順番もあまり気にしたくないよ!いい感じに並べ替えてほしいよ!poetry run isort . --check --profile black● --checkを外すとファイルを修正する● --profile blackとすることでblackの方針に合わせた修正をする● これもpyproject.tomlで指定可能● https://github.com/PyCQA/isort25
mypyでType Hintsを徹底活用しよう26
型付けについて● 型付けってなに?○ 関数の引数がstrなのかintなのか等、その”型”を明示しておくことだよ● 何が嬉しいの?○ パッと見で関数から返ってくる型&引数の型がわかる■ 型が合わなくて処理停止(動的な言語なので実行時にわかる)!がなりにくくなる○ mypyが勝手に型情報をもとにCodeをチェックしてくれるようになる● mypyはなんなの?○ そんな型情報に基づいてオレたち開発者をこっそり守ってくれるものだよ!■ 静的な言語(Scalaとか)だともっと強力にオレたちを守ってくれるよ!(移行したい)○ 型があってないと警告をだしてくれたりする● mypy以外にもそういうライブラリを有名所が出していてくれたりもするよ!○ ここは好み&宗教戦争になりそうなので深く言及しない○ Pyre (Facebook)、Pyright (Microsoft)、Pytype (Google)27
mypypoetry run mypy . --platform linux --config-file mypy.ini● 3.9系のPythonだとまだ完璧には動かないぽいから、必要に応じて #type: ignoreをつけて凌いでいこう!● こちらがマージされれば3.9対応(including PEP585)● 設定ファイルを適当なiniファイルに書いておけば --config-file mypy.ini で読ませられるよ● https://github.com/python/mypy28
退屈なことはGithub Actionsにやらせよう29
退屈なことはGithub Actionsにやらせよう● この手の整形・チェックは人間がやるのは時間の無駄です○ 無駄というかミスが出て余計な工数がかかります○ “やった感”があるので個人の業務達成感はあるが、1円も売上にならない● こういうのは何も考えずに勝手に誰か()がやってくれているべき● https://github.co.jp/features/actions がそれをサポートしてくれるよ!● とりあえず .github/workflows/ というディレクトリを掘って、 適当なyamlファイルを作ろう!○ ここではci.ymlにしておくよ!30
.github/workflows/ci.yml はこんな感じに書いておくと良いよ31※写経が面倒な人は https://github.com/forcas/analysis-example-app-gbizinfo をCloneしてしまおう!● 我々はナウい集団なのですでにPython3.9系のみを使っているよ!!!
Pushするたびに勝手にCIが走って今まで説明してきたことの全てを勝手にやってくれるよ!32
開発を進めていこう!33
開発を進めていこう!● まとめ○ 現状弊チームでは以下で運用しているよ■ パッケージマネージャ:poetry■ コードフォーマッター:black/autoflake/isort■ Type Hintsの活用:mypy● これらのチェックがgit pushする度にGithub Actionsにより勝手に走っているよ● これで冒険に出る準備は整ったので、一緒にヤッテイキましょう!● ここで紹介したコードは以下にありるよ!○ https://github.com/forcas/analysis-example-app-gbizinfo34
※ここからエンジニア採用広告35
Uzabase データサイエンティスト 機械学習エンジニア 検索 データサイエンティスト/機械学習エンジニア募集中keyword機械学習、データサイエンス自然言語処理、クローリング、ソフトウェア開発※経営統合によりUzabase採用になります36