FastAPI × Uvicorn:最強のAPI高速化コンビ誕生!
Uvicornとは何か?
答え:Uvicornは、uvloopとhttptoolsを基盤とした、非常に高速なASGI(Asynchronous Server Gateway Interface)サーバーです。これは、asyncioに基づいて開発された軽量で効率的なWebサーバーフレームワークです。
Uvicornは当初、2つの目標を掲げて設計されました。
- uvloopとhttptoolsを使って、極めて高速なasyncioサーバーを実装すること。
- ASGIに基づく最小限のアプリケーションインターフェースを実装すること。
現在、これはHTTP、WebSocket、Pub/Subブロードキャストをサポートしており、他のプロトコルやメッセージタイプに拡張することも可能です。
公式サイト:uvicorn (https://uvicorn.org/)
uvloopとhttptoolsとは何か?
答え:uvloopは、標準ライブラリのasyncio内のイベントループを置き換えるために使用されます。これはCythonで実装されており、非常に高速で、asyncioの速度を2~4倍速くすることができます。あなたはasyncioに精通していると思います。なぜなら、非同期コードを書く際にはそれが不可欠だからです。
httptoolsは、Node.jsのHTTPパーサーのPython実装です。
ASGIサーバーとは何か?
答え:ASGI(Asynchronous Server Gateway Interface)は、ネットワークプロトコルサービスとPythonアプリケーションの間の標準的なインターフェースです。これは、HTTP、HTTP2、WebSocketなどの複数の一般的なプロトコルタイプを処理することができます。
ASGIプロトコル:https://asgi.readthedocs.io/en/latest/specs/main.html
Uvicornの概要
答え:現在、Pythonには非同期ゲートウェイプロトコルインターフェースが欠けていました。ASGIの登場により、このギャップが埋められました。これからは、共通の標準を使って全ての非同期フレームワーク用のツールを実装することができます。ASGIは、PythonがWebフレームワーク分野でNode.JSやGolangと競争するのを助け、高性能なI/O集中型タスクを実現することを目指しています。ASGIはHTTP2とWebSocketをサポートしていますが、WSGIはそれをサポートしていません。
Uvicornは現在、HTTP1.1とWebSocketをサポートしており、HTTP2のサポートも計画されています。
Uvicornの使い方
-
インストール
pip install uvicorn
を実行します。 -
新しい
example.py
ファイルを作成する
async def app(scope, receive, send):
assert scope['type'] == 'http'
await send({
'type': 'http.response.start',
'status': 200,
'headers': [
[b'content-type', b'text/plain'],
]
})
await send({
'type': 'http.response.body',
'body': b'Hello, world!',
})
-
コマンドラインからUvicornを起動する
uvicorn example:app
を実行します。 -
スクリプト形式で起動する
import uvicorn
async def app(scope, receive, send):
...
if __name__ == "__main__":
uvicorn.run("example:app", host="127.0.0.1", port=8000, log_level="info")
Uvicornは複数のコマンドをサポートしており、uvicorn --help
で表示できます。
➜ ~ uvicorn --help
Usage: uvicorn [OPTIONS] APP
Options:
--host TEXT Bind socket to this host. [default:
127.0.0.1]
--port INTEGER Bind socket to this port. If 0, an available
port will be picked. [default: 8000]
--uds TEXT Bind to a UNIX domain socket.
--fd INTEGER Bind to socket from this file descriptor.
--reload Enable auto-reload.
--reload-dir PATH Set reload directories explicitly, instead
of using the current working directory.
--reload-include TEXT Set glob patterns to include while watching
for files. Includes '*.py' by default; these
defaults can be overridden with `--reload-
exclude`. This option has no effect unless
watchfiles is installed.
--reload-exclude TEXT Set glob patterns to exclude while watching
for files. Includes '.*,.py[cod],.sw.*,
~*' by default; these defaults can be
overridden with `--reload-include`. This
option has no effect unless watchfiles is
installed.
--reload-delay FLOAT Delay between previous and next check if
application needs to be. Defaults to 0.25s.
[default: 0.25]
--workers INTEGER Number of worker processes. Defaults to the
$WEB_CONCURRENCY environment variable if
available, or 1. Not valid with --reload.
--loop [auto|asyncio|uvloop] Event loop implementation. [default: auto]
--http [auto|h11|httptools] HTTP protocol implementation. [default:
auto]
--ws [auto|none|websockets|wsproto]
WebSocket protocol implementation.
[default: auto]
--ws-max-size INTEGER WebSocket max size message in bytes
[default: 16777216]
--ws-max-queue INTEGER The maximum length of the WebSocket message
queue. [default: 32]
--ws-ping-interval FLOAT WebSocket ping interval in seconds.
[default: 20.0]
--ws-ping-timeout FLOAT WebSocket ping timeout in seconds.
[default: 20.0]
--ws-per-message-deflate BOOLEAN
WebSocket per-message-deflate compression
[default: True]
--lifespan [auto|on|off] Lifespan implementation. [default: auto]
--interface [auto|asgi3|asgi2|wsgi]
Select ASGI3, ASGI2, or WSGI as the
application interface. [default: auto]
--env-file PATH Environment configuration file.
--log-config PATH Logging configuration file. Supported
formats:.ini,.json,.yaml.
--log-level [critical|error|warning|info|debug|trace]
--access-log / --no-access-log Enable/Disable access log.
--use-colors / --no-use-colors Enable/Disable colorized logging.
--proxy-headers / --no-proxy-headers
Enable/Disable X-Forwarded-Proto,
X-Forwarded-For, X-Forwarded-Port to
populate remote address info.
--server-header / --no-server-header
Enable/Disable default Server header.
--date-header / --no-date-header
Enable/Disable default Date header.
--forwarded-allow-ips TEXT Comma separated list of IPs to trust with
proxy headers. Defaults to the
$FORWARDED_ALLOW_IPS environment variable if
available, or '127.0.0.1'.
--root-path TEXT Set the ASGI 'root_path' for applications
submounted below a given URL path.
--limit-concurrency INTEGER Maximum number of concurrent connections or
tasks to allow, before issuing HTTP 503
responses.
--backlog INTEGER Maximum number of connections to hold in
backlog
--limit-max-requests INTEGER Maximum number of requests to service before
terminating the process.
--timeout-keep-alive INTEGER Close Keep-Alive connections if no new data
is received within this timeout. [default:
5]
--timeout-graceful-shutdown INTEGER
Maximum number of seconds to wait for
graceful shutdown.
--ssl-keyfile TEXT SSL key file
--ssl-certfile TEXT SSL certificate file
--ssl-keyfile-password TEXT SSL keyfile password
--ssl-version INTEGER SSL version to use (see stdlib ssl module's)
[default: 17]
--ssl-cert-reqs INTEGER Whether client certificate is required (see
stdlib ssl module's) [default: 0]
--ssl-ca-certs TEXT CA certificates file
--ssl-ciphers TEXT Ciphers to use (see stdlib ssl module's)
[default: TLSv1]
--header TEXT Specify custom default HTTP response headers
as a Name:Value pair
--version Display the uvicorn version and exit.
--app-dir TEXT Look for APP in the specified directory, by
adding this to the PYTHONPATH. Defaults to
the current working directory.
--h11-max-incomplete-event-size INTEGER
For h11, the maximum number of bytes to
buffer of an incomplete event.
--factory Treat APP as an application factory, i.e. a
() -> <ASGI app> callable.
--help Show this message and exit.
➜ ~
設定とサーバーインスタンス
設定とサーバーのライフサイクルをより細かく制御するには、uvicorn.Config
とuvicorn.Server
を使います。
import uvicorn
async def app(scope, receive, send):
...
if __name__ == "__main__":
config = uvicorn.Config("main:app", port=5000, log_level="info")
server = uvicorn.Server(config)
server.run()
既に実行中の非同期環境からUvicornを起動したい場合は、uvicorn.Server.serve()
を使います。
import asyncio
import uvicorn
async def app(scope, receive, send):
...
async def main():
config = uvicorn.Config("main:app", port=5000, log_level="info")
server = uvicorn.Server(config)
await server.serve()
if __name__ == "__main__":
asyncio.run(main())
Uvicornを使ったFastAPIプロジェクトの起動
import uvicorn
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
if __name__ == '__main__':
uvicorn.run(app=app)
FastAPIがUvicornを使う理由は?
FastAPIは、現代的で高性能なWebフレームワークです。これは、Pythonの非同期プログラミング機能を使って、Webアプリケーションの性能を高めています。一方、Uvicornは、uvloopとhttptoolsで実装された高性能なASGIサーバーで、HTTPリクエストを非同期で処理することができます。FastAPIがUvicornをデフォルトのWebサーバーとして使うのは、Uvicornが非常に高速で、信頼性が高く、使いやすいからです。多数の同時接続を処理する際にも、安定して効率的に機能します。さらに、UvicornはWebSocketやHTTP/2などの新機能をサポートしており、FastAPIが提唱する現代的なWeb開発哲学と合致しています。したがって、FastAPIのWebサーバーとしてUvicornを使うのは、素晴らしい選択肢です。
Leapcell: ウェブホスティング、非同期タスク、Redis向け次世代サーバーレスプラットフォーム
最後に、FastAPIサービスをデプロイするのに最適なプラットフォーム、Leapcellを紹介します。
Leapcellには以下の特徴があります:
-
1. 多言語サポート
JavaScript、Python、Go、またはRustで開発できます。 -
2. 無制限のプロジェクトを無料でデプロイ
使用量に応じて支払えばよく、リクエストがなければ料金はかかりません。 -
3. 比類なきコスト効率
使いた分だけ支払い、アイドル時の料金はかかりません。
例:25ドルで平均応答時間60msで694万件のリクエストをサポートします。 -
4. 簡素化された開発者体験
直感的なUIで簡単にセットアップできます。
完全自動化されたCI/CDパイプラインとGitOps統合。
アクション可能な洞察のためのリアルタイムメトリクスとロギング。 -
5. 簡単なスケーラビリティと高性能
自動スケーリングで高い同時性を容易に処理できます。
オペレーションオーバーヘッドはゼロ - 開発に集中できます。
Leapcell Twitter: https://x.com/LeapcellHQ
Discussion