Spaces:
Sleeping
Sleeping
| #!/usr/bin/env python3 | |
| import requests | |
| import sys | |
| from typing import Dict, Any | |
| API_BASE = "http://127.0.0.1:8000/api/v1" | |
| class EmailQueryCLI: | |
| def __init__(self): | |
| self.session = requests.Session() | |
| def check_connection(self) -> bool: | |
| """Check if API server is running""" | |
| try: | |
| response = self.session.get(f"{API_BASE}/health") | |
| response.raise_for_status() | |
| return True | |
| except: | |
| return False | |
| def pretty_print_email(self, email: Dict) -> str: | |
| """Format email for display""" | |
| return f""" | |
| π§ {email['subject']} | |
| π {email['date']} {email['time']} | |
| π¬ {email['content'][:200]}... | |
| π {email['message_id'][:20]}... | |
| {"β" * 60}""" | |
| def handle_query(self, query: str): | |
| """Handle a natural language query""" | |
| print(f"\nπ Processing: '{query}'") | |
| try: | |
| # Try to get emails directly | |
| response = self.session.post( | |
| f"{API_BASE}/get_emails", | |
| json={"query": query} | |
| ) | |
| if response.status_code == 200: | |
| data = response.json() | |
| self.display_email_results(data) | |
| return True | |
| elif response.status_code == 400: | |
| error_detail = response.json()["detail"] | |
| # Check if we need email mapping | |
| if isinstance(error_detail, dict) and error_detail.get("type") == "need_email_input": | |
| mapping_success = self.handle_missing_mapping(error_detail) | |
| if mapping_success and hasattr(self, '_retry_query'): | |
| # Retry the query after successful mapping | |
| print(f"π Retrying query...") | |
| delattr(self, '_retry_query') | |
| return self.handle_query(query) # Recursive retry | |
| return mapping_success | |
| else: | |
| print(f"β Error: {error_detail}") | |
| return False | |
| else: | |
| print(f"β API Error: {response.status_code}") | |
| return False | |
| except Exception as e: | |
| print(f"β Connection Error: {e}") | |
| return False | |
| def handle_missing_mapping(self, error_detail: Dict) -> bool: | |
| """Handle case where email mapping is needed""" | |
| sender_intent = error_detail["sender_intent"] | |
| print(f"\nβ {error_detail['message']}") | |
| try: | |
| email = input(f"π§ Enter email for '{sender_intent}': ").strip() | |
| if not email or "@" not in email: | |
| print("β Invalid email address") | |
| return False | |
| # Add the mapping | |
| mapping_response = self.session.post( | |
| f"{API_BASE}/add_email_mapping", | |
| json={"name": sender_intent, "email": email} | |
| ) | |
| if mapping_response.status_code == 200: | |
| print(f"β Mapping saved: '{sender_intent}' β '{email}'") | |
| self._retry_query = True # Flag to retry the original query | |
| return True | |
| else: | |
| print(f"β Failed to save mapping: {mapping_response.text}") | |
| return False | |
| except KeyboardInterrupt: | |
| print("\nβ Cancelled") | |
| return False | |
| def display_email_results(self, data: Dict): | |
| """Display email search results""" | |
| print(f"\nβ Found {data['total_emails']} emails") | |
| print(f"π€ From: {data['resolved_email']}") | |
| print(f"π Period: {data['start_date']} to {data['end_date']}") | |
| if data['emails']: | |
| print(f"\nπ§ Emails:") | |
| for email in data['emails'][:10]: # Show first 10 | |
| print(self.pretty_print_email(email)) | |
| if len(data['emails']) > 10: | |
| print(f"\n... and {len(data['emails']) - 10} more emails") | |
| else: | |
| print("\nπ No emails found in this date range") | |
| def show_mappings(self): | |
| """Display all stored name-to-email mappings""" | |
| try: | |
| response = self.session.get(f"{API_BASE}/view_mappings") | |
| if response.status_code == 200: | |
| data = response.json() | |
| mappings = data["mappings"] | |
| print(f"\nπ Stored Mappings ({len(mappings)}):") | |
| if mappings: | |
| for name, email in mappings.items(): | |
| print(f" π€ {name} β π§ {email}") | |
| else: | |
| print(" (No mappings stored)") | |
| else: | |
| print(f"β Failed to load mappings: {response.text}") | |
| except Exception as e: | |
| print(f"β Error: {e}") | |
| def run(self): | |
| """Main CLI loop""" | |
| if not self.check_connection(): | |
| print("β Cannot connect to API server at http://127.0.0.1:8000") | |
| print(" Make sure to run: uvicorn main:app --reload") | |
| sys.exit(1) | |
| print("β Connected to Email Query System") | |
| print("π‘ Try queries like:") | |
| print(" β’ 'emails from john last week'") | |
| print(" β’ 'show amazon emails from last month'") | |
| print(" β’ 'get dev@iitj.ac.in emails yesterday'") | |
| print("\nπ Commands:") | |
| print(" β’ 'mappings' - View stored name-to-email mappings") | |
| print(" β’ 'quit' or Ctrl+C - Exit") | |
| print("=" * 60) | |
| while True: | |
| try: | |
| query = input("\nπ¨οΈ You: ").strip() | |
| if not query: | |
| continue | |
| if query.lower() in ['quit', 'exit', 'q']: | |
| break | |
| elif query.lower() in ['mappings', 'map', 'm']: | |
| self.show_mappings() | |
| elif query.lower() in ['help', 'h']: | |
| print("\nπ‘ Examples:") | |
| print(" β’ emails from amazon last 5 days") | |
| print(" β’ show john smith emails this week") | |
| print(" β’ get notifications from google yesterday") | |
| else: | |
| self.handle_query(query) | |
| except KeyboardInterrupt: | |
| break | |
| except Exception as e: | |
| print(f"β Unexpected error: {e}") | |
| print("\nπ Goodbye!") | |
| def main(): | |
| """Entry point for CLI""" | |
| cli = EmailQueryCLI() | |
| cli.run() | |
| if __name__ == "__main__": | |
| main() |