from fastapi import APIRouter, HTTPException, Query from pydantic import BaseModel import requests from bs4 import BeautifulSoup from duckduckgo_search import DDGS router = APIRouter() class SearchResponse(BaseModel): results: list error: str = None @router.get("/search", response_model=SearchResponse) def perform_search(q: str = Query(..., description="The search query")): """ Performs a web search using DuckDuckGo. """ try: with DDGS() as ddgs: results = list(ddgs.text(q, max_results=10)) return SearchResponse(results=results) except Exception as e: return SearchResponse(results=[], error=str(e)) @router.get("/scrape") def perform_scrape(url: str = Query(..., description="The URL to scrape")): """ Scrapes the text content of a given URL using Jina Reader (or fallback). """ try: # We can use jina.ai for extremely clean markdown extraction jina_url = f"https://r.jina.ai/{url}" response = requests.get(jina_url, timeout=15) response.raise_for_status() return {"text": response.text} except Exception as e: return {"error": str(e)} @router.get("/shop") def perform_shopping(q: str = Query(..., description="The shopping search query")): """ Performs a shopping search. Since DDG doesn't have a native shopping API in the python package, we can use a fallback or simply search with "kaufen" appended. (This can be expanded later). """ try: with DDGS() as ddgs: # Simple text search for now, could parse images/prices if needed results = list(ddgs.text(q + " kaufen", max_results=5)) return {"results": results} except Exception as e: return {"error": str(e)}