Spaces:
Runtime error
Runtime error
| 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) | |
| 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} |