Initial commit: CI Agent competitive-intelligence monitoring app
FastAPI + Celery + Next.js + Postgres/Redis app with company monitoring, source collection, LLM-based change analysis, enrichment, and account security (Turnstile, escalating lockout, email verification).
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
"""Brave Search API provider. A fixed, trusted, first-party integration
|
||||
endpoint (like Twilio/Resend) - calls httpx directly rather than through
|
||||
`safe_fetch`, which exists specifically to guard arbitrary/user-supplied
|
||||
collector targets, not our own known-safe API integrations."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import httpx
|
||||
|
||||
from app.core.config import Settings
|
||||
from app.search.base import SearchResult
|
||||
|
||||
_API_URL = "https://api.search.brave.com/res/v1/web/search"
|
||||
|
||||
|
||||
class BraveSearchProvider:
|
||||
provider_name = "brave"
|
||||
|
||||
def __init__(self, settings: Settings) -> None:
|
||||
self._settings = settings
|
||||
|
||||
async def search(self, query: str, *, count: int = 5) -> list[SearchResult]:
|
||||
async with httpx.AsyncClient(timeout=15) as client:
|
||||
response = await client.get(
|
||||
_API_URL,
|
||||
params={"q": query, "count": count},
|
||||
headers={
|
||||
"Accept": "application/json",
|
||||
"X-Subscription-Token": self._settings.brave_search_api_key,
|
||||
},
|
||||
)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
results = data.get("web", {}).get("results", [])
|
||||
return [
|
||||
SearchResult(
|
||||
title=r.get("title", ""),
|
||||
url=r.get("url", ""),
|
||||
snippet=r.get("description", ""),
|
||||
)
|
||||
for r in results[:count]
|
||||
]
|
||||
Reference in New Issue
Block a user