Рубрики
Без рубрики

Как построить API JSON с Python

Автор оригинала: Peter Gleeson.

Спецификация JSON API Мощный способ обеспечить связь между клиентом и сервером. Он определяет структуру запросов и ответов, отправленных между двумя, используя формат JSON.

В качестве формата данных JSON имеет преимущества легкого и читаемого. Это делает очень легко работать быстро и продуктивно. Спецификация предназначена для минимизации количества запросов и объема данных, которые требуют отправки между клиентом и сервером.

Здесь вы можете узнать, как создать базовый JSON API с помощью Python и Flask. Затем остальная часть статьи покажет вам, как попробовать некоторые из функций, которые предлагают спецификацию JSON API.

Флэк – библиотека Python Это обеспечивает «микро-каркас» для веб-разработки. Это отлично подходит для быстрой разработки, так как он поставляется с простым, но-расширяемым основным функционалом.

Действительно простой пример того, как отправить json-подобное ответу с использованием колбы, показан ниже:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def example():
   return '{"name":"Bob"}'

if __name__ == '__main__':
    app.run()

Эта статья будет использовать два дополнителя для колба:

  • Flask-Rest-Jsonapi Поможет разработать API, который тесно следует описать спецификацию API JSON.
  • Flask-Sqlalchemy будет использовать SQLalchemy Чтобы создать и взаимодействовать с простой базой данных очень простой.

Большая картинка

Конечная цель состоит в том, чтобы создать API, который позволяет взаимодействию на стороне клиента с базовой базой данных. Существует пару слоев между базой данных и клиентом – слой абстракции данных и слой менеджера ресурсов.

Вот обзор участвующих шагов:

  1. Определите базу данных с помощью Flask-Sqlalchemy
  2. Создайте абстракцию данных с Зефир-jsonapi
  3. Создайте менеджеры ресурсов с Flask-Rest-Jsonapi
  4. Создайте конечные точки URL и запустите сервер с колбой

Этот пример будет использовать простую схему, опискующую современные художники и их отношения для разных произведений искусства.

Установите все

Прежде чем начать, вам нужно будет настроить проект. Это включает в себя создание рабочей области и виртуальной среды, установив необходимые модули и создавая основные файлы Python и базы данных для проекта.

Из командной строки создайте новый каталог и перейдите внутрь.

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

Это хорошая практика до Создать виртуальную среду Для каждого из ваших проектов Python. Вы можете пропустить этот шаг, но это настоятельно рекомендуется.

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

Как только ваша виртуальная среда была создана и активирована, вы можете установить модули, необходимые для этого проекта.

$ pip install flask-rest-jsonapi flask-sqlalchemy

Все, что вам нужно будет установлено как требования для этих двух расширений. Это включает в себя саму колбу и SQLALCHEMY.

Следующим шагом является создание файла Python и базы данных для проекта.

$ touch application.py artists.db

Создайте схему базы данных

Здесь вы начнете модифицировать application.py Чтобы определить и создать схему базы данных для проекта.

Открыть application.py В вашем предпочтительном текстовом редакторе. Начните, импортируя некоторые модули. Для ясности модули будут импортированы, как вы идете.

Далее создайте объект под названием приложение в качестве экземпляра класса колба.

После этого используйте SQLALCHEMY, чтобы подключиться к созданному вами файлу базы данных. Последний шаг – определить и создать таблицу под названием Художники Отказ

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

# Create a new Flask application
app = Flask(__name__)

# Set up SQLAlchemy
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////artists.db'
db = SQLAlchemy(app)

# Define a class for the Artist table
class 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 table
db.create_all()

Создание слоя абстракции

Следующий шаг использует Зефир-jsonapi Модуль для создания логических данных абстракции по поводу таблиц только что определено.

Причина создания этого уровня абстракции проста. Это дает вам больше контроля над тем, как ваши базовые данные выставляются через API. Подумайте об этом слое в качестве объектива, через которую клиент API может ясно просматривать базовые данные, и только биты, которые им нужно увидеть.

В приведенном ниже коде слой абстракции данных определяется как класс, который наследует от Marshmallow-Jsonapi’s Схема класс. Он обеспечит доступ через API как для одиночных записей, так и для нескольких записей от таблицы художников.

Внутри этого блока Мета класс определяет некоторые метаданные. В частности, название конечной точки URL для взаимодействия с одиночными записями будет Artist_One , где каждый художник будет идентифицирован параметром URL Отказ Название конечной точки для взаимодействия со многими записями будет Artist_Many Отказ

Остальные атрибуты, определенные относится к столбцам в таблице художников. Здесь вы можете контролировать дальше, как каждый выставлен через API.

Например, при создании последующих запросов добавить новые артисты в базу данных, вы можете убедиться, что Имя поле обязательно, установив требуется = правда Отказ

И если по какой-либо причине вы не хотели Рождение_ИЭРА Поле, которое будет возвращено при получении запросов, вы можете указать так, установив load_only = true Отказ

from marshmallow_jsonapi.flask import Schema
from marshmallow_jsonapi import fields

# Create data abstraction layer
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()

Создайте менеджеры ресурсов и конечные точки URL

Окончательный кусок головоломки состоит в том, чтобы создать диспетчер ресурсов и соответствующую конечную точку для каждой из маршрутов/художников и/артистов/ID.

Каждый диспетчер ресурсов определяется как класс, который наследуется от классов Flask-Rest-Jsonapi Ресурс и ResourceSetail Отказ

Здесь они принимают два атрибута. Схема Используется для указания уровня абстракции данных, используемый диспетчером ресурсов, а data_layer Указывает, что сеанс и модель данных, которые будут использоваться для слоя данных.

Далее определите API Как экземпляр колб-ресторанов – Jsonapi’s API Класс и создайте маршруты для API с API.ROUTE () Отказ Этот метод принимает три аргумента – класс слоя абстракции данных, имя конечного точка и путь URL.

Последний шаг – написать основной цикл, чтобы запустить приложение в режиме отладки, когда скрипт работает напрямую. Режим отладки отлично подходит для разработки, но он не подходит для работы в производстве.

# Create resource managers and endpoints

from flask_rest_jsonapi import Api, ResourceDetail, ResourceList

class 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 mode
if __name__ == '__main__':
    app.run(debug=True)

Сделайте запросы Get и Post

Теперь вы можете начать использовать API для Сделать HTTP-запросы Отказ Это может быть из веб-браузера или из инструмента командной строки, такого как Curl, или из другой программы (например, скрипт Python с использованием библиотеки запросов).

Чтобы запустить сервер, запустите application.py Сценарий с:

$ python application.py

В вашем браузере перейдите к http://localhost: 5000/Художники Отказ Вы увидите вывод JSON всех записей в базе данных. Кроме того, нет.

Чтобы начать добавление записей в базу данных, вы можете сделать запрос на пост. Один из способов сделать это из командной строки, используя CURL. В качестве альтернативы, вы можете использовать инструмент, похожий на Бессонница Или, возможно, код простого пользовательского интерфейса HTML, который публикует данные, использующие форму.

С Curl , из командной строки:

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

Теперь, если вы перейдите к http://localhost: 5000/Художники , вы увидите запись, которую вы только что добавили. Если бы вы могли добавить больше записей, они все также будут отображаться здесь, так как этот путь URL вызывает Artists_Many конечная точка.

Чтобы посмотреть просто один художник по их ID Номер, вы можете перейти к соответствующему URL. Например, чтобы увидеть первый художник, попробуйте http://localhost: 5000/Художники/1 Отказ

Фильтрация и сортировка

Одной из аккуратных особенностей спецификации API JSON является возможность более полезных способов возврата отклика, определяя некоторые параметры в URL. Например, вы можете отсортировать результаты в соответствии с выбранным полем или фильтром на основе некоторых критериев.

Flask-Rest-Jsonapi поставляется с этим встроенным.

Сортировать исполнители в порядке рождения года, просто перейдите к http://localhost: 5000/Художники? Сортировать = onity_year Отказ В веб-приложении это спасит вас от необходимости сортировки результатов на стороне клиента, что может быть дорогостоящим с точки зрения производительности и, следовательно, влияет на пользовательский опыт.

Фильтрация также легко. Вы добавите к URL-адресу критерии, которые вы хотите фильтровать, содержащиеся в квадратных скобках. Есть три части информации, чтобы включить:

  • «Имя» – поле вы фильтруете (например, Рождение_ИЭРА )
  • «OP» – операция фильтра («равна», «больше», «меньше» и т. Д.)
  • «Val» – ценность фильтрации против (например, 1900)

Например, URL ниже извлекает художников, чьи год рождения больше 1900:

http://localhost:5000/artists?filter=[{“name”:”birth_year”,”op”:”gt”,”val”:1900}]

Эта функциональность упрощает намного проще для получения только соответствующей информации при вызове API. Это ценно для улучшения производительности, особенно при получении потенциально больших объемов данных по медленной связи.

Пагинация

Еще одна особенность спецификации API JSON, что производительность СПИДа является пегирование. Это когда большие ответы отправляются на несколько «страниц», а не все в одном. Вы можете управлять размером страницы и количество страницы, которую вы запросите в URL.

Таким образом, например, вы можете получить 100 результатов более 10 страниц вместо загрузки все 100 в один. Первая страница будет содержать результаты 1-10, вторая страница будет содержать результаты 11-20 и так далее.

Чтобы указать количество результатов, которые вы хотите получить на странице, вы можете добавить параметр на URL-адрес, где X – количество результатов. Flask-Rest-Jsonapi использует 30 в качестве размера страницы по умолчанию.

Чтобы запросить данный номер страницы, вы можете добавить параметр, где номер страницы. Вы можете объединить оба параметра, как показано ниже:

http://localhost:5000/artists?page[size]=2&page[number]=2

Этот URL устанавливает размер страницы до двух результатов на страницу и запрашивает вторую страницу результатов. Это вернет третий и четвертый результаты от общего ответа.

Отношения

Почти всегда данные в одной таблице будут связаны с данными, хранящимися в другом. Например, если у вас есть таблица художников, шансы вы можете также захотете таблицу произведений произведений работы. Каждое произведение искусства связано с художником, который создал его.

Спецификация API JSON позволяет легко работать с реляционными данными, и Flask-Rest-Jsonapi позволяет вам воспользоваться этим. Здесь это будет продемонстрировано путем добавления таблицы произведений искусства в базу данных и включая отношения между художником и произведениями искусства.

Для реализации примера произведений искусства необходимо будет внести несколько изменений в код в application.py Отказ

Во-первых, сделайте пару дополнительных импорта, а затем создайте новую таблицу, которая связана с каждыми произведениями художника:

from marshmallow_jsonapi.flask import Relationship
from flask_rest_jsonapi import ResourceRelationship


# Define the Artwork table
class 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'))

Далее переписать уровень абстракции:

# 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)

Это определяет слой абстракции для таблицы искусства, и добавляет отношения между художником и произведением искусства к ArtiSschema класс.

Далее определите новые менеджеры ресурсов для доступа к произведениям искусства многих сразу и по одному за раз, а также для доступа к отношениям между художником и произведением искусства.

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}

Наконец, добавьте новые конечные точки:

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

Беги 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

Это создаст произведение, связанные с художником с ID = 1 Отказ

В браузере перейдите к http://localhost: 5000/Художники/1/Отношения/Artworks Отказ Это должно показать художественные работы, связанные с художником с ID = 1 Отказ Это спасает вас от написания более сложного URL-адреса с параметрами для фильтрации художественных работ по их Artist_id поле. Вы можете быстро перечислить все отношения между данным художником и их произведениями искусства.

Другая функция – это возможность включить связанные результаты в ответ на вызов Artists_One Конечная точка:

http://localhost:5000/artists/1?include=artworks

Это вернет обычный ответ для конечной точки художников, а также приводит к каждому из этих произведений художника.

Редкие поля

Одна последняя функция стоит упомянуть – редкие поля. При работе с большим ресурсами данных со многими сложными отношениями размеры ответа могут взорвать реально быстро. Это полезно только получить только поля, которые вас интересуют.

Спецификация JSON API позволяет вам сделать это, добавив параметр поля на URL-адрес. Например, URL ниже получает ответ для данного художника и их связанных произведений. Однако вместо того, чтобы возвращать все поля для данного произведения искусства, он возвращает только название.

http://localhost:5000/artists/1?include=artworks&fields[artwork]=title

Это снова очень полезно для улучшения производительности, особенно за медленные соединения. Как правило, вы должны сделать только запросы на сервер только с минимальным количеством необходимых данных.

Последние замечания

Спецификация API JSON – это очень полезная структура для отправки данных между сервером и клиентом в чистом виде, гибком формате. Эта статья предоставила обзор того, что вы можете сделать с ним, с работающим приведением в Python с использованием библиотеки Flask-Rest-Jsonapi.

Так что вы будете делать дальше? Есть много возможностей. Примером в этой статье была простая доказательство концепции, только с двумя столами и единой связь между ними. Вы можете разработать приложение как утонченное, как вам нравится, и создайте мощные API, чтобы взаимодействовать с ним, используя все инструменты, предоставляемые здесь.

Спасибо за чтение и продолжайте кодирование в Python!