Фреймворк flask.
Basics of Python and Django. -> Фреймворк flask.
Фреймворк flask.
Установим flask.
pip install flask
Создадим минимальное приложение run.py.
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
Для того, чтобы запускать приложение, необходимо иметь переменную FLASK_APP в окружении коммандного интерпретатора bash.
Ее можно добавить в адресной строке.
export FLASK_APP=start.py
Или добавить этоу строку в .bashrc файл для того, чтобы она присутствовала при любом запуске терминала.
Но мы создадим файл .env c переменными, которые должны входить в окружение.
FLASK_APP=run.py
Теперь нам необходима библиотека, которая способна его прочитать и добавить эти переменные в окружение (конфигурацию приложения) на этапе выполнения программы.
Одна из таких библиотек называется dotenv.
pip install python-dotenv
Теперь создадим функцию создания приложения с заданной конфигурацией.
from flask import Flask
from dotenv import load_dotenv, dotenv_values
def create_app():
flask_app = Flask(__name__)
load_dotenv()
flask_app.config.update(dotenv_values())
return flask_app
app = create_app()
@app.route('/')
def hello_world():
return 'Hello, World!'
Добавим еще пару переменных в .env.
FLASK_APP=run.py
DEBUG = True
FLASK_ENV=development
DEBUG - режим отладки
FLASK_ENV - режим при котором приложение будет перегружаться при изменениях скриптов.
Например так:
* Detected change in '/home/zdimon/Desktop/flask-api/run.py', reloading
* Restarting with stat
* Debugger is active!
* Debugger PIN: 319-920-800
Альтернативным способом можно настроить окружение не через .env файл, а через классы в файле, например в configmodule.py:
class Config(object):
DEBUG = False
TESTING = False
DATABASE_URI = 'sqlite:///:memory:'
class ProductionConfig(Config):
DATABASE_URI = 'mysql://user@localhost/foo'
class DevelopmentConfig(Config):
DEBUG = True
class TestingConfig(Config):
TESTING = True
И потом ‘втолкнуть’ в приложение так:
app.config.from_object('configmodule.ProductionConfig')
Перенос роутов в отдельный файл.
Мы можем перенести роуты в отдельные файлы и не хранить все в run.py
Облечгим до предела run.py
from app import app
import apps
if __name__ == '__main__':
app.run(host='0.0.0.0')
Вынесем настройки приложения в отдельный модуль app.py
from flask import Flask
from dotenv import load_dotenv, dotenv_values
def create_app():
flask_app = Flask(__name__)
load_dotenv()
flask_app.config.update(dotenv_values())
return flask_app
app = create_app()
В новой папке apps/route создадим модуль index.py
from app import app
@app.route('/')
def index():
return 'Hello, World!'
И для того, чтобы сработал импорт import apps в run.py добавим следующее в apps/init.py
from .route.index import index
Тут мы будем импортировать каждый новый модуль роутов.
База данных
Установим библиотеки
pip install Flask-SQLAlchemy psycopg2-binary
Создадим объект базы данных в app.py
...
from flask_sqlalchemy import SQLAlchemy
def create_db(c_app):
return SQLAlchemy(c_app)
...
app = create_app()
db = create_db(app)
Для подключения к БД необходимо задать специальные переменные в окружении.
Задаем переменную SQLALCHEMY_DATABASE_URI с правами и прочим для коннекта.
SQLALCHEMY_DATABASE_URI=postgresql://postgres:1q2w3e@localhost:5432/flask-api
Создадим класс модели данных в новой папке models и в файле users.py
from app import db
class Users(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String())
password = db.Column(db.String())
def __repr__(self):
return '<id {}-{}>'.format(self.id, self.username)
Теперь для того, чтобы добавить эту таблицу необходимо создать и запустить миграцию.
Для этого установим инструмент flask-migrate
pip install flask-migrate
Создадим объект миграций в app.py
from flask_migrate import Migrate
...
app = create_app()
db = create_db(app)
migrate = Migrate(app, db)
Создадим базу данных fask-api в любом клиенте postgres например в pgAdmin3
Теперь у нас стала доступной команда
flask db
Следующим шагом будет создание репозитория (директории) для миграций.
flask db init
И далее создание первой миграции.
flask db migrate
При этом получаем
No changes in schema detected.
Импортируем модели после создания объекта миграций в app.py
...
migrate = Migrate(app, db)
from apps.models.users import Users
Теперь можно последовательно запускать команды
flask db migrate
Которая создаст миграцию.
И второй командой ее запустить.
flask db upgrade
Установка swagger
Эта библиотка создаст удобный интерфейс для тестирования.
pip install flasgger
Создаем обьект Swagger из приложения.
from flasgger import Swagger
swagger = Swagger(app)
Добавляем описание в функцию роутинга.
from app import app
@app.route('/')
def index():
"""Example endpoint returning a list of colors by palette
This is using docstrings for specifications.
---
parameters:
- name: palette
in: path
type: string
enum: ['all', 'rgb', 'cmyk']
required: true
default: all
definitions:
Palette:
type: object
properties:
palette_name:
type: array
items:
$ref: '#/definitions/Color'
Color:
type: string
responses:
200:
description: A list of colors (may be filtered by palette)
schema:
$ref: '#/definitions/Palette'
examples:
rgb: ['red', 'green', 'blue']
"""
return 'Hello, World!'
Использование схем Marshmallow.
Эти схемы позволяют преобразовывать python объекты схем модели в json.
Устанавливаем библиотеку.
pip install marshmallow apispec
Создадим новый модуль schemas/user.py
from flasgger import Schema, fields
class User(Schema):
name = fields.Str()
username = fields.Str()
password = fields.Str()
Создадим контроллер (представление) в новом модуле routes/users.py
from flasgger import Swagger, SwaggerView
from ..shemas.user import User
from app import app
class UsersView(SwaggerView):
parameters = [
{
"name": "name",
"type": "string",
"required": True,
},
{
"name": "username",
"type": "string",
"required": True,
},
{
"name": "password",
"type": "string",
"required": True,
}
]
responses = {
200: {
"description": "Create user",
"schema": User
}
}
def post(self):
"""
Creating a new user.
"""
return jsonify({'message': 'Ok'})
app.add_url_rule(
'/user/create',
view_func=UsersView.as_view('create user'),
methods=['POST']
)
Подключим этот роут в apps/init.py
from .routes.users import UsersView
Добавим файл к параметрам.
class UsersView(SwaggerView):
parameters = [
...
{
"name": "file",
"type": "file",
"required": False,
}
....