Spaces:
Sleeping
Sleeping
| import json | |
| import gradio as gr | |
| import os | |
| from groq import Groq | |
| from duckduckgo_search import DDGS | |
| # List of Groq models | |
| groq_models = [ | |
| "qwen-2.5-32b", | |
| "qwen-2.5-coder-32b", | |
| "qwen-qwq-32b", | |
| "deepseek-r1-distill-qwen-32b", | |
| "deepseek-r1-distill-llama-70b", | |
| "gemma2-9b-it", | |
| "distil-whisper-large-v3-en", | |
| "llama-3-1-8b-instant", | |
| "llama-3-2-11b-vision-preview", | |
| "llama-3.2-1b-preview", | |
| "llama-3.2-3b-preview", | |
| "llama-3.2-90b-vision-preview", | |
| "llama-3.3-70b-specdec", | |
| "llama-3.3-70b-versatile", | |
| "llama-guard-3-8b", | |
| "llama3-70b-8192", | |
| "llama3-8b-8192", | |
| "mistral-saba-24b", | |
| "mixtral-8x7b-32768" | |
| ] | |
| # Disclaimer note | |
| DISCLAIMER = ( | |
| "\n\n**Disclaimer**: This information is for informational purposes only and does not constitute investment advice. " | |
| "Please consult with a qualified financial advisor before making any investment decisions." | |
| ) | |
| # Function to format JSON into readable Markdown | |
| def format_json_to_markdown(data): | |
| markdown = "# Company Overview\n\n" | |
| # Profile Section | |
| profile = data.get("research", {}).get("profile", {}) | |
| markdown += "## Company Profile\n" | |
| markdown += f"- **Company Name**: {profile.get('company_name', 'N/A')}\n" | |
| markdown += f"- **Business Description**: {profile.get('business_description', 'N/A')}\n" | |
| markdown += f"- **Headquarters**: {profile.get('headquarters', 'N/A')}\n" | |
| markdown += f"- **Founded Year**: {profile.get('founded_year', 'N/A')}\n" | |
| markdown += f"- **CEO**: {profile.get('ceo', 'N/A')}\n" | |
| markdown += f"- **Employees**: {profile.get('employees', 'N/A')}\n" | |
| markdown += f"- **Target Market**: {profile.get('target_market', 'N/A')}\n" | |
| markdown += f"- **Products/Services**: \n" | |
| for service in profile.get('products_services', []): | |
| markdown += f" - {service}\n" | |
| markdown += f"- **Business Model**: {profile.get('business_model', 'N/A')}\n" | |
| markdown += f"- **Growth Strategy**: {profile.get('growth_strategy', 'N/A')}\n\n" | |
| # Financials Section | |
| financials = data.get("research", {}).get("financials", {}) | |
| markdown += "## Financial Highlights\n" | |
| markdown += f"- **Revenue**: {financials.get('revenue', {}).get('₹ Crores', 'N/A') or financials.get('revenue', {}).get('total_revenue_2024', 'N/A')} ₹ Crores\n" | |
| markdown += f"- **Revenue Growth**: {financials.get('revenue_growth', 'N/A')}% \n" | |
| markdown += f"- **Net Income**: {financials.get('net_income', {}).get('₹ Crores', 'N/A') or financials.get('net_income', {}).get('2024', 'N/A')} ₹ Crores\n" | |
| markdown += f"- **Profit Margin**: {financials.get('profit_margin', 'N/A')}% \n" | |
| markdown += f"- **Debt to Equity**: {financials.get('debt_to_equity', 'N/A')}\n" | |
| # Key Ratios Table | |
| ratios = financials.get("key_ratios", {}) | |
| if ratios: | |
| markdown += "\n### Key Financial Ratios\n" | |
| markdown += "| Ratio | Value |\n" | |
| markdown += "|-------------------|-------------|\n" | |
| for key, value in ratios.items(): | |
| markdown += f"| {key.replace('_', ' ').title()} | {value} |\n" | |
| # IPO Details Section | |
| ipo = data.get("research", {}).get("ipo_details", {}) | |
| markdown += "\n## IPO Details\n" | |
| markdown += f"- **IPO Date**: {ipo.get('ipo_date', 'N/A')}\n" | |
| markdown += f"- **Price Range**: {ipo.get('price_range', 'N/A')}\n" | |
| markdown += f"- **Final Price**: {ipo.get('final_price', 'N/A')} ₹\n" | |
| markdown += f"- **Shares Offered**: {ipo.get('shares_offered', 'N/A')}\n" | |
| markdown += f"- **Total Raised**: {ipo.get('total_raised', 'N/A')} ₹ Crores\n" | |
| markdown += f"- **Use of Proceeds**: {ipo.get('use_of_proceeds', 'N/A')}\n" | |
| markdown += f"- **Lock-Up Period**: {ipo.get('lock_up_period', 'N/A')}\n\n" | |
| # Recommendation Section | |
| recommendation = data.get("recommendation", {}) | |
| markdown += "## Investment Recommendation\n" | |
| markdown += f"- **Recommendation**: {recommendation.get('recommendation', 'N/A')}\n" | |
| markdown += f"- **Confidence Level**: {recommendation.get('confidence_level', 'N/A')}/10\n" | |
| markdown += f"- **Price Targets**: Low: {recommendation.get('price_targets', {}).get('low', 'N/A')} | Base: {recommendation.get('price_targets', {}).get('base', 'N/A')} | High: {recommendation.get('price_targets', {}).get('high', 'N/A')} ₹\n" | |
| markdown += f"- **Investment Horizon**: {recommendation.get('investment_horizon', 'N/A')}\n" | |
| markdown += f"- **Key Metrics to Watch**: \n" | |
| for metric in recommendation.get('key_metrics_to_watch', []): | |
| markdown += f" - {metric}\n" | |
| markdown += f"- **Entry Strategy**: {recommendation.get('entry_strategy', 'N/A')}\n" | |
| markdown += f"- **Exit Conditions**: \n" | |
| for condition in recommendation.get('exit_conditions', []): | |
| markdown += f" - {condition}\n" | |
| markdown += f"- **Summary Rationale**: {recommendation.get('summary_rationale', 'N/A')}\n" | |
| # Add the disclaimer | |
| markdown += DISCLAIMER | |
| return markdown | |
| # Function to convert JSON to formatted text | |
| def json_to_text(filename): | |
| try: | |
| if not filename or filename == "No JSON files found": | |
| return "Please select a valid JSON file." | |
| with open(filename, 'r') as json_file: | |
| data = json.load(json_file) | |
| return format_json_to_markdown(data) | |
| except (FileNotFoundError, json.JSONDecodeError) as e: | |
| return f"Error: Could not load JSON file - {str(e)}" | |
| # Function to search DuckDuckGo using DDGS | |
| def search_duckduckgo(query): | |
| try: | |
| with DDGS() as ddgs: | |
| results = list(ddgs.text(query, max_results=3)) | |
| if results: | |
| return "\n".join([f"[{result['title']}]({result['href']}): {result['body']}" for result in results]) | |
| return "No results found on DuckDuckGo." | |
| except Exception as e: | |
| return f"Error during DuckDuckGo search: {str(e)}" | |
| # Function to chat with JSON content using Groq API with smarter handling | |
| def chat_with_json(api_key, model_name, filename, question): | |
| if not api_key or not model_name or not filename or not question: | |
| return "Please provide all required inputs: API key, model, JSON file, and question." | |
| try: | |
| client = Groq(api_key=api_key) | |
| with open(filename, 'r') as json_file: | |
| data = json.load(json_file) | |
| # Enhanced prompt to guide the LLM | |
| prompt = ( | |
| f"Here is the JSON data about a company:\n{json.dumps(data, indent=2)}\n\n" | |
| f"User question: {question}\n\n" | |
| "Answer the question based solely on the provided JSON data. " | |
| "If the exact information is not available in the JSON, provide a thoughtful response using related information from the JSON. " | |
| "For example, if asked about the CEO and the CEO is not listed, state that the CEO is not specified and provide other relevant details like the company's headquarters, founded year, or business description. " | |
| "Do NOT suggest searching the web unless the user explicitly asks for a web search or the question is completely unrelated to the JSON content (e.g., asking about weather or unrelated topics). " | |
| "If a web search is needed, respond with 'I can search the web for this information if you'd like. Please confirm.'" | |
| ) | |
| completion = client.chat.completions.create( | |
| model=model_name, | |
| messages=[{"role": "user", "content": prompt}], | |
| temperature=1, | |
| max_completion_tokens=1024, | |
| top_p=1, | |
| stream=False | |
| ) | |
| answer = completion.choices[0].message.content | |
| # Add disclaimer to the chat response | |
| answer += DISCLAIMER | |
| # Check if the LLM suggests a web search | |
| if "I can search the web" in answer: | |
| return answer # Let the user decide if they want a web search | |
| return answer | |
| except (FileNotFoundError, json.JSONDecodeError) as e: | |
| return f"Error: Could not load JSON file - {str(e)}" | |
| except Exception as e: | |
| return f"Error with Groq API: {str(e)}" | |
| # Function to get list of JSON files dynamically | |
| def get_json_files(): | |
| json_files = [f for f in os.listdir('.') if f.endswith('.json')] | |
| return json_files if json_files else ["No JSON files found"] | |
| # Gradio Interface for JSON to Text | |
| iface = gr.Interface( | |
| fn=json_to_text, | |
| inputs=gr.Dropdown(choices=get_json_files(), label="Select JSON File"), | |
| outputs=gr.Markdown(), | |
| title="JSON to Text", | |
| description="Convert a JSON file to a formatted, readable overview." | |
| ) | |
| # Gradio Interface for Chat with JSON | |
| chat_iface = gr.Interface( | |
| fn=chat_with_json, | |
| inputs=[ | |
| gr.Textbox(label="Enter Groq API Key", type="password"), | |
| gr.Dropdown(choices=groq_models, label="Select Model"), | |
| gr.Dropdown(choices=get_json_files(), label="Select JSON File"), | |
| gr.Textbox(label="Ask your question") | |
| ], | |
| outputs=gr.Markdown(), | |
| title="Chat with JSON and DuckDuckGo", | |
| description="Ask questions about a JSON file. The system will answer based on the JSON data, providing related insights if the exact answer is missing. Web searches are performed only if explicitly requested." | |
| ) | |
| # Launch the tabbed interface | |
| if __name__ == "__main__": | |
| gr.TabbedInterface([iface, chat_iface], ["JSON to Text", "Chat with JSON"]).launch() |