Files
ApiGatewayTest/service-2-main.py
2026-01-04 23:01:46 +03:00

207 lines
7.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Второй микросервис - Service 2
Предоставляет API для управления заказами и продуктами
"""
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List, Optional
from datetime import datetime
import logging
app = FastAPI(
title="Service 2 - Order Service",
description="Микросервис для управления заказами и продуктами",
version="1.0.0"
)
# Логирование
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Модели данных
class Product(BaseModel):
id: int
name: str
price: float
quantity: int
class ProductCreate(BaseModel):
name: str
price: float
quantity: int
class Order(BaseModel):
id: int
user_id: int
product_id: int
quantity: int
total_price: float
created_at: str
class OrderCreate(BaseModel):
user_id: int
product_id: int
quantity: int
# Имитация базы данных
products_db = {
1: {"id": 1, "name": "Ноутбук", "price": 50000.00, "quantity": 5},
2: {"id": 2, "name": "Монитор", "price": 15000.00, "quantity": 10},
3: {"id": 3, "name": "Клавиатура", "price": 3000.00, "quantity": 25},
}
orders_db = {
1: {
"id": 1,
"user_id": 1,
"product_id": 1,
"quantity": 1,
"total_price": 50000.00,
"created_at": "2025-01-01T10:00:00"
},
}
next_product_id = 4
next_order_id = 2
# Маршруты
@app.get("/", tags=["Health"])
async def root():
"""Проверка работоспособности Service 2"""
logger.info("Health check для Service 2")
return {
"service": "Service 2 - Order Service",
"status": "operational",
"version": "1.0.0"
}
@app.get("/health", tags=["Health"])
async def health_check():
"""Health check endpoint"""
return {"status": "healthy", "service": "order-service"}
# Endpoints для продуктов
@app.get("/products", response_model=List[Product], tags=["Products"])
async def list_products(skip: int = 0, limit: int = 10):
"""Получить список всех продуктов"""
logger.info(f"Получение списка продуктов (skip={skip}, limit={limit})")
products_list = list(products_db.values())
return products_list[skip:skip + limit]
@app.get("/products/{product_id}", response_model=Product, tags=["Products"])
async def get_product(product_id: int):
"""Получить продукт по ID"""
logger.info(f"Получение продукта с ID: {product_id}")
if product_id not in products_db:
logger.warning(f"Продукт с ID {product_id} не найден")
raise HTTPException(status_code=404, detail="Продукт не найден")
return products_db[product_id]
@app.post("/products", response_model=Product, tags=["Products"])
async def create_product(product: ProductCreate):
"""Создать новый продукт"""
global next_product_id
logger.info(f"Создание нового продукта: {product.name}")
new_product = {
"id": next_product_id,
"name": product.name,
"price": product.price,
"quantity": product.quantity
}
products_db[next_product_id] = new_product
next_product_id += 1
logger.info(f"Продукт создан с ID: {new_product['id']}")
return new_product
@app.put("/products/{product_id}", response_model=Product, tags=["Products"])
async def update_product(product_id: int, product: ProductCreate):
"""Обновить продукт"""
logger.info(f"Обновление продукта с ID: {product_id}")
if product_id not in products_db:
raise HTTPException(status_code=404, detail="Продукт не найден")
updated_product = {
"id": product_id,
"name": product.name,
"price": product.price,
"quantity": product.quantity
}
products_db[product_id] = updated_product
return updated_product
@app.delete("/products/{product_id}", tags=["Products"])
async def delete_product(product_id: int):
"""Удалить продукт"""
logger.info(f"Удаление продукта с ID: {product_id}")
if product_id not in products_db:
raise HTTPException(status_code=404, detail="Продукт не найден")
del products_db[product_id]
return {"message": f"Продукт {product_id} удален"}
# Endpoints для заказов
@app.get("/orders", response_model=List[Order], tags=["Orders"])
async def list_orders(skip: int = 0, limit: int = 10):
"""Получить список всех заказов"""
logger.info(f"Получение списка заказов (skip={skip}, limit={limit})")
orders_list = list(orders_db.values())
return orders_list[skip:skip + limit]
@app.get("/orders/{order_id}", response_model=Order, tags=["Orders"])
async def get_order(order_id: int):
"""Получить заказ по ID"""
logger.info(f"Получение заказа с ID: {order_id}")
if order_id not in orders_db:
logger.warning(f"Заказ с ID {order_id} не найден")
raise HTTPException(status_code=404, detail="Заказ не найден")
return orders_db[order_id]
@app.post("/orders", response_model=Order, tags=["Orders"])
async def create_order(order: OrderCreate):
"""Создать новый заказ"""
global next_order_id
logger.info(f"Создание нового заказа для пользователя {order.user_id}")
if order.product_id not in products_db:
raise HTTPException(status_code=404, detail="Продукт не найден")
product = products_db[order.product_id]
if product["quantity"] < order.quantity:
raise HTTPException(status_code=400, detail="Недостаточно товара на складе")
total_price = product["price"] * order.quantity
new_order = {
"id": next_order_id,
"user_id": order.user_id,
"product_id": order.product_id,
"quantity": order.quantity,
"total_price": total_price,
"created_at": datetime.utcnow().isoformat()
}
orders_db[next_order_id] = new_order
product["quantity"] -= order.quantity
next_order_id += 1
logger.info(f"Заказ создан с ID: {new_order['id']}")
return new_order
@app.get("/stats", tags=["Stats"])
async def get_stats():
"""Получить статистику по заказам"""
logger.info("Получение статистики")
total_revenue = sum(order["total_price"] for order in orders_db.values())
return {
"total_orders": len(orders_db),
"total_products": len(products_db),
"total_revenue": total_revenue,
"service": "order-service"
}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8002)