使用python调用comfyui-api,实现出图自由
AI魔法学院
2024-06-21
分享海报

使用python调用comfyui-api,实现出图自由

1.     

title: 使用python调用comfyui-api,实现出图自由

2.     

date: 2024-03-13 22:31:33

1、comfyui设置

打开comfyui,记录下对应的端口,设置开发者模式

1718878898079

1718878902637

打开一条workflow工作流,这里以comfyui自带的工作流为例,保存为api格式

1718878907226

再次打开api格式工作流

这里一定再次点击查看是否能运行正常,因为有的节点可能在api格式中无法运作

确定可以在comfyui中正常启动就可以下一步了

2、python设置

新建一个python脚本,将以下内容粘贴进去

1.     

import json

2.     

import websocket  # NOTE: websocket-client (https://github.com/websocket-client/websocket-client)

3.     

import uuid

4.     

import urllib.request

5.     

import urllib.parse

6.     

import random

7.     

# 定义一个函数来显示GIF图片

8.     

def show_gif(fname):

9.     

    import base64

10. 

    from IPython import display

11. 

12. 

    with open(fname, 'rb') as fd:

13. 

        b64 = base64.b64encode(fd.read()).decode('ascii')

14. 

    return display.HTML(f'<img src="data:image/gif;base64,{b64}" />')

15. 

# 定义一个函数向服务器队列发送提示信息

16. 

def queue_prompt(prompt):

17. 

    p = {"prompt": prompt, "client_id": client_id}

18. 

    data = json.dumps(p).encode('utf-8')

19. 

    req = urllib.request.Request("http://{}/prompt".format(server_address), data=data)

20. 

    return json.loads(urllib.request.urlopen(req).read())

21. 

# 定义一个函数来获取图片

22. 

def get_image(filename, subfolder, folder_type):

23. 

    data = {"filename": filename, "subfolder": subfolder, "type": folder_type}

24. 

    url_values = urllib.parse.urlencode(data)

25. 

    with urllib.request.urlopen("http://{}/view?{}".format(server_address, url_values)) as response:

26. 

        return response.read()

27. 

# 定义一个函数来获取历史记录

28. 

def get_history(prompt_id):

29. 

    with urllib.request.urlopen("http://{}/history/{}".format(server_address, prompt_id)) as response:

30. 

        return json.loads(response.read())

31. 

# 定义一个函数来获取图片,这涉及到监听WebSocket消息

32. 

def get_images(ws, prompt):

33. 

    prompt_id = queue_prompt(prompt)['prompt_id']

34. 

    print('prompt')

35. 

    print(prompt)

36. 

    print('prompt_id:{}'.format(prompt_id))

37. 

    output_images = {}

38. 

    while True:

39. 

        out = ws.recv()

40. 

        if isinstance(out, str):

41. 

            message = json.loads(out)

42. 

            if message['type'] == 'executing':

43. 

                data = message['data']

44. 

                if data['node'] is None and data['prompt_id'] == prompt_id:

45. 

                    print('执行完成')

46. 

                    break  # 执行完成

47. 

        else:

48. 

            continue  # 预览为二进制数据

49. 

    history = get_history(prompt_id)[prompt_id]

50. 

    print(history)

51. 

    for o in history['outputs']:

52. 

        for node_id in history['outputs']:

53. 

            node_output = history['outputs'][node_id]

54. 

            # 图片分支

55. 

            if 'images' in node_output:

56. 

                images_output = []

57. 

                for image in node_output['images']:

58. 

                    image_data = get_image(image['filename'], image['subfolder'], image['type'])

59. 

                    images_output.append(image_data)

60. 

                output_images[node_id] = images_output

61. 

            # 视频分支

62. 

            if 'videos' in node_output:

63. 

                videos_output = []

64. 

                for video in node_output['videos']:

65. 

                    video_data = get_image(video['filename'], video['subfolder'], video['type'])

66. 

                    videos_output.append(video_data)

67. 

                output_images[node_id] = videos_output

68. 

    print('获取图片完成')

69. 

    print(output_images)

70. 

    return output_images

71. 

# 解析工作流并获取图片

72. 

def parse_worflow(ws, prompt, seed, workflowfile):

73. 

    workflowfile = workflowfile

74. 

    print('workflowfile:'+workflowfile)

75. 

    with open(workflowfile, 'r', encoding="utf-8") as workflow_api_txt2gif_file:

76. 

        prompt_data = json.load(workflow_api_txt2gif_file)

77. 

        # 设置文本提示

78. 

        prompt_data["6"]["inputs"]["text"] = prompt

79. 

        return get_images(ws, prompt_data)

80. 

# 生成图像并显示

81. 

def generate_clip(prompt, seed, workflowfile, idx):

82. 

    print('seed:'+str(seed))

83. 

    ws = websocket.WebSocket()

84. 

    ws.connect("ws://{}/ws?clientId={}".format(server_address, client_id))

85. 

    images = parse_worflow(ws, prompt, seed, workflowfile)

86. 

    for node_id in images:

87. 

        for image_data in images[node_id]:

88. 

            from datetime import datetime

89. 

            # 获取当前时间,并格式化为 YYYYMMDDHHMMSS 的格式

90. 

            timestamp = datetime.now().strftime("%Y%m%d%H%M%S")

91. 

            # 使用格式化的时间戳在文件名中

92. 

            GIF_LOCATION = "{}/{}_{}_{}.png".format(SageMaker_ComfyUI, idx, seed, timestamp)

93. 

            print('GIF_LOCATION:'+GIF_LOCATION)

94. 

            with open(GIF_LOCATION, "wb") as binary_file:

95. 

                # 写入二进制文件

96. 

                binary_file.write(image_data)

97. 

            show_gif(GIF_LOCATION)

98. 

            print("{} DONE!!!".format(GIF_LOCATION))

99. 

import pandas as pd

100.                     

# Example of reading from a CSV file

101.                     

def read_prompts_from_csv(csv_file_path):

102.                     

    df = pd.read_excel(csv_file_path)

103.                     

    return df['prompt'].tolist()

104.                     

# Execute the main function

105.                     

if __name__ == "__main__":

106.                     

    # 设置工作目录和项目相关的路径

107.                     

    WORKING_DIR = 'output'

108.                     

    SageMaker_ComfyUI = WORKING_DIR

109.                     

    workflowfile = 'workflow_api.json'

110.                     

    COMFYUI_ENDPOINT = '127.0.0.1:8188'

111.                     

    server_address = COMFYUI_ENDPOINT

112.                     

    client_id = str(uuid.uuid4())  # 生成一个唯一的客户端ID

113.                     

    seed = 15465856

114.                     

    csv_file_path = 'prompt.xlsx'

115.                     

    prompts = read_prompts_from_csv(csv_file_path)

116.                     

    idx = 1

117.                     

    for prompt in prompts:

118.                     

        generate_clip(prompt, seed, workflowfile, idx)

119.                     

        idx += 1

120.                     

替换相应的参数,比如workflowfile文件名、COMFYUI_ENDPOINT地址,

WORKING_DIR输出文件的目录是对应脚本文件的

接着打开存储工作流api信息的josn文件

找到我们要修改的参数,比如我要修改正向提示词参数

1718878920596

可以看到其对应的键值位置是["6"]["inputs"]["text"]

就可以设置对应的参数,在函数中解析替换这个键值

我在最后还设置了一个文件'prompt.xlsx',方便写入大量的prompt进行替换

这样就可以解放双手,996的压榨显卡啦(不是)

3、参考来源

[【全网首发】ComfyUI-API详解,应用开发调用全流程!哔哩哔哩bilibili](https://www.bilibili.com/video/BV1Pm4y1K7Ey/?spmidfrom=333.337.search-card.all.click&vd_source=90ce3ea8a5a8a661b09e5d13bfb5f43a)


出自:https://mp.weixin.qq.com/s/CT8IBOJZVeMhV0ktlOiSRg

© THE END

转载请联系本网站获得授权

投稿或版权问题请加微信:skillupvip