graph2reckon / main.py
shreyankisiri's picture
Rename app.py to main.py
d0eb37e verified
from fastapi import FastAPI, HTTPException
import numpy as np
import matplotlib.pyplot as plt
from io import BytesIO
from google.cloud import storage
import os
app = FastAPI()
# Google Cloud Storage settings
GCS_BUCKET_NAME = "your-bucket-name" # Replace with your GCS bucket name
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "path/to/your/service-account-key.json" # Replace with your service account key path
class FinancialAnalyzer:
def __init__(self, categories, hardcoded_limits):
self.categories = categories
self.hardcoded_limits = hardcoded_limits
def generate_spending_data(self):
spending_data = {}
for category in self.categories:
avg_daily_limit = self.hardcoded_limits[category] / 100
spending_data[category] = np.random.uniform(0.8 * avg_daily_limit, 1.2 * avg_daily_limit, 100)
return spending_data
def analyze_spending(self, spending_data):
overspent_categories = []
category_to_avoid = None
largest_excess = 0
analysis_result = {"overspent_categories": [], "category_to_avoid": None, "details": {}}
for category, daily_spending in spending_data.items():
avg_daily_spending = np.mean(daily_spending)
hardcoded_limit = self.hardcoded_limits[category] / 100
analysis_result["details"][category] = {
"average_daily_spending": avg_daily_spending,
"daily_limit": hardcoded_limit,
"status": "Within limit"
}
if avg_daily_spending > 1.10 * hardcoded_limit:
overspent_categories.append(category)
excess = avg_daily_spending - hardcoded_limit
if excess > largest_excess:
largest_excess = excess
category_to_avoid = category
analysis_result["details"][category]["status"] = "Overspending"
analysis_result["overspent_categories"] = overspent_categories
analysis_result["category_to_avoid"] = category_to_avoid
return analysis_result
def estimate_days_left(self, spending_data, current_balance):
avg_daily_spending_all = np.mean([np.mean(spending) for spending in spending_data.values()])
days_left = current_balance / avg_daily_spending_all if avg_daily_spending_all != 0 else float('inf')
return days_left
def plot_spending_trends(self, spending_data, days_left):
plt.figure(figsize=(12, 8))
for category, daily_spending in spending_data.items():
plt.plot(range(1, 101), daily_spending, label=f"{category} (Actual)")
extended_days = int(np.ceil(days_left))
extended_spending = daily_spending[:extended_days]
if len(extended_spending) < extended_days:
extended_spending = np.concatenate([extended_spending, np.full(extended_days - len(extended_spending), daily_spending[-1])])
plt.plot(range(101, 101 + extended_days), extended_spending, '--', label=f"{category} (Continued)")
plt.axvline(x=100, color='red', linestyle='--', label="End of 100 Days")
plt.xlabel("Days")
plt.ylabel("Daily Spending ($)")
plt.title("Spending Trends with Continued Spending until Balance Exhausts")
plt.legend()
plt.grid(True)
# Save the plot to a BytesIO object
buf = BytesIO()
plt.savefig(buf, format="png")
plt.close()
buf.seek(0)
return buf
def upload_to_gcs(bucket_name, file_name, file_data):
"""Uploads a file to Google Cloud Storage and makes it publicly accessible."""
client = storage.Client()
bucket = client.bucket(bucket_name)
blob = bucket.blob(file_name)
blob.upload_from_file(file_data, rewind=True)
# Make the file publicly accessible
blob.make_public()
return blob.public_url
# Initialize the financial analyzer
categories = ['Food', 'Entertainment', 'Shopping', 'Rent', 'Travel']
hardcoded_limits = {
'Food': 10000,
'Entertainment': 1000,
'Shopping': 4000,
'Rent': 2600,
'Travel': 3000
}
analyzer = FinancialAnalyzer(categories, hardcoded_limits)
@app.get("/analyze")
async def analyze(current_balance: float):
# Generate spending data
spending_data = analyzer.generate_spending_data()
# Analyze spending
analysis_result = analyzer.analyze_spending(spending_data)
# Estimate days left
days_left = analyzer.estimate_days_left(spending_data, current_balance)
analysis_result["days_left"] = days_left
# Generate the plot
plot_buffer = analyzer.plot_spending_trends(spending_data, days_left)
# Upload the plot to Google Cloud Storage
file_name = f"spending_trends_{np.random.randint(1000, 9999)}.png"
try:
image_url = upload_to_gcs(GCS_BUCKET_NAME, file_name, plot_buffer)
except Exception as e:
raise HTTPException(status_code=500, detail=f"Failed to upload image to GCS: {str(e)}")
# Return the GCS URL
return {"analysis_result": analysis_result, "image_url": image_url}