mj_api.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. from curl_cffi import requests
  2. from api.error import unauthorized_error
  3. from api.error import system_error
  4. import oss2
  5. import random
  6. import string
  7. # 查询历史所有任务列表
  8. def thomas_jobs(cookie, user_id, page_size=50):
  9. url = f"https://www.midjourney.com/api/pg/thomas-jobs?user_id={user_id}&page_size={page_size}"
  10. response = requests.get(url, headers=nec_headers(cookie), impersonate="chrome101")
  11. return response_catch(response)
  12. # 查询指定任务状态
  13. def query_job_status(job_id, cookie):
  14. url = "https://www.midjourney.com/api/app/job-status"
  15. response = requests.post(url=url, headers=nec_headers(cookie), impersonate="chrome101", json={"jobIds": [job_id]})
  16. return response_catch(response)
  17. # 查询任务队列
  18. def query_job_queue(cookie, user_id):
  19. url = f"https://www.midjourney.com/api/app/users/queue?userId={user_id}"
  20. response = requests.get(url, headers=nec_headers(cookie), impersonate="chrome101")
  21. return response_catch(response)
  22. # 提交任务 mode: relaxed/fast
  23. def submit_job(cookie, prompt, user_id, mode):
  24. mode = mode or "fast"
  25. request_data = {
  26. "f": {
  27. "mode": mode,
  28. "private": False
  29. },
  30. "channelId": f"singleplayer_{user_id}",
  31. "roomId": None,
  32. "metadata": {
  33. "imagePrompts": 1,
  34. "imageReferences": 0,
  35. "characterReferences": 0
  36. },
  37. "t": "imagine",
  38. "prompt": prompt
  39. }
  40. url = "https://www.midjourney.com/api/app/submit-jobs"
  41. response = requests.post(url=url, headers=nec_headers(cookie), impersonate="chrome101", json=request_data)
  42. return response_catch(response)
  43. # 提交任务 mode: relaxed/fast
  44. def submit_video_job(cookie, prompt, user_id, mode):
  45. mode = mode or "fast"
  46. request_data = {
  47. "f": {
  48. "mode": mode,
  49. "private": False
  50. },
  51. "channelId": f"singleplayer_{user_id}",
  52. "roomId": None,
  53. "metadata": {
  54. "isMobile": None,
  55. "imagePrompts": None,
  56. "imageReferences": None,
  57. "characterReferences": None,
  58. "depthReferences": None,
  59. "lightboxOpen": None
  60. },
  61. "t": "video",
  62. "videoType": "vid_1.1_i2v_480",
  63. "newPrompt": prompt,
  64. "parentJob": None,
  65. "animateMode": "manual"
  66. }
  67. url = "https://www.midjourney.com/api/app/submit-jobs"
  68. response = requests.post(url=url, headers=nec_headers(cookie), impersonate="chrome101", json=request_data)
  69. return response_catch(response)
  70. def generate_random_string(length=15):
  71. characters = string.ascii_letters + string.digits
  72. return ''.join(random.choice(characters) for _ in range(length))
  73. def upload_image_to_oss(job_id, image_num=4):
  74. OSS_ACCESS_KEY_ID = 'LTAI5tEYvefc4U3fyU5du225'
  75. OSS_ACCESS_KEY_SECRET = 'Z1gZtAGe8NwRtXgPzVgRMkRez4Ex4K'
  76. OSS_ENDPOINT = 'oss-ap-southeast-1-internal.aliyuncs.com'
  77. OSS_BUCKET_NAME = 'aigc-admin'
  78. results = []
  79. for i in range(image_num):
  80. object_name = 'saas/mjImage/' + generate_random_string(32) + ".png"
  81. # 下载网络图片
  82. response = requests.get(f"https://cdn.midjourney.com/{job_id}/0_{i}.png",
  83. headers=nec_headers(""),
  84. impersonate="chrome101")
  85. if response.ok:
  86. # 连接OSS
  87. auth = oss2.Auth(OSS_ACCESS_KEY_ID, OSS_ACCESS_KEY_SECRET)
  88. bucket = oss2.Bucket(auth, OSS_ENDPOINT, OSS_BUCKET_NAME)
  89. # 上传图片到OSS
  90. bucket.put_object(object_name, response.content)
  91. # 构造OSS文件URL
  92. oss_url = f"https://res.aiddit.com/{object_name}"
  93. results.append(oss_url)
  94. return results
  95. def upload_video_to_oss(job_id, image_num=4):
  96. OSS_ACCESS_KEY_ID = 'LTAI5tEYvefc4U3fyU5du225'
  97. OSS_ACCESS_KEY_SECRET = 'Z1gZtAGe8NwRtXgPzVgRMkRez4Ex4K'
  98. OSS_ENDPOINT = 'oss-ap-southeast-1-internal.aliyuncs.com'
  99. OSS_BUCKET_NAME = 'aigc-admin'
  100. results = []
  101. for i in range(image_num):
  102. object_name = 'saas/mjVideo/' + generate_random_string(32) + ".mp4"
  103. # 下载网络视频
  104. response = requests.get(f"https://cdn.midjourney.com/video/{job_id}/{i}.mp4",
  105. headers=nec_headers(""),
  106. impersonate="chrome101")
  107. if response.ok:
  108. # 连接OSS
  109. auth = oss2.Auth(OSS_ACCESS_KEY_ID, OSS_ACCESS_KEY_SECRET)
  110. bucket = oss2.Bucket(auth, OSS_ENDPOINT, OSS_BUCKET_NAME)
  111. # 上传视频到OSS
  112. bucket.put_object(object_name, response.content)
  113. # 构造OSS文件URL
  114. oss_url = f"https://res.aiddit.com/{object_name}"
  115. results.append(oss_url)
  116. return results
  117. def response_catch(response):
  118. if response.ok:
  119. return response.json()
  120. elif response.status_code == 401:
  121. raise unauthorized_error("unauthorized access (401)")
  122. else:
  123. raise system_error(f"system_error ({response.status_code})")
  124. def nec_headers(cookie):
  125. headers = {
  126. 'accept': '*/*',
  127. 'accept-language': 'zh-CN,zh;q=0.9',
  128. 'cache-control': 'no-cache',
  129. 'cookie': cookie,
  130. 'pragma': 'no-cache',
  131. 'priority': 'u=1, i',
  132. 'referer': 'https://www.midjourney.com/explore',
  133. 'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"',
  134. 'sec-ch-ua-mobile': '?0',
  135. 'sec-ch-ua-platform': '"Windows"',
  136. 'sec-fetch-dest': 'empty',
  137. 'sec-fetch-mode': 'cors',
  138. 'sec-fetch-site': 'same-origin',
  139. 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36',
  140. 'x-requested-with': 'XMLHttpRequest',
  141. 'x-csrf-protection': 1
  142. }
  143. return headers