在python中使用fastapi入门

这篇博客介绍了如何使用Python的FastAPI框架构建RESTful服务。FastAPI基于标准的Python类型提示,提供了高性能和现代的特性。文章涵盖了从安装FastAPI和uvicorn,创建基本的API程序,指定路径和查询参数,发送请求正文,处理表格数据,上传文件,到利用Swagger自动生成API文档等步骤。FastAPI与传统的Flask和Django框架不同,它基于异步的ASGI服务器,适用于处理高并发的非阻塞操作。
摘要由CSDN通过智能技术生成

The most commonly used web frameworks for building REST APIs with python is Flask and Django. Though we could build APIs with django, the real purpose of Django is building an end to end web application. On the other hand, flask is pretty light weight and can help us quickly build REST APIs. Before jumping into fastapi let’s quickly revisit a basic flask application.

使用python构建REST API的最常用Web框架是Flask和Django。 尽管我们可以使用django构建API,但是Django的真正目的是构建端到端的Web应用程序。 另一方面,flask重量很轻,可以帮助我们快速构建REST API。 在进入fastapi之前,让我们快速回顾一下基本的flask应用程序。

from flask import Flask, jsonify

app = Flask(__name__)


@app.route("/", methods = ["GET"])
def index():
return jsonify({"appname" :"firstapp"}),200


if __name__ == "__main__":
app.run(debug=True)

Running the above code should give the following logs and output

运行上面的代码应提供以下日志和输出

* Serving Flask app "myflaskapi" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 207-495-435
127.0.0.1 - - [25/Sep/2020 12:35:03] "GET / HTTP/1.1" 200 -Output:
{
"appname": "firstapp"
}

The fundamental problem of flask is it is based on WSGI server which is synchronous. This means that these cannot perform any non blocking asynchronous operations. For instance , consider the example below.

flask的根本问题是它基于同步的WSGI服务器。 这意味着它们不能执行任何非阻塞异步操作。 例如,请考虑以下示例。

@app.route("/", methods=["GET"])
def index():
response = requests.get(url="https://google.com")
print(response.content)
return jsonify({"content" : str(response.content)}), 200

In the above code, the response is returned only after the execution of requests.get method. Until then, the API is blocked and unavailable to handle further requests.

在上面的代码中,仅在执行requests.get方法之后返回响应。 在此之前,该API被阻止并且无法处理其他请求。

This use case is still valid with a WSGI server like gunicorn handling the requests with worker threads. Ofcourse one would argue that this could still be made asynchronous using Klein or other libraries. But that still adds further overhead.

这种用例对于像gunicorn这样的WSGI服务器仍然有效,该服务器使用工作线程处理请求。 当然有人会说,仍然可以使用Klein或其他库将其异步化。 但这仍然增加了额外的开销。

We also cannot use the asyncio library with flask apis as asyncio expects a coroutine and flask is incompatible with a coroutine.

我们也不能将asyncio库与flask api一起使用,因为asyncio期望coroutine并且flask与协程不兼容。

To get around this, we have fastapi which is based on asyncio.

为了解决这个问题,我们有fastapi这是基于ASYNCIO

介绍Fastapi (Introducing Fastapi)

FastAPI is a modern, high-performance, web framework for building APIs with Python 3.6+ based on standard Python type hints.FastAPI is actually a sub-class of Starlette. So, if you already know or use Starlette, most of the functionality will work the same way.Fast API claims to be one of the fastest web frameworks on par with Go and Nodejs.

FastAPI是一种现代的高性能Web框架,用于基于标准Python类型提示使用Python 3.6+构建API。 FastAPI实际上是一个子类的Starlette 。 因此,如果您已经了解或使用Starlette,则大多数功能将以相同的方式工作.Fast API声称是与GoNodejs相提并论的最快的Web框架Nodejs

We will discuss the following basic features here:

我们将在这里讨论以下基本功能:

  1. A basic fastapi program

    基本的fastapi程序
  2. How to specify path and query parameters

    如何指定路径和查询参数
  3. How to send a request body to fast api

    如何将请求正文发送到快速API
  4. Specifying form data

    指定表格数据
  5. How to perform HTTP file upload to fast api

    如何执行HTTP文件上传到快速api
  6. Generating swagger files for APIs

    生成API的swagger文件

安装快速API(Installing fast api)

pip install fastapi

We use an ASGI server to start a fastapi unlike WSGI in a flask application. The ASGI server is uvicorn.

我们在烧瓶应用程序中使用ASGI服务器来启动与WSGI不同的fastapi。 ASGI服务器是uvicorn

安装uvicorn (Installing uvicorn)

pip install uvicorn

Run fastapi using uvicorn

fastapi using uvicorn运行fastapi using uvicorn

#Syntax
uvicorn <filename>:<app-name> --reloaduvicorn myapp:app --reloadOutput:
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [33149] using statreload
INFO: Started server process [33151]
INFO: Waiting for application startup.
INFO: Application startup complete.

The default port of fastapi is 8000.

fastapi的默认端口是8000。

1.基本的fastapi程序 (1. A basic fastapi program)

Let’s quickly rewrite the basic flask program using fastapi

让我们使用fastapi快速重写基本的flask程序

from fastapi import FastAPI
app = FastAPI()




@app.get("/")
async def index():
    return {"appname": "firstapp"}


# Calling API with http://localhost:8000

Access this using localhost:8000 and it will give the below output.

使用localhost:8000进行访问,它将给出以下输出。

Output:{"appname": "firstapp"}

Let’s quickly check the differences(or similarities) with flask:

让我们快速检查一下flask的差异(或相似点):

  • app.<http-method-name> is used instead of app.route(methods=[]).i.e For GET we say @app.get()

    app.<http-method-name>代替app.route(methods=[]) ie对于GET,我们说@app.get()

  • We don’t have to import jsonify/json.dumps like we do in flask. The response is already returned as json. However we still have JSONResponse in fastapi if we have to return a customized response.

    我们不必导入jsonify / json 。 像我们在flask一样dumps 。 该响应已作为json 。 但是,如果必须返回自定义的响应,则在fastapi仍然有JSONResponse

2.指定路径参数和查询参数 (2.Specifying path parameters and query parameters)

Let’s see how to specify path and query parameters in fastapi.

让我们看看如何在fastapi中指定路径和查询参数。

from fastapi import FastAPI


app = FastAPI()




@app.get("/getuser/{username}/")
async def index(username: str, user_id: int):
    return {"username": username, 'user_id': user_id}
  
# Calling API with http://localhost:8000/getuser/defaultuser?user_id=123
Output:
{
"username": "defaultuser",
"user_id": "123"
}
Output:{"username": "defaultuser",
"user_id" : "123"
}

There is a little addition here which you may or may not be familiar with. We have declared a type hintfor the username path parameter to specify that it is of type str. To know more about type hints kindly check my other article here.

这里可能有您可能不熟悉的一些附加内容。 我们已经为用户名path参数声明了type hint ,以指定它的类型为str 。 要了解有关type hints更多信息,请在此处查看我的其他文章。

Any arguments declared that are not as part of the url path will automatically be considered as query parameters. In the above code, user_id is a query parameter and username is a path parameter.

声明的不属于url路径的任何参数将自动被视为查询参数。 在上面的代码中, user_id是一个查询参数,而username是一个路径参数。

Failing to provide any required query parameters will throw an error like so.

未能提供任何必需的查询参数将引发类似的错误。

缺少字段参数时出错 (Error for missing fields parameter)


{
"detail": [{
"loc": [
"query",
"user_id"
],
"msg": "field required",
"type": "value_error.missing"
}]}

3.指定请求正文 (3. Specifying request body)

To send a request body, we have to use pydantic models. Pydantic models define a blueprint for your request body and their types. For more details on pydantic check here.

要发送请求正文,我们必须使用pydantic模型。 Pydantic模型为您的请求主体及其类型定义了一个蓝图。 有关pydantic的更多详细信息,请点击此处

from pydantic import BaseModel


class Basic(BaseModel):
    username : str
    userid : int
    designation : str
    pay : float


# We are just returning the request body as a response
@app.post("/user/createuser", status_code=201)
async def create_user(user: Basic):
    return user

The request body is automatically read as json and we don’t have to use request.json() as we do in flask.The http status codes can be specified as part of the decorator.

请求主体会自动读取为json而我们不必像在flask中那样使用request.json()http状态代码可以指定为装饰器的一部分。

We could also use default variables for status codes specified in fastapi as shown below.

我们还可以将默认变量用于在fastapi指定的状态代码,如下所示。

from fastapi import FastAPI, status


# We are just returning the request body as a response
# Note the status code imported from status module
@app.post("/user/createuser", status_code=status.HTTP_201_CREATED)
async def create_user(user: Basic):
    return user

4.指定表格数据(4. Specifying Form Data)

Using form data requires installing python-multipart module.

使用表单数据需要安装python-multipart模块。

pip install python-multipart

After installing multi-part library, add form data as shown below

安装多部分库后,如下所示添加表单数据

from fastapi import FastAPI,Form


@app.post("/user/createuser", status_code=status.HTTP_201_CREATED)
async def create_user(username: str = Form(...), password: str = Form(..., min_length=8)):
    return username

In the above code username and password are mandatory form data to be sent as part of the POST request. If you are wondering about the ... (ellipsis) in the Form object, it is used to specify that they are mandatory arguments when using a Form() object.

在上面的代码中,用户名和密码是必填表格数据,将作为POST请求的一部分发送。 如果您想知道Form对象中的... (省略号),则可以在使用Form()对象时将其指定为必需参数。

This is a convention across fastapi functions to specify mandatory parameters without mentioning default values.

这是fastapi函数之间的约定,用于指定必需参数而不提及默认值。

The first parameter of the Form function is the default parameter which is None here because it is not necessary.

Form函数的第一个参数是default参数,此处为None ,因为它不是必需的。

@app.post("/user/createuser", status_code=status.HTTP_201_CREATED)
async def create_user(username: str = Form(default=None), password: str = Form(default=None, min_length=5))):
    return username

Specifying None like above, makes username and password fields optional and the API will work even if the consumer does not send the username and password fields.

如上所述指定None,则使用户名和密码字段为可选,即使使用者未发送用户名和密码字段,API也将起作用。

However, we want to mandate the user to pass username and password fields as part form data.

但是,我们希望授权用户传递用户名和密码字段作为表单数据的一部分。

That’s why we have to set the default positional argument to ... ellipsis which ensures we don’t have default values for arguments and also mandate the username/password arguments.

这就是为什么我们必须将默认位置参数设置为...省略号,以确保我们没有参数的默认值,并且还必须强制使用用户名/密码参数。

Similar to Form data, Path parameters and Query parameters as well can be specified as shown above.

与表单数据类似,也可以如上所述指定Path参数和Query参数。

5.上传文件 (5. Uploading Files)

Files can be uploaded via HTTP using File and UploadFile in fastapi.The response returned here is a message and the uploaded filetype

可以使用UploadFile in fastapi. FileUploadFile in fastapi.通过HTTP上传File UploadFile in fastapi. 此处返回的响应是一条消息和上传的文件类型

from fastapi import FastAPI, File, UploadFile




@app.post("/files/uploadfile", status_code=status.HTTP_201_CREATED)
async def upload_file(file: UploadFile = File(...)):
    return {"message": " Valid file uploaded", "filetype": file.content_type}


# Uploading a pdf file 
# API : http://localhost:8000/files/uploadfile

Output:{"message": " Valid file uploaded",
"filetype": "application/pdf"}

6.自动生成的Swagger API: (6. Auto generated Swagger APIs:)

This is my personal favourite feature of fastapi. The most annoying thing about being a developer is documenting the APIs in a swagger file in our busy schedule. Well we all hate it , don’t we? fastapi provides a brilliant auto doc generation feature for our APIs based on openAPI standards.

这是我最喜欢的fastapi功能。 成为开发人员最烦人的事情是,在我们繁忙的日程中将API记录在庞大的文件中。 好吧,我们都讨厌它,不是吗? fastapi为我们的基于openAPI标准的API提供了出色的自动文档生成功能。

For all the routes written, the swagger file will be available in the following route.

对于所有写入的路由,swagger文件将在以下路由中可用。

http://localhost:8000/docs

This is a screenshot from our swagger file listing one of the GET APIs.

这是我们的庞大文件的屏幕截图,其中列出了GET API之一。

Image for post

Summary:

概要:

  • Fast API is used for asynchronous non blocking API programming.

    快速API用于异步非阻塞API编程。
  • FastApi claims to be the one of the fastest web frameworks for python on par with Go and Nodejs

    FastApi声称是与Go和Nodejs相当的最快的python Web框架之一
  • An ASGI server is used to run fastapi

    ASGI服务器用于运行fastapi
  • Automatically constructs the swagger file with open-id standards

    使用开放ID标准自动构建swagger文件
  • The default port on which uvicorn runs is 8000.

    运行uvicorn的默认端口是8000。

翻译自: https://medium.com/python-in-plain-english/getting-started-with-fastapi-in-python-84d7aecc988f

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值