1. 程式人生 > 其它 >使用 Hypercorn HTTP/2 ASGI 部署 FastAPI

使用 Hypercorn HTTP/2 ASGI 部署 FastAPI

Another ASGI web server that supports HTTP/2 and HTTP/3 specifications

我已經介紹了很多關於 FastAPI 的教程,其中伺服器部署了 Uvicorn,一個快速的 ASGI Web 伺服器。在撰寫本文時,Uvicorn 目前僅支援 HTTP/1.1 和 WebSockets。根據官方文件,計劃支援 HTTP/2,但沒有預計完成時間。

HTTP/2 是舊 HTTP/1 的繼承者,它在減少延遲的同時保持相同的高階語義(方法、標頭欄位、狀態程式碼等)。基於維基百科,它通過以下方式改進了網頁的載入:


This articles covers FastAPI server deployment for HTTP/2 using another ASGI web server called Hypercorn. For your information, Hypercorn is

… an ASGI web server based on the sans-io hyper, h11h2, and wsproto libraries and inspired by Gunicorn. Hypercorn supports HTTP/1, HTTP/2, WebSockets (over HTTP/1 and HTTP/2), ASGI/2, and ASGI/3 specifications. Hypercorn can utilise asyncio, uvloop, or trio worker types.

Let’s proceed to the next section and start installing the necessary modules.

 

Setup

It is highly recommended to create a virtual environment before you continue with the installation. Activate the virtual environment and continue installing the necessary packages via pip install.

FastAPI

Run the following command to install FastAPI:

pip install fastapi

Hypercorn

Install Hypercorn as follows:

pip install hypercorn

Implementation

In this section, you will learn to write a simple FastAPI script and run it using Hypercorn.

FastAPI Server

Let’s create a new Python file called myapp.py in the same working directory with the following code:

from fastapi import FastAPIapp = FastAPI()@app.get("/")
async def root():
return {"message": "Hello world!"}

Deploying with Hypercorn

Next, run the following command at the terminal to start your server. By default, it will run as localhost on port 8000.

hypercorn myapp:app

Similar to Uvicorn, Hypercorn uses the following syntax

hypercorn <module_name>:<variable_name>
  • module_name — name of the module (filename)
  • variable_name — name of the variable defined for FastAPI

Binding to Specific Address

However, the configuration or available options are a lot different compared to Uvicorn. For example, you have to use the bind option for specifying the host and port as follows:

# Hypercorn
hypercorn myapp:app --bind 0.0.0.0:8080# Uvicorn
uvicorn myapp:app --host 0.0.0.0 --port 8080

Binding to Multiple Addresses

In fact, you can bind it to multiple servers and serve them simultaneously. This is extremely useful when you need to serve the server on both IPv4 and IPv6. For example:

hypercorn myapp:app --bind "0.0.0.0:5000" --bind "[::]:5000"

Other Configurations Options

Furthermore, you can use the following options when running Hypercorn in the command line as well.

  • --access-logformat — The log format for the access log, see Logging.
  • --access-logfile — The target logger for access logs, use - for stdout.
  • --backlog —The maximum number of pending connections.
  • --ca-certs — Path to the SSL CA certificate file.
  • --certfile — Path to the SSL certificate file.
  • --cipher — Ciphers to use for the SSL setup.
  • --debug — Enable debug mode, i.e. extra logging and checks.
  • --error-logfile --log-file — The target location for the error log, use — for stderr.
  • --graceful-timeout — Time to wait after SIGTERM or Ctrl-C for any remaining requests (tasks) to complete.
  • --keep-alive — Seconds to keep inactive connections alive before closing.
  • --keyfile — Path to the SSL key file.
  • --log-config — A Python logging configuration file.
  • --log-level — The (error) log level.
  • --pid — Location to write the PID (Program ID) to.
  • --reload —Enable automatic reloads on code changes.
  • --worker-class — The type of worker to use. Options include asyncio, uvloop (requires pip install hypercorn[uvloop]), and trio (requires pip install hypercorn[trio]).
  • --workers —The number of workers to spawn and use.

Result

Assuming that you have ran the following command:

hypercorn myapp:app

You should get the following output at the console when you run it:

[2021-07-10 21:24:19 +0800] [5464] [INFO] Running on http://127.0.0.1:8000 (CTRL + C to quit)

Open up a browser and head over to the following URL mentiond in the console:

http://localhost:8000/

The output should be as follows:

{"message":"Hello world!"}

However, the server indicated in the response headers is hypercorn-h11 which refers to HTTP/1.1

Image by the author

This is mainly because HTTP/2 requires a mandatory encryption. You have to serve it with certificates even if you are running it as localhost.

Generate a Self-signed Certificate

Let’s create a temporary self-signed certificate using rsa for 365 days. Run the following command in your command line:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes

如果您在讀取檔案時遇到openssl.cnf如下問題:

Can't open .../openssl.cnf for reading. No such file or directory
它只是意味著它無法找到配置檔案。如果你已經安裝了 openssl 附帶的 Git,只需將其指向openssl.cnf使用-config選項的位置。例如:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes -config "C:\Program Files\Git\usr\ssl\openssl.cfg"


它將生成兩個新檔案:

  • key.pem
  • cert.pem
  • 金鑰.pem
  • 證書.pem

接下來,將這兩個檔案放在與 myapp.py 相同的目錄中,並使用--keyfile--certfile命令執行它:


hypercorn --keyfile key.pem --certfile cert.pem myapp:app

在您的瀏覽器上,重新載入頁面,但這次使用 https 代替:

https://localhost:8000/

它應該提示一個警告頁面表明(如果您使用的是自簽名證書,這是正常的):

localhost:8000 uses an invalid security certificate.

The certificate is not trusted because it is self-signed.

接受風險並繼續訪問請求的 URL。您應該獲得以下響應標頭:

 

hypercorn-h2表示伺服器正在執行 HTTP/2。對於生產伺服器,建議改用有效證書。您可以使用Let's Encrypt為您的網站獲取免費證書。

 

結論

讓我們回顧一下您今天所學的內容。

本文以對 HTTP/2 的簡要說明開始。它還涵蓋了對 Uvicorn 和 Hypercorn ASGI 伺服器的 HTTP/2 支援。

然後,它通過pip install.

它繼續使用 FastAPI 伺服器的標準樣板並在本地主機上執行它。除此之外,它還介紹了使用 Hypercorn 部署 FastAPI 伺服器時可用的配置。

本教程還包括一個關於生成自簽名證書的簡單部分,因為 HTTP/2 在部署期間需要強制證書。

References

  1. FastAPI — Deploy manually
  2. Hypercorn — Gitlab
  3. Hypercorn — Documentation
  4. HTTP2 — Wikipedia