Создание простого API на Flask

Создание простого API на Flask REST API

Привет! Мы уже знаем, как создавать веб-приложения на Flask. Теперь пришло время научиться создавать API — серверную часть, которая общается с клиентом через JSON.

В этой статье мы создадим простое API для управления списком пользователей (CRUD).

В этой статье мы разберём:

  • Настройку Flask-приложения
  • GET — получение данных
  • POST — создание данных
  • PUT — обновление данных
  • DELETE — удаление данных

Что нужно знать перед началом

Для этого урока тебе понадобится:

  • Установленный Flask
  • Базовое понимание HTTP-методов и JSON

Совет: CRUD — это основа любого API: Create, Read, Update, Delete.

Основная часть

Настройка приложения

Создай файл app.py:

from flask import Flask, request, jsonify

app = Flask(__name__)

# Заглушка базы данных
users = [
    {"id": 1, "name": "Анна", "age": 25},
    {"id": 2, "name": "Иван", "age": 30}
]
next_id = 3

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

GET — получение всех пользователей

@app.route('/users', methods=['GET'])
def get_users():
    return jsonify(users)

Пример запроса: GET /users

Ответ:

[
    {"id": 1, "name": "Анна", "age": 25},
    {"id": 2, "name": "Иван", "age": 30}
]

GET — получение одного пользователя

@app.route('/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
    user = next((u for u in users if u["id"] == user_id), None)
    if user is None:
        return jsonify({"error": "Пользователь не найден"}), 404
    return jsonify(user)

Пример запроса: GET /users/1

Ответ:

{"id": 1, "name": "Анна", "age": 25}

POST — создание пользователя

@app.route('/users', methods=['POST'])
def create_user():
    data = request.get_json()

    if not data or "name" not in data or "age" not in data:
        return jsonify({"error": "Имя и возраст обязательны"}), 400

    global next_id
    user = {"id": next_id, "name": data["name"], "age": data["age"]}
    users.append(user)
    next_id += 1

    return jsonify(user), 201

Пример запроса:

POST /users
{
    "name": "Петр",
    "age": 35
}

Ответ:

{"id": 3, "name": "Петр", "age": 35}

PUT — полное обновление пользователя

@app.route('/users/<int:user_id>', methods=['PUT'])
def update_user(user_id):
    data = request.get_json()

    if not data or "name" not in data or "age" not in data:
        return jsonify({"error": "Имя и возраст обязательны"}), 400

    user = next((u for u in users if u["id"] == user_id), None)
    if user is None:
        return jsonify({"error": "Пользователь не найден"}), 404

    user["name"] = data["name"]
    user["age"] = data["age"]

    return jsonify(user)

PATCH — частичное обновление пользователя

@app.route('/users/<int:user_id>', methods=['PATCH'])
def patch_user(user_id):
    data = request.get_json()

    user = next((u for u in users if u["id"] == user_id), None)
    if user is None:
        return jsonify({"error": "Пользователь не найден"}), 404

    if "name" in data:
        user["name"] = data["name"]
    if "age" in data:
        user["age"] = data["age"]

    return jsonify(user)

DELETE — удаление пользователя

@app.route('/users/<int:user_id>', methods=['DELETE'])
def delete_user(user_id):
    global users
    user = next((u for u in users if u["id"] == user_id), None)
    if user is None:
        return jsonify({"error": "Пользователь не найден"}), 404

    users = [u for u in users if u["id"] != user_id]
    return jsonify({"message": "Пользователь удалён"})

Полный код

from flask import Flask, request, jsonify

app = Flask(__name__)

users = [
    {"id": 1, "name": "Анна", "age": 25},
    {"id": 2, "name": "Иван", "age": 30}
]
next_id = 3

@app.route('/users', methods=['GET'])
def get_users():
    return jsonify(users)

@app.route('/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
    user = next((u for u in users if u["id"] == user_id), None)
    if user is None:
        return jsonify({"error": "Пользователь не найден"}), 404
    return jsonify(user)

@app.route('/users', methods=['POST'])
def create_user():
    data = request.get_json()
    if not data or "name" not in data or "age" not in data:
        return jsonify({"error": "Имя и возраст обязательны"}), 400

    global next_id
    user = {"id": next_id, "name": data["name"], "age": data["age"]}
    users.append(user)
    next_id += 1
    return jsonify(user), 201

@app.route('/users/<int:user_id>', methods=['PUT'])
def update_user(user_id):
    data = request.get_json()
    if not data or "name" not in data or "age" not in data:
        return jsonify({"error": "Имя и возраст обязательны"}), 400

    user = next((u for u in users if u["id"] == user_id), None)
    if user is None:
        return jsonify({"error": "Пользователь не найден"}), 404

    user["name"] = data["name"]
    user["age"] = data["age"]
    return jsonify(user)

@app.route('/users/<int:user_id>', methods=['PATCH'])
def patch_user(user_id):
    data = request.get_json()
    user = next((u for u in users if u["id"] == user_id), None)
    if user is None:
        return jsonify({"error": "Пользователь не найден"}), 404

    if "name" in data:
        user["name"] = data["name"]
    if "age" in data:
        user["age"] = data["age"]
    return jsonify(user)

@app.route('/users/<int:user_id>', methods=['DELETE'])
def delete_user(user_id):
    global users
    user = next((u for u in users if u["id"] == user_id), None)
    if user is None:
        return jsonify({"error": "Пользователь не найден"}), 404

    users = [u for u in users if u["id"] != user_id]
    return jsonify({"message": "Пользователь удалён"})

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

Задачи для закрепления

Задача 1. Создай эндпоинт для получения списка товаров.

Задача 2. Создай эндпоинт для создания товара.

Задача 3. Создай эндпоинт для обновления товара.

Задача 4. Создай эндпоинт для удаления товара.

Задача 5. Что возвращает request.get_json()?

Ответы:

Задача 1.

@app.route('/products', methods=['GET'])
def get_products():
    return jsonify(products)

Задача 2.

@app.route('/products', methods=['POST'])
def create_product():
    data = request.get_json()
    # ...
    return jsonify(product), 201

Задача 3.

@app.route('/products/<int:product_id>', methods=['PUT'])
def update_product(product_id):
    # ...
    return jsonify(product)

Задача 4.

@app.route('/products/<int:product_id>', methods=['DELETE'])
def delete_product(product_id):
    # ...
    return jsonify({"message": "Товар удалён"})

Задача 5.

# request.get_json() возвращает словарь с данными из тела запроса

Нюансы и подводные камни

  • Flask по умолчанию возвращает HTML. Для JSON используй jsonify().
  • request.get_json() — для получения JSON из запроса.
  • Статус-коды возвращаются вторым аргументом: jsonify(data), 201.
  • В режиме debug=True сервер перезагружается при изменениях.
  • Flask не валидирует данные автоматически — нужно делать вручную.
  • Глобальные переменные (usersnext_id) — небезопасны для многопоточности.

Частые ошибки и как их избежать

Ошибка 1: Забыл jsonify() для JSON-ответа

Используй jsonify(data) для JSON.

Ошибка 2: Неправильная обработка request.get_json()

Проверяй, что данные получены: if not data: return jsonify({"error": "Нет данных"}), 400

Ошибка 3: Глобальные переменные для хранения данных

Используй базу данных для продакшена.

Шпаргалка

Что нужноКак пишется
GET@app.route('/users', methods=['GET'])
POST@app.route('/users', methods=['POST'])
PUT@app.route('/users/<int:id>', methods=['PUT'])
DELETE@app.route('/users/<int:id>', methods=['DELETE'])
Получить JSONrequest.get_json()
Вернуть JSONjsonify(data)
Статус-кодreturn jsonify(data), 201

Заключение

Сегодня мы:

  • Создали простое API на Flask
  • Реализовали CRUD операции
  • Работали с JSON-данными
  • Разобрали обработку ошибок

КВИЗ

Что дальше?

Оцените статью
IMI-DS - PYTHON LERNEN
Содержание
Оглавление ×