101 lines
3.5 KiB
Python

from fastapi import APIRouter, HTTPException, Query, Request, status as http_status
from app.models import StrategyStartRequest
from app.services.strategy_service import (
start_strategy,
resume_strategy,
stop_strategy,
get_strategy_status,
get_strategy_summary,
get_engine_status,
get_market_status,
get_strategy_logs as fetch_strategy_logs,
)
from app.services.tenant import get_request_user_id
router = APIRouter(prefix="/api")
def _raise_strategy_error(payload: dict, *, default_status: int) -> None:
message = payload.get("message") or payload.get("detail") or "Strategy operation failed"
raise HTTPException(
status_code=default_status,
detail={
"status": payload.get("status", "error"),
"message": message,
"run_id": payload.get("run_id"),
"redirect_url": payload.get("redirect_url"),
"broker": payload.get("broker"),
},
)
@router.post("/strategy/start")
def start(req: StrategyStartRequest, request: Request):
user_id = get_request_user_id(request)
return start_strategy(req, user_id)
@router.post("/strategy/stop")
def stop(request: Request):
try:
user_id = get_request_user_id(request)
result = stop_strategy(user_id)
if result.get("status") not in {"stopped", "already_stopped"}:
_raise_strategy_error(result, default_status=http_status.HTTP_409_CONFLICT)
return result
except HTTPException:
raise
except Exception as exc:
print(f"[STRATEGY] unhandled stop route failure: {exc}", flush=True)
raise HTTPException(
status_code=http_status.HTTP_500_INTERNAL_SERVER_ERROR,
detail={"status": "stop_failed", "message": f"Unable to stop strategy: {exc}"},
) from exc
@router.post("/strategy/resume")
def resume(request: Request):
try:
user_id = get_request_user_id(request)
result = resume_strategy(user_id)
success_statuses = {"resumed", "already_running"}
if result.get("status") == "broker_auth_required":
_raise_strategy_error(result, default_status=http_status.HTTP_401_UNAUTHORIZED)
if result.get("status") not in success_statuses:
_raise_strategy_error(result, default_status=http_status.HTTP_409_CONFLICT)
return result
except HTTPException:
raise
except Exception as exc:
print(f"[STRATEGY] unhandled resume route failure: {exc}", flush=True)
raise HTTPException(
status_code=http_status.HTTP_500_INTERNAL_SERVER_ERROR,
detail={"status": "resume_failed", "message": f"Unable to resume strategy: {exc}"},
) from exc
@router.get("/strategy/status")
def status(request: Request):
user_id = get_request_user_id(request)
return get_strategy_status(user_id)
@router.get("/strategy/summary")
def summary(request: Request):
user_id = get_request_user_id(request)
return get_strategy_summary(user_id)
@router.get("/engine/status")
def engine_status(request: Request):
user_id = get_request_user_id(request)
return get_engine_status(user_id)
@router.get("/market/status")
def market_status():
return get_market_status()
@router.get("/logs")
def get_logs(request: Request, since_seq: int = Query(0)):
user_id = get_request_user_id(request)
return fetch_strategy_logs(user_id, since_seq)
@router.get("/strategy/logs")
def get_strategy_logs_endpoint(request: Request, since_seq: int = Query(0)):
user_id = get_request_user_id(request)
return fetch_strategy_logs(user_id, since_seq)