hotspot / App /Metrics /MetricsRoutes.py
Mbonea's picture
added metrics
c353d4b
raw
history blame
4.52 kB
from fastapi import APIRouter
from typing import List
from datetime import datetime, timedelta
from decimal import Decimal
from tortoise.functions import Sum
from App.Payments.Model import Payment
from App.Users.Model import User
from .Schema import (
RevenueMetricsResponse,
RecurringUserResponse,
)
metrics_router = APIRouter(tags=["Metrics"])
# Helper function to get the start of the week, month, and day
def get_time_frames():
today = datetime.now()
start_of_day = today.replace(hour=0, minute=0, second=0, microsecond=0)
start_of_week = start_of_day - timedelta(
days=start_of_day.weekday()
) # Start of the current week (Monday)
start_of_month = start_of_day.replace(
day=1, hour=0, minute=0, second=0, microsecond=0
) # Start of the current month
return start_of_day, start_of_week, start_of_month
@metrics_router.get("/metrics/revenue/daily", response_model=RevenueMetricsResponse)
async def get_daily_revenue():
start_of_day, _, _ = get_time_frames()
# Sum up the payments made today using Tortoise ORM's annotate and values
revenue_data = (
await Payment.filter(created_time__gte=start_of_day)
.annotate(total_revenue=Sum("amount"))
.values("total_revenue")
)
if revenue_data and revenue_data[0]["total_revenue"] is not None:
total_revenue = revenue_data[0]["total_revenue"]
else:
total_revenue = Decimal("0.00")
return RevenueMetricsResponse(
period="daily",
revenue=float(total_revenue),
)
@metrics_router.get("/metrics/revenue/weekly", response_model=RevenueMetricsResponse)
async def get_weekly_revenue():
_, start_of_week, _ = get_time_frames()
# Sum up the payments made in the current week
revenue_data = (
await Payment.filter(created_time__gte=start_of_week)
.annotate(total_revenue=Sum("amount"))
.values("total_revenue")
)
if revenue_data and revenue_data[0]["total_revenue"] is not None:
total_revenue = revenue_data[0]["total_revenue"]
else:
total_revenue = Decimal("0.00")
return RevenueMetricsResponse(
period="weekly",
revenue=float(total_revenue),
)
@metrics_router.get("/metrics/revenue/monthly", response_model=RevenueMetricsResponse)
async def get_monthly_revenue():
_, _, start_of_month = get_time_frames()
# Sum up the payments made in the current month
revenue_data = (
await Payment.filter(created_time__gte=start_of_month)
.annotate(total_revenue=Sum("amount"))
.values("total_revenue")
)
if revenue_data and revenue_data[0]["total_revenue"] is not None:
total_revenue = revenue_data[0]["total_revenue"]
else:
total_revenue = Decimal("0.00")
return RevenueMetricsResponse(
period="monthly",
revenue=float(total_revenue),
)
@metrics_router.get(
"/metrics/recurring-users", response_model=List[RecurringUserResponse]
)
async def get_recurring_users():
# Get the start of the day and 6 days ago (total of 7 days including today)
start_of_day, _, _ = get_time_frames()
seven_days_ago = start_of_day - timedelta(days=6)
# Find all payments in the last 7 days
payments = await Payment.filter(created_time__gte=seven_days_ago).values(
"user_id", "created_time"
)
# Initialize a dictionary to hold payment dates per user
user_payment_dates = {}
# Collect payment dates per user
for payment in payments:
user_id = payment["user_id"]
payment_date = payment["created_time"].date()
if user_id not in user_payment_dates:
user_payment_dates[user_id] = set()
user_payment_dates[user_id].add(payment_date)
# Calculate the set of dates we expect payments on
expected_dates = set((start_of_day - timedelta(days=i)).date() for i in range(7))
# Filter users who have made payments on each expected date
recurring_users = [
user_id
for user_id, payment_dates in user_payment_dates.items()
if payment_dates == expected_dates
]
# Fetch user details for recurring users
recurring_user_details = await User.filter(id__in=recurring_users).all()
return [
RecurringUserResponse(
user_id=str(user.id),
username=user.username, # Adjust this field based on your User model
email=user.email, # Adjust as necessary
)
for user in recurring_user_details
]