博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python构建json_如何使用Python构建JSON API
阅读量:2531 次
发布时间:2019-05-11

本文共 19540 字,大约阅读时间需要 65 分钟。

python构建json

The is a powerful way for enabling communication between client and server. It specifies the structure of the requests and responses sent between the two, using the JSON format.

是启用客户端和服务器之间通信的强大方法。 它使用JSON格式指定在两者之间发送的请求和响应的结构。

As a data format, JSON has the advantages of being lightweight and readable. This makes it very easy to work with quickly and productively. The specification is designed to minimise the number of requests and the amount of data that needs sending between client and server.

JSON作为一种数据格式,具有轻巧易读的优点。 这使得快速高效地工作变得非常容易。 该规范旨在最大程度地减少请求数量以及需要在客户端和服务器之间发送的数据量。

Here, you can learn how to create a basic JSON API using Python and Flask. Then, the rest of the article will show you how to try out some of the features the JSON API specification has to offer.

在这里,您可以学习如何使用Python和Flask创建基本的JSON API。 然后,本文的其余部分将向您展示如何尝试JSON API规范必须提供的某些功能。

that provides a 'micro-framework' for web development. It is great for rapid development as it comes with a simple-yet-extensible core functionality.

,为Web开发提供了“微框架”。 它具有简单但可扩展的核心功能,因此对于快速开发非常有用。

A really basic example of how to send a JSON-like response using Flask is shown below:

下面显示了一个如何使用Flask发送类似于JSON的响应的非常基本的示例:

from flask import Flaskapp = Flask(__name__)@app.route('/')def example():   return '{"name":"Bob"}'if __name__ == '__main__':    app.run()

This article will use two add-ons for Flask:

本文将为Flask使用两个附加组件:

  • will help develop an API that closely follows the JSON API specification.

    将帮助开发一个严格遵循JSON API规范的API。

  • will use to make creating and interacting with a simple database very straightforward.

    将使用使创建和与简单数据库交互非常简单。

大图 (The big picture)

The end goal is to create an API that allows client-side interaction with an underlying database. There will be a couple of layers between the database and the client - a data abstraction layer and a resource manager layer.

最终目标是创建一个API,该API允许客户端与基础数据库进行交互。 数据库和客户端之间将有几层-数据抽象层和资源管理器层。

Here's an overview of the steps involved:

以下是有关步骤的概述:

  1. Define a database using Flask-SQLAlchemy

    使用Flask-SQLAlchemy定义数据库
  2. Create a data abstraction with

    使用创建数据抽象

  3. Create resource managers with Flask-REST-JSONAPI

    使用Flask-REST-JSONAPI创建资源管理器
  4. Create URL endpoints and start the server with Flask

    创建URL端点并使用Flask启动服务器

This example will use a simple schema describing modern artists and their relationships to different artworks.

本示例将使用一个简单的模式来描述现代艺术家及其与不同艺术品的关系。

安装一切 (Install everything)

Before getting started, you'll need to set up the project. This involves creating a workspace and virtual environment, installing the modules required, and creating the main Python and database files for the project.

在开始之前,您需要设置项目。 这涉及创建工作区和虚拟环境,安装所需的模块以及为项目创建主要的Python和数据库文件。

From the command line create a new directory and navigate inside.

从命令行创建一个新目录并在其中导航。

$ mkdir flask-jsonapi-demo$ cd flask-jsonapi-demo/

It is good practice to for each of your Python projects. You can skip this step, but it is strongly recommended.

为每个Python项目是一个好习惯。 您可以跳过此步骤,但强烈建议您这样做。

$ python -m venv .venv$ source .venv/bin/activate

Once your virtual environment has been created and activated, you can install the modules needed for this project.

创建并激活虚拟环境后,即可安装该项目所需的模块。

$ pip install flask-rest-jsonapi flask-sqlalchemy

Everything you'll need will be installed as the requirements for these two extensions. This includes Flask itself, and SQLAlchemy.

您需要的所有内容都将安装为这两个扩展的要求。 这包括Flask本身和SQLAlchemy。

The next step is to create a Python file and database for the project.

下一步是为项目创建Python文件和数据库。

$ touch application.py artists.db

创建数据库架构 (Create the database schema)

Here, you will start modifying application.py to define and create the database schema for the project.

在这里,您将开始修改application.py以定义和创建项目的数据库模式。

Open application.py in your preferred text editor. Begin by importing some modules. For clarity, modules will be imported as you go.

在首选的文本编辑器中打开application.py 。 首先导入一些模块。 为了清楚起见,模块将随您导入。

Next, create an object called app as an instance of the Flask class.

接下来,创建一个名为app的对象作为Flask类的实例。

After that, use SQLAlchemy to connect to the database file you created. The final step is to define and create a table called artists.

之后,使用SQLAlchemy连接到您创建的数据库文件。 最后一步是定义并创建一个名为artists的表。

from flask import Flaskfrom flask_sqlalchemy import SQLAlchemy# Create a new Flask applicationapp = Flask(__name__)# Set up SQLAlchemyapp.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:artists.db'db = SQLAlchemy(app)# Define a class for the Artist tableclass Artist(db.Model):    id = db.Column(db.Integer, primary_key=True)    name = db.Column(db.String)    birth_year = db.Column(db.Integer)    genre = db.Column(db.String)# Create the tabledb.create_all()

创建一个抽象层 (Creating an abstraction layer)

The next step uses the module to create a logical data abstraction over the tables just defined.

下一步使用模块在刚刚定义的表上创建逻辑数据抽象。

The reason to create this abstraction layer is simple. It gives you more control over how your underlying data is exposed via the API. Think of this layer as a lens through which the API client can view the underlying data clearly, and only the bits they need to see.

创建此抽象层的原因很简单。 它使您可以更好地控制如何通过API公开基础数据。 将这一层视为透镜,API客户端可以通过它清楚地查看基础数据,并且仅查看它们需要查看的位。

In the code below, the data abstraction layer is defined as a class which inherits from Marshmallow-JSONAPI's Schema class. It will provide access via the API to both single records and multiple records from the artists table.

在下面的代码中,数据抽象层被定义为从Marshmallow-JSONAPI的Schema类继承的类。 它将通过API提供对Artists表中的单个记录和多个记录的访问。

Inside this block, the Meta class defines some metadata. Specifically, the name of the URL endpoint for interacting with single records will be artist_one, where each artist will be identified by a URL parameter <id>. The name of the endpoint for interacting with many records will be artist_many.

在此块内部, Meta类定义一些元数据。 具体来说,用于与单个记录进行交互的URL端点的名称将是artist_one ,其中每个艺术家都将通过URL参数<id>进行标识。 与许多记录进行交互的端点的名称将为artist_many

The remaining attributes defined relate to the columns in the artists table. Here, you can control further how each is exposed via the API.

定义的其余属性与Artists表中的列有关。 在这里,您可以进一步控制每个API的公开方式。

For example, when making POST requests to add new artists to the database, you can make sure the name field is mandatory by setting required=True.

例如,在发出POST请求以将新的演出者添加到数据库时,可以通过设置required=True来确保name字段是必填项。

And if for any reason you didn't want the birth_year field to be returned when making GET requests, you can specify so by setting load_only=True.

并且,如果由于某种原因您不希望在发出GET请求时返回birth_year字段,则可以通过设置load_only=True来指定。

from marshmallow_jsonapi.flask import Schemafrom marshmallow_jsonapi import fields# Create data abstraction layerclass ArtistSchema(Schema):    class Meta:        type_ = 'artist'        self_view = 'artist_one'        self_view_kwargs = {'id': '
'} self_view_many = 'artist_many' id = fields.Integer() name = fields.Str(required=True) birth_year = fields.Integer(load_only=True) genre = fields.Str()

创建资源管理器和URL端点 (Create resource managers and URL endpoints)

The final piece of the puzzle is to create a resource manager and corresponding endpoint for each of the routes /artists and /artists/id.

难题的最后一步是为/ artists和/ artists / id的每条路线创建资源管理器和相应的端点。

Each resource manager is defined as a class that inherits from the Flask-REST-JSONAPI classes ResourceList and ResourceDetail.

每个资源管理器都定义为一个从Flask-REST-JSONAPI类ResourceListResourceDetail继承的类。

Here they take two attributes. schema is used to indicate the data abstraction layer the resource manager uses, and data_layer indicates the session and data model that will be used for the data layer.

在这里,它们具有两个属性。 schema用于指示资源管理器使用的数据抽象层,而data_layer指示将用于数据层的会话和数据模型。

Next, define api as an instance of Flask-REST-JSONAPI's Api class, and create the routes for the API with api.route(). This method takes three arguments - the data abstraction layer class, the endpoint name, and the URL path.

接下来,将api定义为Flask-REST-JSONAPI的Api类的实例,并使用api.route()为API创建路由。 此方法采用三个参数-数据抽象层类,端点名称和URL路径。

The last step is to write a main loop to launch the app in debug mode when the script is run directly. Debug mode is great for development, but it is not suitable for running in production.

最后一步是编写一个主循环,以在直接运行脚本时以调试模式启动应用程序。 调试模式非常适合开发,但不适用于生产环境。

# Create resource managers and endpointsfrom flask_rest_jsonapi import Api, ResourceDetail, ResourceListclass ArtistMany(ResourceList):    schema = ArtistSchema    data_layer = {'session': db.session,                  'model': Artist}class ArtistOne(ResourceDetail):    schema = ArtistSchema    data_layer = {'session': db.session,                  'model': Artist}api = Api(app)api.route(ArtistMany, 'artist_many', '/artists')api.route(ArtistOne, 'artist_one', '/artists/
')# main loop to run app in debug modeif __name__ == '__main__': app.run(debug=True)

发出GET和POST请求 (Make GET and POST requests)

Now you can start using the API to . This could be from a web browser, or from a command line tool like curl, or from within another program (e.g., a Python script using the Requests library).

现在,您可以开始使用API 。 这可能来自Web浏览器,或者来自诸如curl的命令行工具,也可能来自另一个程序(例如,使用Requests库的Python脚本)。

To launch the server, run the application.py script with:

要启动服务器,请使用以下命令运行application.py脚本:

$ python application.py

In your browser, navigate to .  You will see a JSON output of all the records in the database so far. Except, there are none.

在浏览器中,导航到 。 到目前为止,您将看到数据库中所有记录的JSON输出。 除了,没有。

To start adding records to the database, you can make a POST request. One way of doing this is from the command line using curl. Alternatively, you could use a tool like , or perhaps code up a simple HTML user interface that posts data using a form.

要开始将记录添加到数据库,您可以发出POST请求。 一种方法是从命令行使用curl。 另外,您可以使用类的工具,或者编写一个简单HTML用户界面,该界面使用表单发布数据。

With , from the command line:

在命令行中使用 :

curl -i -X POST -H 'Content-Type: application/json' -d '{"data":{"type":"artist", "attributes":{"name":"Salvador Dali", "birth_year":1904, "genre":"Surrealism"}}}' http://localhost:5000/artists

Now if you navigate to , you will see the record you just added. If you were to add more records, they would all show here as well, as this URL path calls the artists_many endpoint.

现在,如果您导航到 ,您将看到刚刚添加的记录。 如果要添加更多记录,它们也会在此处显示,因为此URL路径称为artists_many端点。

To view just a single artist by their id number, you can navigate to the relevant URL. For example, to see the first artist, try .

要仅通过其id号查看单个艺术家,您可以导航至相关URL。 例如,要查看第一个艺术家,请尝试 。

筛选和排序 (Filtering and sorting)

One of the neat features of the JSON API specification is the ability to return the response in more useful ways by defining some parameters in the URL. For instance, you can sort the results according to a chosen field, or filter based on some criteria.

JSON API规范的简洁功能之一是能够通过在URL中定义一些参数以更有用的方式返回响应。 例如,您可以根据所选字段对结果进行排序,也可以根据某些条件进行过滤。

Flask-REST-JSONAPI comes with this built in.

Flask-REST-JSONAPI内置于此。

To sort artists in order of birth year, just navigate to . In a web application, this would save you from needing to sort results on the client side, which could be costly in terms of performance and therefore impact the user experience.

要按出生年份的顺序对艺术家进行排序,只需导航至 。 在Web应用程序中,这将使您无需在客户端对结果进行排序,这可能会导致性能高昂并因此影响用户体验。

Filtering is also easy. You append to the URL the criteria you wish to filter on, contained in square brackets. There are three pieces of information to include:

过滤也很容易。 您将希望过滤的条件附加到URL上,并包含在方括号中。 共有三部分信息:

  • "name" - the field you are filtering by (e.g., birth_year)

    “名称”-您要过滤的字段(例如, birth_year )

  • "op" - the filter operation ("equal to", "greater than", "less than" etc.)

    “ op”-过滤器操作(“等于”,“大于”,“小于”等)
  • "val" - the value to filter against (e.g., 1900)

    “ val”-要过滤的值(例如1900)

For example, the URL below retrieves artists whose birth year is greater than 1900:

例如,下面的URL检索出生年份大于1900的艺术家:

This functionality makes it much easier to retrieve only relevant information when calling the API. This is valuable for improving performance, especially when retrieving potentially large volumes of data over a slow connection.

此功能使调用API时仅检索相关信息变得更加容易。 这对于提高性能非常有价值,尤其是在通过慢速连接检索潜在的大量数据时。

分页 (Pagination)

Another feature of the JSON API specification that aids performance is pagination. This is when large responses are sent over several "pages", rather than all in one go. You can control the page size and the number of the page you request in the URL.

有助于提高性能的JSON API规范的另一个功能是分页。 在这种情况下,大型响应是通过多个“页面”发送的,而不是一次性发送的。 您可以在URL中控制页面大小和您请求的页面数。

So, for example, you could receive 100 results over 10 pages instead of loading all 100 in one go. The first page would contain results 1-10, the second page would contain results 11-20, and so on.

因此,例如,您可能在10页内收到100个结果,而不是一次加载全部100个结果。 第一页将包含结果1-10,第二页将包含结果11-20,依此类推。

To specify the number of results you want to receive per page, you can add the parameter ?page[size]=X to the URL, where X is the number of results. Flask-REST-JSONAPI uses 30 as the default page size.

要指定每页要接收的结果数,可以在URL中添加参数?page [size] = X,其中X是结果数。 Flask-REST-JSONAPI使用30作为默认页面大小。

To request a given page number, you can add the parameter ?page[number]=X, where is the page number. You can combine both parameters as shown below:

要请求给定的页码,可以添加参数?page [number] = X,其中页码是。 您可以组合两个参数,如下所示:

This URL sets the page size to two results per page, and asks for the second page of results. This would return the third and fourth results from the overall response.

此URL将页面大小设置为每页两个结果,并要求第二页结果。 这将从总体响应中返回第三和第四结果。

人际关系 (Relationships)

Almost always, data in one table will be related to data stored in another. For instance, if you have a table of artists, chances are you might also want a table of artworks. Each artwork is related to the artist who created it.

几乎总是,一个表中的数据将与另一个表中的数据相关。 例如,如果您有艺术家桌,则可能还需要一张艺术品表。 每件艺术品都与创作它的艺术家有关。

The JSON API specification allows you to work with relational data easily, and the Flask-REST-JSONAPI lets you take advantage of this. Here, this will be demonstrated by adding an artworks table to the database, and including relationships between artist and artwork.

JSON API规范使您可以轻松处理关系数据,而Flask-REST-JSONAPI使您可以利用此优势。 在这里,将通过向数据库添加艺术品表并包括艺术家和艺术品之间的关系来证明这一点。

To implement the artworks example, it will be necessary to make a few changes to the code in application.py.

要实现艺术品示例,有必要对application.py的代码进行一些更改。

First, make a couple of extra imports, then create a new table which relates each artwork to an artist:

首先,进行一些额外的导入,然后创建一个新表,将每个艺术品与艺术家相关联:

from marshmallow_jsonapi.flask import Relationshipfrom flask_rest_jsonapi import ResourceRelationship# Define the Artwork tableclass Artwork(db.Model):    id = db.Column(db.Integer, primary_key=True)    title = db.Column(db.String)    artist_id = db.Column(db.Integer,         db.ForeignKey('artist.id'))    artist = db.relationship('Artist',        backref=db.backref('artworks'))

Next, rewrite the abstraction layer:

接下来,重写抽象层:

# Create data abstraction class ArtistSchema(Schema):    class Meta:        type_ = 'artist'        self_view = 'artist_one'        self_view_kwargs = {'id': '
'} self_view_many = 'artist_many' id = fields.Integer() name = fields.Str(required=True) birth_year = fields.Integer(load_only=True) genre = fields.Str() artworks = Relationship(self_view = 'artist_artworks', self_view_kwargs = {'id': '
'}, related_view = 'artwork_many', many = True, schema = 'ArtworkSchema', type_ = 'artwork')class ArtworkSchema(Schema): class Meta: type_ = 'artwork' self_view = 'artwork_one' self_view_kwargs = {'id': '
'} self_view_many = 'artwork_many' id = fields.Integer() title = fields.Str(required=True) artist_id = fields.Integer(required=True)

This defines an abstraction layer for the artwork table, and adds a relationship between artist and artwork to the ArtistSchema class.

这为艺术品表定义了一个抽象层,并将艺术家和艺术品之间的关系添加到ArtistSchema类。

Next, define new resource managers for accessing artworks many at once and one at a time, and also for accessing the relationships between artist and artwork.

接下来,定义新的资源管理器,以便一次访问多个艺术品,也可以访问艺术家和艺术品之间的关系。

class ArtworkMany(ResourceList):    schema = ArtworkSchema    data_layer = {'session': db.session,                  'model': Artwork}class ArtworkOne(ResourceDetail):    schema = ArtworkSchema    data_layer = {'session': db.session,                  'model': Artwork}class ArtistArtwork(ResourceRelationship):    schema = ArtistSchema    data_layer = {'session': db.session,                  'model': Artist}

Finally, add some new endpoints:

最后,添加一些新的端点:

api.route(ArtworkOne, 'artwork_one', '/artworks/
')api.route(ArtworkMany, 'artwork_many', '/artworks')api.route(ArtistArtwork, 'artist_artworks', '/artists/
/relationships/artworks')

Run application.py and trying posting some data from the command line via curl:

运行application.py并尝试通过curl从命令行发布一些数据:

curl -i -X POST -H 'Content-Type: application/json' -d '{"data":{"type":"artwork", "attributes":{"title":"The Persistance of Memory", "artist_id":1}}}' http://localhost:5000/artworks

This will create an artwork related to the artist with id=1.

这将创建与id=1的艺术家相关的艺术品。

In the browser, navigate to . This should show the artworks related to the artist with id=1. This saves you from writing a more complex URL with parameters to filter artworks by their artist_id field. You can quickly list all the relationships between a given artist and their artworks.

在浏览器中,导航到 。 这应该显示与id=1的艺术家有关的艺术品。 这使您artist_id编写带有参数的更复杂的URL,即可按其artist_id字段过滤艺术品。 您可以快速列出给定艺术家与其作品之间的所有关系。

Another feature is the ability to include related results in the response to calling the artists_one endpoint:

另一个功能是能够在调用artists_one端点的响应中包括相关结果:

This will return the usual response for the artists endpoint, and also results for each of that artist's artworks.

这将返回艺术家端点的通常响应,并返回该艺术家的每件艺术品的结果。

稀疏字段 (Sparse Fields)

One last feature worth mentioning - sparse fields. When working with large data resources with many complex relationships, the response sizes can blow up real fast. It is helpful to only retrieve the fields you are interested in.

值得一提的最后一项功能-稀疏字段。 当使用具有许多复杂关系的大型数据资源时,响应大小可能会Swift增大。 仅检索您感兴趣的字段会很有帮助。

The JSON API specification lets you do this by adding a fields parameter to the URL. For example URL below gets the response for a given artist and their related artworks. However, instead of returning all the fields for the given artwork, it returns only the title.

JSON API规范允许您通过向URL添加一个fields参数来做到这一点。 例如,下面的URL获取给定艺术家及其相关艺术作品的响应。 但是,它不返回给定图稿的所有字段,而是仅返回标题。

This is again very helpful for improving performance, especially over slow connections. As a general rule, you should only make requests to and from the server with the minimal amount of data required.

这对于提高性能(特别是在连接速度较慢的情况下)非常有帮助。 通常,您只应使用最少的数据量向服务器发出请求或从服务器发出请求。

结束语 (Final remarks)

The JSON API specification is a very useful framework for sending data between server and client in a clean, flexible format. This article has provided an overview of what you can do with it, with a worked example in Python using the Flask-REST-JSONAPI library.

JSON API规范是一个非常有用的框架,用于以干净,灵活的格式在服务器和客户端之间发送数据。 本文概述了如何使用它,并提供了一个使用Flask-REST-JSONAPI库的Python示例。

So what will you do next? There are many possibilities. The example in this article has been a simple proof-of-concept, with just two tables and a single relationship between them. You can develop an application as sophisticated as you like, and create a powerful API to interact with it using all the tools provided here.

那你接下来要做什么? 有很多可能性。 本文中的示例是一个简单的概念验证,只有两个表,并且它们之间只有一个关系。 您可以开发自己喜欢的复杂应用程序,并使用此处提供的所有工具创建强大的API与之交互。

Thanks for reading, and keep coding in Python!

感谢您的阅读,并继续使用Python编码!

翻译自:

python构建json

转载地址:http://mjuzd.baihongyu.com/

你可能感兴趣的文章
批量删除某些后缀结尾的文件
查看>>
二、VUE项目BaseCms系列文章:项目目录结构介绍
查看>>
leetcode289- Game of Life- medium
查看>>
开通博客
查看>>
Arduino编程器 USBasp USBtinyISP FT232-ISP 对比 区别
查看>>
RDLC交叉报表动态列空白页问题
查看>>
Python学习之字典集合篇
查看>>
多分类问题中,实现不同分类区域颜色填充的MATLAB代码(demo:Random Forest)
查看>>
同事是竞合关系不是零和关系
查看>>
python 获取当前运行的 class 和 方法的名字
查看>>
centos7 重启网卡失败
查看>>
springboot(一)注解
查看>>
07 Mybatis的多表查询1----1对多和多对1
查看>>
debian和ubuntu的sh dash bash
查看>>
java9-8 局部内部类
查看>>
数据库分页
查看>>
Centos6.8源码编译安装PHP7
查看>>
012 debug调试工具的指令
查看>>
慕课网消息的接收与响应3
查看>>
第三十二讲:UML类图(下)
查看>>