GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Python 3
  • Скачать Python
  • IDE
  • Скачать PyCharm
  • Django
  • Tkinter
  • Книги

This view

  • Original page
  • New address

GeezerVison is showing python-scripts.com — Создаем REST API в Python за пять минут

В этой статье мы рассмотрим новый фреймворк Arrested, который используется для создания REST API при помощи Python. Мы используем Docker, SQLAlchemy и прочие инструменты для создания API на тему Звездных Войн всего за пять минут!

Это первый пост в серии в будущей серии статей, нацеленных на помощь людям в построении REST API Python. Мы собрали коллекцию инструментов, которые помогут вам быстро начать и не слишком напрягаться на протяжении работы. В данном материале мы представим вам фреймворк Arrested, который используется для создания API при помощи Flask. Данный фреймворк нацелен сделать создание REST API безболезненным процессом. Подходит для быстрого использования в проектах, при этом легко расширяется для особых требований.

В данной статье мы рассмотрим

  1. Использование Cookie Cutter шаблона для установки приложения Flask вместе с базой данных SQLAlchemy ORM для взаимодействия с базой данных, Kim Mappers для сериализации и сортировки, хранилище Docker для среды разработки и пример пользовательского API;
  2. Создание ресурсов на тему Звездных Войн, для получения списков персонажей, создания новых персонажей, поиск персонажей по ID и наконец, обновление и удаление персонажа.

Список ресурсов инструментов, которые мы будем использовать

  • Docker – используется во всех наших примерах;
  • Git – для клонирования некоторых хранилищ;
  • Cookie Cutter – инструмент для создания проектных шаблонов;
  • Flask – наш фреймворк Arrested работает на Flask, микро-фреймворке для Python, который в свою очередь базируется на Werkzeug;
  • Kim – фреймворк Python для сортировки и сериализации;
  • Arrested – фреймворк для быстрого создания API при помощи Flask

Создаем приложение ?

Мы используем Cookie Cutter для быстрого создания базовой структуры приложения и избегания всех скучных этапов перед созданием ресурса, который будет выдавать персонажей из нашей базы данных «Звездных Войн«. Если вы не хотите использовать Cookie Cutter,  вы можете скачать готовую структуру здесь.

Shell
1
2
3
4
$ cookiecutter gh:mikeywaites/arrested-cookiecutter
project_name [Arrested Users API]: star wars
project_slug [star-wars]:
package_name [star_wars]:

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

Shell
1
2
3
$ cd star_wars
$ docker-compose build
$ docker-compose run --rm api flask db upgrade

Есть вопросы по Python?

На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!

Python Форум Помощи

Telegram Чат & Канал

Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!

Чат
Канал

Паблик VK

Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!

Подписаться

Теперь запускаем контейнер API и создаем запрос к конечной точке, чтобы убедиться в том, что все работает корректно.

Shell
1
2
3
4
5
$ docker-compose up api
$ curl -u admin:secret localhost:8080/v1/users | python -m json.tool
{
    "payload": []
}

Ву а ля. Мы создали рабочий REST API за 5 минут.

Конечно, мы получили рабочий REST API, но вся тяжелая работа уже была сделана за вас, но вы все еще понятия не имеет, как использовать Arrested для создания API в Python. В следующем разделе мы рассмотрим, как создавать базовый API для нашей базы данных персонажей Звездных Войн.

Создаем ресурс персонажей

Теперь, когда у нас есть установленное приложение, мы можем начать создание Python API наших персонажей. Мы добавим конечные точки, которые позволяют клиенту получать список персонажей, создавать новых, выполнять поиск персонажей, обновлять и удалять персонажей. Перед созданием нового API нам нужно создать модель Character и CharacterMapper.

Shell
1
2
3
$ touch star_wars/models/character.py
$ touch star_wars/apis/v1/characters.py
$ touch star_wars/apis/v1/mappers/character.py

Начнем с очень простого объекта Character, который нужно назвать.

Python
1
2
3
4
5
6
7
8
9
10
from .base import db, BaseMixin
 
__all__ = ['Character']
 
 
class Character(BaseMixin, db.Model):
  
  __tablename__ = 'character'
  
  name = db.Column(db.Unicode(255), nullable=False)

Далее нам нужно импортировать модель в models/__init__.py

Shell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import datetime
 
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.ext.declarative import declared_attr
 
db = SQLAlchemy()
 
 
class BaseMixin(object):
 
    @declared_attr
    def id(cls):
 
        return db.Column(db.Integer, primary_key=True)
 
    @declared_attr
    def created_at(cls):
 
        return db.Column(db.DateTime, default=datetime.datetime.utcnow)
 
    @declared_attr
    def updated_at(cls):
 
        return db.Column(db.DateTime, default=datetime.datetime.utcnow)
 
 
from .user import *
from .character import *

Создаем миграцию для новой модели

Python
1
2
3
4
5
6
7
8
$ docker-compose run --rm api flask db revision "character model"
INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.autogenerate.compare] Detected added table 'character'
  Generating /opt/code/star_wars/migrations/d7d80c02d806_character_model.py ... done
 
# Выполняем файлы миграции для создание таблиц в базе данных
$ docker-compose run --rm api flask db upgrade

Редактируем файл «star_wars/apis/v1/mappers/character.py» который мы ранее создали для объекта CharacterMapper. Он отвечает за сериализацию и сортировку наших данных в API.

Python
1
2
3
4
5
6
7
8
9
10
11
12
from kim import field
 
from .base import BaseMapper
 
from star_wars.models import Character
 
 
class CharacterMapper(BaseMapper):
 
    __type__ = Character
 
    name = field.String()

Теперь импортируем мэппер в модуль mapper/__init__.py

Python
1
2
from .user import UserMapper
from .character import CharacterMapper

Великолепно! Теперь у нас есть модель базы данных и способ её сериализации, давайте создадим конечную точку, которая позволяет нашим клиентам API получить список персонажей. Добавьте следующий код в созданный нами файл «api/v1/characters.py«.

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from arrested import Resource
from arrested.contrib.kim_arrested import KimEndpoint
from arrested.contrib.sql_alchemy import DBListMixin
 
from star_wars.models import db, Character
from .mappers import CharacterMapper
 
characters_resource = Resource('characters', __name__, url_prefix='/characters')
 
 
class CharactersIndexEndpoint(KimEndpoint, DBListMixin):
 
    name = 'list'
    many = True
    mapper_class = CharacterMapper
    model = Character
 
    def get_query(self):
 
        stmt = db.session.query(Character)
        return stmt
 
characters_resource.add_endpoint(CharactersIndexEndpoint)

Теперь нам нужно зарегистрировать наш Resource при помощи объекта Arrested API. Откройте модуль «api/v1/__init__.py» и импортируйте characters_resource. Укажите «defer=True«, чтобы Arrested отложил регистрацию маршрутов с Flask, пока объект API не инициализируется.

Python
1
2
3
4
5
6
7
8
from arrested import ArrestedAPI
from .users import users_resource
from .characters import characters_resource
from .middleware import basic_auth
 
api_v1 = ArrestedAPI(url_prefix='/v1', before_all_hooks=[basic_auth])
api_v1.register_resource(users_resource, defer=True)
api_v1.register_resource(characters_resource, defer=True)

Давайте проведем тестовый запуск нашего API. Убедитесь в том, что контейнер Docker запущен и затем используйте команду curl, которая выполнит GET запрос к ресурсу персонажей.

Shell
1
2
3
4
5
6
$ docker-compose up api
$ curl -u admin:secret localhost:8080/v1/characters | python -m json.tool
{
    "payload": []
}

Чудесно! Мы получили ответ, но не получили ни одного объекта персонажа из нашей базы данных, но это пока что. Теперь нам нужно получить способность создавать новых персонажей при помощи DBCreateMixin

Наш модуль characters.py теперь выглядит следующим образом:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from arrested import Resource
from arrested.contrib.kim_arrested import KimEndpoint
from arrested.contrib.sql_alchemy import DBListMixin, DBCreateMixin
 
from star_wars.models import db, Character
from .mappers import CharacterMapper
 
characters_resource = Resource('characters', __name__, url_prefix='/characters')
 
 
class CharactersIndexEndpoint(KimEndpoint, DBListMixin, DBCreateMixin):
 
    name = 'list'
    many = True
    mapper_class = CharacterMapper
    model = Character
 
    def get_query(self):
 
        stmt = db.session.query(Character)
        return stmt
 
 
characters_resource.add_endpoint(CharactersIndexEndpoint)

Все, что нам нужно для поддержки создания нашего объекта Character – это добавить DBCreateMixin в CharactersIndexEndpoint. Интеграция Arrested с SQLAlchemy и Kim позволяет обработать входящие данные, конвертируя вводные данные JSON Python в объект Character, с последующим сохранением в базе данных. Давайте пойдем дальше и создадим Персонажа.

Shell
1
2
3
4
5
6
7
8
9
10
curl -u admin:secret -H "Content-Type: application/json" -d '{"name":"Darth Vader"}' -X POST localhost:8080/v1/characters | python -m json.tool
 
{
    "payload": {
        "created_at": "2017-11-22T08:18:26.044931",
        "id": 1,
        "name": "Darth Vader",
        "updated_at": "2017-11-22T08:18:26.044958"
    }
}

Дарт Вейдер удачно создан! Теперь, если мы выполним запрос GET, как мы делали это ранее в нашем API, то наш Дарт Вейдер должен вернуться.

Shell
1
2
3
4
5
6
7
8
9
10
11
12
curl -u admin:secret localhost:8080/v1/characters | python -m json.tool
 
{
    "payload": [
        {
            "created_at": "2017-11-22T08:18:26.044931",
            "id": 1,
            "name": "Darth Vader",
            "updated_at": "2017-11-22T08:18:26.044958"
        }
    ]
}

Теперь нам нужно установить конечную точку, которая позволяет клиентам получить персонажа, используя ID ресурса.

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
from arrested import Resource
from arrested.contrib.kim_arrested import KimEndpoint
from arrested.contrib.sql_alchemy import DBListMixin, DBCreateMixin, DBObjectMixin
 
from star_wars.models import db, Character
from .mappers import CharacterMapper
 
characters_resource = Resource('characters', __name__, url_prefix='/characters')
 
 
class CharactersIndexEndpoint(KimEndpoint, DBListMixin, DBCreateMixin):
 
    name = 'list'
    many = True
    mapper_class = CharacterMapper
    model = Character
 
    def get_query(self):
 
        stmt = db.session.query(Character)
        return stmt
 
 
class CharacterObjectEndpoint(KimEndpoint, DBObjectMixin):
 
    name = 'object'
    url = '/<string:obj_id>'
    mapper_class = CharacterMapper
    model = Character
 
    def get_query(self):
 
        stmt = db.session.query(Character)
        return stmt
 
 
characters_resource.add_endpoint(CharactersIndexEndpoint)
characters_resource.add_endpoint(CharacterObjectEndpoint)

Мы добавили новую конечную точку – CharacterObjectEndpoint и зарегистрировали её в ресурсе персонажей. DBObjectMixin позволяет нам получать ресурс по ID, обновлять тот или иной ресурс, а также удалить ресурс. Давайте попробуем!

 

Shell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# Получаем персонажа с ID 1
curl -u admin:secret localhost:8080/v1/characters/1 | python -m json.tool
 
{
    "payload": {
        "created_at": "2017-11-22T08:18:26.044931",
        "id": 1,
        "name": "Darth Vader",
        "updated_at": "2017-11-22T08:18:26.044958"
    }
}
 
# После этого мы можем обновить имя персонажа
curl -u admin:secret -H "Content-Type: application/json" -d '{"id": 1, "name":"Anakin Skywalker"}' -X PUT localhost:8080/v1/characters/1 | python -m json.tool
 
{
    "payload": {
        "created_at": "2017-11-22T08:18:26.044931",
        "id": 1,
        "name": "Anakin Skywalker",
        "updated_at": "2017-11-22T08:18:26.044958"
    }
}
 
# И наконец, мы можем удалить персонажа
curl -u admin:secret -X DELETE localhost:8080/v1/characters/1

Что-ж, вот и все. Это было введение в создание REST API в Python при помощи Arrested. Следите за дальнейшими обновлениями, у нас готовится много чего полезного!

Vasile Buldumac

Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.

E-mail: [email protected]

Образование
Universitatea Tehnică a Moldovei (utm.md)

  • 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
  • 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.