XYHLF / App /routers /utt /routes.py
Mbonea's picture
initial commit
9d4bd7c
from fastapi import APIRouter, BackgroundTasks
from .models import UTTFund, UTTFundData
from .schemas import UTTFundResponse, UTTFundListResponse, ResponseModel
from .service import fetch_all_utt_data, parse_utt_api_row
from App.routers.tasks.models import ImportTask
from App.routers.utt.utils import run_utt_import_task
from App.schemas import AppException
from tortoise.contrib.pydantic import pydantic_queryset_creator
UTTFundData_Pydantic_List = pydantic_queryset_creator(UTTFundData)
UTTFund_Pydantic_List = pydantic_queryset_creator(UTTFund)
router = APIRouter(prefix="/utt", tags=["UTT"])
@router.get("/", response_model=ResponseModel)
async def list_funds_orm():
"""
Alternative using Tortoise ORM - less efficient but more ORM-friendly
"""
try:
# Get all funds
funds = await UTTFund.all()
if not funds:
raise AppException(status_code=404, detail="No UTT funds found")
# Get latest data for each fund
fund_ids = [fund.id for fund in funds]
latest_data = {}
# For each fund, get only the latest data (most recent date)
for fund_id in fund_ids:
latest = await UTTFundData.filter(fund_id=fund_id).order_by("-date").first()
if latest:
latest_data[fund_id] = latest
# Build the response
fund_list = []
for fund in funds:
latest = latest_data.get(fund.id)
fund_data = {
"id": fund.id,
"symbol": fund.symbol,
"name": fund.name,
"nav_per_unit": latest.nav_per_unit if latest else None,
"sale_price_per_unit": latest.sale_price_per_unit if latest else None,
"repurchase_price_per_unit": (
latest.repurchase_price_per_unit if latest else None
),
"outstanding_number_of_units": (
latest.outstanding_number_of_units if latest else None
),
"net_asset_value": latest.net_asset_value if latest else None,
"latest_date": latest.date.isoformat() if latest else None,
}
fund_list.append(fund_data)
return ResponseModel(
success=True,
message=f"Retrieved {len(fund_list)} UTT funds with latest data",
data={"funds": fund_list, "count": len(fund_list)},
)
except Exception as e:
raise AppException(
status_code=500, detail=f"Error retrieving UTT funds: {str(e)}"
)
@router.get("/{symbol}", response_model=ResponseModel)
async def get_fund_data(symbol: str):
fund = await UTTFund.get_or_none(symbol=symbol)
if not fund:
raise AppException(status_code=404, detail="Fund not found")
data_queryset = UTTFundData.filter(fund=fund).order_by("-date").limit(100)
utt_fund_data_pydantic = await UTTFundData_Pydantic_List.from_queryset(
data_queryset
)
return ResponseModel(
success=True,
message="Fund data",
data={"data": utt_fund_data_pydantic.model_dump()},
)
@router.post("/import-all", response_model=ResponseModel)
async def queue_import_utt(background_tasks: BackgroundTasks):
task = await ImportTask.create(task_type="utt", status="pending", details={})
background_tasks.add_task(run_utt_import_task, task.id)
return ResponseModel(
success=True, message="UTT import task queued", data={"task_id": task.id}
)