# app/routes/question.py import os import requests from fastapi import APIRouter from pydantic import BaseModel from typing import List from redis_client import redis_client as r from dotenv import load_dotenv from huggingface_hub import InferenceClient import re load_dotenv() GNEWS_API_KEY = os.getenv("GNEWS_API_KEY") HF_TOKEN = os.getenv("HF_TOKEN") # Hugging Face token for private models if needed askMe = APIRouter() client = InferenceClient("mistralai/Mistral-7B-Instruct-v0.3", token=os.getenv("HF_TOKEN")) class QuestionInput(BaseModel): question: str @askMe.post("/ask") async def ask_question(input: QuestionInput): question = input.question # Extract keywords (simple version) keywords = re.findall(r"\b\w{4,}\b", question) query_string = " AND ".join(f'"{kw}"' for kw in keywords[:7]) print("Keywords are", query_string) gnews_url = f"https://gnews.io/api/v4/search?q={query_string}&lang=en&max=3&expand=content&token={GNEWS_API_KEY}" try: response = requests.get(gnews_url, timeout=10) response.raise_for_status() articles = response.json().get("articles", []) except Exception as e: return {"error": f"GNews API error: {str(e)}"} # Combine article content for context context = "\n\n".join([ article.get("content") or article.get("description") or "" for article in articles ])[:1500] # truncate to keep model input size safe print("And context is", context) # Build prompt prompt = f"[INST] Use the context below to answer the question. If the context is insufficient, say 'I am unable to answer'.\n\nContext:\n{context}\n\nQuestion: {question} [/INST]" result = client.text_generation(prompt, max_new_tokens=256, temperature=0.7) return { "question": question, "answer": result.strip(), "sources": [ {"title": a["title"], "url": a["url"]} for a in articles ] }