import os import fal_client import asyncio # Ключ берем из переменных окружения FAL_KEY = os.environ.get("FAL_KEY") fal_client.api_key = FAL_KEY def clean_url(url): """ Очистка URL от лишних параметров. Для ВК-фото оставляем как есть, для остальных (включая Supabase) отсекаем query-параметры, если они мешают загрузке в API. """ if not url: return url if "userapi.com" in url: return url # Для прямых ссылок из бакета Supabase часто требуется чистый путь return url.split('?')[0] async def generate_image(prompt, gender, photo_url=None, lora_model=None): """ Основная функция генерации (Face Swap через Nano Banana). lora_model игнорируется, так как функционал отключен. """ # Используем актуальный эндпоинт Nano Banana 2 для редактирования и Face Swap endpoint = "fal-ai/nano-banana/edit" # Очищаем промпт от плейсхолдера, если он попал из старой логики final_prompt = prompt.replace("{trigger}", "a person") try: # --- ВАРИАНТ Б: Face Swap (Nano Banana) --- # Оставляем только этот функционал с текущими настройками print(f"🚀 Генерация через Face Swap. Промпт: {final_prompt[:50]}...") # Подготавливаем URL (будь то ссылка из ВК или из вашего бакета) user_photo = clean_url(photo_url) arguments = { "image_urls": [user_photo], "prompt": final_prompt, "negative_prompt": "deformed face, blurry, low quality, bad anatomy, extra fingers, distorted features", "guidance_scale": 7.5, "image_size": "portrait_16_9", "num_inference_steps": 30, "strength": 0.55 # Оптимальная настройка для сохранения сходства и наложения стиля } # Вызов API Nano Banana 2 result = await fal_client.subscribe_async(endpoint, arguments=arguments) if result and 'images' in result and len(result['images']) > 0: return result['images'][0]['url'] else: print("⚠️ API вернуло пустой результат") return None except Exception as e: print(f"❌ Ошибка в генераторе (Endpoint: {endpoint}): {e}") return None