puff-n-parse-backend / services /summarizer.py
Gifted-oNe's picture
chore: prepare backend for production release
2b2c2f7
Raw
History Blame Contribute Delete
2.57 kB
import os
import logging
from openai import OpenAI
from huggingface_hub import InferenceClient
logger = logging.getLogger(__name__)
# Fallback open-source model via HF Serverless API
HF_MODEL = "facebook/bart-large-cnn"
HF_MAX_INPUT_CHARS = 4000 # truncate input to roughly 1000 tokens to avoid timeouts/limits
# OpenAI
OPENAI_MODEL = "gpt-4o-mini"
OPENAI_MAX_INPUT_CHARS = 40000 # larger context window
def generate_summary(text: str, is_registered: bool = False) -> str:
"""
Generate a summary of the extracted text.
Uses OpenAI for registered users (if key exists),
and Hugging Face Serverless API for anonymous users.
"""
if not text or len(text.strip()) < 50:
return "Not enough text to generate a meaningful summary."
if is_registered:
api_key = os.environ.get("OPENAI_API_KEY")
if api_key:
return _summarize_openai(text, api_key)
else:
logger.warning("OPENAI_API_KEY not found. Falling back to HF Serverless API.")
return _summarize_hf(text)
else:
return _summarize_hf(text)
def _summarize_openai(text: str, api_key: str) -> str:
try:
client = OpenAI(api_key=api_key)
truncated_text = text[:OPENAI_MAX_INPUT_CHARS]
response = client.chat.completions.create(
model=OPENAI_MODEL,
messages=[
{"role": "system", "content": "You are a professional assistant. Provide a concise, highly readable 2-3 sentence summary of the following document. Focus on the core facts, purpose, or conclusions."},
{"role": "user", "content": truncated_text}
],
max_tokens=150,
temperature=0.3
)
return response.choices[0].message.content.strip()
except Exception as e:
logger.error(f"OpenAI summarization failed: {e}")
return ""
def _summarize_hf(text: str) -> str:
try:
# Use InferenceClient (uses the HF_TOKEN env var if present in Space, or anonymous if not)
client = InferenceClient()
truncated_text = text[:HF_MAX_INPUT_CHARS]
response = client.summarization(truncated_text, model=HF_MODEL)
if isinstance(response, list) and len(response) > 0:
return response[0].get("summary_text", "").strip()
elif isinstance(response, dict):
return response.get("summary_text", "").strip()
else:
return str(response)
except Exception as e:
logger.error(f"HF summarization failed: {e}")
return ""