Spaces:
Running
Running
| import os | |
| import requests | |
| import gradio as gr | |
| from PIL import Image | |
| import torch | |
| from transformers import BlipProcessor, BlipForConditionalGeneration | |
| # 1) Устройство | |
| device = torch.device("cuda" if torch.cuda.is_available() else "cpu") | |
| print("🖥️ Using device:", device) | |
| # 2) Лёгкая BLIP-модель (~240 MiB) | |
| processor = BlipProcessor.from_pretrained("Salesforce/blip-image-captioning-base") | |
| model = BlipForConditionalGeneration.from_pretrained( | |
| "Salesforce/blip-image-captioning-base" | |
| ).to(device) | |
| # 3) TMDb API key | |
| TMDB_KEY = os.environ.get("TMDB_API_KEY") | |
| if not TMDB_KEY: | |
| raise RuntimeError("❌ TMDB_API_KEY is missing in your Secrets") | |
| TMDB_SEARCH_URL = "https://api.themoviedb.org/3/search/movie" | |
| def caption_and_search(image: Image.Image): | |
| print("➡️ Received request, image size:", image.size) | |
| # 4) caption | |
| inputs = processor(images=image, return_tensors="pt").to(device) | |
| with torch.no_grad(): | |
| out_ids = model.generate(**inputs, max_new_tokens=30) | |
| caption = processor.decode(out_ids[0], skip_special_tokens=True).strip() | |
| print("🔖 Caption:", caption) | |
| # 5) TMDb search | |
| resp = requests.get(TMDB_SEARCH_URL, params={"api_key": TMDB_KEY, "query": caption}, timeout=10) | |
| if resp.status_code != 200: | |
| print("⚠️ TMDb returned", resp.status_code) | |
| return caption, [{"error": f"TMDb {resp.status_code}"}] | |
| data = resp.json().get("results", [])[:3] | |
| results = [{"title": m["title"], "url": f"https://www.themoviedb.org/movie/{m['id']}"} for m in data] | |
| print("✅ Returning", len(results), "results") | |
| return caption, results | |
| # 6) Интерфейс с очередью | |
| iface = gr.Interface( | |
| fn=caption_and_search, | |
| inputs=gr.Image(type="pil", label="Постер или кадр фильма"), | |
| outputs=[ | |
| gr.Textbox(label="Auto‑caption"), | |
| gr.JSON(label="Top‑3 Movies (title + URL)") | |
| ], | |
| title="Fast Movie Finder (BLIP‑Base + TMDb)", | |
| description="Генерирует подпись и ищет топ‑3 фильма в TMDb" | |
| ).queue() # <— включает очередь обработки долгих запросов | |
| if __name__ == "__main__": | |
| # debug=True позволит вывести стектрейсы ошибок в браузер | |
| iface.launch(debug=True) | |