Middle
63
Las capturas de pantalla contienen código Python para una función asíncrona que crea un pedido en un servicio web. El código implica: - Analizar datos JSON de la solicitud para user_id, items y promo_code. - Calcular el precio total de los artículos. - Aplicar un descuento opcional llamando a un servicio externo de descuentos. - Insertar el pedido en una base de datos PostgreSQL. - Reservar los artículos llamando a un servicio de almacén. - Publicar un evento de pedido creado en un adaptador Kafka. - Actualizar el estado del pedido a 'procesado'. La tarea implícita en el código es: "Implementar un endpoint de API asíncrono para crear un pedido que: - Valide los datos de entrada. - Calcule el precio total del pedido. - Aplique un descuento si se proporciona un código promocional llamando a un servicio externo de descuentos. - Inserte el pedido en una base de datos PostgreSQL y recupere el nuevo ID del pedido. - Llame a un servicio de almacén para reservar los artículos pedidos. - Publique un evento de pedido creado en un adaptador Kafka. - Actualice el estado del pedido a 'procesado' en la base de datos. - Maneje errores potenciales como la desconexión del servicio de descuentos de manera elegante."
Empresas donde se preguntó
ГК АСК
Respuesta de la IA
sobes.tech AI
Для реализации асинхронного API эндпоинта создания заказа в Python можно использовать asyncio и библиотеки, поддерживающие асинхронность, например, aiohttp для веб-сервера, asyncpg для работы с PostgreSQL, а также асинхронные HTTP клиенты для вызова внешних сервисов.
Основные шаги:
- Валидация входных данных — проверяем, что
user_id,itemsи опциональноpromo_codeкорректны. - Расчет стоимости — суммируем цены товаров из
items. - Применение скидки — если есть
promo_code, вызываем внешний сервис скидок асинхронно, обрабатываем ошибки (например, таймауты, недоступность сервиса) и корректируем итоговую сумму. - Вставка заказа в БД — асинхронно вставляем запись в PostgreSQL, получаем
order_id. - Резервирование товаров — вызываем асинхронно складской сервис для резервирования, обрабатываем ошибки.
- Публикация события — отправляем сообщение в Kafka (через асинхронный адаптер).
- Обновление статуса заказа — меняем статус на "processed" в БД.
Пример упрощенного кода с использованием aiohttp и asyncpg:
import aiohttp
import asyncpg
from aiohttp import web
async def create_order(request):
data = await request.json()
user_id = data.get('user_id')
items = data.get('items')
promo_code = data.get('promo_code')
if not user_id or not items:
return web.json_response({'error': 'Invalid input'}, status=400)
total_price = sum(item['price'] * item['quantity'] for item in items)
# Применяем скидку
if promo_code:
try:
async with aiohttp.ClientSession() as session:
async with session.get(f'http://discount-service/apply?code={promo_code}&amount={total_price}') as resp:
if resp.status == 200:
discount_data = await resp.json()
total_price = discount_data.get('discounted_amount', total_price)
except Exception:
# Логируем ошибку, но продолжаем без скидки
pass
pool = request.app['db_pool']
async with pool.acquire() as conn:
async with conn.transaction():
order_id = await conn.fetchval(
'INSERT INTO orders(user_id, total_price, status) VALUES($1, $2, $3) RETURNING id',
user_id, total_price, 'pending'
)
# Резервируем товары
try:
async with aiohttp.ClientSession() as session:
reserve_payload = {'order_id': order_id, 'items': items}
async with session.post('http://warehouse-service/reserve', json=reserve_payload) as resp:
if resp.status != 200:
raise Exception('Warehouse reservation failed')
except Exception:
await conn.execute('UPDATE orders SET status=$1 WHERE id=$2', 'failed', order_id)
return web.json_response({'error': 'Failed to reserve items'}, status=500)
# Публикуем событие в Kafka (псевдокод)
# await kafka_producer.send('order_created', {'order_id': order_id, 'user_id': user_id})
await conn.execute('UPDATE orders SET status=$1 WHERE id=$2', 'processed', order_id)
return web.json_response({'order_id': order_id, 'total_price': total_price})
Важные моменты:
- Все внешние вызовы и операции с БД выполняются асинхронно.
- Ошибки внешних сервисов обрабатываются, чтобы не прерывать весь процесс.
- Транзакция в БД гарантирует целостность данных.
- Публикация в Kafka может быть реализована через асинхронный клиент.
Такой подход обеспечивает отзывчивость API и устойчивость к сбоям внешних сервисов.