百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

FastAPI - 好的、坏的和丑陋的。(好的坏的说说)

toyiye 2024-04-04 11:41 24 浏览 0 评论

FastAPI 是一个相对较新的 Python Web 框架,号称是可用的最快的 Python 框架之一。在本文中,我将在我短暂的使用过程中讨论该框架的优缺点。我还将提供一些示例和解决方案,以尽量减少缺点。

好的

1.它确实是FastAPI

FastAPIFlask当我们将它与其他主要 Python 框架(如和 )进行比较时,它的速度相当快Django。以下来自Techempower的分数图表显示了这些框架之间的性能差异有多大。

我自己也做了一个小测试,看看哪个框架最快,结果其实很有趣。对于此测试,我为所有 3 个框架设置了基本的“Hello world”API。我通过调用 API 来测试响应时间并获取平均响应时间。结果可以分为两种情况:

A。 服务器启动后第一次调用的平均时间
b. 第一次通话后连续通话的平均时间

Django并且FastAPI在第一次 API 调用中响应速度比平常慢。Flask在所有 API 调用期间始终保持一致,但比其他两个慢得多。
所有 3 个 API 所花费的平均时间如下所示:

框架

案例一

情况b

FastAPI

17 毫秒

6.2毫秒

Django

517.2 毫秒

5.834 毫秒

Flask

507.2 毫秒

508.9 毫秒

这里值得注意的一件有趣的事情是,在第一次调用后,Django 实际上比 FastAPI 执行得更快一些。但在某些场景(例如无服务器环境)中,Django 的高首次调用和启动时间可能会成为一个问题。需要注意的是,测量是在特定环境下用很少的数据完成的,而且我对 Flask 和 Django 的经验非常有限,所以结果可能会因你而异。

2.支持异步代码

FastAPI 最令人兴奋的功能是它支持使用 Python 关键字开箱即用的异步代码async/await。下面是一个从 Reddit 异步获取数据的 API 示例。(示例参考:Scott Robinson 的 Python async/await 教程)

app = FastAPI()

async def get_json(client: ClientSession, url: str) -> bytes:
    async with client.get(url) as response:
        assert response.status == 200
        return await response.read()

async def get_reddit_top(subreddit: str, client: ClientSession, data: dict):
    data1 = await get_json(client, 'https://www.reddit.com/r/' + subreddit + '/top.json?sort=top&t=day&limit=5')

    j = json.loads(data1.decode('utf-8'))
    subreddit_data = []
    for i in j['data']['children']:
        score = i['data']['score']
        title = i['data']['title']
        link = i['data']['url']
        print(str(score) + ': ' + title + ' (' + link + ')')
        subreddit_data.append(str(score) + ': ' + title + ' (' + link + ')')
    data[subreddit] = subreddit_data
    print('DONE:', subreddit + '\n')


@app.get("/")
async def get_reddit_data_api() -> dict:
    start_time: float = time.time()
    client: ClientSession = aiohttp.ClientSession()
    data: dict = {}

    await asyncio.gather(
        get_reddit_top('python', client, data),
        get_reddit_top('programming', client, data),
        get_reddit_top('compsci', client, data),
    )
    await client.close()

    print("Got reddit data in ---" + str(time.time() - start_time) + "seconds ---")
    return data

异步代码的神奇之处在于,由于协程get_reddit_top同时运行,API 的执行时间与串行运行的执行时间相比显着减少。

3. 开发时间极短

要创建基本的“Hello world”API,框架需要以下代码行数(考虑整个项目):

框架

代码行数

FastAPI

8行

Flask

7行

我没有考虑过 Django,因为我认为它的结构与其他两个不同。
如果您想扩展 FastApi 应用程序,其工作量也与 Flask 类似。两者都通过 Flask 中的 Blueprint 和 FastAPI 中的 Router 实现了模块化概念。所以,我想说 Flask 和 FastAPI 的开发时间非常相似。

4. 测试方便

测试 FastAPI 端点非常简单,可以使用FastAPI 提供的TestClient来完成。这使得测试驱动开发(TDD)变得非常容易。

app = FastAPI()

@app.get("/")
async def read_main():
    return {"msg": "Hello World"}

client = TestClient(app)

def test_read_main():
    response = client.get("/")
    assert response.status_code == 200
    assert response.json() == {"msg": "Hello World"}

您可以轻松模拟 API 定义函数中的服务调用或代码,read_main并使用 TestClient 对其进行测试。

5. 无缝的中央异常处理

要在 FastAPI 中进行异常处理,您只需使用@app.exception_handler注释或app.add_exception_handler函数来注册 an 的响应Exception,它将由 FastAPI 处理。

app = FastAPI()

@app.exception_handler(SomeException)
async def http_exception_handler(request: Request, exc: SomeException) -> PlainTextResponse:
    return PlainTextResponse(str(exc.detail), status_code=exc.status_code)

async def request_exception_handler(request: Request, exc: SomeOtherException) -> PlainTextResponse: 
return PlainTextResponse(str(exc.detail),status_code=exc.status_code)

app.add_exception_handler(exc_class_or_status_code=SomeOtherException,
handler=request_exception_handler)

6. 优秀的文档

FastAPI 有非常广泛且示例丰富的文档,这使事情变得更容易。如果您需要查找有关 FastAPI 的信息,通常无需到其他地方查找。

7. 轻松部署

您可以使用 FastAPI 提供的docker 镜像通过 Docker 轻松部署 FastAPI 应用程序。您还可以使用Mangum将其部署到 AWS Lamdba 。

坏处

1.主文件拥挤

在 FastAPI 中,一切都与FastAPI app. 因此,您的main.py文件很容易变得非常拥挤。这是一个例子。

app = FastAPI()

app.include_router(users.router)
app.include_router(items.router)
app.include_router(shops.router)
app.include_router(other.router)

@app.exception_handler(SomeException)
async def http_exception_handler(request: Request, exc: SomeException) -> PlainTextResponse:
    return PlainTextResponse(str(exc.detail), status_code=exc.status_code)

@app.exception_handler(SomeOtherException)
async def http_exception_handler(request: Request, exc: SomeOtherException) -> PlainTextResponse:
    return PlainTextResponse(str(exc.detail), status_code=exc.status_code)

现在假设您有 10 个路由器和 20 个异常需要处理,main.py那么该文件可能会变得非常难以维护。幸运的是,这个问题很容易解决。

app = FastAPI()

include_routers(app);
add_exception_handlers(app);

include_routers并add_exception_handlers可以保存在单独的文件中。

2. 依赖注入中没有单例

singleton根据此Github 线程, FastAPI 中的依赖注入不支持实例,但它支持每个 HTTP 请求的单个实例。您要么必须自己创建单例类,要么使用不同的 DI 库。

丑陋的

请求验证

我在使用 FastAPI 时最糟糕的经历是处理请求验证。它使用来自 的验证Pydantic,据我所知,没有直接的方法将验证消息从验证点传递到响应。Pydantic您可以凑合使用通过传递下来的任何消息RequestValidationError或编写自定义验证器。例如,

app = FastAPI()

class SomeDto(BaseModel):
    data: str = Field(min_length=1, description="Minimum length must be greater than 1",
                      title="Minimum length must be greater than 1")

@app.post(path="/")
async def get_response(request: SomeDto):
    return "some response"

@app.exception_handler(RequestValidationError)
async def handle_error(request: Request, exc: RequestValidationError) -> PlainTextResponse:
    return PlainTextResponse(str(exc.errors()), status_code=400)

exc.errors()返回验证违规列表,其中包含来自 的硬编码消息Pydantic。FastAPI我发现没有办法从和的文档中更改它Pydantic。甚至description和title参数值也会丢失。

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码