ai-assistant / app.py
dravidmathavan07's picture
Update app.py
847f404 verified
Raw History Blame Contribute Delete
4.77 kB
import logging
import os
from typing import Any
import gradio as gr
import requests
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
logger = logging.getLogger(__name__)
# Hugging Face Inference Router settings
API_BASE_URL = os.getenv(
"API_BASE_URL", "https://router.huggingface.co/v1/chat/completions"
).rstrip("/")
MODEL_NAME = os.getenv("MODEL_NAME", "deepseek-ai/DeepSeek-R1:fastest").strip()
HF_TOKEN = os.getenv("HF_TOKEN", "").strip()
REQUEST_TIMEOUT_SECONDS = float(os.getenv("REQUEST_TIMEOUT_SECONDS", "20"))
def _auth_headers() -> dict[str, str]:
if not HF_TOKEN:
return {}
return {"Authorization": f"Bearer {HF_TOKEN}"}
def query(payload: dict[str, Any]) -> dict[str, Any] | list[Any]:
request_body = {
"model": MODEL_NAME,
"messages": [{"role": "user", "content": payload.get("inputs", "")}],
}
try:
response = requests.post(
API_BASE_URL,
headers=_auth_headers(),
json=request_body,
timeout=REQUEST_TIMEOUT_SECONDS,
)
except requests.exceptions.Timeout:
logger.warning("Request timed out for model=%s", MODEL_NAME)
return {"error": "Request timed out. Please try again."}
except requests.exceptions.RequestException as exc:
logger.exception("Request failed: %s", exc)
return {"error": f"Network error: {exc}"}
if not response.ok:
error_message = f"HTTP {response.status_code}"
if response.status_code in (401, 403):
logger.error("Hugging Face auth failed for model=%s", MODEL_NAME)
return {
"error": (
"Unauthorized request to Hugging Face. Check that HF_TOKEN is set "
"correctly in the Space secrets and that it has access to the model."
)
}
if response.status_code == 404:
logger.error("Hugging Face route not found for model=%s", MODEL_NAME)
return {
"error": (
"Hugging Face route not found. Check API_BASE_URL and MODEL_NAME, "
"and make sure the model is available on the router."
)
}
try:
body = response.json()
if isinstance(body, dict) and body.get("error"):
error_message = f"{error_message}: {body['error']}"
except ValueError:
# Keep the HTTP status only when body is not valid JSON.
pass
logger.error("Inference API error: %s", error_message)
return {"error": error_message}
try:
return response.json()
except ValueError:
logger.error("Inference API returned non-JSON response")
return {"error": "Model returned an invalid response format."}
def _extract_text(data: dict[str, Any] | list[Any]) -> str:
if isinstance(data, dict):
if data.get("error"):
return f"Error: {data['error']}"
choices = data.get("choices")
if isinstance(choices, list) and choices:
first_choice = choices[0]
if isinstance(first_choice, dict):
message = first_choice.get("message")
if isinstance(message, dict):
content = message.get("content")
if isinstance(content, str) and content.strip():
return content.strip()
content = first_choice.get("text")
if isinstance(content, str) and content.strip():
return content.strip()
return "No response generated."
if isinstance(data, list) and data:
first_item = data[0]
if isinstance(first_item, dict):
for key in ("generated_text", "answer", "summary_text", "text"):
value = first_item.get(key)
if isinstance(value, str) and value.strip():
return value.strip()
if isinstance(first_item, str) and first_item.strip():
return first_item.strip()
return "No response generated."
def respond(message: str) -> str:
clean_message = (message or "").strip()
if not clean_message:
return "Please enter a valid message."
data = query({"inputs": clean_message})
return _extract_text(data)
iface = gr.Interface(
fn=respond,
inputs=gr.Textbox(lines=3, placeholder="Ask something..."),
outputs=gr.Textbox(label="Assistant Response"),
title="AI Assistant",
description="Simple AI assistant powered by the Hugging Face Inference API.",
)
if __name__ == "__main__":
port = int(os.getenv("PORT", "7860"))
iface.launch(server_name="0.0.0.0", server_port=port, show_error=True)