import httpx from bs4 import BeautifulSoup from fastapi import FastAPI, HTTPException from pydantic import BaseModel import uvicorn app = FastAPI() class SearchQuery(BaseModel): query: str class BraveSearch: def __init__(self, query): self.query = query self.url = f"https://search.brave.com/search?q={query.replace(' ', '+')}&source=web" async def fetch_results(self): try: async with httpx.AsyncClient() as client: response = await client.get(self.url) response.raise_for_status() soup = BeautifulSoup(response.text, "html.parser") results = { "searchResults": [], "additionalData": [], "faq": [] } for el in soup.select(".snippet"): title = el.select_one(".title") description = el.select_one(".snippet-description") link = el.select_one("a") results["searchResults"].append({ "title": title.text.strip() if title else "No Title", "description": description.text.strip() if description else "No Description", "link": link["href"] if link else "#" }) for el in soup.select(".t-tertiary.svelte-1yt5tdo"): attribution = el.select_one(".attribution") citation_link = el.select_one("cite a") results["additionalData"].append({ "attribution": attribution.text.strip() if attribution else "No Attribution", "citationLink": citation_link["href"] if citation_link else "#" }) for el in soup.select(".fq-item"): question = el.select_one(".faq-q") answer = el.select_one(".faq-a") faq_link = el.select_one("a") results["faq"].append({ "question": question.text.strip() if question else "No Question", "answer": answer.text.strip() if answer else "No Answer", "faqLink": faq_link["href"] if faq_link else "#" }) return results except httpx.HTTPStatusError as e: raise HTTPException(status_code=e.response.status_code, detail=f"HTTP error occurred: {e}") except Exception as e: raise HTTPException(status_code=500, detail=f"An error occurred: {e}") @app.post("/search") async def search(search_query: SearchQuery): if not search_query.query: raise HTTPException(status_code=400, detail="Query is required") search = BraveSearch(search_query.query) data = await search.fetch_results() return data if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=8000)