什么是 FastAPI?

FastAPI 是一个直观的 Python Web 框架,用于创建 API 应用程序。它是最快的 Web 框架之一,也是最容易(如果不是最容易)学习的框架之一。

此外,FastAPI 默认与异步任务集成 - 从而使应用程序更快。 FastAPI 还与 swagger 文档 进行默认集成,使其易于配置和更新。

这些只是使用 FastAPI 的一些优点;现在,让我们动手编写代码吧!

我们正在构建的应用程序

我们将构建一个哈希表 API。这样我们就可以利用 Python 的dict数据结构,从而可以将我们的重点放在创建 FastAPI 应用程序上。

下载包

我们需要pytestfastapiuvicorn(用于 Web 服务器)和deta用于本教程,所以如果您还没有下载它们,请务必下载!

pip install pytest, fastapi, uvicorn[standard], deta

开发我们的哈希表

首先让我们使用以下文件夹结构设置我们的项目。

├───app   
├───tests
└───main.py

app中创建一个名为hash_table.py的文件并粘贴以下代码。

class HashTable:
    def __init__(self):
        self.hash_table = {}

    def add(self, key, value):
        self.hash_table[key] = value

    def delete(self, key):
        self.hash_table.pop(key, None)

    def get(self, key):
        return self.hash_table.get(key, None)

每个开发人员都必须了解在应用程序中使用测试的重要性。在tests目录中,创建一个名为test_hash_table.py的新文件并粘贴以下代码。

import pytest
import sys 

sys.path.append('..')
from app.hash_table import HashTable

test_hashtable = HashTable()

def test_add():
    test_hashtable.add('key', 'value')
    assert test_hashtable.get('key') == 'value'

def test_replace_word():
    og_value = test_hashtable.get('key')
    test_hashtable.add('key', 'new value')
    assert test_hashtable.get('key') != og_value

def test_get():
    test_hashtable.add('key', 'value')
    assert test_hashtable.get('key') == 'value'

def test_delete():
    test_hashtable.delete('key')
    assert test_hashtable.get('key') is None

在我的机器上,从tests目录运行pytest将产生以下结果:4 passed in 0.05s。有了这些,现在让我们专注于开发 API!

开发API

好了,现在是时候开始编写我们的 FastAPI API 了!为简单起见,我们将 FastAPI 代码直接放在main.py文件中。从根目录创建一个名为main.py的新文件。我们的项目目录现在看起来像这样。

├───app
│   ├───hash_table.py
├───tests
│   ├───test_hash_table.py
├───main.py

在我们的main.py文件中,我们首先导入 FastAPI 框架和我们的hash_table.py文件。

from fastapi import FastAPI
import app.hash_table as HashTable

从这里我们通过调用FastAPIHashTable构造函数来初始化我们的 API 应用程序。

hash_table = HashTable()
app = FastAPI()

我们现在可以开始编写我们的 API 代码了!我们需要的第一件事是定义root路径。对于该路径,我们将简单地显示一条问候消息。

@app.get("/")
async def root():
    return {"Greetings": "Welcome to FastAPI!"}

现在通过在命令行中输入uvicorn main:app --reload来运行服务器。该命令参考以下

main: the file main.py
app: the object created inside of main.py with the line app = FastAPI()
--reload: make the server restart after code changes. Only use for development. Similar to Flutter's hot restart

现在转到服务器提供的 URL,http://127.0.0.1:8000。您应该看到以下内容。

{"Greetings":"Welcome to FastAPI!"}

那么下面的代码是做什么的呢?让我们逐行剖析。

@app.get("/")

FastAPI 命令需要@appget是一种 HTTP 方法,而"/"是该特定 API 请求的 url 路径。在此之下,我们调用一个将返回某些内容的函数。这里我们返回一个dict对象。

请注意,我们使用术语async;我们不一定需要使用async关键字调用函数,因为我们不使用与某些东西(数据库、API、文件系统等)通信的库,您仍然可以使用普通的def function_name(),但请确保该功能不会与上述任何事物进行通信。

有了这些,我们现在有了一个用于编写 FastAPI 端点的模板。

@app.http_method("url_path")
async def function():
    return something

我们现在对制作 FastAPI 端点有了基本的了解。现在让我们为我们的哈希表类创建我们的第一个端点!

我们将为散列表的add方法创建端点。让我们首先回到哈希表中该方法的实现。

# in hash_table.py
def add(self, key, value):
        self.hash_table[key] = value

这里我们看到add有两个值,keyvalue。在 FastAPI 中,我们可以使用 path parameters 来制作接受值的 API 端点。此外,由于我们正在向 API 添加新的键值对,因此我们将使用post请求。

@app.post("/add/{key}-{value}")
async def add_entry(key, value):
    hash_table.add(key, value)
    return f"Key-value pair {key}-{value} added"

@app.post("/add/{key}-{value}")中,FastAPI 会将keyvalue的值分别作为参数keyvalue传递给函数add_entry

为了测试这一点,我们将转到 FastAPIhttp://127.0.0.1:8000/docs提供的内置文档。

image.png

POST,我们看到如下。

image.png

如您所见,我们可以通过 FastAPI 提供的内置文档轻松试用 API 端点!尝试添加一个键值对,看看它是如何工作的!

image.png

Execute将让我们看到响应正文。就我而言,这将是。

"Key-value pair FastAPI-is Awesome! added"

现在让我们分别为哈希表的deleteget方法创建端点。

@app.delete("/delete/{key}")
async def delete_entry(key):
    hash_table.delete(key)
    return f"Key: {key} deleted"

对于 HTTP 方法,我们在这里使用delete,因为我们明确地从服务器中删除了一些东西。

@app.get("/get/{key}")
async def get_value(key):
    return hash_table.get(key)

另一方面,这里我们使用 HTTP 方法get,因为我们只是请求查看与我们提供的key关联的value

回到内置文档,您现在将看到现在有四个端点。

image.png

让我们测试这些端点!在add端点中,分别添加hashnodeblog作为keyvalue的参数,然后按Execute。您应该看到以下响应。

"Key-value pair hashnode-blog added"

现在在get端点中,将hashnode作为key的参数放入,然后按执行。您应该看到以下响应。

"blog"

现在让我们从服务器中删除这个key。在delete端点中添加hashnode作为key的参数,然后按执行。您应该看到以下响应。

"Key: hashnode deleted"

现在回到get端点并搜索hashnode。您应该在响应正文中看到null响应。这是因为我们试图查找服务器中不存在的密钥。

这是我们的main.py文件的完整代码。

from fastapi import FastAPI
from app.hash_table import HashTable

hash_table = HashTable()
app = FastAPI()

@app.get("/")
async def root():
    return {"Greetings": "Welcome to FastAPI!"}

@app.post("/add/{key}-{value}")
async def add_entry(key, value):
    hash_table.add(key, value)
    return f"Key-value pair {key}-{value} added"

@app.delete("/delete/{key}")
async def delete_entry(key):
    hash_table.delete(key)
    return f"Key: {key} deleted"

@app.get("/get/{key}")
async def get_value(key):
    return hash_table.get(key)

这就是 API 代码的全部内容!现在让我们开始为我们的 API 编写测试!

测试API

tests目录中,创建一个名为test_main.py的新文件,该文件将包含我们 API 的测试。 FastAPI 已经为我们提供了一个内置的测试客户端。我们需要做的就是导入它。

# in test_main.py
from fastapi.testclient import TestClient

from main import app

client = TestClient(app)

与编写端点类似,我们将首先编写代码来测试我们的root端点。

def test_read_main():
    response = client.get("/")
    assert response.status_code == 200
    assert response.json() ==  {"Greetings": "Welcome to FastAPI!"}

与测试非 API 应用程序类似,我们使用assert关键字。在这里,我们测试我们从root端点获得的响应与我们在文档中前面看到的类似。

请注意,我们在这里没有使用async关键字。这使我们能够使用pytest而不会出现任何并发症。

TestClient实际上在底层使用了Starlette,因此我们可以直接通过 FastAPI 使用pytest。在我的机器上,在tests目录下运行pytest test_main.py会显示如下。

1 passed in 0.28s

现在让我们测试我们的第二个端点,即add端点。我将分别使用FastAPItutorial作为keyvalue的参数。

def test_post_method_add():
    key = "FastAPI"
    value = "tutorial"
    response = client.post(f"/add/{key}-{value}")
    assert response.status_code == 200
    assert response.json() == f"Key-value pair {key}-{value} added"

现在让我们以FastAPI作为key来测试get方法。

def test_get_method_get():
    key = "FastAPI"
    expected_value = "tutorial"
    response = client.get(f"/get/{key}")
    assert response.status_code == 200
    assert response.json() == expected_value

现在让我们为get方法编写另一个测试,这次使用哈希表中不存在的key。我将使用Flask作为key参数。

def test_get_method_get2():
    key = "Flask"
    expected_value = None
    response = client.get(f"/get/{key}")
    assert response.status_code == 200
    assert response.json() == expected_value

最后,让我们通过删除我们之前在哈希表中添加的键值对来编写delete方法的测试。

def test_delete_method_delete():
    key = "FastAPI"
    expected_value = f"Key: {key} deleted"
    response = client.delete(f"/delete/{key}")
    assert response.status_code == 200
    assert response.json() == expected_value

现在让我们再次运行pytest test_main.py

5 passed in 0.31s

这是我们的test_main.py文件的完整代码。

from fastapi.testclient import TestClient

from main import app

client = TestClient(app)

def test_read_main():
    response = client.get("/")
    assert response.status_code == 200
    assert response.json() ==  {"Greetings": "Welcome to FastAPI!"}

def test_post_method_add():
    key = "FastAPI"
    value = "tutorial"
    response = client.post(f"/add/{key}-{value}")
    assert response.status_code == 200
    assert response.json() == f"Key-value pair {key}-{value} added"

def test_get_method_get():
    key = "FastAPI"
    expected_value = "tutorial"
    response = client.get(f"/get/{key}")
    assert response.status_code == 200
    assert response.json() == expected_value

def test_get_method_get2():
    key = "Flask"
    expected_value = None
    response = client.get(f"/get/{key}")
    assert response.status_code == 200
    assert response.json() == expected_value

def test_delete_method_delete():
    key = "FastAPI"
    expected_value = f"Key: {key} deleted"
    response = client.delete(f"/delete/{key}")
    assert response.status_code == 200
    assert response.json() == expected_value

我们现在已经完成了 API 测试的编写!我们现在可以部署这个 API! FastAPI 通过使用 Deta 再次使这变得简单。

部署API

详细信息是 FastAPI 的赞助商之一,因此他们的平台和 FastAPI 框架之间的集成是无缝的。

您需要做的第一件事是在 Deta](https://www.deta.sh/?ref=fastapi)上创建一个[免费帐户。

拥有 Deta 帐户后,您需要下载其 CLI。

在 Linux 和 macOS 上,以下命令会安装 Deta CLI。

curl -fsSL https://get.deta.dev/cli.sh | sh

另一方面,Windows 有不同的命令。

iwr https://get.deta.dev/cli.ps1 -useb | iex

确保通过运行检测到 Deta CLI;

deta --help

接下来,使用以下命令登录您的帐户;

deta login

这将打开一个网络浏览器,让您登录到您的 Deta 帐户。

现在,在项目根目录中,创建一个名为requirements.txt的新文件并放入其中fastapi

# requirements.txt
fastapi

完成后,您可以通过运行轻松地在 Deta 上部署应用程序;

deta new

您应该会看到与此类似的json

{
        "name": "fastapi-tutorial",
        "runtime": "python3.7",
        "endpoint": "https://f2n9x0.deta.dev",
        "visor": "enabled",
        "http_auth": "disabled"
}

转到链接https://f2n9x0.deta.dev,我们看到了这个!

{"Greetings":"Welcome to FastAPI!"}

导航到https://f2n9x0.deta.dev/docs,您将看到文档!

image.png

我们现在已经完成了我们的申请!您可以在此处查看完整的源代码。

结论

恭喜!您现在已经了解了开发、测试和部署 FastAPI 应用程序的基础知识!如果您想更多地探索 FastAPI,我强烈建议您阅读其惊人的文档!

如果您觉得这很有用,请考虑给我买一杯咖啡!我会很感激我能得到的任何支持!请随时通过twitter与我联系!

Logo

学AI,认准AI Studio!GPU算力,限时免费领,邀请好友解锁更多惊喜福利 >>>

更多推荐