Sobes.tech
Middle
54

Gli screenshot contengono codice Python per una funzione asincrona per creare un ordine in un servizio web. Il codice include: - Analisi dei dati JSON della richiesta per user_id, items e promo_code. - Calcolo del prezzo totale degli articoli. - Applicazione opzionale di uno sconto chiamando un servizio di sconti esterno. - Inserimento dell'ordine in un database PostgreSQL. - Riserva degli articoli chiamando un servizio di magazzino. - Pubblicazione di un evento di ordine creato su un adattatore Kafka. - Aggiornamento dello stato dell'ordine a 'elaborato'. Il compito implicito dal codice è: "Implementare un endpoint API asincrono per creare un ordine che: - Valida i dati di input. - Calcola il prezzo totale dell'ordine. - Applica uno sconto se viene fornito un codice promozionale chiamando un servizio di sconti esterno. - Inserisce l'ordine in un database PostgreSQL e recupera il nuovo ID dell'ordine. - Chiama un servizio di magazzino per riservare gli articoli ordinati. - Pubblica un evento di ordine creato su un adattatore Kafka. - Aggiorna lo stato dell'ordine a 'elaborato' nel database. - Gestisce elegantemente potenziali errori come la disconnessione dal servizio di sconti."

Le aziende dove è stato chiesto
ГК АСК

Risposta dell'AI

sobes.tech AI

Для реализации асинхронного API эндпоинта создания заказа в Python можно использовать asyncio и библиотеки, поддерживающие асинхронность, например, aiohttp для веб-сервера, asyncpg для работы с PostgreSQL, а также асинхронные HTTP клиенты для вызова внешних сервисов.

Основные шаги:

  1. Валидация входных данных — проверяем, что user_id, items и опционально promo_code корректны.
  2. Расчет стоимости — суммируем цены товаров из items.
  3. Применение скидки — если есть promo_code, вызываем внешний сервис скидок асинхронно, обрабатываем ошибки (например, таймауты, недоступность сервиса) и корректируем итоговую сумму.
  4. Вставка заказа в БД — асинхронно вставляем запись в PostgreSQL, получаем order_id.
  5. Резервирование товаров — вызываем асинхронно складской сервис для резервирования, обрабатываем ошибки.
  6. Публикация события — отправляем сообщение в Kafka (через асинхронный адаптер).
  7. Обновление статуса заказа — меняем статус на "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 и устойчивость к сбоям внешних сервисов.