""" TapToAIService — Python клас за TapTo AI API (Django, Flask, скриптове). Нужно е: pip install requests Документация: https://tapto.bg/app/ai-api-integration ПРИМЕР from TapToAIService import TapToAIService ai = TapToAIService("ВАШИЯТ_API_ТОКЕН") print(ai.get_credits()) # AI студио — 2 снимки на легло за куче в хол, с куче (0,10 кр.) r = ai.studio_generate({"type": "pets", "scene": "living", "subject": "dog"}, "bed.jpg") for img in r.get("images", []): print(img["url"]) """ import requests class TapToAIService: def __init__(self, api_token, base_url="https://tapto.bg/api/ai"): self.api_token = api_token self.base_url = base_url.rstrip("/") def _send_request(self, endpoint, method="POST", data=None, files=None, timeout=120): url = f"{self.base_url}/{endpoint.lstrip('/')}" headers = {"Authorization": f"Bearer {self.api_token}", "Accept": "application/json"} data = {k: v for k, v in (data or {}).items() if v is not None and v != ""} try: if method == "GET": response = requests.get(url, headers=headers, params=data, timeout=timeout) elif files: response = requests.post(url, headers=headers, data=data, files=files, timeout=timeout) else: response = requests.post(url, headers=headers, json=data, timeout=timeout) return response.json() except Exception as e: return {"status": False, "messages": f"Грешка при връзка: {e}"} finally: for f in (files or {}).values(): try: f.close() except Exception: pass def get_credits(self): """Наличните кредити.""" return self._send_request("credits", "GET") def get_transactions(self, params=None): """Транзакциите: search, status, type, sort_by, sort_order, per_page, page.""" return self._send_request("transactions", "GET", data=params) def get_history(self, params=None): """Генерираните снимки: search, per_page, page.""" return self._send_request("history", "GET", data=params) def studio_presets(self, locale="bg"): """AI студио: видове продукти, сцени, хора/животни, формати и цена.""" return self._send_request("studio/presets", "GET", data={"locale": locale}) def studio_generate(self, options, image_path=None): """ AI студио: 2 продуктови снимки наведнъж (0,10 кр.). :param options: type, scene, subject, format, color, lighting, mood, angle, season, fidelity, product, extra, avoid, seed, steps, cfg :param image_path: снимка на продукта; без нея е задължително "product" """ files = {"input_image": open(image_path, "rb")} if image_path else None return self._send_request("studio/generate", "POST", data=options, files=files, timeout=240) def blog_article_start(self, options): """ Блог статия (0,20 кр. + 0,10 кр. корица): пуска писането и връща {"id": ...}. options: topic (задължително), keywords, language, length (short|medium|long), tone (friendly|expert|selling|simple), audience, notes, cover (True/False), cover_style. """ return self._send_request("blog-article", "POST", data=options) def blog_article(self, article_id): """Блог статия: състоянието (pending|done|error) и статията, когато е готова.""" return self._send_request(f"blog-article/{int(article_id)}", "GET") def write_blog_article(self, options, max_seconds=300): """Блог статия: пуска и чака (до max_seconds), докато стане готова.""" import time start = self.blog_article_start(options) if not start.get("id"): return start until = time.time() + max_seconds while True: time.sleep(5) r = self.blog_article(start["id"]) if r.get("state") != "pending" or time.time() > until: return r def blog_articles(self, params=None): """Вашите блог статии: per_page, page.""" return self._send_request("blog-articles", "GET", data=params) def generate_image(self, prompt, options=None, input_image_path=None): """Снимка по свободно описание (prompt) — 0,10 кр. Опции: model, width, height, steps, cfg_scale, negative_prompt, output_format.""" data = {"prompt": prompt, **(options or {})} files = {"input_image": open(input_image_path, "rb")} if input_image_path else None return self._send_request("generate", "POST", data=data, files=files, timeout=180) def remove_background(self, image_path_or_url, model=None, output_format="PNG"): """Премахване на фон — локален файл или адрес (0,01 кр.).""" data = {"model": model, "output_format": output_format} if image_path_or_url.startswith(("http://", "https://")): data["image_url"] = image_path_or_url return self._send_request("remove-background", "POST", data=data) return self._send_request("remove-background", "POST", data=data, files={"image": open(image_path_or_url, "rb")}) def generate_seo_agent(self, site_name, site_url, languages, product_name, product_price, currency, description, image_paths=None, additional_reqs=None, include_icons=False): """SEO Agent — SEO текстове за продукт на няколко езика (0,01 кр.).""" data = { "site_name": site_name, "site_url": site_url, "languages": ", ".join(languages) if isinstance(languages, (list, tuple)) else languages, "product_name": product_name, "product_price": product_price, "currency": currency, "description": description, "additional_requirements": additional_reqs, "include_icons": 1 if include_icons else 0, } files = {f"images[{i}]": open(p, "rb") for i, p in enumerate(image_paths or [])} return self._send_request("seo-agent", "POST", data=data, files=files or None, timeout=180)