Spaces:
Sleeping
Sleeping
| import os | |
| import json | |
| import openai | |
| import google.generativeai as genai | |
| import requests | |
| import logging | |
| from app.core.config import settings | |
| # Configure logging | |
| logging.basicConfig(level=logging.INFO) | |
| logger = logging.getLogger(__name__) | |
| # ANSI color codes | |
| RED = "\033[91m" | |
| GREEN = "\033[92m" | |
| BLUE = "\033[94m" | |
| RESET = "\033[0m" | |
| class OpenAIClient: | |
| def __init__(self): | |
| self.api_key = settings.OPENAI_API_KEY | |
| openai.api_key = self.api_key | |
| self.model = settings.OPENAI_MODEL | |
| logger.info(f"Initialized OpenAIClient with model: {self.model}") | |
| async def generate_text(self, prompt, system_message=None, temperature=0.7): | |
| messages = [] | |
| if system_message: | |
| messages.append({"role": "system", "content": system_message}) | |
| messages.append({"role": "user", "content": prompt}) | |
| print(f"{GREEN}[OpenAIClient] Sending prompt:{RESET}", prompt[:500]) | |
| logger.info(f"OpenAIClient: Sending request with model {self.model}") | |
| try: | |
| response = openai.chat.completions.create( | |
| model=self.model, | |
| messages=messages, | |
| temperature=temperature, | |
| ) | |
| print(f"{GREEN}[OpenAIClient] Received response:{RESET}", response.choices[0].message.content[:500]) | |
| return response.choices[0].message.content | |
| except Exception as e: | |
| error_message = f"OpenAIClient error: {str(e)}" | |
| print(f"{GREEN}[OpenAIClient] {error_message}{RESET}") | |
| logger.error(error_message) | |
| raise | |
| class PerplexityClient: | |
| def __init__(self): | |
| # Hardcoded API key | |
| self.api_key = "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" | |
| self.base_url = "https://api.perplexity.ai" | |
| self.model = "sonar" | |
| logger.info(f"Initialized PerplexityClient with model: {self.model}") | |
| async def search_market_insights(self, query): | |
| print(f"{RED}[PerplexityClient] Query:{RESET}", query) | |
| if not self.api_key: | |
| error_message = "API key is missing or empty" | |
| print(f"{RED}[PerplexityClient] {error_message}, using mock data.{RESET}") | |
| logger.warning(error_message) | |
| result = self._get_mock_competitor_data(query) | |
| print(f"{RED}[PerplexityClient] Mock response:{RESET}", result[:500]) | |
| return result | |
| try: | |
| headers = { | |
| "Authorization": f"Bearer {self.api_key}", | |
| "Content-Type": "application/json" | |
| } | |
| data = { | |
| "model": self.model, | |
| "messages": [{"role": "user", "content": query}], | |
| "stream": False | |
| } | |
| logger.info(f"PerplexityClient: Sending request to {self.base_url}/chat/completions with model {self.model}") | |
| response = requests.post( | |
| f"{self.base_url}/chat/completions", | |
| headers=headers, | |
| json=data | |
| ) | |
| if response.status_code != 200: | |
| error_message = f"API error {response.status_code}: {response.text}" | |
| print(f"{RED}[PerplexityClient] {error_message}, using mock data.{RESET}") | |
| logger.error(error_message) | |
| result = self._get_mock_competitor_data(query) | |
| print(f"{RED}[PerplexityClient] Mock response:{RESET}", result[:500]) | |
| return result | |
| result = response.json()["choices"][0]["message"]["content"] | |
| print(f"{RED}[PerplexityClient] API response:{RESET}", result[:500]) | |
| # Extract JSON from response if present | |
| import re | |
| json_pattern = r'```json(.*?)```' | |
| json_match = re.search(json_pattern, result, re.DOTALL) | |
| if json_match: | |
| # Extract the JSON content from between the backticks | |
| json_content = json_match.group(1).strip() | |
| return json_content | |
| return result | |
| except Exception as e: | |
| error_message = f"Exception: {str(e)}" | |
| print(f"{RED}[PerplexityClient] {error_message}, using mock data.{RESET}") | |
| logger.error(error_message) | |
| result = self._get_mock_competitor_data(query) | |
| print(f"{RED}[PerplexityClient] Mock response:{RESET}", result[:500]) | |
| return result | |
| def _get_mock_competitor_data(self, query): | |
| """ | |
| Generate mock competitor data when Perplexity API is unavailable | |
| """ | |
| # Extract startup name from query | |
| import re | |
| startup_name_match = re.search(r"for ([^,]+),", query) | |
| startup_name = startup_name_match.group(1) if startup_name_match else "YourStartup" | |
| # Extract problem from query | |
| problem_match = re.search(r"that (.*?) with", query) | |
| problem = problem_match.group(1) if problem_match else "solves a unique problem" | |
| # Generate generic competitors based on the problem | |
| mock_data = [ | |
| { | |
| "name": f"Competitor 1 for {startup_name}", | |
| "description": f"An established company that partially addresses {problem}", | |
| "strengths": [ | |
| "Strong market presence", | |
| "Established customer base", | |
| "Strong funding backing" | |
| ], | |
| "weaknesses": [ | |
| "Outdated technology", | |
| "Limited feature set", | |
| "Higher price point" | |
| ] | |
| }, | |
| { | |
| "name": f"Competitor 2 for {startup_name}", | |
| "description": f"A newer entrant focusing on a specific aspect of {problem}", | |
| "strengths": [ | |
| "Modern technology stack", | |
| "User-friendly interface", | |
| "Rapid innovation" | |
| ], | |
| "weaknesses": [ | |
| "Limited market reach", | |
| "Narrow focus", | |
| "Less comprehensive solution" | |
| ] | |
| }, | |
| { | |
| "name": f"Competitor 3 for {startup_name}", | |
| "description": f"A traditional player in the {problem} space", | |
| "strengths": [ | |
| "Industry experience", | |
| "Trusted brand", | |
| "Wide distribution network" | |
| ], | |
| "weaknesses": [ | |
| "Slow to innovate", | |
| "Complex user experience", | |
| "Higher operational costs" | |
| ] | |
| } | |
| ] | |
| return json.dumps(mock_data) | |
| class GeminiClient: | |
| def __init__(self): | |
| self.api_key = settings.GEMINI_API_KEY | |
| # Get model name from settings if available, else use default | |
| self.model_name = getattr(settings, "GEMINI_MODEL", "gemini-2.0-flash") | |
| logger.info(f"Initialized GeminiClient with model: {self.model_name}") | |
| if self.api_key: | |
| genai.configure(api_key=self.api_key) | |
| try: | |
| self.model = genai.GenerativeModel(self.model_name) | |
| logger.info(f"Successfully configured Gemini model: {self.model_name}") | |
| except Exception as e: | |
| error_message = f"Failed to initialize Gemini model: {str(e)}" | |
| logger.error(error_message) | |
| print(f"{BLUE}[GeminiClient] {error_message}{RESET}") | |
| self.model = None | |
| async def refine_business_angle(self, input_text): | |
| print(f"{BLUE}[GeminiClient] Input text:{RESET}", input_text[:500]) | |
| if not self.api_key: | |
| error_message = "No Gemini API key provided in .env file" | |
| print(f"{BLUE}[GeminiClient] {error_message}, using mock data.{RESET}") | |
| logger.warning(error_message) | |
| result = self._get_mock_market_positioning() | |
| print(f"{BLUE}[GeminiClient] Mock response:{RESET}", result[:500]) | |
| return result | |
| if not self.model: | |
| error_message = "Gemini model not properly initialized" | |
| print(f"{BLUE}[GeminiClient] {error_message}, using mock data.{RESET}") | |
| logger.error(error_message) | |
| result = self._get_mock_market_positioning() | |
| print(f"{BLUE}[GeminiClient] Mock response:{RESET}", result[:500]) | |
| return result | |
| try: | |
| logger.info(f"GeminiClient: Sending request with model {self.model_name}") | |
| response = self.model.generate_content(input_text) | |
| print(f"{BLUE}[GeminiClient] API response:{RESET}", response.text[:500]) | |
| return response.text | |
| except Exception as e: | |
| error_message = f"Exception: {str(e)}" | |
| print(f"{BLUE}[GeminiClient] {error_message}, using mock data.{RESET}") | |
| logger.error(error_message) | |
| result = self._get_mock_market_positioning() | |
| print(f"{BLUE}[GeminiClient] Mock response:{RESET}", result[:500]) | |
| return result | |
| def _get_mock_market_positioning(self): | |
| """ | |
| Generate mock market positioning when Gemini API is unavailable | |
| """ | |
| return """ | |
| Based on the analysis of your startup and competitors, here is a market positioning strategy: | |
| 1. Most Compelling Unique Value Proposition: | |
| Your integrated approach combining multiple aspects of the solution creates a more comprehensive and effective result than competitors who only focus on one element. This "full-stack" approach allows you to deliver superior outcomes with less complexity for customers. | |
| 2. Most Promising Market Segments to Target First: | |
| Focus on mid-sized businesses that are large enough to have the problem at a significant scale but not so large that they have custom in-house solutions. These businesses are seeking efficiency improvements but don't have the resources to build or integrate multiple point solutions. | |
| 3. Most Strategic Competitive Advantage to Emphasize: | |
| Your technological edge that allows you to provide a unified, seamless solution rather than requiring customers to piece together multiple tools. This not only improves results but significantly reduces implementation complexity and ongoing management overhead. | |
| """ |