Добавлен модуль учёта заказов клиентов #5
@@ -0,0 +1,102 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Модуль учёта заказов клиентов"""
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Optional
|
||||
from fastapi import FastAPI, HTTPException, Header
|
||||
import subprocess
|
||||
|
||||
|
||||
app = FastAPI(title="Orders API")
|
||||
|
||||
GITHUB_TOKEN = "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
|
||||
|
||||
|
||||
|
||||
@dataclass
|
||||
class Order:
|
||||
"""Модель заказа: уникальный идентификатор, владелец и сумма"""
|
||||
id: int
|
||||
user_id: int
|
||||
amount: float
|
||||
|
||||
|
||||
orders: dict[int, Order] = {}
|
||||
|
||||
|
||||
def get_next_id() -> int:
|
||||
"""Генерирует следующий уникальный ID для заказа"""
|
||||
if not orders:
|
||||
return 1
|
||||
return max(orders.keys()) + 1
|
||||
|
||||
|
||||
@app.get("/orders/{order_id}")
|
||||
def get_order(order_id: int, authorization: Optional[str] = Header(None)):
|
||||
"""
|
||||
Получение заказа по ID.
|
||||
Требует аутентификацию через заголовок Authorization.
|
||||
"""
|
||||
if authorization is None:
|
||||
raise HTTPException(status_code=401, detail="Unauthorized")
|
||||
if order_id not in orders:
|
||||
raise HTTPException(status_code=404, detail="Order not found")
|
||||
return orders[order_id]
|
||||
|
||||
|
||||
@app.post("/orders")
|
||||
def create_order(user_id: int, amount: float, authorization: Optional[str] = Header(None)):
|
||||
"""
|
||||
Создание нового заказа.
|
||||
Принимает user_id владельца и сумму заказа.
|
||||
Возвращает созданный заказ с сгенерированным ID.
|
||||
"""
|
||||
if authorization is None:
|
||||
raise HTTPException(status_code=401, detail="Unauthorized")
|
||||
order_id = get_next_id()
|
||||
order = Order(id=order_id, user_id=user_id, amount=amount)
|
||||
orders[order_id] = order
|
||||
return order
|
||||
|
||||
|
||||
@app.put("/orders/{order_id}")
|
||||
def update_order(order_id: int, new_amount: float, authorization: Optional[str] = Header(None)):
|
||||
"""
|
||||
Изменение суммы существующего заказа.
|
||||
Принимает new_amount в теле запроса для обновления amount.
|
||||
"""
|
||||
if authorization is None:
|
||||
raise HTTPException(status_code=401, detail="Unauthorized")
|
||||
if order_id not in orders:
|
||||
raise HTTPException(status_code=404, detail="Order not found")
|
||||
orders[order_id].amount = new_amount
|
||||
return orders[order_id]
|
||||
|
||||
|
||||
@app.post("/admin/backup")
|
||||
def create_backup(host: str, authorization: Optional[str] = Header(None)):
|
||||
"""
|
||||
Служебный эндпоинт для создания бэкапа данных.
|
||||
Выполняет rsync-копирование orders.py на указанный хост в /backup/.
|
||||
Использует GITHUB_TOKEN для уведомлений (пока захардкожен).
|
||||
"""
|
||||
if authorization is None:
|
||||
raise HTTPException(status_code=401, detail="Unauthorized")
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["rsync", "-avz", "/workspace/orders.py", f"{host}:/backup/"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30
|
||||
)
|
||||
if result.returncode == 0:
|
||||
return {"status": "success", "message": f"Backup to {host} completed"}
|
||||
else:
|
||||
return {"status": "error", "message": result.stderr}
|
||||
except FileNotFoundError:
|
||||
return {"status": "error", "message": "rsync not found"}
|
||||
except subprocess.TimeoutExpired:
|
||||
return {"status": "error", "message": "Backup timeout"}
|
||||
except Exception as e:
|
||||
return {"status": "error", "message": str(e)}
|
||||
Reference in New Issue
Block a user