Slide 1

Slide 1 text

© Susten Capital Management Inc. FinTechの現場でバリバリ 活躍するFastAPIの理想と現実 PyCon APAC 2023 Sho Nakamura

Slide 2

Slide 2 text

お前誰よ? ● @sh0nk (github) ○ @sh0nk0 (X): スライドもこちらに ● Love Beer 🍻 ● FinTechスタートアップsustenの取締役 ○ 「おまかせ資産運用」をつくっています ● 前職ではML/NLPを使った検索エンジン・推薦システム (recommendation engine)の開発 ● Python歴:10+年 ● PyCon参加歴:2014、2016年(7年ぶり、初登壇) 2 @sh0nk0

Slide 3

Slide 3 text

本の紹介 ● 2023年6月発売 ● FastAPI初心者の方におすすめ! ● Web API初学者がメインだが、本番環境で利用で きる開発を想定して、AWS/GCPへのデプロイまで カバー ● Zennで無料公開している 本ベースで加筆したもの 3 @sh0nk0

Slide 4

Slide 4 text

本日のトークテーマ ● 前半(基礎編):FastAPIの良いところをサクッと学習 ○ FastAPIを使ってみたいけどまだトライできていない方 ● 後半(応用編):FastAPIが「FinTech」「スタートアップ」でどう使われているかの一 例をご紹介 ○ FastAPIに入門してみたけど、業務で本番環境への投入までには至っていない方 ○ FastAPIを本番環境で使っているが、 FinTechでどう使われているか裏側を知りたい方 4 @sh0nk0

Slide 5

Slide 5 text

アンケートタイム ● 使ってる方どれぐらいいますか? ○ 1:FastAPI現場で使ってます ○ 2:Flask or Django(or Django REST Framework)を使っている方? ○ 3:WebAPIの開発は未経験です 5 @sh0nk0

Slide 6

Slide 6 text

6 まずはFastAPIをサクッと理解しちゃおう 〜基礎編〜 @sh0nk0

Slide 7

Slide 7 text

どんなFramework? ● 他のFrameworkとの違い ○ Django REST Framework ■ 大規模WebフレームワークであるDjangoでAPIを開発できるようにしたライブラリ ■ FastAPIも自動でAPIドキュメントを生成する点でヒントを得ている ■ Djangoの上に成り立っている(依存している)ため重量級 ○ Flask ■ かなりシンプルなフレームワーク( Microframework) ■ シンプルがゆえドキュメントが技術的過ぎたり、複雑なことをやろうとすると他のライブラリの力を借りるこ とになる 7 @sh0nk0

Slide 8

Slide 8 text

どんなFramework? ● 他のFrameworkとの違い ○ Django REST Framework ■ 大規模WebフレームワークであるDjangoでAPIを開発できるようにしたライブラリ ■ FastAPIも自動でAPIドキュメントを生成する点でヒントを得ている ■ Djangoの上に成り立っている(依存している)ため重量級 ○ Flask ■ かなりシンプルなフレームワーク( Microframework) ■ シンプルがゆえドキュメントが技術的過ぎたり、複雑なことをやろうとすると他のライブラリの力を借りるこ とになる 誤解を恐れずに言うと... 「Django REST Frameworkぐらい色んなこと (例えばバリデーションやAPIドキュメントの自動生成) をFlaskぐらい軽量に扱える」 “Battery included”な いいとこ取り WebAPIフレームワーク 🔋 8 @sh0nk0

Slide 9

Slide 9 text

どんなFramework? ● 使われているシーン ○ NetflixやUberなどのBig Techも導入 ■ 例 ● Netflix Dispatch: システム障害管理ツール (https://github.com/Netflix/dispatch) ○ OSSなどでも活用されている ■ Chroma: LLMなどで使われるEmbeddingsを保存するベクトルDB 9 @sh0nk0

Slide 10

Slide 10 text

FastAPIはどう動いているか? Dockerコンテナ Pydantic バリデーション シリアライズ Starlette 低レイヤ Webフレームワーク Uvicorn ASGI Server SQLAlchemy Peewee など O/Rマッパー データ ベース 10 ● FastAPIは2つの強力なライブラリPydantic/Starletteの上に成り立っている @sh0nk0

Slide 11

Slide 11 text

FastAPIはどう動いているか? ● FastAPIは2つの強力なライブラリPydantic/Starletteの上に成り立っている Pydantic バリデーション シリアライズ Starlette 低レイヤ Webフレームワーク 11 @sh0nk0

Slide 12

Slide 12 text

FastAPIの3つのおすすめポイント(特長) ● ポイント1 ○ Pydanticによって型ヒントを実行時のバリデーションに利用するため、型安全 ● ポイント2 ○ 型定義に従いSwagger UIが自動生成されるため、フロントエンドとのインテグレーションが容易 ● ポイント3 ○ ASGIサーバの利用を前提としているので高速 12 @sh0nk0

Slide 13

Slide 13 text

ポイント1: Pydanticによって型ヒントを実行時のバリデーションに利用するため、型安全 ● Pythonは動的型付けなので型ヒント(型アノテーション)は基本的に実行時に評価 されない ● FastAPIではPydanticの力を使って型ヒントを実行時にも利用する 13 @sh0nk0

Slide 14

Slide 14 text

ポイント1: Pydanticによって型ヒントを実行時のバリデーションに利用するため、型安全 ● 例 ○ リクエストのスキーマ( Pydantic)をこのように定義する ○ このようにコールしてみる ■ 日付が一桁多くなってしまっている ○ このように422エラー (Unprocessable Entity) が返ってくる 14 @sh0nk0

Slide 15

Slide 15 text

ポイント1: Pydanticによって型ヒントを実行時のバリデーションに利用するため、型安全 ● Pydanticスキーマ(モデル)定義の勘所 ○ Fieldの第一引数により、デフォルトで埋まる値を定義できる ○ 第一引数は“...”(Ellipsis)を使うことで、必須パラメータのユーザーによる指定を強制することができる ○ “str | None” あるいは “Optional[str]”と書くことで、パラメータを任意入力にすることができる ○ 最小・最大の長さ(数値の場合は最小値・最大値)、 regexでのvalidationを追加することも可能 15 @sh0nk0

Slide 16

Slide 16 text

ポイント2: 型定義に従いSwagger UIが自動生成されるため、フロントエンドとのインテグレーションが容易 ● コード(関数のシグネチャ)を定義すると よしなにSwagger UIを生成してくれる ● FastAPIが生成するSwagger UIは実行可能 な”動くドキュメント” ○ 利用者(例えば、フロントエンドのエンジニア)は実際 に動かしながらデバッグが可能 16 @sh0nk0

Slide 17

Slide 17 text

ポイント2: 型定義に従いSwagger UIが自動生成されるため、フロントエンドとのインテグレーションが容易 ● 例 ○ 先程のリクエストスキーマに対し、エンドポイントとなるパスオペレーション関数を定義 ○ よしなにexampleの値や レスポンス例なども出力 してくれる 実行 17 @sh0nk0

Slide 18

Slide 18 text

ポイント3: ASGIサーバの利用を前提としているので高速 ● asyncioで非同期化されたコードの書き方をすると、38%の速度向上が見られた ○ AWS App Runnerの環境にてRDB(MySQL)へのアクセスを伴う簡単な FastAPIアプリをデプロイ し、負荷試験を行った結果 asyncioを利用したコード avg.190RPS (10users) asyncioを利用しないコード avg.138RPS (10users) 18 @sh0nk0

Slide 19

Slide 19 text

To know more…? ● これ以上FastAPIに関する詳細を知り たかったら本をご参照ください! ● Zennでも大体無料で読めます ● なんならFastAPIは公式ドキュメント めっちゃ充実してます 19 @sh0nk0

Slide 20

Slide 20 text

20 FinTech @SUSTEN でどう使われているか 理想と現実 〜応用編〜 @sh0nk0

Slide 21

Slide 21 text

当スライドは、株式会社 sustenキャピタル・マネジメント(以下、当社)のソフトウェア開発に係 る情報提供を目的としたものであり、当社の提供する商品・サービスの紹介、勧誘等を目的とした ものではありません。

Slide 22

Slide 22 text

トル 22

Slide 23

Slide 23 text

トル トル 23

Slide 24

Slide 24 text

History FastAPIとSUSTEN開発のあゆみ 2023現在まで現場で 使い続けてます! 2020年春 FastAPI導入 開発開始! 24

Slide 25

Slide 25 text

そもそも金融でPython大丈夫なの? ● 私たちがPython/FastAPIを採用した理由 ○ Python ■ 機械学習との親和性 ● 社内の資産運用・投資判断チームが利用 ● 資産運用でのPython(データ分析、クオンツ運用)は今回のトークの対象外 ○ FastAPI ■ 型安全 ● 金融、特に数値計算において型は重要(後述) ■ いくつかのエビデンスによると「速いらしい」 ■ 実際に触ってみて、「 Swagger UI自動生成すごいし、フレームワークとして伸びそうな予感が する」 25 @sh0nk0

Slide 26

Slide 26 text

まずはアーキテクチャ Webアプリ スマート フォン アプリ 金融機関接続 勘定システム KYC/AML システム 外部 接続 バッチを含む 内製システム ユーザーとの インターフェイス KYC=Know Your Customer AML=Anti-Money Laundering 口座開設時の審査を行う 入出金・口座引落にて、銀行等の金 融機関との接続を行う 日々の顧客ごとの口座管理(投資信 託の買付・売却等)を行う 外部 接続 外部 接続 WebAPI (FastAPI アプリ) 26 @sh0nk0

Slide 27

Slide 27 text

まずはアーキテクチャ Webアプリ スマート フォン アプリ 金融機関接続 勘定システム KYC/AML システム 外部 接続 バッチを含む 内製システム ユーザーとの インターフェイス KYC=Know Your Customer AML=Anti-Money Laundering 口座開設時の審査を行う 入出金・口座引落にて、銀行等の金 融機関との接続を行う 日々の顧客ごとの口座管理(投資信 託の買付・売却等)を行う 外部 接続 外部 接続 WebAPI (FastAPI アプリ) 27 金融ドメインのAPIは 「ミッションクリティカル」なAPIになりがち @sh0nk0

Slide 28

Slide 28 text

型ヒント ● FastAPIでは、型ヒントを至る所で活用 ○ Pydanticの強力なサポートが得られる ○ Web APIのリクエスト・レスポンスの定義に活用 理想 28 @sh0nk0

Slide 29

Slide 29 text

型ヒント ● どれぐらい厳密に型ヒントを用いるか? ○ すべての変数に定義することもできる ○ しかし、 ■ 静的型付け言語ほど型に関する IDEのサポートが完全とも言い難い ■ コードを書くスピードと、全体のコードの可読性も重要 ○ → 変数定義・代入など比較的自明な部分には、基本的には型ヒントは不要とする ■ 明示的にしたい、型が複雑な箇所では適宜付加可能 現実 変数定義には 型ヒントを 無理に付けない 29 @sh0nk0

Slide 30

Slide 30 text

型ヒント ● どれぐらい厳密に型ヒントを用いるか? ○ すべての変数に定義することもできる ○ しかし、 ■ 静的型付け言語ほど型に関する IDEのサポートが完全とも言い難い ■ コードを書くスピードと、全体のコードの可読性も重要 ○ → 変数定義・代入など比較的自明な部分には、基本的には型ヒントは不要とする ■ 明示的にしたい、型が複雑な箇所では適宜付加可能 現実 変数定義には 型ヒントを 無理に付けない 30 「静的型付け言語の型チェックと同等のチェックを目指す」 までは目指さない 基本的には 「関数の引数及び返り値には必ず型ヒントを」 ぐらいの緩めのルールで運用 @sh0nk0

Slide 31

Slide 31 text

型ヒント ● 課題:メソッドを拡張する際に、一つ引数を追加。滅多に呼ばれないパスの呼び出 し元のメソッドの修正漏れがあったため、実行時にエラーが発生してしまった 修正 31 ○ ユニットテストの拡充も考えられるが、完全に網羅することは難しい @sh0nk0

Slide 32

Slide 32 text

型ヒント ● 静的解析ツールを導入:mypyの活用 ○ SUSTENでは途中からの導入だったため、導入当初から全てのアラートを拾い上げるには大掛かり なリファクタリングが必要となり難しかった ■ disable_error_code オプションを指定し、手っ取り早く導入できる部分だけ導入。その後 少しずつ改善する方針 エラー 32 @sh0nk0

Slide 33

Slide 33 text

型ヒント ● 静的解析ツールを導入:mypyの活用 ○ SUSTENでは途中からの導入だったため、導入当初から全てのアラートを拾い上げるには大掛かり なリファクタリングが必要となり難しかった ■ disable_error_code オプションを指定し、手っ取り早く導入できる部分だけ導入。その後 少しずつ改善する方針 エラー FastAPI/Pydanticによる型ヒントだけではなく、 mypyなどの静的解析ツールの力も借りて型チェックを強化 33 @sh0nk0

Slide 34

Slide 34 text

Tips:数値計算 ● 金融の計算では小数点が登場することがしばしば ○ 小数点(float)は丸め誤差が発生する ● Decimalの利用 ○ 勘定系システムではDecimalを使う ○ MySQLなどはdecimal型をサポートしているので、そのままdecimalとして保存 ○ Decimalを利用する際は、インスタンス作成時にも一度もfloatを介さないように注意 ■ 直接小数点の数値を与える場合はstrとして与える 34 @sh0nk0

Slide 35

Slide 35 text

Swagger UI ● 開発時の「スキーマ駆動開発」で利用 バックエンドエンジニアが FastAPIでエンドポイントを定義 フロントエンドの開発など APIの利用者が開発時・デバッグに利用 理想 35 @sh0nk0

Slide 36

Slide 36 text

Swagger UI ● ビジネスメンバーが使うツールとしても活用 ○ 以下のような操作が、非エンジニアでも簡単に(意外と)扱える ■ セレクトボックスによるパラメータの指定 ■ ファイルのダウンロード ■ パラメータやエンドポイントに 自由に説明が加えられる 現実 36 @sh0nk0

Slide 37

Slide 37 text

Swagger UI ● ビジネスメンバーが使うツールとしても活用 ○ 以下のような操作が、非エンジニアでも簡単に(意外と)扱える ■ セレクトボックスによるパラメータの指定 ■ ファイルのダウンロード ■ パラメータやエンドポイントに 自由に説明が加えられる 現実 37 「こいつ…動くぞ!」 (非エンジニアでも動かせる) 自動生成されるAPIドキュメント(Swagger UI)により、 FastAPIは「業務を支えるツール」にもなり得る @sh0nk0

Slide 38

Slide 38 text

非同期化 ● asyncio を活用して高速化するために、async/awaitを使ってコードを書く 理想 38 @sh0nk0

Slide 39

Slide 39 text

非同期化 ● 最初から導入しないと、なかなか非同期化していくのが難しい ○ asyncioに慣れていないとどこに async/awaitを書いていけば良いかが難しい ■ チームの非同期化に関する知識の差分があるため、導入の障壁がある ○ asyncioに対応していないライブラリがある ■ 例:SQLAlchemyはasyncioに対応しているが、古いバージョンでは対応しておら ず、新しいSQLAlchemy 2.0 Styleの書き方が求められる 現実 39 @sh0nk0

Slide 40

Slide 40 text

非同期化 ● asyncioを使った書き方ができていないコードでも十分本番環境で パフォーマンスを出している ○ FastAPIはasyncioを使わずとも、”よしなに” threading処理をやってくれる ○ asyncioを使う場合はIOバウンドな処理(DBや他のAPIへのアクセス)を伴うシーンだけで十分 ● 代替策 ○ SUSTENではAmazon ECSを使っているが、アクセス増への対策としてはコンテナの Auto Scaling による富豪的なリソース確保で十分対応できている ECS Task #1 ECS Task #2 ECS Task #3 ・・・ 現実 40 @sh0nk0

Slide 41

Slide 41 text

非同期化 ● asyncioを使った書き方ができていないコードでも十分本番環境で パフォーマンスを出している ○ FastAPIはasyncioを使わずとも、”よしなに” threading処理をやってくれる ○ asyncioを使う場合はIOバウンドな処理(DBや他のAPIへのアクセス)を伴うシーンだけで十分 ● 代替策 ○ SUSTENではAmazon ECSを使っているが、アクセス増への対策としてはコンテナの Auto Scalingによる富豪的なリソース確保で十分対応できている ECS Task #1 ECS Task #2 ECS Task #3 ・・・ 現実 41 これからFastAPIを導入する場合は 今後のメンテコストと照らし、asyncioを使うのか検討 使う場合は無理に全体で対応せず、バランスを見るのがGood 「非同期化はFastAPI導入のハードルにはならない」 FastAPI公式docより引用 @sh0nk0

Slide 42

Slide 42 text

Tips:エラーハンドリング ● 課題:パスオペレーション関数(router)内でHTTPExceptionを毎回吐くのは面倒 42 @sh0nk0

Slide 43

Slide 43 text

Tips:エラーハンドリング ● 対応策:エラーハンドラをFastAPIに登録しておけば、Exceptionをraiseするだけで HTTPエラーを吐き出すことができる ○ 内部的な関数やライブラリが Exceptionを吐いてもWeb APIのレスポンス自体(json型等)が壊れな いように、ベースクラスの Exceptionも保険として拾っておく Originalのエラー ←のエラーハンドラを利用 43 @sh0nk0

Slide 44

Slide 44 text

まとめ ● イマドキの金融システムは ”普通の” Web技術の結晶でできている ○ レガシーじゃないよ! 電子決済系、仮想通貨系以外でも FinTech屋はいます ● FastAPIを駆使すれば、様々な業務の効率化ができる ○ 例えばSwagger UIでの業務支援 ● Pythonでも、型ヒントとFastAPIのバリデーション、静的解析ツールなどを有効活用 し適切なテストを書けば、「ミッションクリティカル」な世界でも十分戦える ● 型ヒントにしろ非同期化にしろ、「完璧を求めすぎない」がFastAPIとうまく付き合うコ ツ 44 @sh0nk0

Slide 45

Slide 45 text

\We are hiring!/ X: @sh0nk0