Intelex / backend /vision /captioner.py
yakub
Initial cloud-ready commit
b2b6341
Raw
History Blame Contribute Delete
2.84 kB
#!/usr/bin/env python3
import os
import requests
import base64
from pathlib import Path
from backend.config import HF_API_KEY, HF_IMAGE_MODEL_ID
from backend.database.connection import get_connection
from backend.ingestion.image_loader import get_pending_image_jobs, mark_job_completed, mark_job_failed
def get_hf_api_url():
model_id = HF_IMAGE_MODEL_ID or "Salesforce/blip-image-captioning-large"
return f"https://api-inference.huggingface.co/models/{model_id}"
def caption_single_image_hf(image_path: str) -> str:
"""
Generates a caption for a single image using Hugging Face Inference API.
Zero local VRAM usage.
"""
if not HF_API_KEY:
print("[Captioner] Error: HF_API_KEY not set in backend/.env")
return "Caption generation failed: No API Key."
headers = {"Authorization": f"Bearer {HF_API_KEY}"}
api_url = get_hf_api_url()
try:
with open(image_path, "rb") as f:
data = f.read()
print(f"[Captioner] Calling HF API ({api_url}) for {Path(image_path).name}...")
response = requests.post(api_url, headers=headers, data=data)
if response.status_code == 200:
result = response.json()
if isinstance(result, list) and len(result) > 0 and "generated_text" in result[0]:
caption = result[0]["generated_text"].strip()
return caption
elif "error" in result:
print(f"[Captioner] HF API Error: {result['error']}")
return "Caption generation failed."
else:
print(f"[Captioner] HF API failed with status {response.status_code}: {response.text}")
return "Caption generation failed."
except Exception as e:
print(f"[Captioner] Error processing {image_path}: {e}")
return "Caption generation failed."
return "Caption generation failed."
def run_caption_pipeline():
"""
Main pipeline to process pending image jobs via Hugging Face API.
"""
print("[Captioner] Starting HF Image Captioning pipeline")
jobs = get_pending_image_jobs()
print(f"[Captioner] Found {len(jobs)} pending jobs")
if not jobs:
print("No jobs. Exiting.")
return
for job in jobs:
print(f"[Captioner] Processing: {job['image_path']}")
caption = caption_single_image_hf(job['image_path'])
if caption and not caption.startswith("Caption generation failed"):
mark_job_completed(job['id'], caption)
print(f"[Captioner] Job {job['id']} completed: {caption}")
else:
mark_job_failed(job['id'], caption)
print(f"[Captioner] Job {job['id']} failed.")
print("[Captioner] Pipeline finished.")
if __name__ == "__main__":
run_caption_pipeline()