Автор оригинала: Mide Olarewaju.
В течение некоторого времени я работал с Python, но недавно мне довелось попробовать Flask, поэтому я почувствовал, что было бы неплохо написать об этом. В этой статье я расскажу о Flask и о том, как вы можете использовать его для создания Restful API.
Flask-это микрорамка на основе Python, которая позволяет быстро создавать веб-приложения; “микро” в микрорамке просто означает, что Flask стремится сохранить ядро простым, но расширяемым .
Что такое ОТДЫХ?
REST – это аббревиатура RE presentational S tate T ransfer. Это архитектурный стиль и подход к коммуникациям, который часто используется при разработке веб – сервисов.
REST веб-сервисы-это способ обеспечения взаимодействия между компьютерными системами в Интернете. Веб-службы, совместимые с REST, позволяют запрашивающим системам получать доступ к текстовым представлениям веб-ресурсов и манипулировать ими с помощью единого и предопределенного набора операций без сохранения состояния.
В этом руководстве вы познакомитесь с созданием API Restful с помощью Flask в сочетании с другими расширениями – Flask-RESTful, flask_migrate, marshmallow и т. Д. В конце вы создадите простой API для комментариев. API будет иметь конечные точки, которые можно использовать для добавления категории
, просмотра категорий
, обновления категории
, удаления категории
, добавления комментариев
и просмотра комментариев
.
Flask не выходит из коробки со всеми расширениями, необходимыми для создания полного API fledge. Однако есть много расширений, которые можно подключить к Flask, чтобы вы могли создавать потрясающие API.
В конце этого руководства у вас должны быть доступны конечные точки этого API:
GET –
/api/Category
– Получение всех категорийPOST –
/api/Категория
– Добавить новую категориюPUT –
/api/Category
– Обновление категорииУДАЛИТЬ –
/api/Категория
– Удалить категориюGET –
/api/Comment
– Получение всех сохраненных комментариевСООБЩЕНИЕ –
/api/Комментарий
– Добавить новый комментарий
Прежде Чем Вы Начнете
Убедитесь, что в вашей системе установлен Python3.x .
Для этого урока мы будем использовать PostgreSQL database. Установите базу данных Postgres, если она еще не установлена.
Убедитесь, что virtualenv установлен в вашей системе.
Шаг 0: Настройка приложения
- Во-первых, создайте структуру приложения в любом месте вашей системы:
project/ ├── app.py ├── migrate.py ├── Model.py ├── requirements.txt ├── resources │ └── Hello.py └── run.py
Если вы предпочитаете командную строку для создания папок и файлов, вы можете использовать следующую команду:
# Create folders $ mkdir project && cd project && mkdir resources # Create files $ touch app.py migrate.py Model.py requirements.txt run.py config.py && cd resources && touch Hello.py && cd ../
Затем откройте терминал и компакт-диск (изменить каталог) в корневую папку приложения –
project
.Затем создайте и активируйте виртуальную среду .
virtualenv-это инструмент для создания изолированных сред Python. virtualenv создает папку, содержащую все необходимые исполняемые файлы для использования пакетов, необходимых проекту Python.
Создает виртуальную среду
$ python3.6 -m venv env
ОПЕРАЦИОННАЯ:
$ python -m venv env
Используемая команда зависит от того, какая из них связана с вашей установкой python3.
Активирует виртуальную среду
$ source env/bin/activate
Добавьте следующие расширения в requirements.txt
:
flask==0.12.2 flask_restful==0.3.6 flask_script==2.0.6 flask_migrate==2.1.1 marshmallow==2.14.0 flask_sqlalchemy==2.3.2 flask_marshmallow==0.8.0 marshmallow-sqlalchemy==0.13.2 psycopg2==2.7.5
Приведенный выше файл содержит все расширения python, которые будет использовать наш API.
колба – Это микрорамка для Python
flask_restful – Это расширение для Flask, которое добавляет поддержку для быстрого создания API REST.
flask_script – Это расширение, которое обеспечивает поддержку написания внешних сценариев в Flask.
flask_migrate – Это расширение, которое обрабатывает миграции баз данных SQLAlchemy для приложений Flask с использованием перегонного куба.
marshmallow – Это библиотека ORM/ODM/framework-agnostic для преобразования сложных типов данных, таких как объекты, в собственные типы данных Python и из них. Мы будем использовать это для проверки. Это используется для сериализации и десериализации объектов.
flask_sqlalchemy – Это расширение для Flask, которое добавляет поддержку SQLAlchemy.
flask_marshmallow – Это уровень интеграции для Flask и marshmallow (библиотека сериализации/десериализации объектов), который добавляет дополнительные функции в marshmallow.
marshmallow-sqlalchemy – Это добавляет дополнительные функции в marshmallow.
psycopg – Это адаптер PostgreSQL для языка программирования Python.
Шаг 1: Установите все зависимости:
С вашего терминала убедитесь, что вы находитесь в корневой папке проекта, а затем выполните следующую команду:
$ pip install -r requirements.txt
Это позволит загрузить и установить все расширения в requirements.txt
.
Шаг 2: Настройка конфигурации
Добавьте следующий код в config.py
:
import os # You need to replace the next values with the appropriate values for your configuration basedir = os.path.abspath(os.path.dirname(__file__)) SQLALCHEMY_ECHO = False SQLALCHEMY_TRACK_MODIFICATIONS = True SQLALCHEMY_DATABASE_URI = "postgresql://username:password@localhost/database_name"
Здесь мы определили некоторую конфигурацию, которую будет использовать API. Мы также используем базу данных PostgreSQL. Если вы предпочитаете другие базы данных, вам просто нужно соответствующим образом изменить значение.
Пример: если вы хотите использовать SQLite
, вы должны изменить эту строку следующим образом::
SQLALCHEMY_DATABASE_URI = "sqlite:///app.db"
Убедитесь, что вы изменили вышеуказанные параметры с соответствующими значениями для вашей конфигурации. Измените имя пользователя
и пароль
на правильные учетные данные базы данных.
Шаг 3: Создайте точки входа в API
Добавьте следующий код в app.py
:
from flask import Blueprint from flask_restful import Api from resources.Hello import Hello api_bp = Blueprint('api', __name__) api = Api(api_bp) # Route api.add_resource(Hello, '/Hello')
Здесь мы импортировали Blueprint
из flask, а также Api
из flask_restful. Импортированный Api
добавит в flask некоторую функциональность, которая поможет нам добавить маршруты и упростить некоторые процессы.
api_bp('api', __name__)
– создает схему, которая позже будет зарегистрирована в приложении.
api.add_resource(Hello, '/Hello')
– создает маршрут – /Hello
. add_resource принимает два параметра – Hello
и Hello/|, где
Hello - это класс, который мы импортировали, и
Hello |/- это маршрут, который мы определили для этого ресурса.
Теперь давайте создадим класс Hello
, о котором мы упоминали выше. Добавьте следующий код в – resources/Hello.py
:
from flask_restful import Resource class Hello(Resource): def get(self): return {"message": "Hello, World!"}
В классе Hello мы определили функцию – get
. Это означает, что любой запрос GET на конечной точке /Hello
будет попадать в эту функцию.
Поэтому, если вам нужен метод POST, у вас будет что-то вроде:
def post(self): return {"message": "Hello, World!"}
Наконец, добавьте следующий код в run.py
:
from flask import Flask def create_app(config_filename): app = Flask(__name__) app.config.from_object(config_filename) from app import api_bp app.register_blueprint(api_bp, url_prefix='/api') from Model import db db.init_app(app) return app if __name__ == "__main__": app = create_app("config") app.run(debug=True)
Шаг 4: Запуск сервера
С вашего терминала убедитесь, что вы находитесь в корневой папке приложения, а затем выполните эту команду:
$ python run.py
Если на данный момент все идет нормально, у вас должен быть вывод, как показано ниже:
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) * Restarting with stat * Debugger is active! * Debugger PIN: 136-695-873
Теперь посетите URL-адрес(http://127.0.0.1:5000/api/Hello), вы должны увидеть вывод, как показано ниже:
{ "hello": "world" }
Потрясающе!
Шаг 5: Создание моделей.
Следующий шаг – написать наши модели. Flask предоставляет разработчикам мощь и гибкость ORM SQLAlchemy для управления данными приложения и запроса к ним. ORM расшифровывается как Object Relational Mapper, это инструмент, который позволяет разработчикам хранить и извлекать данные с использованием объектно-ориентированных подходов и решает проблему несоответствия импеданса объектно-реляционных данных.
Кроме того, Flask-SQLAlchemy-это расширение, которое обеспечивает поддержку ORM SQLAlchemy в рамках Flask.
В … Model.py
файл, добавьте в него следующий код:
from flask import Flask from marshmallow import Schema, fields, pre_load, validate from flask_marshmallow import Marshmallow from flask_sqlalchemy import SQLAlchemy ma = Marshmallow() db = SQLAlchemy() class Comment(db.Model): __tablename__ = 'comments' id = db.Column(db.Integer, primary_key=True) comment = db.Column(db.String(250), nullable=False) creation_date = db.Column(db.TIMESTAMP, server_default=db.func.current_timestamp(), nullable=False) category_id = db.Column(db.Integer, db.ForeignKey('categories.id', ondelete='CASCADE'), nullable=False) category = db.relationship('Category', backref=db.backref('comments', lazy='dynamic' )) def __init__(self, comment, category_id): self.comment = comment self.category_id = category_id class Category(db.Model): __tablename__ = 'categories' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(150), unique=True, nullable=False) def __init__(self, name): self.name = name class CategorySchema(ma.Schema): id = fields.Integer() name = fields.String(required=True) class CommentSchema(ma.Schema): id = fields.Integer(dump_only=True) category_id = fields.Integer(required=True) comment = fields.String(required=True, validate=validate.Length(1)) creation_date = fields.DateTime()
Здесь у нас есть две модели – Комментарий
и Категория
класс. Этот класс определяет структуру таблицы. __имя таблицы__
используется для объявления имени таблицы, связанного с этой моделью.
Мы также определили столбцы для нашей таблицы, используя, например:
id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(150), unique=True, nullable=False)
id
и name
являются столбцами таблицы, а значение после =
определяет структуру столбцов. Вы можете прочитать больше о создании схемы таблицы здесь
Далее для проверки используются схемы Category
и Comment Schema
. Здесь мы определили некоторые правила (например: required=True
). Вы можете прочитать больше здесь
Шаг 6: Запуск миграций
В migrate.py
файл добавьте в него следующий код:
from flask_script import Manager from flask_migrate import Migrate, MigrateCommand from Model import db from run import create_app app = create_app('config') migrate = Migrate(app, db) manager = Manager(app) manager.add_command('db', MigrateCommand) if __name__ == '__main__': manager.run()
В приведенном выше коде мы создали команду для запуска миграции из командной строки.
Миграции
Миграции подобны контролю версий для вашей базы данных, позволяя вашей команде легко изменять и совместно использовать схему базы данных приложения. Если вам когда-либо приходилось просить товарища по команде вручную добавить столбец в схему локальной базы данных, вы столкнулись с проблемой, которую решают миграции баз данных. В этом уроке мы используем расширение колбы – миграция колбы для достижения этой цели.
- Запустите инициализацию миграции, используя команду db init следующим образом:
$ python migrate.py db init
Creating directory /home/user/Desktop/pylinone/migrations ... done Creating directory /home/user/Desktop/pylinone/migrations/versions ... done Generating /home/user/Desktop/pylinone/migrations/alembic.ini ... done Generating /home/user/Desktop/pylinone/migrations/README ... done Generating /home/user/Desktop/pylinone/migrations/env.py ... done Generating /home/user/Desktop/pylinone/migrations/script.py.mako ... done Please edit configuration/connection/logging settings in '/home/user/Desktop/pylinone/migrations/alembic.ini' before proceeding.
Сценарий также создал новую подпапку миграции в папке с подпапкой версий и многими другими файлами.
Запустите второй сценарий, который заполнит сценарий миграции обнаруженными изменениями в моделях. В этом случае мы впервые заполняем сценарий миграции, и, следовательно, сценарий миграции создаст таблицы, в которых будут сохранены наши две модели: Категория и комментарий:
Запустите миграцию:
$ python migrate.py db migrate
INFO [alembic.runtime.migration] Context impl SQLiteImpl. INFO [alembic.runtime.migration] Will assume non-transactional DDL. INFO [alembic.autogenerate.compare] Detected added table 'category' INFO [alembic.autogenerate.compare] Detected added table 'comment' Generating /home/user/Desktop/pylinone/migrations/versions/015c8b601c6b_.py ... done
Затем примените миграцию к базе данных. Выполните команду обновления:
Выполните команду обновления:
python migrate.py db upgrade
INFO [alembic.runtime.migration] Context impl SQLiteImpl. INFO [alembic.runtime.migration] Will assume non-transactional DDL. INFO [alembic.runtime.migration] Running upgrade -> 015c8b601c6b, empty message
При каждом изменении моделей баз данных повторяйте команды migrate
и upgrade
.
Шаг 7: Добавление ресурсов категории
Создайте новый файл resources/Category.py
. Это позаботится обо всей логике, связанной с категориями. Добавьте приведенный ниже код в resources/Category.py
:
from flask import request from flask_restful import Resource from Model import db, Category, CategorySchema categories_schema = CategorySchema(many=True) category_schema = CategorySchema() class CategoryResource(Resource): def get(self): categories = Category.query.all() categories = categories_schema.dump(categories).data return {'status': 'success', 'data': categories}, 200
Здесь мы создали метод get
для извлечения категорий. Теперь у нас есть новая конечная точка – http://127.0.0.1:5000/api/Category
.
Использование Категории.query.all()
, мы извлекли все категории в базе данных и использовали categories_schema.dump(категории).data
, мы десериализовали полученные данные.
Далее, давайте добавим метод POST для создания новой категории. Добавьте следующий код в resources/Category.py
:
... def post(self): json_data = request.get_json(force=True) if not json_data: return {'message': 'No input data provided'}, 400 # Validate and deserialize input data, errors = category_schema.load(json_data) if errors: return errors, 422 category = Category.query.filter_by(name=data['name']).first() if category: return {'message': 'Category already exists'}, 400 category = Category( name=json_data['name'] ) db.session.add(category) db.session.commit() result = category_schema.dump(category).data return { "status": 'success', 'data': result }, 201
Далее, давайте добавим метод PUT для обновления категории. Обновление resources/Category.py
как показано ниже:
... def put(self): json_data = request.get_json(force=True) if not json_data: return {'message': 'No input data provided'}, 400 # Validate and deserialize input data, errors = category_schema.load(json_data) if errors: return errors, 422 category = Category.query.filter_by(id=data['id']).first() if not category: return {'message': 'Category does not exist'}, 400 category.name = data['name'] db.session.commit() result = category_schema.dump(category).data return { "status": 'success', 'data': result }, 204
Наконец, давайте добавим метод УДАЛЕНИЯ для удаления категории. Добавьте следующий код в resources/Category.py
:
... def delete(self): json_data = request.get_json(force=True) if not json_data: return {'message': 'No input data provided'}, 400 # Validate and deserialize input data, errors = category_schema.load(json_data) if errors: return errors, 422 category = Category.query.filter_by(id=data['id']).delete() db.session.commit() result = category_schema.dump(category).data return { "status": 'success', 'data': result}, 204
Наконец, импортируйте эти ресурсы в app.py
. Обновление app.py
точно так, как показано ниже:
from flask import Blueprint from flask_restful import Api from resources.Hello import Hello from resources.Category import CategoryResource api_bp = Blueprint('api', __name__) api = Api(api_bp) # Routes api.add_resource(Hello, '/Hello') api.add_resource(CategoryResource, '/Category')
В категории ресурсы мы создали 4 конечные точки:
ПОЛУЧИТЬ … http://127.0.0.1:5000/api/Category
ПОСТ – http://127.0.0.1:5000/api/Category
ПОЛОЖИТЬ – http://127.0.0.1:5000/api/Category
УДАЛИТЬ – http://127.0.0.1:5000/api/Category
Шаг 8: Добавление ресурсов комментариев
Создайте новый файл resources/Comment.py
. Это позаботится обо всех комментариях, связанных с логикой.
from flask import jsonify, request from flask_restful import Resource from Model import db, Comment, Category, CommentSchema comments_schema = CommentSchema(many=True) comment_schema = CommentSchema() class CommentResource(Resource): def get(self): comments = Comment.query.all() comments = comments_schema.dump(comments).data return {"status":"success", "data":comments}, 200 def post(self): json_data = request.get_json(force=True) if not json_data: return {'message': 'No input data provided'}, 400 # Validate and deserialize input data, errors = comment_schema.load(json_data) if errors: return {"status": "error", "data": errors}, 422 category_id = Category.query.filter_by(id=data['category_id']).first() if not category_id: return {'status': 'error', 'message': 'comment category not found'}, 4 # Routes api.add_resource(Hello, '/Hello') api.add_resource(CategoryResource, '/Category') api.add_resource(CommentResource, '/Comment')
Шаг 9: Конечные точки тестирования
Теперь у нас есть следующие доступные конечные точки:
- ПОСТ – http://127.0.0.1:5000/api/category – для добавления категорий.