$30 off During Our Annual Pro Sale. View Details »

【PyCon APAC 2023 登壇資料】FinTechの現場でバリバリ活躍するFastAPIの理想と現実

【PyCon APAC 2023 登壇資料】FinTechの現場でバリバリ活躍するFastAPIの理想と現実

10/26(木)-29(日)に開催された『PyCon APAC 2023』にて、CTOの中村が登壇しました。
FastAPIを使用したFinTechサービス開発についてまとめております。

Susten Capital Management Inc.

November 20, 2023
Tweet

More Decks by Susten Capital Management Inc.

Other Decks in Programming

Transcript

  1. © Susten Capital Management Inc.
    FinTechの現場でバリバリ
    活躍するFastAPIの理想と現実
    PyCon APAC 2023
    Sho Nakamura
    X: @sh0nk0
    ↑スライド上げてます

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  22. トル
    22

    View Slide

  23. トル
    トル
    23

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  41. 非同期化
    ● 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

    View Slide

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

    View Slide

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

    View Slide

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

    44
    @sh0nk0

    View Slide

  45. \We are hiring!/
    X: @sh0nk0

    View Slide

  46. View Slide

  47. Appendix

    View Slide

  48. トル
    トル

    View Slide

  49. Gitレポジトリ
    Web API
    バッチ
    DBモデル
    共通ライブラリ
    金融機関連携
    モジュール
    勘定システム
    モジュール
    submodule
    submodule

    View Slide

  50. Dockerと開発環境
    ● Local環境はdocker composeを利用
    ● デプロイ環境はAWSを利用
    ○ 開発・ステージング・本番環境ではPull Requestマージをトリガーにして、Github ActionsによりECRにDocker imageをpushしたのち、ECSにデ
    プロイ(CD)
    ○ 本番環境は「検証されたイメージをデプロイする」方針により、ステージング環境のDockerイメージを指定してデプロイ
    開発環境
    ECR
    staging/
    本番環境
    ECR
    Local環境
    Github Actions
    Github Actions

    View Slide

  51. デプロイの現実
    ● ECS
    ○ 基本的にローカル環境と異なる設
    定はすべて環境変数に逃がす。
    ECSの場合はTask Definitionで定

    ○ 環境変数の中でもcredentialsなど
    のsecretsはAWS Secrets
    Managerで管理

    View Slide

  52. 監視の現実
    ● Datadogインテグレーション
    ○ リアルタイムLogとProfileが見られる

    View Slide

  53. 監視の現実
    ● Datadogインテグレーション
    ○ サイドカーによって実現
    ■ 1. ECSの同一タスク上にDatadog Agent用のコンテナを立てる
    ■ 2. FastAPIアプリ側にインストールしたトレーサーライブラリ(
    dd-trace)がDatadog Agentに
    プロファイルを送信
    ■ 3. AgentはDatadog上で表示できるアプリのトレース情報および環境情報を送信
    Amazon ECS
    ECS Task
    FastAPI Appコンテナ
    (ddtraceインストール済
    み)
    Datadog
    Agent
    コンテナ
    トレース
    ・ログ
    情報
    アプリ
    ・環境情報

    ② ③

    View Slide

  54. Swagger UI
    ● ただし、DBに直接アクセスできるような超法規的ツールなので、セキュリティの担
    保が必要
    ○ これはAPI Gatewayのレイヤーでカバー

    View Slide

  55. ユニットテスト
    ● ユニットテストでクオリティを担保するのは重要
    ● 基本的な「同値クラス分割」や「境界値分析」に基づくテスト
    ● 金融の世界での具体例
    ○ 生年月日周り
    ■ 口座開設には厳密な年齢制限がある
    ○ NISAの枠管理
    ■ 年間の投資額には上限がある
    ○ 休日のチェック
    ■ 世界の株式市場は複数あるので、市場の休日は OR条件で判断しなければならない

    View Slide

  56. ユニットテスト
    ● 複数のenum、条件分岐などを網羅するためにpytestのparameterized testを積極活

    ● テストカバレッジとしても、90%超えの結果

    View Slide

  57. ユニットテストの現実(cont.)
    ● DB関係のテストはSQLiteを用いて実際に入出力を行う
    ○ conftest (Pytestの設定ファイル)にSQLiteのsessionを定義し、FastAPIがサポートする
    DI(Dependency Injection)を利用し本番DBとの切り替えを行う
    ● AWS関係のIO(S3やSNS)はmock(boto3)を活用
    ● Mockオブジェクトも活用
    ○ mockerだと静的なmockの生成も容易
    ○ 時刻はfreezegun

    View Slide

  58. セキュリティ
    ● FastAPIで無理にやろうとしない
    ○ ログインまわりではIDaaSを活用(餅は餅屋)
    ○ IDaaS連携もインフラレイヤーがカバー( AWS API Gateway)
    ○ 特にログインまわりは車輪の再発明をしない

    View Slide

  59. 躓きポイント1
    ● Git submoduleの多重import
    ○ 依存先のmoduleがupdateされたときに、片方を最新化するのを忘れがち
    ○ pythonでは同名のモジュールは 2つimportできないので、どちらかのコードが走ることになるた
    め、コードのバージョン差分によって問題が発生する可能性がある
    Web API
    バッチ
    DBモデル
    共通ライブラリ
    金融機関連携
    モジュール
    勘定システム
    モジュール
    submodule
    submodule

    View Slide