Download backend/utils.py from umar-100/fello-iq: direct link, hf CLI and curl.
- Browser
- Download file 4.26 kB
-
https://huggingface.co/spaces/umar-100/fello-iq/resolve/main/backend/utils.py
- Command line
-
hf download hf://spaces/umar-100/fello-iq/backend/utils.py
-
curl -L -o utils.py https://huggingface.co/spaces/umar-100/fello-iq/resolve/main/backend/utils.py
4.26 kB
| import os | |
| from fpdf import FPDF | |
| from googleapiclient.discovery import build | |
| from google.oauth2 import service_account | |
| from typing import List | |
| from dotenv import load_dotenv | |
| import json | |
| load_dotenv() | |
| class FelloUtils: | |
| def generate_pdf_report(data: dict) -> bytes: | |
| """Generates a professional PDF report with heavy debugging.""" | |
| try: | |
| pdf = FPDF() | |
| pdf.add_page() | |
| # Helper function to sanitize text for Latin-1 (FPDF default) | |
| def s(text): | |
| if text is None: return "" | |
| # Replace common problematic unicode characters that crash FPDF | |
| return str(text).encode('latin-1', 'replace').decode('latin-1') | |
| # 1. Title | |
| pdf.set_font("Arial", 'B', 20) | |
| pdf.set_text_color(37, 99, 235) | |
| pdf.cell(200, 15, txt="Fello IQ Account Intelligence", ln=True, align='C') | |
| pdf.ln(10) | |
| # 2. Company Identity | |
| pdf.set_font("Arial", 'B', 14) | |
| pdf.set_text_color(15, 23, 42) | |
| company = s(data.get('company_name', 'N/A')) | |
| domain = s(data.get('domain', 'N/A')) | |
| pdf.cell(0, 10, txt=f"Account: {company} ({domain})", ln=True) | |
| pdf.set_font("Arial", size=10) | |
| industry = s(data.get('industry', 'N/A')) | |
| revenue = s(data.get('annual_revenue', 'N/A')) | |
| pdf.cell(0, 7, txt=f"Industry: {industry} | Revenue: {revenue}", ln=True) | |
| pdf.ln(5) | |
| # 3. Strategic Intelligence | |
| pdf.set_font("Arial", 'B', 12) | |
| score = data.get('intent_score', 0) | |
| stage = s(data.get('intent_stage', 'Unknown')) | |
| pdf.cell(0, 10, txt=f"Intent Score: {score}/10 - {stage}", ln=True) | |
| pdf.set_font("Arial", 'I', 10) | |
| summary = s(data.get('ai_summary', 'No summary available.')) | |
| pdf.multi_cell(0, 7, txt=f"AI Summary: {summary}") | |
| pdf.ln(5) | |
| # 4. Recommended Actions | |
| pdf.set_font("Arial", 'B', 12) | |
| pdf.cell(0, 10, txt="Recommended Sales Actions:", ln=True) | |
| pdf.set_font("Arial", size=10) | |
| actions = data.get('recommended_sales_actions', []) | |
| if not actions: | |
| pdf.cell(0, 7, txt="- No specific actions recommended.", ln=True) | |
| else: | |
| for action in actions: | |
| pdf.multi_cell(0, 7, txt=s(f"- {action}")) | |
| pdf_output = pdf.output(dest='S') | |
| return pdf_output.encode('latin-1', 'replace') | |
| except Exception as e: | |
| print("!!! PDF GENERATION CRASHED !!!") | |
| print(traceback.format_exc()) | |
| raise e | |
| def sync_to_google_sheets(data: dict): | |
| """Appends research data to Google Sheets using your reference logic.""" | |
| SCOPES = ["https://www.googleapis.com/auth/spreadsheets"] | |
| SPREADSHEET_ID = os.getenv("SPREADSHEET_ID") | |
| try: | |
| creds_json = os.getenv("GOOGLE_CREDENTIALS_JSON") | |
| creds_info = json.loads(creds_json) | |
| creds = service_account.Credentials.from_service_account_info( | |
| creds_info, scopes=SCOPES | |
| ) | |
| service = build("sheets", "v4", credentials=creds) | |
| # Formatting the row based on the Pydantic model | |
| values = [ | |
| data['company_name'], | |
| data['domain'], | |
| data['intent_score'], | |
| data['intent_stage'], | |
| data['industry'], | |
| data['annual_revenue'], | |
| ", ".join(data['recommended_sales_actions'][:2]) | |
| ] | |
| body = {"values": [values]} | |
| service.spreadsheets().values().append( | |
| spreadsheetId=SPREADSHEET_ID, | |
| range="Sheet1", | |
| valueInputOption="USER_ENTERED", | |
| insertDataOption="INSERT_ROWS", | |
| body=body | |
| ).execute() | |
| return True | |
| except Exception as e: | |
| print(f"Google Sheets Sync Error: {e}") | |
| return False |