Бэкенд на Python: создаем простое API с Flask

Привет, меня зовут Кирилл Алехин. Я предприниматель, айтишник и основатель веб-студии XSL в ОАЭ. Сегодня хочу поделиться с вами опытом создания простого API на Python с использованием фреймворка Flask. Это отличный способ быстро развернуть серверную часть для вашего проекта, будь то мобильное приложение, веб-сервис или даже микросервисная архитектура.

Почему Flask?

Flask — это микрофреймворк для Python, который идеально подходит для создания RESTful API. Он легкий, гибкий и не перегружен лишними зависимостями. В отличие от Django, Flask дает вам больше свободы в выборе инструментов и архитектуры проекта. Это особенно важно, когда вы работаете над MVP или небольшим проектом, где скорость разработки играет ключевую роль.

Что нам понадобится?

  • Python 3.6+ (рекомендую последнюю стабильную версию)
  • Установленный пакетный менеджер pip
  • Базовые знания Python и HTTP-протокола
  • Текстовый редактор или IDE (например, VS Code, PyCharm)

Установка Flask

Первым делом установим Flask. Откройте терминал и выполните команду:

pip install flask

Для работы с JSON-данными нам также понадобится модуль flask-jsonify, который обычно идет в комплекте с Flask. Если вы планируете работать с базой данных, установите Flask-SQLAlchemy:

pip install flask-sqlalchemy

Создаем простое API

Давайте создадим простой API для управления списком задач (to-do list). Начнем с базовой структуры проекта:

todo_api/
├── app.py
└── requirements.txt

Шаг 1: Инициализация Flask-приложения

Откройте файл app.py и добавьте следующий код:

from flask import Flask, jsonify, request

app = Flask(__name__)

# Временное хранилище задач
tasks = [
    {
        'id': 1,
        'title': 'Купить продукты',
        'description': 'Молоко, сыр, хлеб',
        'done': False
    },
    {
        'id': 2,
        'title': 'Изучить Flask',
        'description': 'Создать простое API',
        'done': False
    }
]

@app.route('/')
def home():
    return "Добро пожаловать в API для управления задачами!"

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

Здесь мы создали простое Flask-приложение с одним маршрутом, который возвращает приветственное сообщение. Запустите приложение командой:

python app.py

Откройте браузер и перейдите по адресу http://127.0.0.1:5000/. Вы должны увидеть сообщение «Добро пожаловать в API для управления задачами!».

Шаг 2: Добавление маршрутов для API

Теперь добавим маршруты для работы с задачами. В файл app.py добавьте следующие функции:

@app.route('/api/tasks', methods=['GET'])
def get_tasks():
    return jsonify({'tasks': tasks})

@app.route('/api/tasks/', methods=['GET'])
def get_task(task_id):
    task = [task for task in tasks if task['id'] == task_id]
    if len(task) == 0:
        return jsonify({'error': 'Задача не найдена'}), 404
    return jsonify({'task': task[0]})

@app.route('/api/tasks', methods=['POST'])
def create_task():
    if not request.json or not 'title' in request.json:
        return jsonify({'error': 'Отсутствует заголовок задачи'}), 400
    task = {
        'id': tasks[-1]['id'] + 1 if len(tasks) > 0 else 1,
        'title': request.json['title'],
        'description': request.json.get('description', ""),
        'done': False
    }
    tasks.append(task)
    return jsonify({'task': task}), 201

@app.route('/api/tasks/', methods=['PUT'])
def update_task(task_id):
    task = [task for task in tasks if task['id'] == task_id]
    if len(task) == 0:
        return jsonify({'error': 'Задача не найдена'}), 404
    task[0]['title'] = request.json.get('title', task[0]['title'])
    task[0]['description'] = request.json.get('description', task[0]['description'])
    task[0]['done'] = request.json.get('done', task[0]['done'])
    return jsonify({'task': task[0]})

@app.route('/api/tasks/', methods=['DELETE'])
def delete_task(task_id):
    task = [task for task in tasks if task['id'] == task_id]
    if len(task) == 0:
        return jsonify({'error': 'Задача не найдена'}), 404
    tasks.remove(task[0])
    return jsonify({'result': True})

Шаг 3: Тестирование API

Теперь у нас есть полноценное API с методами GET, POST, PUT и DELETE. Для тестирования можно использовать инструменты вроде Postman или curl. Вот несколько примеров запросов:

  • Получить все задачи:
    GET http://127.0.0.1:5000/api/tasks
  • Получить задачу по ID:
    GET http://127.0.0.1:5000/api/tasks/1
  • Создать новую задачу:
    POST http://127.0.0.1:5000/api/tasks
    Content-Type: application/json
    
    {
        "title": "Новая задача",
        "description": "Описание новой задачи"
    }
            
  • Обновить задачу:
    PUT http://127.0.0.1:5000/api/tasks/1
    Content-Type: application/json
    
    {
        "title": "Обновленная задача",
        "done": true
    }
            
  • Удалить задачу:
    DELETE http://127.0.0.1:5000/api/tasks/1

Добавляем базу данных

Временное хранилище задач в памяти — это хорошо для тестирования, но в реальном проекте вам понадобится база данных. Давайте интегрируем SQLite с помощью Flask-SQLAlchemy.

Шаг 1: Установка зависимостей

Убедитесь, что у вас установлен Flask-SQLAlchemy:

pip install flask-sqlalchemy

Шаг 2: Настройка базы данных

Обновите файл app.py:

from flask import Flask, jsonify, request
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///tasks.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)

class Task(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(100), nullable=False)
    description = db.Column(db.String(200))
    done = db.Column(db.Boolean, default=False)

    def to_dict(self):
        return {
            'id': self.id,
            'title': self.title,
            'description': self.description,
            'done': self.done
        }

# Создаем таблицы в базе данных
with app.app_context():
    db.create_all()

Шаг 3: Обновление маршрутов для работы с базой данных

Теперь обновим маршруты, чтобы они работали с базой данных:

@app.route('/api/tasks', methods=['GET'])
def get_tasks():
    tasks = Task.query.all()
    return jsonify({'tasks': [task.to_dict() for task in tasks]})

@app.route('/api/tasks/', methods=['GET'])
def get_task(task_id):
    task = Task.query.get(task_id)
    if task is None:
        return jsonify({'error': 'Задача не найдена'}), 404
    return jsonify({'task': task.to_dict()})

@app.route('/api/tasks', methods=['POST'])
def create_task():
    if not request.json or not 'title' in request.json:
        return jsonify({'error': 'Отсутствует заголовок задачи'}), 400
    task = Task(
        title=request.json['title'],
        description=request.json.get('description', ""),
        done=request.json.get('done', False)
    )
    db.session.add(task)
    db.session.commit()
    return jsonify({'task': task.to_dict()}), 201

@app.route('/api/tasks/', methods=['PUT'])
def update_task(task_id):
    task = Task.query.get(task_id)
    if task is None:
        return jsonify({'error': 'Задача не найдена'}), 404
    task.title = request.json.get('title', task.title)
    task.description = request.json.get('description', task.description)
    task.done = request.json.get('done', task.done)
    db.session.commit()
    return jsonify({'task': task.to_dict()})

@app.route('/api/tasks/', methods=['DELETE'])
def delete_task(task_id):
    task = Task.query.get(task_id)
    if task is None:
        return jsonify({'error': 'Задача не найдена'}), 404
    db.session.delete(task)
    db.session.commit()
    return jsonify({'result': True})

Заключение

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

В нашей веб-студии XSL в ОАЭ мы часто используем Flask для создания MVP и микросервисов, так как он позволяет быстро разрабатывать и масштабировать приложения. Если у вас есть вопросы или вы хотите обсудить проект — пишите, всегда рад помочь!

Удачи в разработке!

от автора

написал в