File size: 2,657 Bytes
75d9b3c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | """
Perplexity API Client — Thin async wrapper for deep financial research queries.
Uses the Sonar model for fast, web-grounded responses.
"""
import logging
import os
import httpx
logger = logging.getLogger(__name__)
PERPLEXITY_BASE_URL = "https://api.perplexity.ai"
DEFAULT_MODEL = "sonar"
RESEARCH_SYSTEM_PROMPT = """You are a financial research analyst. Provide concise, data-backed answers to investment and market questions. Focus on:
- Current market data and trends
- Specific numbers, dates, and percentages
- Impact on the user's portfolio holdings
- Actionable insights
Keep responses under 200 words. Use bullet points for clarity. Include source attribution where possible."""
async def research(query: str, context: str = "") -> str:
"""
Perform deep financial research via Perplexity API.
Returns a structured research summary.
Args:
query: The research question
context: Optional context about user's portfolio
"""
api_key = os.getenv("PERPLEXITY_API_KEY", "").strip()
if not api_key:
return "Perplexity API key not configured. Unable to perform deep research."
messages = [
{"role": "system", "content": RESEARCH_SYSTEM_PROMPT},
]
if context:
messages.append({"role": "user", "content": f"Context about my portfolio: {context}"})
messages.append({"role": "assistant", "content": "Understood. I'll factor in your portfolio context."})
messages.append({"role": "user", "content": query})
try:
async with httpx.AsyncClient(timeout=30) as client:
resp = await client.post(
f"{PERPLEXITY_BASE_URL}/chat/completions",
json={
"model": DEFAULT_MODEL,
"messages": messages,
"temperature": 0.1,
"max_tokens": 1000,
},
headers={
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
},
)
resp.raise_for_status()
data = resp.json()
content = data["choices"][0]["message"]["content"]
logger.info(f"Perplexity research completed for: {query[:60]}...")
return content
except httpx.HTTPStatusError as e:
logger.error(f"Perplexity API error: {e.response.status_code} — {e.response.text[:200]}")
return f"Research API error (status {e.response.status_code}). Please try again."
except Exception as e:
logger.error(f"Perplexity client error: {e}")
return f"Unable to perform research: {str(e)}"
|