| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- import requests
- import time
- import hmac
- import hashlib
- import uuid
- import base64
- import os
- import sys
- from dotenv import load_dotenv
- # 设置 UTF-8 输出编码(Windows 兼容)
- if sys.platform == 'win32':
- sys.stdout.reconfigure(encoding='utf-8')
- load_dotenv()
- class LibLibControlNet:
- def __init__(self):
- self.ak = os.getenv("LIBLIBAI_ACCESS_KEY") or "你的AccessKey"
- self.sk = os.getenv("LIBLIBAI_SECRET_KEY") or "你的SecretKey"
- self.domain = "https://openapi.liblibai.cloud"
- # 先替换为更通用的模板ID(避免旧ID失效)
- # 文生图模板(必须是 1.5 体系的模板)
- self.TEMPLATE_UUID = "e10adc3949ba59abbe56e057f20f883e"
- # SD1.5 底模
- self.CHECKPOINT_ID = "0ea388c7eb854be3ba3c6f65aac6bfd3"
- # SD1.5 Canny(来自你给的官方表)
- self.CANNY_MODEL_ID = "b6806516962f4e1599a93ac4483c3d23"
- def _generate_signature(self, uri):
- ts = str(int(time.time() * 1000))
- nonce = uuid.uuid4().hex
- sign_str = f"{uri}&{ts}&{nonce}"
- dig = hmac.new(self.sk.encode(), sign_str.encode(), hashlib.sha1).digest()
- signature = base64.urlsafe_b64encode(dig).rstrip(b"=").decode()
- return f"{self.domain}{uri}?AccessKey={self.ak}&Timestamp={ts}&SignatureNonce={nonce}&Signature={signature}"
- def submit_canny_task(self, image_url, prompt):
- uri = "/api/generate/webui/text2img"
- url = self._generate_signature(uri)
-
- payload = {
- "templateUuid": self.TEMPLATE_UUID,
- "generateParams": {
- "checkPointId": self.CHECKPOINT_ID,
- "prompt": prompt,
- "negativePrompt": "lowres, bad anatomy, text, error, extra digit, fewer digits, cropped, worst quality, low quality",
- "sampler": 15,
- "steps": 20,
- "cfgScale": 7.0, # 修复:改为浮点数(部分版本要求)
- "width": 512,
- "height": 512,
- "imgCount": 1,
- "seed": -1,
- "controlNet": [
- {
- "unitOrder": 1,
- "sourceImage": image_url,
- "width": 512,
- "height": 512,
- "preprocessor": 1,
- "annotationParameters": {
- "canny": {
- "preprocessorResolution": 512,
- "lowThreshold": 100,
- "highThreshold": 200
- }
- },
- "model": self.CANNY_MODEL_ID,
- "controlWeight": 1.0,
- "startingControlStep": 0.0,
- "endingControlStep": 1.0,
- "pixelPerfect": 1,
- "controlMode": 0,
- "resizeMode": 1
- }
- ]
- }
- }
- try:
- print(f"📤 提交ControlNet生图任务...")
- print(f"🔍 请求URL: {url}")
- print(f"🔍 请求Payload: {payload}") # 打印完整参数
- resp = requests.post(
- url,
- headers={"Content-Type": "application/json"},
- json=payload,
- timeout=10
- )
- # 打印完整响应(关键调试信息)
- print(f"🔍 响应状态码: {resp.status_code}")
- print(f"🔍 响应内容: {resp.text}")
-
- result = resp.json()
- if result.get("code") == 0:
- task_id = result["data"]["generateUuid"]
- print(f"✅ 任务提交成功!任务ID: {task_id}")
- return task_id
- else:
- print(f"❌ 任务提交失败: {result.get('msg')}")
- return None
- except Exception as e:
- print(f"❌ 提交任务异常: {str(e)}")
- return None
- def poll_task_status(self, task_id):
- uri = "/api/generate/webui/status"
- max_retry = 60
- retry_count = 0
- while retry_count < max_retry:
- try:
- url = self._generate_signature(uri)
- resp = requests.post(
- url,
- headers={"Content-Type": "application/json"},
- json={"generateUuid": task_id},
- timeout=10
- )
- resp.raise_for_status()
- result = resp.json()
- if result.get("code") != 0:
- print(f"❌ 查询状态失败: {result.get('msg')}")
- return None
- data = result.get("data", {})
- status = data.get("generateStatus")
- if status == 5:
- img_url = data["images"][0]["imageUrl"]
- print(f"🎉 生图成功!最终图片URL: {img_url}")
- return img_url
- elif status in [6, 7]:
- print(f"❌ 任务失败: {data.get('generateMsg', '未知错误')}")
- return None
- else:
- print(f"⏳ 任务处理中(状态码: {status}),已等待{retry_count*5}秒...")
- except Exception as e:
- print(f"❌ 轮询异常: {str(e)}")
-
- retry_count += 1
- time.sleep(5)
-
- print(f"❌ 任务轮询超时(超过5分钟)")
- return None
- if __name__ == "__main__":
- client = LibLibControlNet()
- # 替换为更稳定的公开测试图
- PUBLIC_IMAGE_URL = "https://liblibai-airship-temp.oss-cn-beijing.aliyuncs.com/aliyun-cn-prod/73ed6ae42b144d21bf566e05b5a6c138.png"
- PROMPT = "simple white line art, cat, black background, 512x512" # 简化提示词(避免过长)
-
- task_id = client.submit_canny_task(PUBLIC_IMAGE_URL, PROMPT)
- if task_id:
- client.poll_task_status(task_id)
|