Встановимо 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
від .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
Ця бібліотека створить зручний інтерфейс для тестування.
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!'
Ці схеми дозволяють перетворювати 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,
}
....