Skip to content

Commit d06b106

Browse files
committed
feat: not utilize nest_asyncio if only async APIs are used
erdewit/nest_asyncio#87
1 parent 7ad5a71 commit d06b106

File tree

3 files changed

+35
-6
lines changed

3 files changed

+35
-6
lines changed

script/runtime/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,23 @@
11
# Runtime
2+
## Async support
3+
The runtime is internally asynchronous, but only exposes synchronous APIs for the following reasons:
4+
- To make the script more friendly to Python newbies
5+
- To avoid being infectious
6+
7+
Some libraries, such as ipywidgets, do not support async yet.
8+
- To make scripts shorter
9+
10+
If you want to use the asynchronous APIs, you need to:
11+
- Prefix all APIs support async with an underscore and await
12+
13+
For example:
14+
- `load()``await runtime._load()`
15+
- `queue.cancel_all()``await queue._cancel_all()`
16+
- `obj.display()` (and `display(obj)`) → `await obj._display()`
17+
- Replace `with Workflow` with `async with Workflow`
18+
- Replace `obj.wait()` with `await obj`, `obj.wait_result()` with `await obj.result()`
19+
- Replace `ImageBatchResult[i]` with `await ImageBatchResult.get(i)`
20+
221
## Other differences from ComfyUI's web UI
322
- No limitations on input precision and range.
423

script/runtime/__init__.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ async def _watch(self):
109109
if self.queue_remaining == 0:
110110
for task in self._tasks.values():
111111
print(f'ComfyScript: The queue is empty but {task} has not been executed')
112-
task._set_result_threadsafe(None, {})
112+
await task._set_result_threadsafe(None, {})
113113
self._tasks.clear()
114114

115115
for callback in self._queue_remaining_callbacks:
@@ -120,15 +120,15 @@ async def _watch(self):
120120
outputs = {}
121121
if history is not None:
122122
outputs = history['outputs']
123-
task._set_result_threadsafe(None, outputs, self._watch_display_task)
123+
await task._set_result_threadsafe(None, outputs, self._watch_display_task)
124124
if self._watch_display_task:
125125
print(f'Queue remaining: {self.queue_remaining}')
126126
elif msg['type'] == 'executed':
127127
data = msg['data']
128128
prompt_id = data['prompt_id']
129129
task: Task = self._tasks.get(prompt_id)
130130
if task is not None:
131-
task._set_result_threadsafe(data['node'], data['output'], self._watch_display_node)
131+
await task._set_result_threadsafe(data['node'], data['output'], self._watch_display_node)
132132
if self._watch_display_node:
133133
print(f'Queue remaining: {self.queue_remaining}')
134134
elif msg['type'] == 'progress':
@@ -311,16 +311,23 @@ def __str__(self):
311311
def __repr__(self):
312312
return f'Task(n={self.number}, id={self.prompt_id})'
313313

314-
def _set_result_threadsafe(self, node_id: str | None, output: dict, display_result: bool = False) -> None:
314+
async def _set_result_threadsafe(self, node_id: str | None, output: dict, display_result: bool = False) -> None:
315315
if node_id is not None:
316316
self._new_outputs[node_id] = output
317317
if display_result:
318318
from IPython.display import display
319-
display(data.Result.from_output(output), clear=True)
319+
320+
display(clear=True)
321+
result = data.Result.from_output(output)
322+
if isinstance(result, data.ImageBatchResult):
323+
await Images(result)._display()
324+
else:
325+
display(result)
320326
else:
321327
self.get_loop().call_soon_threadsafe(self._fut.set_result, output)
322328
if display_result:
323329
from IPython.display import display
330+
324331
image_batches = []
325332
others = []
326333
# TODO: Sort by the parsed id
@@ -333,7 +340,7 @@ def _set_result_threadsafe(self, node_id: str | None, output: dict, display_resu
333340
if image_batches or others:
334341
display(clear=True)
335342
if image_batches:
336-
display(Images(*image_batches))
343+
await Images(*image_batches)._display()
337344
if others:
338345
display(*others)
339346

script/runtime/requirements.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
-r ../requirements.txt
22

3+
# Already required by ComfyUI
4+
Pillow
5+
36
# Jupyter
47
ipywidgets ~= 8.1

0 commit comments

Comments
 (0)