FastAPIの代替、インスピレーション、比較¶
FastAPIがどのようにインスパイアされ、代替手段と比較してどのように、そしてそれらから何を学んだか。
Intro¶
FastAPIは、他者の先行研究がなければ存在しなかったでしょう。
その作成にインスピレーションを与えた多くのツールが以前に作成されてきました。
私は何年もの間、新しいフレームワークの作成を避けてきました。まず、さまざまなフレームワーク、プラグイン、ツールを使用して、FastAPIがカバーするすべての機能を解決しようとしました。
しかし、ある時点で、これらのすべての機能を提供する何かを作成する以外に選択肢はなく、以前のツールから最高のアイデアを取り入れ、これまで利用できなかった言語機能(Python 3.6+の型ヒント)を使用して、可能な限り最良の方法でそれらを組み合わせました。
Previous tools¶
Django¶
最も人気のあるPythonフレームワークであり、広く信頼されています。Instagramのようなシステムを構築するために使用されています。
リレーショナルデータベース(MySQLやPostgreSQLなど)と比較的密接に結合しているため、NoSQLデータベース(Couchbase、MongoDB、Cassandraなど)をメインのストアエンジンとして使用するのはそれほど簡単ではありません。
APIを構築するためではなく、バックエンドでHTMLを生成するために作成されました。現代のフロントエンド(React、Vue.js、Angularなど)またはそれに通信する他のシステム(IoTデバイスなど)によって使用されるAPI。
Django REST Framework¶
Django REST frameworkは、Djangoを基盤としてWeb APIを構築するための柔軟なツールキットとして作成され、API機能を改善しました。
Mozilla、Red Hat、Eventbriteなどの多くの企業によって使用されています。
これは自動APIドキュメントの最初の例の1つであり、これは「検索」FastAPIにインスピレーションを与えた最初のアイデアの1つでした。
Note
Django REST Frameworkは、StarletteとUvicorn(FastAPIの基盤)の作成者と同じTom Christieによって作成されました。
Inspired FastAPI to
自動APIドキュメントのWebユーザーインターフェイスを持つ。
Flask¶
Flaskは「マイクロフレームワーク」であり、データベース統合やDjangoでデフォルトで提供される多くの機能は含まれていません。
このシンプルさと柔軟性により、NoSQLデータベースをメインのデータストレージシステムとして使用するなどのことが可能になります。
非常にシンプルであるため、学習は比較的直感的ですが、ドキュメントは時々技術的になります。
また、データベース、ユーザー管理、またはDjangoにプリビルドされている多くの機能のいずれかを必ずしも必要としない他のアプリケーションにも一般的に使用されます。ただし、これらの機能の多くはプラグインで追加できます。
これらの部分の分離と、必要に応じて拡張できる「マイクロフレームワーク」であることは、私が維持したい重要な機能でした。
Flaskのシンプルさを考えると、APIの構築に適しているように思えました。次に探すべきは、Flask用の「Django REST Framework」でした。
Inspired FastAPI to
マイクロフレームワークであること。必要に応じてツールや部品を簡単に組み合わせられるようにします。
シンプルで使いやすいルーティングシステムを持つ。
Requests¶
FastAPIは実際にはRequestsの代替ではありません。その範囲は非常に異なります。
FastAPIアプリケーション内でRequestsを使用するのは一般的でしょう。
それでも、FastAPIはRequestsからかなりのインスピレーションを得ました。
RequestsはAPI(クライアントとして)と*やり取り*するためのライブラリであり、FastAPIはAPI(サーバーとして)を*構築*するためのライブラリです。
それらは、多かれ少なかれ、反対側の端にあり、互いを補完しています。
Requestsは非常にシンプルで直感的なデザインであり、使いやすく、妥当なデフォルトがあります。しかし同時に、非常に強力でカスタマイズ可能です。
そのため、公式ウェブサイトにあるように
Requestsは、これまでで最もダウンロードされたPythonパッケージの1つです
使用方法は非常に簡単です。たとえば、GETリクエストを行うには、次のように記述します
response = requests.get("http://example.com/some/url")
FastAPIの対応するAPIパス操作は次のようになります
@app.get("/some/url")
def read_url():
return {"message": "Hello World"}
requests.get(...)と@app.get(...)の類似点を確認してください。
Inspired FastAPI to
- シンプルで直感的なAPIを持つ。
- HTTPメソッド名(操作)を直接、わかりやすく直感的に使用する。
- 妥当なデフォルトを持ちながら、強力なカスタマイズ機能を持つ。
Swagger / OpenAPI¶
Django REST Frameworkから欲しかった主な機能は、自動APIドキュメントでした。
次に、JSON(またはJSONの拡張であるYAML)を使用してAPIをドキュメント化する標準、Swaggerがあることを発見しました。
そして、Swagger APIのWebユーザーインターフェイスはすでに作成されていました。そのため、APIのSwaggerドキュメントを生成できると、このWebユーザーインターフェイスを自動的に使用できるようになります。
ある時点で、SwaggerはLinux Foundationに寄贈され、OpenAPIに改名されました。
そのため、バージョン2.0について話すときは「Swagger」、バージョン3以降は「OpenAPI」と言うのが一般的です。
Inspired FastAPI to
カスタムスキーマではなく、API仕様のオープンスタンダードを採用し、使用する。
標準ベースのユーザーインターフェイスツールを統合する
これら2つは、かなり人気があり安定しているため選択されましたが、簡単な検索で、OpenAPIの数十の代替ユーザーインターフェイス(FastAPIで使用できる)を見つけることができます。
Flask REST frameworks¶
いくつかのFlask RESTフレームワークがありますが、時間をかけて調査した結果、多くは廃止または放棄されており、いくつかの未解決の問題があり、それらが不適切であると判断しました。
Marshmallow¶
APIシステムに必要な主な機能の1つは、データ「シリアライゼーション」です。これは、コード(Python)からのデータを取得し、ネットワーク経由で送信できるものに変換することです。たとえば、データベースからのデータを含むオブジェクトをJSONオブジェクトに変換します。datetimeオブジェクトを文字列に変換するなど。
APIに必要なもう1つの大きな機能は、データ検証です。特定のパラメータが与えられた場合にデータが有効であることを確認します。たとえば、あるフィールドがintであり、ランダムな文字列ではないこと。これは、受信データに特に役立ちます。
データ検証システムがない場合、すべてのチェックを手動でコードで行う必要があります。
これらの機能は、Marshmallowが提供するために構築されたものです。これは素晴らしいライブラリであり、以前にたくさん使用しました。
しかし、Pythonの型ヒントが存在する前に作成されたため、各スキーマを定義するには、Marshmallowが提供する特定のユーティリティとクラスを使用する必要があります。
Inspired FastAPI to
コードを使用して、データ型と検証を提供する「スキーマ」を自動的に定義する。
Webargs¶
APIに必要なもう1つの大きな機能は、受信リクエストからのデータのパースです。
Webargsは、Flaskを含むいくつかのフレームワークでそれを提供するために作られたツールです。
データ検証を行うために、内部でMarshmallowを使用しています。そして、それは同じ開発者によって作成されました。
これは素晴らしいツールであり、FastAPIを持つ前にもたくさん使用しました。
情報
Webargsは、Marshmallowと同じ開発者によって作成されました。
Inspired FastAPI to
受信リクエストデータの自動検証を持つ。
APISpec¶
MarshmallowとWebargsは、プラグインとして検証、パース、シリアライゼーションを提供します。
しかし、ドキュメントはまだ欠けています。そこでAPISpecが作成されました。
これは多くのフレームワークのプラグインであり(Starlette用のプラグインもあります)。
その仕組みは、各ルートを処理する関数のdocstring内にYAML形式でスキーマの定義を記述することです。
そして、OpenAPIスキーマを生成します。
Flask、Starlette、Responderなどで機能するのはこの方法です。
しかし、再び、Python文字列(大きなYAML)の中にマイクロ構文があるという問題があります。
エディタはこれにあまり役立ちません。パラメータやMarshmallowスキーマを変更して、そのYAML docstringも変更するのを忘れると、生成されたスキーマは時代遅れになります。
情報
APISpecは、Marshmallowと同じ開発者によって作成されました。
Inspired FastAPI to
APIのオープンスタンダードであるOpenAPIをサポートする。
Flask-apispec¶
これはFlaskプラグインであり、Webargs、Marshmallow、APISpecを連携させます。
WebargsとMarshmallowからの情報を使用して、APISpecを使用してOpenAPIスキーマを自動生成します。
これは素晴らしいツールであり、過小評価されています。ドキュメントが簡潔で抽象的すぎるため、他の多くのFlaskプラグインよりもはるかに人気があるはずです。
これにより、Python docstring内にYAML(別の構文)を記述する必要がなくなりました。
Flask、Flask-apispecとMarshmallowおよびWebargsのこの組み合わせは、FastAPIを構築するまでの私の好きなバックエンドスタックでした。
これを使用すると、いくつかのFlaskフルスタックジェネレーターが作成されました。これらは、私が(およびいくつかの外部チームが)これまで使用してきた主なスタックです。
- https://github.com/tiangolo/full-stack
- https://github.com/tiangolo/full-stack-flask-couchbase
- https://github.com/tiangolo/full-stack-flask-couchdb
そして、これらのフルスタックジェネレーターは、FastAPIプロジェクトジェネレーターの基盤となりました。
情報
Flask-apispecは、Marshmallowと同じ開発者によって作成されました。
Inspired FastAPI to
シリアライゼーションと検証を定義するのと同じコードから、OpenAPIスキーマを自動生成する。
NestJS (and Angular)¶
これはPythonでさえなく、NestJSはAngularにインスパイアされたJavaScript(TypeScript)NodeJSフレームワークです。
Flask-apispecで可能なこととほぼ同様のことを達成しています。
Angular 2にインスパイアされた統合依存性注入システムを備えています。「注入可能なもの」(私が知る他のすべての依存性注入システムと同様)を事前に登録する必要があります。そのため、冗長性とコードの繰り返しが増えます。
パラメータはTypeScript型(Python型ヒントと同様)で記述されているため、エディタのサポートはかなり良好です。
ただし、TypeScriptデータはJavaScriptへのコンパイル後も保持されないため、検証、シリアライゼーション、ドキュメントを同時に定義するために型に依存することはできません。このため、およびいくつかの設計上の決定により、検証、シリアライゼーション、および自動スキーマ生成を取得するには、多くの場所にデコレータを追加する必要があります。そのため、かなり冗長になります。
ネストされたモデルをうまく処理できません。そのため、リクエストのJSON本文が、さらにネストされたJSONオブジェクトであるJSONオブジェクトの場合、正しくドキュメント化および検証することはできません。
Inspired FastAPI to
Python型を使用して、優れたエディタサポートを得る。
強力な依存性注入システムを持つ。コードの繰り返しを最小限に抑える方法を見つける。
Sanic¶
asyncioに基づいた非常に高速なPythonフレームワークの初期のものの一つでした。Flaskに非常に似ています。
技術的な詳細
デフォルトのPython asyncioループの代わりにuvloopを使用しました。それが非常に高速でした。
UvicornとStarletteに明らかにインスピレーションを与え、それらは現在、オープンベンチマークでSanicよりも高速です。
Inspired FastAPI to
クレイジーなパフォーマンスを得る方法を見つける。
そのため、FastAPIはStarletteに基づいており、利用可能な最速のフレームワークです(サードパーティのベンチマークでテスト済み)。
Falcon¶
Falconは別の高性能Pythonフレームワークであり、最小限の設計であり、Hugのような他のフレームワークの基盤として機能するように設計されています。
2つのパラメータ、1つは「リクエスト」、もう1つは「レスポンス」を受け取る関数として設計されています。次に、リクエストから部分を「読み取り」、レスポンスに部分を「書き込み」ます。この設計のため、標準Python型ヒントを関数パラメータとしてリクエストパラメータとボディを宣言することはできません。
そのため、データ検証、シリアライゼーション、ドキュメントはコードで行う必要があり、自動ではありません。または、HugのようにFalconの設計に触発されたフレームワークとして実装する必要があります。この同じ区別は、1つのリクエストオブジェクトと1つのレスポンスオブジェクトをパラメータとして持つFalconの設計に触発された他のフレームワークでも発生します。
Inspired FastAPI to
優れたパフォーマンスを得る方法を見つける。
Hug(HugはFalconに基づいているため)とともに、FastAPIに関数でresponseパラメータを宣言するようにインスパイアされました。
FastAPIではオプションであり、主にヘッダー、Cookie、および代替ステータスコードの設定に使用されます。
Molten¶
FastAPIの構築の初期段階でMoltenを発見しました。そして、それはかなり似たアイデアを持っています。
- Python型ヒントに基づいています。
- これらの型からの検証とドキュメント。
- 依存性注入システム。
Pydanticのようなデータ検証、シリアライゼーション、ドキュメントのサードパーティライブラリを使用せず、独自のライブラリを持っています。そのため、これらのデータ型定義は簡単に再利用できませんでした。
より冗長な設定が必要であり、WSGI(ASGIではなく)に基づいているため、Uvicorn、Starlette、Sanicのようなツールが提供する高性能を活用するように設計されていません。
依存性注入システムでは、依存関係の事前登録が必要であり、依存関係は宣言された型に基づいて解決されます。そのため、特定の型を提供する「コンポーネント」を複数宣言することはできません。
ルートは、他の場所で宣言された関数を使用して1つの場所で宣言されます(エンドポイントを処理する関数の直上に配置できるデコレータを使用するのではなく)。これはDjangoの方法に近く、Flask(およびStarlette)の方法ではありません。コード内で比較的一貫して結合されたものを分離します。
Inspired FastAPI to
モデル属性の「デフォルト」値を使用して、データ型の追加検証を定義します。これにより、エディタのサポートが向上し、以前はPydanticでは利用できませんでした。
これは実際にPydanticの一部を更新して、同じ検証宣言スタイルをサポートするようにインスパイアされました(このすべての機能はすでにPydanticで利用可能です)。
Hug¶
Hugは、Python型ヒントを使用したAPIパラメータ型の宣言を実装した最初のフレームワークの1つでした。これは、他のツールが同様のことを行うようにインスパイアされた素晴らしいアイデアでした。
宣言には標準Python型ではなくカスタム型を使用しましたが、それでも大きな進歩でした。
また、API全体をJSONで宣言するカスタムスキーマを生成した最初のフレームワークの1つでもありました。
OpenAPIやJSON Schemaのような標準に基づいていたわけではないため、Swagger UIのような他のツールとの統合は簡単ではありませんでした。しかし、これも非常に革新的なアイデアでした。
興味深く珍しい機能があります:同じフレームワークを使用して、APIとCLIの両方を作成できます。
同期Python Webフレームワーク(WSGI)の以前の標準に基づいているため、Websocketやその他のものを処理できませんが、それでも高いパフォーマンスを持っています。
情報
Hugは、Pythonファイルのインポートを自動的にソートする素晴らしいツールであるisortの作成者と同じTimothy Crosleyによって作成されました。
Ideas inspiring FastAPI
HugはAPIStarの一部にインスパイアされ、APIStarとともに最も有望なツールの1つでした。
Hugは、FastAPIがPython型ヒントを使用してパラメータを宣言し、APIを自動的に定義するスキーマを生成するようにインスパイアされました。
Hugは、FastAPIが関数でresponseパラメータを宣言してヘッダーとCookieを設定するようにインスパイアされました。
APIStar (<= 0.5)¶
FastAPIを構築することを決定する直前に、APIStarサーバーを見つけました。私が探していたもののほとんどすべてがあり、素晴らしいデザインでした。
私がEver見たPython型ヒントを使用してパラメータとリクエストを宣言するフレームワークの最初の実装の1つでした(NestJSとMoltenより前)。Hugとほぼ同時期に見つけましたが、APIStarはOpenAPI標準を使用しました。
いくつかの場所で、同じ型ヒントに基づいて、自動データ検証、データシリアライゼーション、およびOpenAPIスキーマ生成がありました。
ボディスキーマ定義は、Pydanticのような同じPython型ヒントを使用せず、Marshmallowに少し似ていたため、エディタのサポートはそれほど良くありませんでしたが、それでもAPIStarは利用可能な最良のオプションでした。
当時、最高のパフォーマンスベンチマークを持っていました(Starletteにのみ追い抜かれました)。
最初は自動APIドキュメントWeb UIがありませんでしたが、Swagger UIを追加できることは知っていました。
依存性注入システムがありました。上記で議論された他のツールと同様に、コンポーネントの事前登録が必要でしたが、それでも素晴らしい機能でした。
セキュリティ統合がなかったため、Flask-apispecベースのフルスタックジェネレーターで提供していたすべての機能を置き換えることができなかったため、フルプロジェクトで使用することはできませんでした。その機能を追加するプルリクエストを作成するプロジェクトのバックログがありました。
しかし、その後、プロジェクトの焦点がシフトしました。
作成者がStarletteに焦点を当てる必要があったため、もはやAPI Webフレームワークではありませんでした。
現在、APIStarはOpenAPI仕様を検証するためのツールのセットであり、Webフレームワークではありません。
情報
APIStarは、
- Django REST Framework
- Starlette(FastAPIが基盤としている)
- Uvicorn(StarletteとFastAPIによって使用されている)
Inspired FastAPI to
Exist.
同じPython型で複数のこと(データ検証、シリアライゼーション、ドキュメント)を宣言するというアイデアは、同時に優れたエディタサポートを提供し、素晴らしいアイデアだと考えていました。
そして、同様のフレームワークを長期間探し、さまざまな代替手段をテストした後、APIStarが利用可能な最良のオプションでした。
その後、APIStarはサーバーとしての存在を停止し、Starletteが作成され、そのようなシステムの新しいより良い基盤となりました。これが、FastAPIを構築するための最終的なインスピレーションでした。
私はFastAPIをAPIStarの「精神的後継者」と見なしており、これらのすべての先行ツールの学習に基づいて、機能、型システム、その他の部分を改善および拡大しています。
Used by FastAPI¶
Pydantic¶
Pydanticは、Python型ヒントに基づいてデータ検証、シリアライゼーション、およびドキュメント(JSON Schemaを使用)を定義するためのライブラリです。
これにより、非常に直感的になります。
Marshmallowと比較できます。ベンチマークではMarshmallowよりも高速ですが。そして、同じPython型ヒントに基づいているため、エディタのサポートは優れています。
FastAPIはこれを使用して
すべてのデータ検証、データシリアライゼーション、および自動モデルドキュメント(JSON Schemaに基づく)を処理します。
FastAPIは、そのJSON Schemaデータを取得してOpenAPIに配置し、他のすべての機能とは別に配置します。
Starlette¶
Starletteは、軽量のASGIフレームワーク/ツールキットであり、高性能のasyncioサービスを構築するのに理想的です。
非常にシンプルで直感的です。拡張が容易で、モジュール式コンポーネントを持つように設計されています。
それは持っています
- 本当に印象的なパフォーマンス。
- WebSocketサポート。
- プロセス内バックグラウンドタスク。
- 起動とシャットダウンイベント。
- HTTPXに基づいたテストクライアント。
- CORS、GZip、静的ファイル、ストリーミングレスポンス。
- セッションおよびCookieサポート。
- 100%テストカバレッジ。
- 100%型注釈付きコードベース。
- ハード依存関係は少ない。
Starletteは現在、テストされている最速のPythonフレームワークです。フレームワークではなくサーバーであるUvicornにのみ追い抜かれています。
Starletteは、すべての基本的なWebマイクロフレームワーク機能を提供します。
しかし、自動データ検証、シリアライゼーション、またはドキュメントは提供しません。
これは、FastAPIがPython型ヒント(Pydanticを使用)に基づいて追加する主な機能の1つです。それに加えて、依存性注入システム、セキュリティユーティリティ、OpenAPIスキーマ生成などがあります。
技術的な詳細
ASGIは、Djangoコアチームメンバーによって開発されている新しい「標準」です。まだ「Python標準」(PEP)ではありませんが、そのプロセス中です。
それにもかかわらず、すでにいくつかのツールで「標準」として使用されています。これにより、UvicornをDaphneやHypercornのような他のASGIサーバーに切り替えたり、python-socketioのようなASGI互換ツールを追加したりできるため、相互運用性が大幅に向上します。
FastAPIはこれを使用して
すべてのコアWeb部分を処理します。その上に機能を追加します。
FastAPIクラス自体は、Starletteクラスから直接継承します。
そのため、Starletteでできることはすべて、FastAPIでも直接行うことができます。基本的にStarletteにステロイドを投与したものです。
Uvicorn¶
Uvicornは、uvloopとhttptoolsを基盤とした、超高速のASGIサーバーです。
Webフレームワークではなくサーバーです。たとえば、パスによるルーティングツールは提供しません。これは、Starlette(またはFastAPI)のようなフレームワークがその上に提供するものです。
StarletteとFastAPIに推奨されるサーバーです。
FastAPIはこれを次のように推奨しています
FastAPIアプリケーションを実行するためのメインWebサーバー。
--workersコマンドラインオプションを使用して、非同期マルチプロセスサーバーを持つこともできます。
詳細については、デプロイメントセクションを確認してください。
Benchmarks and speed¶
Uvicorn、Starlette、FastAPIの違いを理解し、比較し、確認するには、ベンチマークセクションを参照してください。