MeUtils 2024.12.13.15.39.7__py3-none-any.whl → 2024.12.19.9.30.53__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,180 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ # @Project : AI. @by PyCharm
4
+ # @File : kaiyuan
5
+ # @Time : 2024/12/18 16:03
6
+ # @Author : betterme
7
+ # @WeChat : meutils
8
+ # @Software : PyCharm
9
+ # @Description :
10
+
11
+ import hmac
12
+ import zlib
13
+ import hashlib
14
+
15
+ from meutils.pipe import *
16
+ from meutils.caches.redis_cache import cache
17
+
18
+
19
+ def random_str(n):
20
+ return ''.join(random.sample('zyxwvutsrqponmlkjihgfedcba0123456789', n))
21
+
22
+
23
+ def hash256(msg):
24
+ return hashlib.sha256(msg.encode('utf-8')).hexdigest()
25
+
26
+
27
+ def hmac_hash256(key, msg):
28
+ if type(key) == str:
29
+ return hmac.new(key.encode('utf-8'), msg.encode('utf-8'), hashlib.sha256)
30
+ elif type(key) == hmac.HMAC:
31
+ return hmac.new(key.digest(), msg.encode('utf-8'), hashlib.sha256)
32
+
33
+
34
+ def fileCRC32(file_buffer):
35
+ return hex(zlib.crc32(file_buffer) & 0xFFFFFFFF)[2:]
36
+
37
+
38
+ def u(params):
39
+ new_params = sorted(params.items(), key=lambda x: x[0])
40
+ new_params = [f"{k}={v}" for k, v in new_params]
41
+ return "&".join(new_params)
42
+
43
+
44
+ class JJRequest:
45
+ def __init__(self, e, t, api, method="GET", params=None, data=None):
46
+ self.t = t
47
+ self.e = e
48
+ self.api = api
49
+ self.method = method
50
+ self.params = params
51
+ self.data = data
52
+
53
+ def getAuthorization(self):
54
+ return f"AWS4-HMAC-SHA256 Credential={self.e['access_key_id']}/{self.t[0:8]}/cn-north-1/imagex/aws4_request, SignedHeaders=x-amz-date;x-amz-security-token, Signature={self.signature()}"
55
+
56
+ def signature(self):
57
+ r = self.getSigningKey()
58
+ return hmac_hash256(r, self.stringToSign()).hexdigest()
59
+
60
+ def getSigningKey(self, r="cn-north-1", n="imagex"):
61
+ o = hmac_hash256("AWS4" + self.e['secret_access_key'], str(self.t[0:8]))
62
+ i = hmac_hash256(o, str(r))
63
+ s = hmac_hash256(i, str(n))
64
+ return hmac_hash256(s, "aws4_request")
65
+
66
+ def stringToSign(self):
67
+ t = []
68
+ t.append("AWS4-HMAC-SHA256")
69
+ t.append(self.t)
70
+ t.append(self.credentialString())
71
+ t.append(hash256(self.canonicalString()))
72
+ return "\n".join(t)
73
+
74
+ def credentialString(self, region="cn-north-1", serviceName="imagex"):
75
+ return "/".join([self.t[0:8], region, serviceName, "aws4_request"])
76
+
77
+ def canonicalString(self):
78
+ e = []
79
+ e.append(self.method)
80
+ e.append("/")
81
+ e.append(u(self.params))
82
+ e.append(self.canonicalHeaders())
83
+ e.append(self.signedHeaders())
84
+ e.append(self.hexEncodedBodyHash())
85
+ return "\n".join(e)
86
+
87
+ def canonicalHeaders(self):
88
+ return f"x-amz-date:{self.t}\nx-amz-security-token:{self.e['session_token']}\n"
89
+
90
+ def signedHeaders(self):
91
+ return "x-amz-date;x-amz-security-token"
92
+
93
+ def hexEncodedBodyHash(self):
94
+ return hash256("")
95
+
96
+
97
+ @cache(ttl=15 * 60)
98
+ def upload(image: bytes, upload_token: dict): # oss 跨账号不知道是否可以使用
99
+ # e = auth = upload_token['data']['auth'] # 豆包
100
+ data = upload_token['data']
101
+
102
+ service_id = data.get('service_id', '3jr8j4ixpe') # 即梦 3jr8j4ixpe
103
+
104
+ session_token = data['session_token']
105
+
106
+ t = time.strftime("%Y%m%dT%H%M%SZ", time.gmtime())
107
+
108
+ params = {
109
+ "Action": "ApplyImageUpload",
110
+ "Version": "2018-08-01",
111
+ "ServiceId": service_id,
112
+ "s": random_str(10),
113
+
114
+ "FileExtension": ".png", #####
115
+ "FileSize": len(image),
116
+ }
117
+
118
+ r = JJRequest(data, t, "https://imagex.bytedanceapi.com/", method="GET", params=params)
119
+ headers = {
120
+ 'authorization': r.getAuthorization(),
121
+ 'x-amz-date': t,
122
+ 'x-amz-security-token': session_token,
123
+ }
124
+ # logger.debug(headers)
125
+ response = requests.get(r.api, params=params, headers=headers)
126
+ response.raise_for_status()
127
+ logger.debug(response.status_code)
128
+ response = response.json()
129
+
130
+ logger.debug(bjson(response))
131
+ if "Result" not in response:
132
+ return
133
+
134
+ store_info = response['Result']['UploadAddress']['StoreInfos'][0]
135
+ logger.debug(bjson(store_info))
136
+
137
+ oss_uri = store_info['StoreUri']
138
+ oss_token = store_info['Auth']
139
+
140
+ headers = {
141
+ "authorization": oss_token,
142
+ "content-length": str(len(image)),
143
+ "content-Type": "image/jpeg",
144
+ "content-crc32": fileCRC32(image),
145
+ }
146
+
147
+ # oss_url = f"https://{resp['Result']['UploadAddress']['UploadHosts'][0]}/{oss_uri}"
148
+
149
+ # image_resp = requests.put( # post
150
+ # oss_url,
151
+ # headers=headers,
152
+ # data=image,
153
+ # )
154
+ # logger.debug(image_resp.json())
155
+
156
+ # return get_url(StoreUri)
157
+
158
+ # upload_url = f"https://tos-hl-x.snssdk.com/upload/v1/{oss_uri}"
159
+ upload_url = f"https://{response['Result']['UploadAddress']['UploadHosts'][0]}/upload/v1/{oss_uri}"
160
+
161
+ response = requests.post(upload_url, headers=headers, data=image)
162
+ response.raise_for_status()
163
+ response = response.json()
164
+
165
+ logger.debug(response)
166
+
167
+ return oss_uri
168
+
169
+
170
+ if __name__ == "__main__":
171
+ from meutils.apis.jimeng.common import get_upload_token
172
+
173
+ token = "693701c43e477b7c405cc7e2fef0ddbd"
174
+
175
+ upload_token = arun(get_upload_token(token))
176
+
177
+ with open("11.jpg", "rb") as f:
178
+ file = image = f.read()
179
+
180
+ upload(image, upload_token)
@@ -0,0 +1,105 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ # @Project : AI. @by PyCharm
4
+ # @File : images
5
+ # @Time : 2024/12/16 17:46
6
+ # @Author : betterme
7
+ # @WeChat : meutils
8
+ # @Software : PyCharm
9
+ # @Description :
10
+
11
+ from meutils.pipe import *
12
+
13
+ from meutils.schemas.jimeng_types import BASE_URL, MODELS_MAP, FEISHU_URL
14
+ from meutils.schemas.image_types import ImageRequest
15
+ from meutils.schemas.task_types import TaskResponse
16
+ from meutils.apis.jimeng.common import create_draft_content, get_headers, check_token
17
+ from meutils.config_utils.lark_utils import get_next_token_for_polling
18
+
19
+ from fake_useragent import UserAgent
20
+
21
+ ua = UserAgent()
22
+
23
+
24
+ async def create_task(request: ImageRequest, token: Optional[str] = None):
25
+ token = token or await get_next_token_for_polling(FEISHU_URL, check_token)
26
+
27
+ url = "/mweb/v1/aigc_draft/generate"
28
+
29
+ headers = get_headers(url, token)
30
+
31
+ if "http" in request.prompt: # 图生
32
+ request.model = "high_aes_general_v20_L:general_v2.0_L"
33
+
34
+ draft_content = await create_draft_content(request, token)
35
+ payload = {
36
+ "extend": {
37
+ "root_model": request.model,
38
+ "template_id": ""
39
+ },
40
+ "submit_id": str(uuid.uuid4()),
41
+ "metrics_extra": "{\"templateId\":\"\",\"generateCount\":1,\"promptSource\":\"custom\",\"templateSource\":\"\",\"lastRequestId\":\"\",\"originRequestId\":\"\"}",
42
+ "draft_content": json.dumps(draft_content),
43
+ "http_common_info": {
44
+ "aid": 513695
45
+ }
46
+ }
47
+
48
+ logger.debug(bjson(payload))
49
+
50
+ async with httpx.AsyncClient(base_url=BASE_URL, headers=headers, timeout=60) as client:
51
+ response = await client.post(url, json=payload)
52
+ response.raise_for_status()
53
+ data = response.json()
54
+ logger.debug(bjson(data))
55
+
56
+ task_id = data.get("data", {}).get("aigc_data", {}).get("history_record_id")
57
+ return TaskResponse(task_id=task_id, system_fingerprint=token)
58
+
59
+
60
+ async def get_task(task_id, token):
61
+ url = "/mweb/v1/get_history_by_ids"
62
+ headers = get_headers(url, token)
63
+ payload = {
64
+ "history_ids": [
65
+ task_id
66
+ ]
67
+ }
68
+
69
+ async with httpx.AsyncClient(base_url=BASE_URL, headers=headers, timeout=60) as client:
70
+ response = await client.post(url, json=payload)
71
+ response.raise_for_status()
72
+ data = response.json()
73
+ # {'ret': '1015', 'errmsg': 'login error', 'systime': '1734524280', 'logid': '20241218201800AC3267447B287E9E6C46', 'data': None}
74
+ item_list = (data.get("data") or {}).get(task_id, {}).get("item_list")
75
+ image_data = map(lambda x: x.get("image", {}).get("large_images"), item_list)
76
+
77
+ task_data = sum(image_data, []) | xmap_(lambda x: {"url": x.get("image_url")})
78
+
79
+ return TaskResponse(
80
+ task_id=task_id,
81
+ data=task_data,
82
+ message=data.get("errmsg"),
83
+ status=task_data and "success",
84
+ )
85
+
86
+
87
+ if __name__ == '__main__':
88
+ token = "693701c43e477b7c405cc7e2fef0ddbd"
89
+
90
+ request = ImageRequest(prompt="一个漂亮的姑娘", size="1024x1024")
91
+ # request = ImageRequest(prompt="https://oss.ffire.cc/files/kling_watermark.png 让她带上墨镜", size="1024x1024")
92
+
93
+ arun(create_task(request))
94
+
95
+ # task_id = "10040025470722"
96
+
97
+ # task_id = "10053536381698"
98
+
99
+ # task_id = "10079694738434"
100
+
101
+ # task_id = "10080831230210" # 图片编辑
102
+
103
+ # task_id = "10082971040514"
104
+ #
105
+ # arun(get_task(task_id, token))
@@ -0,0 +1,92 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ # @Project : AI. @by PyCharm
4
+ # @File : sig
5
+ # @Time : 2024/12/18 15:36
6
+ # @Author : betterme
7
+ # @WeChat : meutils
8
+ # @Software : PyCharm
9
+ # @Description :
10
+ import hashlib
11
+ import hmac
12
+ import datetime
13
+
14
+
15
+ def sign(key, msg):
16
+ return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).digest()
17
+
18
+
19
+ def getSignatureKey(key, dateStamp, regionName, serviceName):
20
+ kDate = sign(('AWS4' + key).encode('utf-8'), dateStamp)
21
+ kRegion = sign(kDate, regionName)
22
+ kService = sign(kRegion, serviceName)
23
+ kSigning = sign(kService, 'aws4_request')
24
+ return kSigning
25
+
26
+
27
+ if __name__ == '__main__':
28
+ pass
29
+ from meutils.pipe import *
30
+ from meutils.apis.jimeng.utils import get_upload_token
31
+
32
+ # data = arun(get_upload_token())
33
+
34
+ # access_key_id = data['data']['auth']['access_key_id']
35
+ # secret_access_key = data['data']['auth']['secret_access_key']
36
+ # session_token = data['data']['auth']['session_token']
37
+
38
+ import hashlib
39
+ import hmac
40
+ import datetime
41
+
42
+
43
+ def sign(key, msg):
44
+ """计算 HMAC-SHA256"""
45
+ return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).digest()
46
+
47
+
48
+ def getSignatureKey(key, dateStamp, regionName, serviceName):
49
+ """生成签名密钥"""
50
+ kDate = sign(('AWS4' + key).encode('utf-8'), dateStamp)
51
+ kRegion = sign(kDate, regionName)
52
+ kService = sign(kRegion, serviceName)
53
+ kSigning = sign(kService, 'aws4_request')
54
+ return kSigning
55
+
56
+
57
+ def calculate_signature(string_to_sign, secret_key, region, service, date):
58
+ """计算 AWS4-HMAC-SHA256 签名"""
59
+ # 生成签名密钥
60
+ signing_key = getSignatureKey(
61
+ secret_key,
62
+ date.strftime('%Y%m%d'),
63
+ region,
64
+ service
65
+ )
66
+
67
+ # 计算最终签名
68
+ signature = hmac.new(
69
+ signing_key,
70
+ string_to_sign.encode('utf-8'),
71
+ hashlib.sha256
72
+ ).hexdigest()
73
+
74
+ return signature
75
+
76
+ # 示例参数
77
+
78
+
79
+ secret_key = 'AKTPN2VkZWY2MWNhNjVlNGZhZThiZmVmNzEwODA3YjM1YTY'
80
+ region = 'cn-north-1'
81
+ service = 'imagex'
82
+ date = datetime.datetime.utcnow()
83
+ print(date)
84
+ hash_of_canonical_request = {
85
+ "SessionKey": "eyJhY2NvdW50VHlwZSI6IkltYWdlWCIsImFwcElkIjoiIiwiYml6VHlwZSI6IiIsImZpbGVUeXBlIjoiaW1hZ2UiLCJsZWdhbCI6IiIsInN0b3JlSW5mb3MiOiJbe1wiU3RvcmVVcmlcIjpcInRvcy1jbi1pLWE5cm5zMnJsOTgvYmQzZGNlZWIzN2Y3NDA5NjlkMTBiZjBiZjhhMzk0NmUuanBlZ1wiLFwiQXV0aFwiOlwiU3BhY2VLZXkvYTlybnMycmw5OC8xLzp2ZXJzaW9uOnYyOmV5SmhiR2NpT2lKSVV6STFOaUlzSW5SNWNDSTZJa3BYVkNKOS5leUpsZUhBaU9qRTNNelExTXpBd016Z3NJbk5wWjI1aGRIVnlaVWx1Wm04aU9uc2lZV05qWlhOelMyVjVJam9pWm1GclpWOWhZMk5sYzNOZmEyVjVJaXdpWW5WamEyVjBJam9pZEc5ekxXTnVMV2t0WVRseWJuTXljbXc1T0NJc0ltVjRjR2x5WlNJNk1UY3pORFV6TURBek9Dd2labWxzWlVsdVptOXpJanBiZXlKdmFXUkxaWGtpT2lKaVpETmtZMlZsWWpNM1pqYzBNRGsyT1dReE1HSm1NR0ptT0dFek9UUTJaUzVxY0dWbklpd2labWxzWlZSNWNHVWlPaUl4SW4xZExDSmxlSFJ5WVNJNmV5SmliRzlqYTE5dGIyUmxJam9pSWl3aVkyOXVkR1Z1ZEY5MGVYQmxYMkpzYjJOcklqb2llMXdpYldsdFpWOXdZM1JjSWpvd0xGd2liVzlrWlZ3aU9qQXNYQ0p0YVcxbFgyeHBjM1JjSWpwdWRXeHNMRndpWTI5dVpteHBZM1JmWW14dlkydGNJanBtWVd4elpYMGlMQ0psYm1OeWVYQjBYMkZzWjI4aU9pSWlMQ0psYm1OeWVYQjBYMnRsZVNJNklpSXNJbVY0ZEY5amIyNTBaVzUwWDNSNWNHVWlPaUpwYldGblpTOXFjR1ZuSWl3aWFYTmZhVzFoWjJWNElqcDBjblZsTENKemNHRmpaU0k2SW1FNWNtNXpNbkpzT1RnaWZYMTkueVFadDJoYWFVMDBuMTFZREJXZDBCbTNIYWdtVlNUN0UzNXMwSkNnOGpzMFwiLFwiVXBsb2FkSURcIjpcIjE3ZThiODUxNzczNDRlYjFiYmM1MDAzMWU3NzQ3NGUyXCIsXCJVcGxvYWRIZWFkZXJcIjpudWxsLFwiU3RvcmFnZUhlYWRlclwiOm51bGx9XSIsInVwbG9hZEhvc3QiOiJ0b3MtZC14LWxmLnNuc3Nkay5jb20iLCJ1cmkiOiJ0b3MtY24taS1hOXJuczJybDk4L2JkM2RjZWViMzdmNzQwOTY5ZDEwYmYwYmY4YTM5NDZlLmpwZWciLCJ1c2VySWQiOiIifQ=="
86
+ }
87
+ hash_of_canonical_request = json.dumps(hash_of_canonical_request)
88
+ string_to_sign = f'AWS4-HMAC-SHA256\n20241218T075358Z\n20241218/cn-north-1/imagex/aws4_request\n{hash_of_canonical_request}'
89
+
90
+ # 计算签名
91
+ signature = calculate_signature(string_to_sign, secret_key, region, service, date)
92
+ print(f'签名结果: {signature}')
@@ -0,0 +1,177 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ # @Project : AI. @by PyCharm
4
+ # @File : utils
5
+ # @Time : 2024/12/18 11:03
6
+ # @Author : betterme
7
+ # @WeChat : meutils
8
+ # @Software : PyCharm
9
+ # @Description :
10
+ import httpx
11
+
12
+ from meutils.pipe import *
13
+ import random
14
+ import base64
15
+ import time
16
+ import uuid
17
+ import secrets
18
+ import string
19
+ import hmac
20
+ import hashlib
21
+
22
+ # 常量定义
23
+ MODEL_NAME = "doubao"
24
+ DEFAULT_ASSISTANT_ID = "497858"
25
+ VERSION_CODE = "20800"
26
+ DEVICE_ID = random.random() * 999999999999999999 + 7000000000000000000
27
+ WEB_ID = random.random() * 999999999999999999 + 7000000000000000000
28
+ USER_ID = str(uuid.uuid4()).replace('-', '')
29
+ MAX_RETRY_COUNT = 3
30
+ RETRY_DELAY = 5000
31
+ FILE_MAX_SIZE = 100 * 1024 * 1024
32
+
33
+ # 伪装headers
34
+ FAKE_HEADERS = {
35
+ "Accept": "*/*",
36
+ "Accept-Encoding": "gzip, deflate, br, zstd",
37
+ "Accept-language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
38
+ "Cache-control": "no-cache",
39
+ "Last-event-id": "undefined",
40
+ "Origin": "https://www.doubao.com",
41
+ "Pragma": "no-cache",
42
+ "Priority": "u=1, i",
43
+ "Referer": "https://www.doubao.com",
44
+ "Sec-Ch-Ua": '"Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"',
45
+ "Sec-Ch-Ua-Mobile": "?0",
46
+ "Sec-Ch-Ua-Platform": '"Windows"',
47
+ "Sec-Fetch-Dest": "empty",
48
+ "Sec-Fetch-Mode": "cors",
49
+ "Sec-Fetch-Site": "same-origin",
50
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
51
+ }
52
+
53
+
54
+ async def acquire_token(refresh_token: str) -> str:
55
+ """
56
+ 获取缓存中的access_token
57
+ 目前doubao的access_token是固定的,暂无刷新功能
58
+
59
+ Args:
60
+ refresh_token: 用于刷新access_token的refresh_token
61
+
62
+ Returns:
63
+ str: access_token
64
+ """
65
+ return refresh_token
66
+
67
+
68
+ def generate_fake_ms_token() -> str:
69
+ """
70
+ 生成伪msToken
71
+ """
72
+ # 生成96字节的随机数据
73
+ random_bytes = secrets.token_bytes(96)
74
+ # 转换为base64,并替换特殊字符
75
+ token = base64.b64encode(random_bytes).decode('utf-8')
76
+ return token.replace('+', '-').replace('/', '_').rstrip('=')
77
+
78
+
79
+ def generate_random_string(length: int) -> str:
80
+ """
81
+ 生成指定长度的随机字符串
82
+ """
83
+ chars = string.ascii_letters + string.digits
84
+ return ''.join(random.choice(chars) for _ in range(length))
85
+
86
+
87
+ def generate_fake_a_bogus() -> str:
88
+ """
89
+ 生成伪a_bogus
90
+ """
91
+ return f"mf-{generate_random_string(34)}-{generate_random_string(6)}"
92
+
93
+
94
+ def generate_cookie(refresh_token: str, ms_token: Optional[str] = None) -> str:
95
+ """
96
+ 生成cookie
97
+ """
98
+ ms_token = ms_token or generate_fake_ms_token()
99
+
100
+ current_timestamp = int(time.time())
101
+ cookie_parts = [
102
+ f"is_staff_user=false",
103
+ f"store-region=cn-gd",
104
+ f"store-region-src=uid",
105
+ f"sid_guard={refresh_token}%7C{current_timestamp}%7C5184000%7CSun%2C+02-Feb-2025+04%3A17%3A20+GMT",
106
+ f"uid_tt={USER_ID}",
107
+ f"uid_tt_ss={USER_ID}",
108
+ f"sid_tt={refresh_token}",
109
+ f"sessionid={refresh_token}",
110
+ f"sessionid_ss={refresh_token}",
111
+ f"msToken={ms_token}",
112
+ ]
113
+ return "; ".join(cookie_parts)
114
+
115
+
116
+ async def get_upload_token(): # 3600过期
117
+ """
118
+
119
+ {'code': 0,
120
+ 'data': {'auth': {'access_key_id': 'AKTPYzNkMjJlNTNjMWE1NDJiN2E5MWFkOTYxMWViYzQxYTM',
121
+ 'current_time': '2024-12-18T11:17:22+08:00',
122
+ 'expired_time': '2024-12-18T12:17:22+08:00',
123
+ 'secret_access_key': 'HFFTkEFKf+0DVpUrYy2yMzvgnkxLMU6+qydnGUSaDmd0vSRedpIi0qmeWSVElyOU',
124
+ 'session_token': 'STS2eyJMVEFjY2Vzc0tleUlkIjoiQUtMVFlUZGhPR0ptWVRNNFl6ZG1OR1JoWVRoaE0yWTJPVFl5TW1SbU0yRmhNREEiLCJBY2Nlc3NLZXlJZCI6IkFLVFBZek5rTWpKbE5UTmpNV0UxTkRKaU4yRTVNV0ZrT1RZeE1XVmlZelF4WVRNIiwiU2lnbmVkU2VjcmV0QWNjZXNzS2V5IjoiTC9WZTVSMmt4N3dsY1kvS0E5alp1WVlpSlVFM0ZjdHMzQ2Q5QjJZMVE3NlRnUDVONWViMmpKQkRQMUdyUEtqeXNYNXRKVkJPdExvVjVNOGFyY24wQ2ZtdUZRRWMxMG8xMSs3UHdKdGY0LzQ9IiwiRXhwaXJlZFRpbWUiOjE3MzQ0OTU0NDIsIlBvbGljeVN0cmluZyI6IntcIlN0YXRlbWVudFwiOlt7XCJFZmZlY3RcIjpcIkFsbG93XCIsXCJBY3Rpb25cIjpbXCJJbWFnZVg6QXBwbHlJbWFnZVVwbG9hZFwiLFwiSW1hZ2VYOkNvbW1pdEltYWdlVXBsb2FkXCJdLFwiUmVzb3VyY2VcIjpbXCJ0cm46SW1hZ2VYOio6KjpTZXJ2aWNlSWQvYTlybnMycmw5OFwiXX0se1wiRWZmZWN0XCI6XCJBbGxvd1wiLFwiQWN0aW9uXCI6W1wiUFNNXCJdLFwiUmVzb3VyY2VcIjpbXCJmbG93LmFsaWNlLnJlc291cmNlX2FwaVwiXX1dfSIsIlNpZ25hdHVyZSI6ImI2MGUxNDZkZTU0Njg2NTdlYzVlZmFjZjJlOWNlOWE5YTdhY2UwNTFlZTdkYTJjZTRmNjdiYmRiM2U4MDQ3N2IifQ=='},
125
+ 'service_id': 'a9rns2rl98',
126
+ 'upload_host': 'imagex.bytedanceapi.com',
127
+ 'upload_path_prefix': 'bot-chat-image'},
128
+ 'msg': ''}
129
+
130
+ :return:
131
+ """
132
+ cookie = generate_cookie('de2215a7bb8e442774cf388f03fac84c')
133
+ url = "https://www.doubao.com/alice/upload/auth_token"
134
+
135
+ headers = {
136
+ 'priority': 'u=1, i',
137
+ 'Cookie': cookie,
138
+ 'User-Agent': 'Apifox/1.0.0 (https://apifox.com)',
139
+ }
140
+ payload = {
141
+ "scene": "bot_chat",
142
+ "data_type": "image"
143
+ }
144
+
145
+ async with httpx.AsyncClient() as client:
146
+ response = await client.post(url, headers=headers, json=payload)
147
+ response.raise_for_status()
148
+
149
+ return response.json()
150
+
151
+
152
+ def hmac_hash256(key, msg):
153
+ if type(key) == str:
154
+ return hmac.new(key.encode('utf-8'), msg.encode('utf-8'), hashlib.sha256)
155
+ elif type(key) == hmac.HMAC:
156
+ return hmac.new(key.digest(), msg.encode('utf-8'), hashlib.sha256)
157
+
158
+
159
+ def get_signing_key(secret_access_key, r="cn-north-1", n="imagex"):
160
+ dt = str(datetime.datetime.now())[:10].replace('-', '')
161
+ o = hmac_hash256("AWS4" + secret_access_key, dt)
162
+ i = hmac_hash256(o, str(r))
163
+ s = hmac_hash256(i, str(n))
164
+ return hmac_hash256(s, "aws4_request")
165
+
166
+ def signature(secret_access_key):
167
+ r = get_signing_key(secret_access_key)
168
+ return hmac_hash256(r, self.stringToSign()).hexdigest()
169
+
170
+ # ccd4fef2cca1a114e776badad7f4b6e73f305a4dbb09e68f336759ddb6ac0025
171
+
172
+ if __name__ == '__main__':
173
+ # generate_cookie("")
174
+
175
+ # arun(get_upload_token())
176
+
177
+ print(get_signing_key('xW9YbDhTlWsXdaN7O2g1lfcyePxf5kJyg/r2mwSZG/iuSmbvVgToO6LVCLmUjVJ3'))
@@ -7,13 +7,16 @@
7
7
  # @WeChat : meutils
8
8
  # @Software : PyCharm
9
9
  # @Description :
10
+ import asyncio
10
11
 
11
12
  from meutils.pipe import *
12
13
  from meutils.caches.redis_cache import cache
14
+ from meutils.io.files_utils import to_url, to_url_fal
13
15
  from meutils.llm.check_utils import check_token_for_siliconflow
14
16
  from meutils.schemas.task_types import TaskResponse
15
17
  from meutils.schemas.siliconflow_types import BASE_URL, VideoRequest
16
18
  from meutils.config_utils.lark_utils import get_next_token_for_polling
19
+ from meutils.apis.translator import deeplx
17
20
 
18
21
  from openai import OpenAI, AsyncOpenAI
19
22
 
@@ -21,38 +24,54 @@ FEISHU_URL_FREE = "https://xchatllm.feishu.cn/sheets/Bmjtst2f6hfMqFttbhLcdfRJnNf
21
24
 
22
25
  check_token = partial(check_token_for_siliconflow, threshold=0.01)
23
26
 
27
+ MODELS_MAP = {
28
+ "hunyuan-video": "tencent/HunyuanVideo",
29
+ "hunyuanvideo": "tencent/HunyuanVideo",
30
+ "mochi-1-preview": "genmo/mochi-1-preview",
31
+ "ltx-video": "Lightricks/LTX-Video",
32
+ }
33
+
24
34
 
25
35
  @cache(ttl=7 * 24 * 3600)
26
36
  async def create_task(request: VideoRequest, token: Optional[str] = None):
27
37
  token = token or await get_next_token_for_polling(FEISHU_URL_FREE, check_token=check_token, from_redis=True)
28
38
 
29
39
  payload = request.model_dump(exclude_none=True)
30
- payload["model"] = "tencent/HunyuanVideo"
40
+ payload["model"] = MODELS_MAP.get(request.model, "Lightricks/LTX-Video")
41
+
42
+ if payload["model"] in {"genmo/mochi-1-preview", "Lightricks/LTX-Video"}: # 中文不友好
43
+ payload['prompt'] = (
44
+ await deeplx.translate(deeplx.DeeplxRequest(text=request.prompt, target_lang="EN"))).get("data")
31
45
 
32
- client = OpenAI(
46
+ client = AsyncOpenAI(
33
47
  base_url=BASE_URL,
34
48
  api_key=token
35
49
  )
36
50
 
37
- response = client.post("/video/submit", cast_to=object, body=payload)
51
+ response = await client.post("/video/submit", body=payload, cast_to=object)
38
52
  logger.debug(response)
39
- task_id = response.get('requestId')
40
53
 
54
+ task_id = response.get('requestId')
41
55
  return TaskResponse(task_id=task_id, system_fingerprint=token)
42
56
 
43
57
 
44
58
  async def get_task(task_id, token: str):
45
- client = OpenAI(
59
+ client = AsyncOpenAI(
46
60
  base_url=BASE_URL,
47
61
  api_key=token
48
62
  )
49
63
  payload = {"requestId": task_id}
50
- response = client.post(f"/video/status", cast_to=object, body=payload)
64
+ response = await client.post(f"/video/status", cast_to=object, body=payload)
51
65
  logger.debug(response)
52
66
 
67
+ data = response.get("results") or {}
68
+
69
+ for video in data.get("videos", []):
70
+ video["url"] = await to_url_fal(video.get("url")) # 异步执行
71
+
53
72
  return TaskResponse(
54
73
  task_id=task_id,
55
- data=response.get("results"),
74
+ data=data,
56
75
  status=response.get("status"),
57
76
  message=response.get("reason"),
58
77
  )
@@ -60,12 +79,22 @@ async def get_task(task_id, token: str):
60
79
 
61
80
  if __name__ == '__main__':
62
81
  token = None
82
+ token = "sk-raapiguffsnsxgkfiwfusjmbpcyqoxhcohhxaybflrnvpqjw"
83
+
84
+ request = VideoRequest(
85
+ model="Lightricks/LTX-Video",
86
+ prompt="这个女人笑起来",
87
+ image='https://oss.ffire.cc/files/kling_watermark.png' # 1148f2e4-0a62-4208-84de-0bf2c88f740d
88
+ )
63
89
  # tokens = config_manager.text.split()
64
90
 
65
91
  # tokens_ = arun(check_token_for_siliconflow(tokens, threshold=0.01))
66
92
 
67
- token = "sk-raapiguffsnsxgkfiwfusjmbpcyqoxhcohhxaybflrnvpqjw"
68
- arun(get_task("73a15e11-310f-4464-a9af-3ab84b201fff", token))
93
+ # arun(create_task(request, token=token))
94
+
95
+ # arun(get_task("fa248aac-00ec-4b00-a2f8-3d6bf1cea6d3", token))
96
+ # arun(get_task("c716a328-438e-4612-aff2-a669034499cb", token))
97
+ arun(get_task("1148f2e4-0a62-4208-84de-0bf2c88f740d", token))
69
98
 
70
99
  # token = "sk-oeptckzkhfzeidbtsqvbrvyrfdtyaaehubfwsxjytszbgohd"
71
100
  # arun(get_task("5ea22f57-45f0-425c-9d1e-bf3dae7e1e81", token))
meutils/data/VERSION CHANGED
@@ -1 +1 @@
1
- 2024.12.13.15.39.07
1
+ 2024.12.19.09.30.53