FastAPI is a very cool open-source framework to construct API using Python. Its syntax is similar to Flask, so if you use it, you should not have any trouble learning it.
FastAPI是一个非常酷的开源框架,可以使用Python构造API。 它的语法类似于Flask ,因此,如果您使用它,那么学习它就不会有任何麻烦。
It has some advantages over Flask, such as:
与Flask相比,它具有一些优势,例如:
- It is fast (as compared with Flask); 它快(与Flask相比);
- It has automatic docs (OpenAPI); 它具有自动文档(OpenAPI);
It can use async functions;
它可以使用异步功能;
- It has support for websocket; 它支持websocket;
And many more;
还有更多 ;
It is a relative new development (< 2 years), but it has already 20k stars on Github.
这是一个相对较新的发展(<2年),但是在Github上已经有2万颗星。
You can learn more about this framework in these articles:
您可以在以下文章中了解有关此框架的更多信息:
MongoDB is a document database where you can store data directly in JSON format. It is very simple to start and create an application using MongoDB. Yet it is a powerful tool.
MongoDB是一个文档数据库,您可以在其中直接以JSON格式存储数据。 使用MongoDB启动和创建应用程序非常简单。 但这是一个强大的工具。
In this article, I’m going to show you how to implement an API for a MongoDB database.
在本文中,我将向您展示如何为MongoDB数据库实现API。
Note: this tutorial was done with MongoDB version 4.4 and Python 3.8, in a machine with Ubuntu 20.04.
注意 :本教程是在装有Ubuntu 20.04的计算机中使用MongoDB 4.4版和Python 3.8完成的。
正在安装 (Installing)
You can install MongoDB following the instructions for your operating system here.
您可以按照此处针对您的操作系统的说明安装MongoDB。
You can use pip
to install FastAPI:
您可以使用pip
安装FastAPI:
pip install fastapi
To connect with the MongoDB database, we’re going to use the PyMongo package:
要连接MongoDB数据库,我们将使用PyMongo软件包:
pip install pymongo
Since FastAPI uses Starlette framework for the web requests, we have to install an ASGI server as well:
由于FastAPI使用Starlette框架处理Web请求,因此我们还必须安装ASGI服务器:
pip install uvicorn
基本应用 (A basic application)
We can create a basic application to see if everything is installed correctly.
我们可以创建一个基本的应用程序,以查看所有内容是否正确安装。
The first step is to create the FastAPI
object:
第一步是创建FastAPI
对象:
app = FastAPI()
After that, we can start creating the endpoints we need. The syntax is simple: is a decorator with the name of the HTTP request, with the path as the parameter. That is:
之后,我们可以开始创建所需的端点。 语法很简单:它是一个装饰器,带有HTTP请求的名称,并将路径作为参数。 那是:
@app.get('/')
async def index():
return {'hello': 'world'}
And that is it! You already have an API created, with very few lines.
就是这样! 您已经创建了一个API,只有很少的几行。
from fastapi import FastAPI
app = FastAPI()
@app.get('/')
async def index():
return {'hello': 'world'}
To run, just use the command:
要运行,只需使用以下命令:
uvicorn run:app --reload
Note:
run
is the name of the python file you declared your main application andapp
is the name of theFastAPI
object you created.注意 :
run
是您声明主应用程序的python文件的名称,而app
是您创建的FastAPI
对象的名称。
You must see an output similar to this:
您必须看到类似于以下内容的输出:
Image by author. 图片由作者提供。If you open access localhost:8000/
you must get {"hello":"world"}
as an output.
如果打开访问localhost:8000/
,则必须获得{"hello":"world"}
作为输出。
创建模型 (Creating the models)
Now is time to connect with the database. For this, we use the PyMongo package and just create a MongoClient
object:
现在是时候连接数据库了。 为此,我们使用PyMongo包并仅创建一个MongoClient
对象:
from pymongo import MongoClientclient = MongoClient()
db = client[database_name]
Note: if your database has a different URI and an authentication, you have to configure it in this step.
注意 :如果您的数据库具有不同的URI和身份验证,则必须在此步骤中对其进行配置。
FastAPI uses the Pydantic library to check the data and process it. It is a fast and yet easy to use package. You can use it on other projects if you need some data validation and schema.
FastAPI使用Pydantic库检查数据并进行处理。 这是一个快速但易于使用的软件包。 如果需要一些数据验证和架构,则可以在其他项目上使用它。
To create a model in Pydantic library, you have to declare a class that inherits from the BaseModel
class. All the fields you want to validate and make part of the model must be declared as attributes.
要在Pydantic库中创建模型,您必须声明一个继承自BaseModel
类的类。 您要验证并成为模型一部分的所有字段都必须声明为属性。
from pydantic import BaseModel
from bson import ObjectIdclass User(BaseModel):
_id: ObjectId
name: str
email: str
username: str
One of the cool features of Pydantic is that it uses the python typing syntax to check the field type. You can use Optional
, Union
, and other features of it.
Pydantic的很酷的功能之一是它使用python输入语法来检查字段类型。 您可以使用Optional
, Union
和其他功能。
对象编号 (ObjectId)
But Pydantic does not have support for the ObjectId
class. Every document stored on the database has a field _id
, which by default is of type ObjectId
.
但是Pydantic不支持ObjectId
类。 数据库中存储的每个文档都有一个_id
字段,默认情况下该字段的类型为ObjectId
。
We have two options here: we can make the _id
as another type which is supported by the library; or we can make a custom validator class.
这里有两个选项:我们可以将_id
为库支持的另一种类型; 或者我们可以创建一个自定义的验证器类。
To use with an already created database, we’re going to choose the second option. Basically, we need to implement two methods, get_validators
and validate
, so Pydantic knows how to deal with it.
要与已经创建的数据库一起使用,我们将选择第二个选项。 基本上,我们需要实现两种方法, get_validators
和validate
,因此Pydantic知道如何处理它。
from pydantic import BaseModel, field
from bson import ObjectId
class PyObjectId(ObjectId):
@classmethod
def __get_validators__(cls):
yield cls.validate
@classmethod
def validate(cls, v):
if not ObjectId.is_valid(v):
raise ValueError('Invalid objectid')
return ObjectId(v)
@classmethod
def __modify_schema__(cls, field_schema):
field_schema.update(type='string')
The method validate
is used to check if the data received is actually valid for this class. So we check it against the ObjectId.is_valid
method. In this way, we can accept also a string
that is a valid ObjectId. This is useful so we can parse a JSON object received from a HTTP request, for example.
validate
方法用于检查接收到的数据是否实际上对于此类有效。 因此,我们根据ObjectId.is_valid
方法对其进行检查。 这样,我们也可以接受一个有效的ObjectId string
。 例如,这很有用,因此我们可以解析从HTTP请求接收到的JSON对象。
Note: the
modify_schema
method is to avoid an error when accessing the documentation.注意 :
modify_schema
方法是为了避免在访问文档时出错。
So now we update our model to use this custom object and accept ObjectId
types:
因此,现在我们更新模型以使用此自定义对象并接受ObjectId
类型:
from pydantic import BaseModel, Field
from pymongo import MongoClient
from bson import ObjectId
from typing import Optional
client = MongoClient()
db = client.test
class PyObjectId(ObjectId):
@classmethod
def __get_validators__(cls):
yield cls.validate
@classmethod
def validate(cls, v):
if not ObjectId.is_valid(v):
raise ValueError('Invalid objectid')
return ObjectId(v)
@classmethod
def __modify_schema__(cls, field_schema):
field_schema.update(type='string')
class User(BaseModel):
id: Optional[PyObjectId] = Field(alias='_id')
name: str
username: str
email: str
class Config:
arbitrary_types_allowed = True
json_encoders = {
ObjectId: str
}
We declared here the class User
, which inherits from pydantic.BaseModel
. This object has four attributes: name
, username
, and email
of string
type. And the id
field of our new custom type.
我们在这里声明了User
类,该类继承自pydantic.BaseModel
。 该对象具有四个属性: name
, username
和string
类型的email
。 还有我们新的自定义类型的id
字段。
MongoDB expects a field with the name _id
, but Pydantic does not accept any field that starts with _
. Then we create an alias so Pydantic can understand our document.
MongoDB需要一个名称为_id
的字段,但Pydantic不接受以_
开头的任何字段。 然后我们创建一个别名,以便Pydantic可以理解我们的文档。
The inner class Config
is used to define some configuration for the model. Here we tell Pydantic that we are using a custom type (by arbitrary_types_allowed
) and also a mapping for JSON serialization (by json_encoders
).
内部类Config
用于定义模型的某些配置。 在这里,我们告诉Pydantic,我们使用的是自定义类型(由arbitrary_types_allowed
),也为JSON序列化映射(由json_encoders
)。
终点 (Endpoints)
Now we must change the run.py
file so we can use the models we declared on models.py
.
现在我们必须更改run.py
文件,以便可以使用在models.py
声明的模型。
We are going to create one endpoint /users
which accepts two methods: GET
and POST
. The first will list all users in database and the latter will insert a new user into the database.
我们将创建一个接受两种方法的端点/users
: GET
和POST
。 前者将列出数据库中的所有用户,而后者将新用户插入数据库。
from fastapi import FastAPI
from models import db, User
app = FastAPI()
@app.get('/users')
async def list_users():
users = []
for user in db.users.find():
users.append(User(**user))
return {'users': users}
@app.post('/users')
async def create_user(user: User):
if hasattr(user, 'id'):
delattr(user, 'id')
ret = db.users.insert_one(user.dict(by_alias=True))
user.id = ret.inserted_id
return {'user': user}
The list_users
method gets all the users available on database and send back as a dictionary. FastAPI (and Pydantic) is responsible for translating it to JSON format so the client can understand it.
list_users
方法获取数据库上所有可用的用户,并作为字典发送回去。 FastAPI(和Pydantic)负责将其转换为JSON格式,以便客户端可以理解它。
The create_user
method receive an object of User
class we declared in our models.py
file. We don’t have to worry about the conversion from the JSON body to our model. This is done by FastAPI, since we declared that we expect an argument of type User
. Isn’t it great?
create_user
方法接收我们在models.py
文件中声明的User
类的对象。 我们不必担心从JSON主体到我们的模型的转换。 这是由FastAPI完成的,因为我们声明期望使用User
类型的参数。 很好吗?
Pymongo method insert_one
expects a dictionary so it can insert it into database. We use the dict
method, passing the argument by_alias
as True
. This guarantees that the field _id
is with the correct name expected by MongoDB.
Pymongo方法insert_one
需要一个字典,以便可以将其插入数据库。 我们使用dict
方法,将参数by_alias
传递为True
。 这样可以保证_id
字段具有MongoDB期望的正确名称。
测试中 (Testing)
And that’s it! Now you can run the program to test it:
就是这样! 现在,您可以运行程序进行测试:
uvicorn run:app
Go to localhost:8000/docs
and you will see a nice Swagger UI page:
转到localhost:8000/docs
,您将看到一个漂亮的Swagger UI页面:
This page is generated automatically by FastAPI and you can use to test your program.
此页面由FastAPI自动生成,您可以用来测试程序。
结论 (Conclusion)
FastAPI is a nice, fast framework to create an API. If you don’t know it yet, I suggest you start learning it.
FastAPI是创建API的不错的快速框架。 如果您还不了解它,建议您开始学习。
In this article, I showed you how you can integrate it with Mongo database in a very nice, simple way.
在本文中,我向您展示了如何以一种非常简单的方式将其与Mongo数据库集成。
There is also a nice package called FastAPI Contrib that supports Mongo object as well in some more advanced way.
还有一个名为FastAPI Contrib的好程序包,它也以某种更高级的方式支持Mongo对象。
If you liked this article, you might enjoy these ones as well:
如果您喜欢这篇文章,您可能也会喜欢这些文章:
Follow me on Twitter to know when I write another article.
在Twitter上关注我,以了解何时撰写其他文章。
普通英语的Python (Python In Plain English)
Did you know that we have three publications and a YouTube channel? Find links to everything at plainenglish.io!
您知道我们有三个出版物和一个YouTube频道吗? 在plainenglish.io上找到所有内容的链接!
翻译自: https://medium.com/python-in-plain-english/how-to-use-fastapi-with-mongodb-75b43c8e541d