diff --git a/dsLightRag/Liblib/LiblibUtil.py b/dsLightRag/Liblib/LiblibUtil.py new file mode 100644 index 00000000..d5fe8274 --- /dev/null +++ b/dsLightRag/Liblib/LiblibUtil.py @@ -0,0 +1,48 @@ +import hmac +from hashlib import sha1 +import base64 +import time +import uuid +import requests +import Config.Config + + +class LiblibUtil: + def __init__(self): + self.base_url = Config.Config.LIBLIB_URL + self.access_key = Config.Config.LIBLIB_ACCESSKEY + self.secret_key = Config.Config.LIBLIB_SECRETKEY + self.timeout = 30 + + def make_sign(self, uri): + """生成API请求签名""" + timestamp = str(int(time.time() * 1000)) + signature_nonce = str(uuid.uuid4()) + content = '&'.join((uri, timestamp, signature_nonce)) + + digest = hmac.new(self.secret_key.encode(), content.encode(), sha1).digest() + sign = base64.urlsafe_b64encode(digest).rstrip(b'=').decode() + return sign, timestamp, signature_nonce + + def post_request(self, uri, payload): + """发送POST请求到Liblib API""" + try: + sign, timestamp, signature_nonce = self.make_sign(uri) + url = f'{self.base_url}{uri}?AccessKey={self.access_key}&Signature={sign}&Timestamp={timestamp}&SignatureNonce={signature_nonce}' + + headers = {'Content-Type': 'application/json'} + response = requests.post(url, json=payload, headers=headers, timeout=self.timeout) + response.raise_for_status() + + response_data = response.json() + if response_data.get('code') == 0: + return response_data.get('data') + else: + print(f"API错误: {response_data.get('message')}") + return None + except requests.exceptions.RequestException as e: + print(f"请求异常: {str(e)}") + return None + except Exception as e: + print(f"处理异常: {str(e)}") + return None \ No newline at end of file diff --git a/dsLightRag/Liblib/T1_VersionGet.py b/dsLightRag/Liblib/T1_VersionGet.py index 3f1584d0..9e8d3d7a 100644 --- a/dsLightRag/Liblib/T1_VersionGet.py +++ b/dsLightRag/Liblib/T1_VersionGet.py @@ -1,95 +1,64 @@ -import hmac -from hashlib import sha1 -import base64 -import time -import uuid -import requests -import Config.Config +from .LiblibUtil import LiblibUtil -def make_sign(uri): - """ - 生成签名 - """ - # API访问密钥 - secret_key = Config.Config.LIBLIB_SECRETKEY +def get_model_version_info(version_uuid): + """获取模型版本信息""" + liblib_util = LiblibUtil() + uri = "/api/model/version/get" + payload = {"versionUuid": version_uuid} + + model_info = liblib_util.post_request(uri, payload) + if model_info: + return { + 'modelName': model_info.get('modelName'), + 'versionName': model_info.get('versionName'), + 'commercialUse': model_info.get('commercialUse'), + 'modelUrl': model_info.get('modelUrl') + } + return None - # 当前毫秒时间戳 - timestamp = str(int(time.time() * 1000)) - # 随机字符串 - signature_nonce = str(uuid.uuid4()) - # 拼接请求数据 - content = '&'.join((uri, timestamp, signature_nonce)) - # 生成签名 - digest = hmac.new(secret_key.encode(), content.encode(), sha1).digest() - # 移除为了补全base64位数而填充的尾部等号 - sign = base64.urlsafe_b64encode(digest).rstrip(b'=').decode() - return sign, timestamp, signature_nonce +def generate_text_to_image(template_uuid, generate_params): + """调用text2img接口生成图片""" + liblib_util = LiblibUtil() + uri = "/api/generate/webui/text2img" + payload = { + "templateUuid": template_uuid, + "generateParams": generate_params + } + return liblib_util.post_request(uri, payload) if __name__ == '__main__': - # 要调用的接口路径 - uri = "/api/model/version/get" - # 获取签名 - sign, timestamp, signature_nonce = make_sign(uri) - url = f'{Config.Config.LIBLIB_URL}{uri}?AccessKey={Config.Config.LIBLIB_ACCESSKEY}&Signature={sign}&Timestamp={timestamp}&SignatureNonce={signature_nonce}' - # 封装调用参数 - # hellonijicute25d官方版 - # https://www.liblib.art/modelinfo/018f2fd5718d45a38546b5e518483856?from=feed&versionUuid=390e7df48aed45d4bc3f0bcbc89fa44c - # 接口文档 - # https://liblibai.feishu.cn/wiki/UAMVw67NcifQHukf8fpccgS5n6d - versionUuid="390e7df48aed45d4bc3f0bcbc89fa44c" - response = requests.post(url, json={"versionUuid":versionUuid}) - response_data = response.json() - if response_data.get('code') == 0: - model_info = response_data.get('data') - modelName= model_info.get('modelName') - versionNam= model_info.get('versionName') - commercialUse=model_info.get('commercialUse') - modelUrl= model_info.get('modelUrl') - print(f"模型名称:{modelName}") - print(f"版本名称:{versionNam}") - print(f"是否允许商业用途:{commercialUse}") - print(f"模型下载地址:{modelUrl}") - else: - print(f"错误信息:{response_data.get('message')}") - -# POST /api/generate/webui/text2img -""" -https://liblibai.feishu.cn/wiki/UAMVw67NcifQHukf8fpccgS5n6d -{ - "templateUuid": "7d888009f81d4252a7c458c874cd017f", // 参数模板ID - "generateParams": { - // 基础参数 - "checkPointId": "0ea388c7eb854be3ba3c6f65aac6bfd3", // 仅 XL模型支持人像换脸 - "prompt": "Asian portrait,A young woman wearing a green baseball cap, close shot, background is coffee store, masterpiece, best quality, ultra resolution", // 选填 - "width": 768, // 宽,必填 - "height": 1152, // 高,必填 - - //以下参数可不传 - "sampler":20, // 默认DPM++ 2M SDE Karras - "steps": 35, // 默认35步 - "cfgScale": 2.0, - "imgCount": 1, // 图片数量,默认1张 + # 测试获取模型版本信息 + print("===== 测试获取模型版本信息 =====") + version_uuid = "390e7df48aed45d4bc3f0bcbc89fa44c" + model_info = get_model_version_info(version_uuid) - // controlNet,最多4组 - "controlNet": [ - // 设置要用的人像人脸 - { - "unitOrder": 1, // 第一步:先识别要用的人像人脸 - "sourceImage": "https://liblibai-online.liblib.cloud/img/081e9f07d9bd4c2ba090efde163518f9/49943c0b-4d79-4e2f-8c55-bc1e5b8c69d8.png", - "width": 1080, // 参考图宽度 - "height": 1432 // 参考图高度 - }, - // 设置面部朝向的人像参考图 - { - "unitOrder": 2, // 第二步:再识别要参考的人物面部朝向 - "sourceImage": "https://liblibai-online.liblib.cloud/img/081e9f07d9bd4c2ba090efde163518f9/e713676d-baaa-4dac-99b9-d5d814a29f9f.png", //这张图可以与上一张不同,可以是任意人像。只参考面部朝向,不参考人物长相。 - "width": 1024, // 参考图宽度 - "height": 1024 // 参考图高度 - } - ] + if model_info: + print(f"模型名称:{model_info['modelName']}") + print(f"版本名称:{model_info['versionName']}") + print(f"是否允许商业用途:{model_info['commercialUse']}") + print(f"模型下载地址:{model_info['modelUrl']}") + else: + print("获取模型信息失败") + + # 测试生成图片 + print("\n===== 测试生成图片 =====") + template_uuid = "7d888009f81d4252a7c458c874cd017f" + generate_params = { + "checkPointId": "0ea388c7eb854be3ba3c6f65aac6bfd3", + "prompt": "Asian portrait,A young woman wearing a green baseball cap", + "width": 768, + "height": 1152, + "sampler": 20, + "steps": 35, + "cfgScale": 2.0, + "imgCount": 1 } -} -""" \ No newline at end of file + + image_data = generate_text_to_image(template_uuid, generate_params) + if image_data: + print(f"图片生成成功,任务UUID: {image_data.get('generateUuid')}") + else: + print("图片生成失败") diff --git a/dsLightRag/Liblib/T2.py b/dsLightRag/Liblib/T2.py new file mode 100644 index 00000000..90efe2fe --- /dev/null +++ b/dsLightRag/Liblib/T2.py @@ -0,0 +1,57 @@ +from .LiblibUtil import LiblibUtil +import time + + +def get_generation_status(generate_uuid): + """查询生图任务状态和结果""" + liblib_util = LiblibUtil() + uri = "/api/generate/webui/status" + payload = {"generateUuid": generate_uuid} + return liblib_util.post_request(uri, payload) + + +def wait_for_generation_completion(generate_uuid, check_interval=5, max_wait_time=300): + """等待生图任务完成并获取最终结果""" + liblib_util = LiblibUtil() + start_time = time.time() + + while time.time() - start_time < max_wait_time: + status_data = get_generation_status(generate_uuid) + + if status_data: + status = status_data.get('status') + progress = status_data.get('percentCompleted', 0) * 100 + print(f"生成进度:{progress:.2f}%") + + if status == 'completed': + print("生图任务已完成") + images = status_data.get('images', []) + if images: + print("生成的最终图片:") + for img in images: + print(f"- {img.get('imageUrl')}") + return status_data + elif status == 'failed': + print(f"生图任务失败: {status_data.get('errorMessage', '未知错误')}") + return None + else: + print(f"生图任务处理中,当前状态: {status}") + + time.sleep(check_interval) + + print(f"生图任务超时({max_wait_time}秒)") + return None + + +if __name__ == '__main__': + print("===== 测试查询生图结果 =====") + test_generate_uuid = "061d402be5af492d9949d53719912737" + + if test_generate_uuid: + status_data = get_generation_status(test_generate_uuid) + if status_data: + print(f"生图任务状态:{status_data}") + else: + print("查询生图任务状态失败") + else: + print("请先设置有效的生图任务UUID") \ No newline at end of file