import os import urllib.request import nest_asyncio import gradio as gr import openai from llama_parse import LlamaParse from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings from llama_index.llms.openai import OpenAI from llama_index.embeddings.openai import OpenAIEmbedding # Apply nest_asyncio to allow nested event loops in a synchronous environment nest_asyncio.apply() # --- 1. ENVIRONMENT & API INITIALIZATION --- OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY") LLAMA_CLOUD_API_KEY = os.environ.get("LLAMA_CLOUD_API_KEY") if not OPENAI_API_KEY or not LLAMA_CLOUD_API_KEY: raise ValueError("Missing essential API credentials. Ensure OPENAI_API_KEY and LLAMA_CLOUD_API_KEY are configured in Secrets.") openai.api_key = OPENAI_API_KEY os.environ["LLAMA_CLOUD_API_KEY"] = LLAMA_CLOUD_API_KEY # --- 2. DATA ACQUISITION & PARSING --- pdf_path = "apple_10k.pdf" url = "https://s2.q4cdn.com/470004039/files/doc_financials/2021/q4/_10-K-2021-(As-Filed).pdf" if not os.path.exists(pdf_path): print("Downloading Apple 10-K report...") urllib.request.urlretrieve(url, pdf_path) print("Parsing document via LlamaParse...") parser = LlamaParse(result_type="markdown") document = parser.load_data(pdf_path) with open("apple_10k.md", "w", encoding="utf-8") as f: f.write(document[0].text) # FIXED: Changed deprecated 'parsing_instruction' to 'system_prompt' documents_with_instruction = LlamaParse( result_type="markdown", system_prompt="This is the Apple annual report. Make sure the language is English, if not translate it to English." ).load_data(pdf_path) with open("apple_10k_instructions.md", "w", encoding="utf-8") as f: f.write(documents_with_instruction[0].text) # --- 3. LLAMAINDEX RAG CONFIGURATION --- Settings.llm = OpenAI( model="gpt-5-nano", temperature=0.1, system_prompt=( "You are an expert financial analyst. Your task is to answer questions strictly " "and accurately based on the provided Apple 10-K report. Provide concise answers, " "directly referencing sections or figures from the report where possible. " "If the information is not explicitly present in the document, " "clearly state that the answer cannot be found in the provided text." ) ) Settings.embed_model = OpenAIEmbedding(model="text-embedding-3-small") Settings.chunk_size = 512 reader = SimpleDirectoryReader(input_files=["apple_10k.md", "apple_10k_instructions.md"]) docs = reader.load_data() index = VectorStoreIndex.from_documents(docs) query_engine = index.as_query_engine(similarity_top_k=5) print("LlamaIndex Knowledge Base initialized.") # --- 4. GRADIO INTERFACE CONFIGURATION --- custom_css = """ .gradio-container { font-family: 'Inter', 'Helvetica Neue', sans-serif !important; background: linear-gradient(135deg, #f3f4f6 0%, #e5e7eb 100%); } .sidebar-panel { background: white; border-radius: 16px; padding: 20px; box-shadow: 0 10px 25px rgba(0,0,0,0.05); border: 1px solid #e5e7eb; } .gradient-text { background: linear-gradient(90deg, #1d4ed8, #9333ea); -webkit-background-clip: text; -webkit-text-fill-color: transparent; font-weight: 800; } .stat-card { background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%); color: white; padding: 20px; border-radius: 12px; margin-bottom: 15px; text-align: center; box-shadow: 0 4px 6px rgba(0,0,0,0.1); } .action-button { background: linear-gradient(90deg, #3b82f6, #2563eb); border: none; color: white; font-weight: bold; } """ def chat_with_financial_analyst(user_message, history): if not user_message.strip(): return "", history history.append({"role": "user", "content": user_message}) history.append({"role": "assistant", "content": "Calculating financials..."}) yield "", history try: response = query_engine.query(user_message) final_answer = str(response) except Exception as e: final_answer = f"⚠️ **Error querying the document:** {str(e)}" history[-1]["content"] = final_answer yield "", history def load_quick_prompt(prompt, history): for text, hist in chat_with_financial_analyst(prompt, history): pass return "", hist # FIXED: Removed 'css=custom_css' from gr.Blocks() (Moved to app.launch()) with gr.Blocks(fill_width=True) as app: with gr.Row(): gr.HTML("""
Powered by LlamaIndex, OpenAI, and LlamaParse
Vector Indexed & Parsed