Skip to content

Commit f83c0a8

Browse files
Add nodes, models and settings api
1 parent 3cd63f8 commit f83c0a8

File tree

11 files changed

+528
-103
lines changed

11 files changed

+528
-103
lines changed

server/api.py

Lines changed: 0 additions & 31 deletions
This file was deleted.

server/api/__init__.py

Whitespace-only changes.

server/api/api.py

Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
from pathlib import Path
2+
import os
3+
import json
4+
from git import Repo
5+
import logging
6+
import sys
7+
from aiohttp import web
8+
9+
from api.nodes.nodes import list_nodes, install_node, delete_node
10+
from api.models.models import list_models, add_model, delete_model
11+
from api.settings.settings import set_twilio_account_info
12+
13+
def add_routes(app):
14+
app.router.add_get("/env/list_nodes", nodes)
15+
app.router.add_post("/env/install_nodes", install_nodes)
16+
app.router.add_post("/env/delete_nodes", delete_nodes)
17+
18+
app.router.add_get("/env/list_models", models)
19+
app.router.add_post("/env/add_models", add_models)
20+
app.router.add_post("/env/delete_models", delete_models)
21+
22+
app.router.add_post("/env/set_account_info", set_account_info)
23+
24+
25+
async def nodes(request):
26+
'''
27+
List all custom nodes in the workspace
28+
29+
# Example response:
30+
{
31+
"error": null,
32+
"nodes":
33+
[
34+
{
35+
"name": ComfyUI-Custom-Node,
36+
"version": "0.0.1",
37+
"url": "https://github.com/custom-node-maker/ComfyUI-Custom-Node",
38+
"branch": "main",
39+
"commit": "uasfg98",
40+
"update_available": false,
41+
},
42+
{
43+
...
44+
},
45+
{
46+
...
47+
}
48+
]
49+
}
50+
51+
'''
52+
workspace_dir = request.app["workspace"]
53+
try:
54+
nodes = await list_nodes(workspace_dir)
55+
return web.json_response({"error": None, "nodes": nodes})
56+
except Exception as e:
57+
return web.json_response({"error": str(e), "nodes": nodes}, status=500)
58+
59+
async def install_nodes(request):
60+
'''
61+
Install ComfyUI custom node from git repository.
62+
63+
Installs requirements.txt from repository if present
64+
65+
# Parameters:
66+
url: url of the git repository
67+
branch: branch of the git repository
68+
depdenencies: comma separated list of dependencies to install with pip (optional)
69+
70+
# Example request:
71+
[
72+
{
73+
"url": "https://github.com/custom-node-maker/ComfyUI-Custom-Node",
74+
"branch": "main"
75+
},
76+
{
77+
"url": "https://github.com/custom-node-maker/ComfyUI-Custom-Node",
78+
"branch": "main",
79+
"dependencies": "requests, numpy"
80+
}
81+
]
82+
'''
83+
workspace_dir = request.app["workspace"]
84+
try:
85+
nodes = await request.json()
86+
installed_nodes = []
87+
for node in nodes:
88+
await install_node(node, workspace_dir)
89+
installed_nodes.append(node['url'])
90+
return web.json_response({"success": True, "error": None, "installed_nodes": installed_nodes})
91+
except Exception as e:
92+
return web.json_response({"success": False, "error": str(e), "installed_nodes": installed_nodes}, status=500)
93+
94+
async def delete_nodes(request):
95+
'''
96+
Delete ComfyUI custom node
97+
98+
# Parameters:
99+
name: name of the repository (e.g. ComfyUI-Custom-Node for url "https://github.com/custom-node-maker/ComfyUI-Custom-Node")
100+
101+
# Example request:
102+
[
103+
{
104+
"name": "ComfyUI-Custom-Node"
105+
},
106+
{
107+
...
108+
}
109+
]
110+
'''
111+
workspace_dir = request.app["workspace"]
112+
try:
113+
nodes = await request.json()
114+
deleted_nodes = []
115+
for node in nodes:
116+
await delete_node(node, workspace_dir)
117+
deleted_nodes.append(node['name'])
118+
return web.json_response({"success": True, "error": None, "deleted_nodes": deleted_nodes})
119+
except Exception as e:
120+
return web.json_response({"success": False, "error": str(e), "deleted_nodes": deleted_nodes}, status=500)
121+
122+
async def models(request):
123+
'''
124+
List all custom models in the workspace
125+
126+
# Example response:
127+
{
128+
"error": null,
129+
"models":
130+
{
131+
"checkpoints": [
132+
{
133+
"name": "dreamshaper-8.safetensors",
134+
"path": "SD1.5/dreamshaper-8.safetensors",
135+
"type": "checkpoint",
136+
"downloading": false"
137+
}
138+
],
139+
"controlnet": [
140+
{
141+
"name": "controlnet.sd15.safetensors",
142+
"path": "SD1.5/controlnet.sd15.safetensors",
143+
"type": "controlnet",
144+
"downloading": false"
145+
}
146+
],
147+
"unet": [
148+
{
149+
"name": "unet.sd15.safetensors",
150+
"path": "SD1.5/unet.sd15.safetensors",
151+
"type": "unet",
152+
"downloading": false"
153+
}
154+
],
155+
"vae": [
156+
{
157+
"name": "vae.safetensors",
158+
"path": "vae.safetensors",
159+
"type": "vae",
160+
"downloading": false"
161+
}
162+
],
163+
"tensorrt": [
164+
{
165+
"name": "model.trt",
166+
"path": "model.trt",
167+
"type": "tensorrt",
168+
"downloading": false"
169+
}
170+
]
171+
}
172+
}
173+
174+
'''
175+
workspace_dir = request.app["workspace"]
176+
try:
177+
nodes = await list_models(workspace_dir)
178+
return web.json_response({"error": None, "models": models})
179+
except Exception as e:
180+
return web.json_response({"error": str(e), "models": models}, status=500)
181+
182+
async def add_models(request):
183+
'''
184+
Download models from url
185+
186+
# Parameters:
187+
url: url of the git repository
188+
type: type of model (e.g. checkpoints, controlnet, unet, vae, onnx, tensorrt)
189+
path: path of the model. supports up to 1 subfolder (e.g. SD1.5/newmodel.safetensors)
190+
191+
# Example request:
192+
[
193+
{
194+
"url": "http://url.to/model.safetensors",
195+
"type": "checkpoints"
196+
},
197+
{
198+
"url": "http://url.to/controlnet.super.safetensors",
199+
"type": "controlnet",
200+
"path": "SD1.5/controlnet.super.safetensors"
201+
}
202+
]
203+
'''
204+
workspace_dir = request.app["workspace"]
205+
try:
206+
models = await request.json()
207+
added_models = []
208+
for model in models:
209+
await add_model(model, workspace_dir)
210+
added_models.append(model['url'])
211+
return web.json_response({"success": True, "error": None, "added_models": added_models})
212+
except Exception as e:
213+
return web.json_response({"success": False, "error": str(e), "added_nodes": added_models}, status=500)
214+
215+
async def delete_models(request):
216+
'''
217+
Delete model
218+
219+
# Parameters:
220+
type: type of model (e.g. checkpoints, controlnet, unet, vae, onnx, tensorrt)
221+
path: path of the model. supports up to 1 subfolder (e.g. SD1.5/newmodel.safetensors)
222+
223+
# Example request:
224+
[
225+
{
226+
"type": "checkpoints",
227+
"path": "model.safetensors"
228+
},
229+
{
230+
"type": "controlnet",
231+
"path": "SD1.5/controlnet.super.safetensors"
232+
}
233+
]
234+
'''
235+
workspace_dir = request.app["workspace"]
236+
try:
237+
models = await request.json()
238+
deleted_models = []
239+
for model in models:
240+
await delete_model(model, workspace_dir)
241+
deleted_models.append(model['path'])
242+
return web.json_response({"success": True, "error": None, "deleted_models": deleted_models})
243+
except Exception as e:
244+
return web.json_response({"success": False, "error": str(e), "deleted_models": deleted_models}, status=500)
245+
246+
async def set_account_info(request):
247+
'''
248+
Set account info for ice server providers
249+
250+
# Parameters:
251+
type: account type (e.g. twilio)
252+
account_id: account id from provider
253+
auth_token: auth token from provider
254+
255+
# Example request:
256+
[
257+
{
258+
"type": "twilio",
259+
"account_id": "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
260+
"auth_token": "your_auth_token"
261+
},
262+
{
263+
...
264+
}
265+
]
266+
267+
'''
268+
try:
269+
accounts = await request.json()
270+
accounts_updated = []
271+
for account in accounts:
272+
if 'type' in account:
273+
if account['type'] == 'twilio':
274+
await set_twilio_account_info(account)
275+
accounts_updated.append(account['type'])
276+
return web.json_response({"success": True, "error": None, "accounts_updated": accounts_updated})
277+
except Exception as e:
278+
return web.json_response({"success": False, "error": str(e), "accounts_updated": accounts_updated}, status=500)

server/api/models/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)