Closed32
PyCon APAC 2023 ノート
興味があったセッションについてのノート
Day1
Reproduce Evangelion Timer on browsers using PyScript
ブラウザで動作するエヴァンゲリオンタイマーをpythonで実装してみたという内容
- https://youtu.be/qM2ZinHiAd8?t=623
- pyscript
- 現状ランタイムのダウンロードに時間がかかるので遅い
- svg
- HTMLで表現が難しいイレギュラーボーダーを表現できる
- ダイナミックに見た目を変えられる
Streamlit meets WebAssembly - stlite
- https://youtu.be/qM2ZinHiAd8?t=6893
- Streamlit meets WebAssembly - stlite
- Streamlitの現状の問題
- Offlineで実行できない
- サーバを運用する必要がある
- データがサーバに送信されることによるデータプライバシーの問題
- stlite
- Pyodideですべてブラウザ上で処理が実行される サーバレス方式ができる- アプリからHTTPリクエスト飛ばしたい時はpyfetch(Pyodideが提供している)
- アプリからHTTPリクエスト飛ばしたい時はpyfetch(Pyodideが提供している)
Enhancing Observability in FastAPI or Python Application with OpenTelemetry
- https://youtu.be/qM2ZinHiAd8?t=15946
- Trace結果出力先の開発・テスト・本番ごとのの切り替えはExporterの設定を変える
- grafana/tempo: Grafana Tempo is a high volume, minimal dependency distributed tracing backend.
- grafana/loki: Like Prometheus, but for logs.
Introduction to Structural Pattern Matching
- https://2023-apac.pycon.jp/live/CtTjApnqb8c
- https://slides.takanory.net/slides/20231027pyconapac/#/
- PEPが3つ!(PEP634, PEP635, PEP636)
- match構文用にソフトキーワードという仕組みができた
- 変数名としては使える(もともとのハードキーワード(classなど)は使えない)
- 組み込みクラスのマッチにも使えるのでint型, str型を別に取り出したりできる
match v:
case {"xxx": int(n)}:
print(n * 2)
case {"xxx": str(s)}:
print(s)
- 独自__eq__メソッドを実装しているクラスだと動きがおもしろいかも
PyPIデビュー 2023
Pythonパッケージをどこからでもpipインストールできるように公開する方法
- https://youtu.be/CtTjApnqb8c?t=14080
- 現在、最低限PyPIに登録できるようにするには以下だけでよい
- パッケージコード本体
- pyproject.toml
- sdistとbdist
- Githubテンプレート作成機能
Pants ではじめる Python Monorepo
- https://youtu.be/CtTjApnqb8c?t=16487
- モノレポの課題のうち以下のものはビルドツールを使うことで解決できる
- 依存管理の複雑化
- テスト・ビルド時間の増加
-
Welcome to Pants!
- Linter・Formatterなど開発ツールの共通化ができる
-
BUILD
ファイルに各プロジェクトのエントリポイントや依存定義のファイル(requirements.txtやpyproject.toml)を指定できる - 複数のAWS Lambda関数の管理に使えないかな
Dev Containers時代のPython開発環境のあり方
- https://youtu.be/bA11hZTIBUE?t=20595
- スライド
- VS CodeやIntelliJのDev Containers機能を使って複数プロジェクトを管理
- Dev Containersの良い点
- MacのDockerでファイルシステム周りが遅いという点は最近かなり改善されている
- コンテナ上でのパッケージ管理
- pyproject.tomlを手書き
- poetryなど
- rye
- 開発時とステージング・本番向けコンテナイメージは別にするが基本
- 開発時に生成したrequirement.txtを本番向けイメージビルドに使う
Write Python for Speed
- https://youtu.be/_T0oSYT1jlw?t=7704
- スライド
- 処理速度が求められる環境ではC++が必要
- pythonとC++では100倍レベルで速度の違いが出るケースも
- 理解が追いつけていないところが多い。。
Pythonでのパッケージング:エコシステムの理解と現場での活用
- https://youtu.be/_T0oSYT1jlw?t=16368
- スライド
- GPU系に依存があるライブラリの依存解決は現在のディストリビューション(sdist/bdist)の依存管理方法だと難しい
- condaは独自のフォーマットを採用していたりする
- NVIDIAがPyPI上でのGPUサポートを進めている
Improving debuggability of complex asyncio applications
- https://youtu.be/_T0oSYT1jlw?t=20528
- aiomonitorを使ったasyncプログラムのデバッグ
- 本番のデバッグは大変
- 特にasync周り
- 誰がこのタスクを作ったのか
- なんでこのタスクが停止したのか
- 特にasync周り
- aiomonitor
- v0.5まではターミナルアプリケーションだったがv0.6でWeb UIを実装
- 非同期のデバッグにはツールが必須!
Pythonはどのようにデータベースと繋がるのか
- https://youtu.be/RvPjFTwXWTI?t=14090
- PostgreSQLサーバへ接続するクライアントをPythonの標準ライブラリで実装する話
- MySQL版を作ってみたくなった
- ソケット通信
- 参考: Webサーバーアーキテクチャ進化論2023 | blog.ojisan.io
- bind: ソケットへアドレスを割り当てる処理
-
PostgreSQL: Documentation: 16: Chapter 55. Frontend/Backend Protocol
- Start up
- ソケットの接続と認証
- Normal Operation
- Simple Query
- row_descriptionで列名や型情報
- data_rowで各行のデータ
- Extended Query
- Simple Query
- Start up
- makefile
- ソケットをmakefile関数に渡すことでread/writeなどファイルと同じようにそうさできるようになる
-
PEP 249 – Python Database API Specification v2.0 | peps.python.org
- Python側に公開するDBクライアントのAPI
- 参考: Webサーバーアーキテクチャ進化論2023 | blog.ojisan.io
型チェックを強化するPython 3.11の新機能Data Class Transforms(PEP 681)
- https://youtu.be/RvPjFTwXWTI?t=15578
- PEP681以前の問題
- ビルトインのdataclassを使うと型チェックが可能だが、dataclassライクなライブラリだとうまく方チェックできない
- 型チェッカー側でもプラグインで対応できるがメンテナンスコストが高い
- PEP681でtypingモジュールにdataclass_transformデコレーターが登場
- 型チェッカー用に__dataclass_transform__属性が付与される。型チェッカーはこれを読み込んで型チェックを実行していく
- つまり「dataclassライクなライブラリ」と「型チェッカー」の両方が対応必要
- 型チェッカー、現時点2023/10ではPyrightのみが対応を宣言している。mypy/pyreは対応中。
- dataclassライクなライブラリはattrs/pydantic/sqlalchemyが対応
業務で使える一歩進んだPython使いになるために
- https://youtu.be/RvPjFTwXWTI?t=20647
- スライド
- 動的型付け言語全般として、開発が始めやすいものの継続して開発するのが難しくなるようなコードも書けてしまう
- 継続可能な開発にむけて努力が必要
- 仮想環境
- 仮想環境とパッケージ管理: 複数プロジェクトを同じPCで同時に開発したい/再現性を高くしたい
- Dockerがデファクトスタンダード
- おすすめ記事: 開発品質とDeveloper eXperienceを高めるコンテナ開発環境のご紹介 (Python) - ABEJA Tech Blog
- パッケージ管理
- Linter/Formatter/Testing Framework
- 仮想環境
- 良いコードを学ぶには公開されている良いコード(ライブラリ)などを読む!
ModuleNotFoundErrorの傾向と対策:仕組みから学ぶImport
- https://youtu.be/RvPjFTwXWTI?t=23661
- スライド
- loggingモジュールで始めるログ出力入門の方 こちらもとてもわかりやすかった
- ModuleNotFoundErrorの解消にかかる時間を減らしたい
-
6. Modules — Python 3.12.0 documentation
-
A module is a file containing Python definitions and statements. The file name is the module name with the suffix .py appended.
-
- Packageは複数のModuleまたはPackageを集めたもの
- Regular Package <-- 今回話す
-
__init__.py
を含むディレクトリ
-
- Regular Package <-- 今回話す
.
└── ./
└── foo/
└── __init__.py
import foo # foo/__init__.pyが実行される
- Namespace Package
-
Importの仕組み
- ♻️すでにインポート済み
-
sys.modules
にあれば再利用
-
- ModuleSpec
- PathFinder
- ♻️すでにインポート済み
-
ModuleNotFoundError よくある原因
- 異なる仮想環境を起動している
-
sys.prefix
(仮想環境ディレクトリ) /sys.base.prefix
(仮想環境のものとなったpythonがある場所) を見る
-
- パッケージのインストール忘れ
-
pip list
/help("modules")
-
- 同名のパッケージとモジュールがある
-
pandas.py
みたいなファイルを作ってしまうと ライブラリのpandasと衝突してしまう - 同名の場合自作モジュールの方が優先される
- 要命名再検討
-
- 異なる仮想環境を起動している
Develop your Python cloud & serverless apps locally with LocalStack!
- https://youtu.be/_T0oSYT1jlw?t=22981
- LocalStackの中の人がスピーカー
- Serverlessアプリケーションのテスタビリティを確保したい
- mock
- Getting Started with Moto — Moto 4.2.8.dev documentation
- 内部動作を全てmockできるわけではない
- Cloud Emulation
- LocalStack
- hot reload機能
- デフォルトではIAMポリシーによるチェックはしない、環境変数ENFORCE_IAM/IAM_SOFT_MODEで有効化できる
- Cloud Pods: LocalStackのスナップショットの共有
- 毎週月曜にAWSの最新APIをLocalStackに取り込んでいる
- AWS Smithyの定義からRPCコードを自動生成している(?) (ASF)
- AWS Service Feature Coverage | Docs
- LocalStack
- 発表中ではAWS CLIを使ってlocalstackにリソース定義をしていたけど、TerraformやCDKでもできるようだった
- 関係ないけどWarpターミナル使ってみたくなった
Day2
Let's implement useless Python objects
- https://youtu.be/mqOQtC9Dt84?t=454
- スライド
- コード
- uselessなオブジェクトはuselessだが、uselessなオブジェクトの作り方はuseful
- Dunderメソッドをカスタマイズしてuselessなオブジェクトを作る
Parallel code with Python 3.12 sub-interpreters
- https://youtu.be/mqOQtC9Dt84?t=6871
- Python 3.12で導入されたsub-interpretersは同じプロセスで複数のPythonインタプリターを生成する
- threadingは同じプロセス内で生成されるがGILによってパラレルにCPUを使えない
- multiprocessingはパラレルにCPUを使えるが、プロセスを複数生成する必要がある(プロセス生成は重い)
-
PEP 703 – Making the Global Interpreter Lock Optional in CPython | peps.python.org に向けての機能
- no GILはC拡張がグローバルな状態を共有しない仕組みであることを要求している
- 他のスレッドやプロセスに渡されるデータはpickle/depickleされる
- Q: gracefulシャットダウンはどうなるか
- A: わからない。おもしろい質問。
- Q: sub-interpretersのインタフェースがmultiprocessingと同等レベルになったらmultiprocessingは置き換えられるべきか
- A: Yes. データを完全に分離したいという要求がなければ。
Reformating your code without AI - let's see how a formatter work
- https://youtu.be/mqOQtC9Dt84?t=9349
- スライド
- OpenSSFのマネージャの方
- 自作のコードフォーマッタを作ろうという話
- コードをパースする
- フォーマットが必要な個所を発見・変更する
- Matchers/Visitors/Transformers
- Matcherで必要な個所を発見
- VisitorはCSTを書き換えられない readonly
- TransformerでCSTを書き換え
- Matchers/Visitors/Transformers
- フォーマッター全部は大変なので、自作isort的なのを作るのはおもしろそう
- AST・CSTはコードの詳細度の違いでそれぞれ使いどころがある
- 例) コンパイラのように元のコードの詳細を気にしない場合はCSTの情報は詳細すぎるのでASTでよい
Comparison of Packaging Tools in 2023
- https://youtu.be/mqOQtC9Dt84?t=13397
-
スライド
- ここからだと飛べないのでタイムテーブルから移動する
- パッケージ選びの観点
- 設定が簡単か vs 自由度が高いか
- PEP621 対応しているか
- リゾルバの速度
- タスクランナー
- ビルダー
- 知名度
- production ready
- スピーカーのおすすめ
- ライブラリ開発者 -> Hatch 自由度が高い
- アプリケーション開発(レベル差がある大人数のチーム開発) -> PDM 使うのが簡単
- 小さいプロジェクト -> pip
- Rye
- flaskの作者による開発
- Rust製
- python自体のバージョン管理も含む
- experimental
メモリプロファイラMemrayのススメ
- https://youtu.be/xXX7u1Xdkmk?t=348
- スライド
- 記事
- メモリのプロファイル方法
- トレーシング(tracing)
- すべての取得
- 実行中のプログラムに影響あり
- サンプリング(sampling)
- 定期的に取得
- psutil
- memory-profiler (メンテナンス終了)
- トレーシング(tracing)
-
Memray
- Pablo Galindo Salgado
- Linux/macOS (Linuxのが対応状況がよい)
-
--live
実行中のプログラムの状況がターミナル上で把握できる -
--native
C拡張の中も見れる - Jupyter Integration マジックコマンドで可視化できる (データ処理プログラム開発で便利!)
- pytestプラグインでメモリ上限テストができる
- 変数上書きの場合でも一瞬上書き前と後のデータ量分のメモリが確保される
- Q: バイナリファイルに一度吐き出す理由は
- A: 複数の可視化方法が可能であったり、トレーシングの負荷を減らすためだと考えられる
- Q: 並列プログラムや非同期プログラムについては
- A: できるはず。
Pythonアプリケーションのオブザーバビリティ強化
- https://youtu.be/xXX7u1Xdkmk?t=6584
- モニタリングは手段の一つ
- オブザーバビリティ確保はシステムの状態が把握できる状態にすること
- オブザーバビリティを確保するには目的を持ち、どのようなデータを出力するかを設計する
- システムから必要なデータを取得する仕組みは開発者が実装(計装)
- ログを出力することも含む
- テレメトリーの関心ごと
- 計装
- エクスポート
- テレメトリー取得の課題
- テレメトリーシグナルの形式がと移されていない
- 取得した情報間の紐づけが大変
- OpenTelemetry
- 計装ライブラリ
- 出力先ごとのエージェント(OTel Collector)
- 各言語・ライブラリ・フレームワークのOpenTelemetry対応について開発者とやりとり
- OpenTelemetry対応ツールの検索
- 自動計装から始めるのが手ごろ
- ソースコードの変更が必要なく計装ができる
- サービスレベル目標(SLO)
- ユーザが期待している目標を定め、期待値以上の過度な最適化をしないように
- SLIの元データ
- リクエスト/レスポンスであれば 可用性・レイテンシー・品質(これらのデータは計装で取る)
- SLIとSLO例
- SLI: あるサービスの良いレスポンスの割合、SLO: 直近28日間の良いレスポンスが99.9%
- SLOが決まると許容できるエラー量がきまる(エラーバジェット)
- エラーバジェットを監視することでサービスの余裕が判断できる
Debugging and Troubleshooting Python Applications: Leveraging Visibility and Observability to Solve Problems Faster
- https://youtu.be/kUvFT4hZdO0?t=6900
- スライド
- Pythonロギングからマイクロサービスのオブザーバビリティまで
- python loggingモジュール
- カスタムログレベルが作れる
- Profiler
-
GitHub - plasma-umass/scalene: Scalene: a high-performance, high-precision CPU, GPU, and memory profiler for Python with AI-powered optimization proposals AI-powered CPU,GPU,memoryプロファイラ
- 行レベルでメモリ省人とかが可視化されていてわかりやすそうだった
- cProfile
-
GitHub - plasma-umass/scalene: Scalene: a high-performance, high-precision CPU, GPU, and memory profiler for Python with AI-powered optimization proposals AI-powered CPU,GPU,memoryプロファイラ
- GitHub - gruns/icecream: 🍦 Never use print() to debug again.
あなたのアプリケーションを本番システムで動かすために
- https://youtu.be/xXX7u1Xdkmk?t=8993
- スライド
- PythonでWebシステムを開発するために考えること
- ORM
- SQLインジェクション防止
- N+1問題、SQLの理解
- テスト
- エラーハンドリング
- HTTPレスポンスコード
- 自分だと404を返すのはAPI自体がないとかそういう場合かも
- HTTPレスポンスコード
- ロギング
- プログラムのホウレンソウ
- 5W1H
- 秘匿情報に注意
- セキュリティ
- 利用しているフレームワークのセキュリティ機能を理解する
FinTechの現場でバリバリ活躍するFastAPIの理想と現実
- https://youtu.be/xXX7u1Xdkmk?t=15472
- スライド
- Fast API: Django REST FrameworkとFlaskの間にある感じ
- 途中からmypy導入したので型エラーが大量に発生
- 必要なもの以外を無効化して、無効化を外している
- Swagger UIがあると非エンジニアの方の運用ツールとしても使える
- セレクトボックス
- ファイルダウンロード
- asyncioは無理に導入しない
Pythonで一歩踏み出すバイナリの世界
- https://youtu.be/4jGS2Uzj0eQ?t=597
- スライド
- Unicode
- 文字集合の大きさ111万4112個!
- バイナリ読み込みUTF8として解釈して出力するプログラムの実装
- バイナリデータにはCSの工夫が詰まっている
- サイズ、アクセス速度、汎用性、互換性....
- SQLiteデータのパース
- すべて1ファイル(main database file)に保存される
- データ仕様
- structモジュール: バイナリパースに便利
- dataclassはtupleからでも生成できる
自作パケット処理系の性能測定と可視化&改善のPDCAを回して最強のパケット処理系の作り方を学ぼう
- https://youtu.be/4jGS2Uzj0eQ?t=6906
- スライド
- 通信事業者周りのお話
- PGW-U開発
- GTPトンネルのEncap/Decap
- パケット処理の高速化
- 並列化
- 個々のコアの処理を高速化
- 並列化
- RSS(Receive Side Scaling)
- 対応しているNICはパケットの受信キューを複数持つ
- 受信キューとCPUを紐づけておき、受信パケットを複数のキューに割り振る
- ハッシュベースだが、全体だと負荷が高いのでIPアドレスなど一部のハッシュを取る
- フローごとにパケット処理しないと順番が変わってしまって服装の原因に
- RSS(Receive Side Scaling)
- 個々のコアの処理を高速化
- XDP速いらしい(わからない)
- パケット処理高速化の考え方
- テーブルの数を少なく
- Longest Prefix Match重い
- 性能実験から分析までpythonツールで
- trex: trafic generator
- 問題
- GTPトンネルの識別には5tupleでは不十分、RSSが機能していなかった
- 全体的に理解が追い付かないところが多い
Pythonのワークフローエンジン Apache Airflowを用いた大規模データパイプライン構築と改善
- https://youtu.be/4jGS2Uzj0eQ?t=15822
- スライド
- 運用を見据えた大規模データパイプライン構築
- バッチ処理からワークフローへ
- 商品数2000万 x 商品属性2.5万
- 業務ロジック(本来注力するべきところ)-> SQL
- リトライ・タスク依存関係(どの順番で実行するかなど) -> ワークフローエンジン(Apache Airflow)
- Apache Airflow
- ワークフローエンジン: Luigi, Prefectなどもある
- 各クラウドサービスとの連携プラグインが多くある
- 動かすだけなら簡単だが、大規模運用は難しい -> マネージドサービスを使おう
- BigQuery/Google Cloudとの親和性の関係でCloud Composerを利用
- アクションが可能になるようなログ出力
- どこで、どの列で、どのくらい
Learn Python by contributing to open source
- https://youtu.be/4qh7lh0XcJ4?t=600
- OSSにコントリビュートすることで多くのことが学べる
- Advanced Python Concepts
- Functional Programming
- Async Programming
- 可読性, TDD, パッケージング...
- 最初は小さい変更に取り組む
- メンテナーが力になってくれる
DjangoRestFrameworkのリファクタリング、レガシーなコードの寿命を延ばすために
- https://youtu.be/4qh7lh0XcJ4?t=2082
- 8年稼働しているDjango Rest Frameworkを使ったコード
- テストがないコードはレガシーコードだ(レガシーコード改善)
- Service層とModelのメソッド
- 自Modelにしか関与しないならModelのメソッド
- 複数のModelに関与するならService層
- 再利用性も考慮
- pythonコードからswagger API仕様を生成することで実態とAPI仕様の乖離をなくした
- failしたときにすぐに失敗した個所が特定できるのがユニットテスト
- factory boy
- カスタムエラーはexceptions.pyのようなファイルで一元管理している
Internals of Generators
- https://youtu.be/4qh7lh0XcJ4?t=13515
- IterableはIteratorを返す
- Iteratorはforループの挙動を制御するインタフェース
-
__next__
メソッドを実装 - raises
StopIteration
-
- Generators PEP255
- ほしかった動機: tokenizeで使いたかった
- 元々の問題
- tokenizeユーザが状態を管理しないといけなかった
- Earger Evaluation
- CPythonのGeneratorsの実装
- GeneratorはGeneratorのコード、現在の状態、実行中のフレーム(PyFrameObject)を保持している
- PyFrameObject
- ローカル・グローバル変数
- バイトコード
- スタック
- Online Python Tutor - visualize, debug, get AI help for Python, Java, C, C++, and JavaScript スタックフレームを可視化してくれる
-
gen_new_with_qualname
- ジェネレータの生成
Dodging Dependency Confusion In A Nutshell
- https://youtu.be/4qh7lh0XcJ4?t=14927
- 誤ったパッケージをインストールさせることによる攻撃と回避策について
- Typosquatting
- 人間のタイポを想定して本物と似たようなドメイン名を利用する
- 研究でtyposquattingを利用したパッケージを配布したところ、多くの人が管理者権限の必要なインストールを実施してしまった
- Dependency confusion
- pipは以下の状況でconfused
- パッケージが存在しない
- pip
--extra-index-url
はPyPIと追加のレポジトリを参照する - 攻撃者がプライベートパッケージの名前を知られた場合、同じパッケージ名を公開されるとそちらがインストールされてしまう
- pip
- バージョンの指定がない
- パッケージバージョンを99.99.99のようなものを公開されるとそれが最新版としてインストールされてしまう
- パッケージ名typo
- 正しいパッケージの似たような名前のパッケージを公開しておくとtypoしたときにインストールされてしまう
- パッケージが存在しない
- pipは以下の状況でconfused
- Real-world example
- User, Yelp, PayPalなどのバグバウンティで発見され数万ドル単位の報償が払われた例がある
- 回避策
- パッケージハッシュの利用
--requires-hashes
オプション - バージョンの明記
- パッケージハッシュの利用
- ただのタイポで致命的な攻撃を受ける可能性もある
- インストールコマンドは公式サイトなどからコピーペーストするのを意識しようとも思った
このスクラップは2023/11/07にクローズされました