Как использовать rest api python

Как использовать rest api python

REST API остаётся основным способом обмена данными между клиентом и сервером в современных веб-приложениях. В Python разработчики чаще всего используют библиотеки Flask, FastAPI и Django REST framework для создания и потребления REST-сервисов. Эти инструменты позволяют быстро реализовать обработку HTTP-запросов, сериализацию данных и авторизацию без избыточного кода.

Например, FastAPI позволяет описывать маршруты с аннотациями типов, автоматически генерирует документацию по OpenAPI и поддерживает валидацию входных данных «из коробки». При этом скорость обработки запросов приближается к Node.js и Go, что делает FastAPI актуальным для high-load систем.

С другой стороны, Django REST framework предоставляет мощную архитектуру для создания сложных API на базе зрелого Django. Он поддерживает сериализацию моделей, маршрутизацию, пагинацию и встроенные механизмы аутентификации. Для небольших REST-сервисов или микросервисов оптимальным будет Flask с библиотекой flask-restful, обеспечивающей базовый функционал для построения REST API.

Практическое применение REST API на Python охватывает автоматизацию бизнес-процессов, интеграцию с внешними сервисами (например, Telegram Bot API, Stripe, GitHub), построение SPA-интерфейсов с React или Vue и разработку мобильных приложений с серверной логикой. В этой статье представлены конкретные примеры реализации REST API с пояснением кода и рекомендациями по выбору инструментов в зависимости от задачи.

Создание REST API с использованием Flask

Установите Flask командой pip install flask. Создайте файл app.py с базовой структурой API. Импортируйте необходимые модули: from flask import Flask, request, jsonify. Инициализируйте приложение: app = Flask(__name__).

Добавьте маршрут для получения данных:

@app.route('/api/items', methods=['GET'])
def get_items():
data = [{'id': 1, 'name': 'Item A'}, {'id': 2, 'name': 'Item B'}]
return jsonify(data)

Для обработки POST-запросов используйте:

@app.route('/api/items', methods=['POST'])
def create_item():
content = request.json
if 'name' not in content:
return jsonify({'error': 'Поле name обязательно'}), 400
item = {'id': 3, 'name': content['name']}
return jsonify(item), 201

Запускайте приложение через if __name__ == '__main__': app.run(debug=True). Для тестирования используйте Postman или curl. Обязательно проверяйте заголовки Content-Type: application/json при отправке POST-запросов.

Обрабатывайте ошибки централизованно с помощью декоратора @app.errorhandler. Пример:

@app.errorhandler(404)
def not_found(error):
return jsonify({'error': 'Ресурс не найден'}), 404

Для масштабирования подключайте Flask Blueprints. Создавайте модули с логической разбивкой по функциям API и регистрируйте их в основном приложении через app.register_blueprint.

Не используйте глобальные переменные для хранения данных. Для разработки прототипа можно применять списки или словари в памяти, но в продакшене – только БД. Подключение SQLite: import sqlite3, создание соединения conn = sqlite3.connect('db.sqlite'), выполнение запросов через курсор.

Настройте CORS, если предполагаются кросс-доменные запросы: from flask_cors import CORS, затем CORS(app). Без этого браузер заблокирует вызовы из внешних источников.

Обработка HTTP-запросов: GET, POST, PUT, DELETE

GET применяется для получения данных без изменения состояния сервера. В Python это реализуется через библиотеку Flask следующим образом:

from flask import Flask, request
app = Flask(__name__)
@app.route('/user/<int:user_id>', methods=['GET'])
def get_user(user_id):
return {'id': user_id, 'name': 'Иван'}

Параметры пути обрабатываются напрямую. Для передачи query-параметров используйте request.args.get(‘key’).

POST используется для создания ресурсов. Данные передаются в теле запроса, чаще в формате JSON:

from flask import jsonify
@app.route('/user', methods=['POST'])
def create_user():
data = request.get_json()
return jsonify({'status': 'created', 'user': data}), 201

Убедитесь, что заголовок Content-Type: application/json установлен на клиентской стороне.

PUT применяется для полного обновления ресурса. Формат тела аналогичен POST, но логика замещает весь объект:

@app.route('/user/<int:user_id>', methods=['PUT'])
def update_user(user_id):
data = request.get_json()
return {'id': user_id, 'updated_data': data}

Важно валидировать данные, чтобы избежать потери информации при неполном теле запроса.

DELETE удаляет указанный ресурс. Возвращайте статус 204 без тела для подтверждения:

@app.route('/user/<int:user_id>', methods=['DELETE'])
def delete_user(user_id):
return '', 204

Идентификаторы должны быть проверены на существование до выполнения удаления.

Передача и валидация данных через JSON

Передача и валидация данных через JSON

REST API на Python, как правило, использует формат JSON для обмена данными между клиентом и сервером. Для корректной работы необходимо строго определять структуру входящих и исходящих данных, а также выполнять валидацию на стороне сервера.

Для передачи данных клиент отправляет HTTP-запрос с заголовком Content-Type: application/json и телом запроса в формате JSON. На стороне сервера Python предоставляет удобные инструменты для работы с такими данными, в частности:

  • request.get_json() в Flask – извлекает JSON из тела запроса и преобразует его в словарь Python;
  • pydantic.BaseModel в FastAPI – выполняет автоматическую проверку и сериализацию данных;
  • json.loads() – стандартный метод для десериализации JSON-строк, используется при ручной обработке.

Пример минимальной валидации в Flask:

from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/api/user', methods=['POST'])
def create_user():
data = request.get_json()
if not data or 'username' not in data or 'age' not in data:
return jsonify({'error': 'Неверные данные'}), 400
if not isinstance(data['username'], str) or not isinstance(data['age'], int):
return jsonify({'error': 'Типы данных некорректны'}), 400
return jsonify({'status': 'успешно'}), 200

Для более строгой и читаемой валидации используйте Pydantic (в составе FastAPI или отдельно):

from pydantic import BaseModel, constr, conint
from fastapi import FastAPI
app = FastAPI()
class User(BaseModel):
username: constr(min_length=3, max_length=20)
age: conint(ge=18, le=120)
@app.post("/api/user")
def create_user(user: User):
return {"status": "успешно"}

Рекомендации:

  • Явно указывайте ограничения на поля: длину строк, диапазон чисел, формат email;
  • Не обрабатывайте JSON вручную, если используется фреймворк с поддержкой схем;
  • Возвращайте однозначные сообщения об ошибках с HTTP-кодами 400/422 и описанием причины;
  • Логируйте некорректные запросы с указанием поля и значения для упрощения отладки.

Грамотная валидация JSON защищает API от некорректных или вредоносных запросов и снижает нагрузку на последующие уровни логики.

Использование библиотеки requests для взаимодействия с внешними API

Использование библиотеки requests для взаимодействия с внешними API

Библиотека requests предоставляет простой и лаконичный интерфейс для отправки HTTP-запросов. Она поддерживает все основные методы: GET, POST, PUT, DELETE, PATCH. Подключение выполняется одной строкой: import requests.

Для получения данных от API используется метод get(). Пример запроса к публичному API:

response = requests.get("https://api.github.com/users/octocat")

Проверка успешности запроса осуществляется через response.status_code. Ожидаемый код – 200. Полученные данные можно преобразовать в словарь с помощью response.json().

При отправке данных на сервер применяется метод post(). Пример отправки JSON:


payload = {"name": "test", "job": "developer"}
response = requests.post("https://reqres.in/api/users", json=payload)

При работе с заголовками используется параметр headers. Это необходимо, например, для авторизации через токен:


headers = {"Authorization": "Bearer your_token_here"}
response = requests.get("https://api.example.com/data", headers=headers)

Для обработки ошибок желательно использовать try-except и встроенные исключения библиотеки, такие как requests.exceptions.RequestException. Это защищает от нестабильного поведения сети и недоступности сервиса.

Если требуется задать параметры запроса в URL, используйте параметр params:


params = {"q": "python", "limit": 10}
response = requests.get("https://api.example.com/search", params=params)

Рекомендуется задавать таймауты для запросов с помощью параметра timeout, чтобы избежать зависания при отсутствии ответа:

response = requests.get("https://api.example.com", timeout=5)

Библиотека requests не поддерживает асинхронные вызовы. Для параллельной работы с несколькими API лучше использовать aiohttp.

Реализация маршрутов и структуры проекта для REST API

Реализация маршрутов и структуры проекта для REST API

Эффективная структура проекта и чёткая организация маршрутов критичны для масштабируемости REST API. При разработке на Python с использованием Flask или FastAPI необходимо сразу определить логические модули: маршруты, схемы, бизнес-логику и доступ к данным.

Разделите проект на директории routers, schemas, services, models и core. В routers помещаются модули с маршрутами, каждый из которых отвечает за отдельную область: пользователи, товары, заказы. В schemas описываются Pydantic-модели для валидации входящих и исходящих данных. В services – бизнес-логика, не зависящая от HTTP. models содержит ORM-классы, отражающие таблицы базы данных. В core – инициализация приложения, настройки, подключение к БД.

Пример маршрута в FastAPI:

from fastapi import APIRouter, Depends
from schemas.user import UserCreate, UserOut
from services.user_service import create_user
router = APIRouter(prefix="/users", tags=["users"])
@router.post("/", response_model=UserOut)
def register_user(user: UserCreate):
return create_user(user)

Подключение маршрутов в основном файле:

from fastapi import FastAPI
from routers import user_router, product_router
app = FastAPI()
app.include_router(user_router.router)
app.include_router(product_router.router)

Именование маршрутов и файлов должно быть предсказуемым: user_router.py, product_service.py, order_schema.py. Используйте префиксы и теги в APIRouter для группировки и генерации документации OpenAPI.

Избегайте хранения логики в файлах маршрутов. Ограничьтесь вызовами функций из services. Это упрощает тестирование и повторное использование кода.

При большом числе маршрутов применяйте автоматическое подключение, перебирая все файлы в директории routers и импортируя их динамически через importlib.

Добавление авторизации через токены (JWT)

Для реализации авторизации с использованием JSON Web Token (JWT) в Python, важно понимать несколько ключевых моментов. JWT предоставляет способ безопасного обмена данными между клиентом и сервером. Он состоит из трех частей: заголовка, полезной нагрузки (payload) и подписи. При каждом запросе сервер проверяет подпись, чтобы удостовериться, что токен не был изменен. JWT часто используется в REST API для аутентификации и авторизации пользователей.

Для создания JWT в Python можно использовать библиотеку PyJWT. Этот пакет позволяет легко работать с токенами и их подписью. Ниже приведен пример генерации и валидации JWT в API-сервисе на Python с использованием Flask и PyJWT.

Установка необходимых библиотек

Для начала необходимо установить Flask и PyJWT:

pip install Flask PyJWT

Пример реализации

Пример реализации

Для генерации токена, вы можете создать следующий код на сервере:


import jwt
import datetime
from flask import Flask, request, jsonify
app = Flask(__name__)
SECRET_KEY = 'your_secret_key'
def generate_token(user_id):
expiration_time = datetime.datetime.utcnow() + datetime.timedelta(hours=1)
payload = {
'user_id': user_id,
'exp': expiration_time
}
token = jwt.encode(payload, SECRET_KEY, algorithm='HS256')
return token
@app.route('/login', methods=['POST'])
def login():
username = request.json.get('username')
password = request.json.get('password')
# Проверка логина и пароля (в реальном приложении эта часть должна быть более сложной)
if username == 'user' and password == 'password':
token = generate_token(user_id=1)
return jsonify({'token': token})
return jsonify({'message': 'Invalid credentials'}), 401
if __name__ == '__main__':
app.run(debug=True)

В этом примере создается токен, который истекает через 1 час. В ответ на успешный логин пользователь получает JWT. В реальном приложении токен нужно передавать через HTTP-заголовки в последующих запросах.

Авторизация с использованием JWT

Авторизация с использованием JWT

Для проверки токена при каждом запросе необходимо извлечь его из заголовка Authorization и проверить его подпись. Пример:


from functools import wraps
from flask import request, jsonify
def token_required(f):
@wraps(f)
def decorated_function(*args, **kwargs):
token = request.headers.get('Authorization')
if not token:
return jsonify({'message': 'Token is missing'}), 403
try:
token = token.split(" ")[1]
jwt.decode(token, SECRET_KEY, algorithms=['HS256'])
except jwt.ExpiredSignatureError:
return jsonify({'message': 'Token has expired'}), 401
except jwt.InvalidTokenError:
return jsonify({'message': 'Invalid token'}), 401
return f(*args, **kwargs)
return decorated_function
@app.route('/protected', methods=['GET'])
@token_required
def protected():
return jsonify({'message': 'This is a protected route'})

В этом примере мы создаем декоратор token_required, который добавляется к защищенным маршрутам. Он проверяет наличие и валидность токена в заголовке запроса. Если токен отсутствует или некорректен, возвращается ошибка с кодом 401.

Обработка ошибок

Для улучшения пользовательского опыта важно обрабатывать ошибки, связанные с токенами. В случае истекшего токена или неверной подписи, сервер должен возвращать соответствующие сообщения об ошибке.

Преимущества использования JWT

JWT обеспечивают безопасность и масштабируемость для API, поскольку не требуют хранения сессий на сервере. Токены могут быть переданы через URL, заголовки HTTP или куки, что упрощает взаимодействие с различными клиентами (например, мобильными приложениями или веб-клиентами).

Заключение

Заключение

Использование JWT позволяет эффективно и безопасно реализовать авторизацию в приложениях на Python. Основной принцип заключается в том, чтобы правильно генерировать, передавать и валидировать токены. Этот подход подходит для распределенных систем и микросервисов, где требуется надежная аутентификация без зависимости от серверных сессий.

Тестирование REST API с помощью Postman и pytest

Тестирование REST API – важный этап в разработке, который позволяет убедиться в корректной работе конечных точек и правильности обработки запросов. Для этого используются инструменты, такие как Postman и pytest, каждый из которых имеет свои особенности и преимущества.

Postman представляет собой инструмент для тестирования API, предоставляющий удобный интерфейс для отправки запросов и получения ответов от серверов. Он подходит для ручного тестирования, а также позволяет создавать коллекции запросов, что упрощает проверку различных сценариев. Для начала достаточно создать запрос, указав метод (GET, POST, PUT и т.д.), URL, заголовки и тело запроса. После отправки запроса Postman отобразит ответ, включая статусный код, тело ответа и заголовки. Это помогает быстро понять, работает ли API как ожидается.

Для автоматизации тестов и интеграции с Python в работу вступает pytest – популярный фреймворк для тестирования. Для работы с REST API в pytest часто используют библиотеку requests, которая позволяет легко отправлять HTTP-запросы и анализировать ответы. Для того чтобы интегрировать API-тесты с pytest, достаточно создать тестовую функцию, в которой будут отправляться запросы, а затем проверяться корректность их ответов.

Пример теста с использованием pytest и requests:

import requests
def test_get_user():
response = requests.get("https://jsonplaceholder.typicode.com/users/1")
assert response.status_code == 200
assert response.json()['id'] == 1

В данном примере мы тестируем GET-запрос на получение пользователя. В тесте проверяется, что статусный код ответа равен 200, а также что ID пользователя соответствует ожидаемому значению.

Тестирование с Postman также можно автоматизировать. Для этого можно использовать Collection Runner или интеграцию с Newman – командной строкой для выполнения коллекций Postman. С помощью Newman можно запускать коллекции Postman на сервере или в CI/CD процессе, обеспечивая автоматическое тестирование API на каждом этапе разработки.

Для интеграции Postman и pytest можно использовать метод, при котором Postman отправляет запросы через коллекцию, а результаты сохраняются в формате JSON. После этого эти данные можно обработать в pytest с помощью парсинга результатов и проверки их соответствия ожидаемым значениям. Пример команды для запуска коллекции Postman с помощью Newman:

newman run collection.json --reporters junit --reporter-junit-export results.xml

В результате выполнения этой команды генерируется отчет в формате XML, который может быть использован для дальнейшего анализа в pytest.

Таким образом, использование Postman для ручного тестирования и pytest для автоматических тестов позволяет значительно повысить качество REST API, обнаруживая ошибки на ранних стадиях разработки и минимизируя риски при выпуске новых версий.

Вопрос-ответ:

Что такое REST API и как оно работает на Python?

REST API (Representational State Transfer) представляет собой архитектурный стиль, который используется для создания веб-сервисов. В Python можно взаимодействовать с такими сервисами с помощью библиотек, например, `requests` или `flask`. REST API работает по принципу обмена данными в формате JSON, где клиент отправляет HTTP-запросы, а сервер обрабатывает их и отправляет ответ. В Python для выполнения таких запросов достаточно использовать несколько строк кода, что делает работу с REST API простой и доступной.

Какие библиотеки Python можно использовать для работы с REST API?

Для работы с REST API на Python существует несколько популярных библиотек. Одна из самых распространенных — это `requests`. Она позволяет отправлять HTTP-запросы, а также получать и обрабатывать ответы. Для создания собственного REST API часто используется фреймворк `Flask`, который предоставляет все необходимые инструменты для создания серверной части. Также есть библиотека `FastAPI`, которая ориентирована на создание быстрых и удобных API с минимальными усилиями.

Ссылка на основную публикацию