diff --git a/.github/workflows/docker-publish-comfy-preview.yaml b/.github/workflows/docker-publish-comfy-preview.yaml new file mode 100644 index 0000000..9f8b4f6 --- /dev/null +++ b/.github/workflows/docker-publish-comfy-preview.yaml @@ -0,0 +1,70 @@ +# Adapted from +# https://github.com/actions/starter-workflows/ci/docker-publish.yml +# If using base images, don't forget to add READ access, eg. from a package settings page like: +# https://github.com/orgs/storytold/packages/container/docker-base-images-rust-ssl/settings/actions_access +name: Build Comfy Preview Server Docker Image +on: + push: + paths: + - 'workflows/preview_server/**' + branches: + # NB: Default-branch doesn't work, despite Github's documentation. + #- $default-branch + - master +env: + IMAGE_NAME: comfy-previews + +jobs: + # Push image to GitHub Packages. + # See also https://docs.docker.com/docker-hub/builds/ + push: + #runs-on: ubuntu-latest + runs-on: github-ubuntu-64core # NB: Premium GitHub runner with more cores + if: github.event_name == 'push' + permissions: + packages: write + contents: read + + steps: + - uses: actions/checkout@v2 + with: + lfs: true # Ensure Git LFS files are checked out + + - name: Login to GitHub Container Registry + uses: docker/login-action@v1 + with: + registry: ghcr.io + #username: ${{ github.repository_owner }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build image + run: cd workflows/preview_server/ && docker build . --file Dockerfile --tag $IMAGE_NAME --label "runnumber=${GITHUB_RUN_ID}" + + - name: Push image to GitHub Container Registry + run: | + IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME + + # Change all uppercase to lowercase + IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') + + # Strip git ref prefix from version + VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,') + + # Strip "v" prefix from tag name + [[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//') + + # Use Docker `latest` tag convention + [ "$VERSION" == "$default-branch" ] && VERSION=latest + + echo IMAGE_ID=$IMAGE_ID + echo VERSION=$VERSION + + docker tag $IMAGE_NAME $IMAGE_ID:$VERSION + docker push $IMAGE_ID:$VERSION + + SHORT_SHA=$(echo ${GITHUB_SHA} | cut -c1-12) + + docker tag $IMAGE_NAME $IMAGE_ID:$SHORT_SHA + docker push $IMAGE_ID:$SHORT_SHA + diff --git a/workflows/preview_server/Dockerfile b/workflows/preview_server/Dockerfile new file mode 100644 index 0000000..0c1c008 --- /dev/null +++ b/workflows/preview_server/Dockerfile @@ -0,0 +1,52 @@ + +# NB(bt, 2022-12-12): The version of containerized CUDA must match (or be less than?) that of the host system running this container. +# Juggling these dependencies, plus the underlying Ubuntu system (which controls Python versions), is tricky. +# Nvidia does not provide a CUDA 11.6 with Ubuntu 22.04, which mirrors my own desktop machine. Their CUDA 11.6 + Ubuntu 20.04 image has +# a stale Python (3.8), so we have to use the DeadSnakes PPA to install a more modern version. +# Gross. +FROM nvidia/cuda:11.8.0-devel-ubuntu22.04 + +# See: https://github.com/opencontainers/image-spec/blob/master/annotations.md +LABEL org.opencontainers.image.title='Storyteller ML: Voice Conversion' +LABEL org.opencontainers.image.authors='adrien@storyteller.ai' + +# tzdata install hangs without presetting the time zone +ENV TZ=UTC +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +# Needed to install "future" release of Python 3.10 under Ubuntu 20.04, which only natively packages Python 3.8. +# We seem to be stuck on Ubuntu 22.04 because containerizd CUDA 11.6 is the only version we can run on my host machine, +# and Nvidia does not supply a (CUDA 11.6, Ubuntu 22.04) docker base image. +RUN apt-get update \ + && apt install software-properties-common -y \ + && add-apt-repository ppa:deadsnakes/ppa + +RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get install -y \ + curl \ + ffmpeg \ + libmagic-dev \ + libmagic1 \ + python3-pip \ + python3.10 \ + python3.10-venv \ + unzip \ + wget \ + git \ + --no-install-recommends + +RUN addgroup --system appgroup && adduser --system --ingroup appgroup appuser +# Copy files to container +COPY --chown=appuser:appgroup initialize_comfy_extensions.py /app/initialize_comfy_extensions.py +COPY --chown=appuser:appgroup install.py /app/install.py +COPY --chown=appuser:appgroup repos.json /app/repos.json +COPY --chown=appuser:appgroup server_requirements.txt.txt /app/server_requirements.txt.txt +COPY --chown=appuser:appgroup required_requirements.txt /app/required_requirements.txt +COPY --chown=appuser:appgroup preview_server.py /app/preview_server.py + +RUN pip3 install --no-cache-dir --upgrade pip setuptools wheel requests argparse + +RUN chmod -R 777 /app + +# protobuf use python implementation (weird error without) +ENV PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python diff --git a/workflows/preview_server/dependencies.json b/workflows/preview_server/dependencies.json new file mode 100644 index 0000000..9a0ee7f --- /dev/null +++ b/workflows/preview_server/dependencies.json @@ -0,0 +1,126 @@ +[ + { + "location": "ComfyUI/models/loras/v3_sd15_adapter.ckpt", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/v3_sd15_adapter.ckpt" + }, + { + "location": "ComfyUI/models/embeddings/badhandv4.pt", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/badhandv4.pt" + }, + { + "location": "ComfyUI/models/embeddings/easynegative.safetensors", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/easynegative.safetensors" + }, + { + "location": "ComfyUI/models/controlnet/v3_sd15_sparsectrl_scribble.ckpt", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/v3_sd15_sparsectrl_scribble.ckpt" + }, + { + "location": "ComfyUI/models/controlnet/control_v11f1e_sd15_tile.bin", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/control_v11f1e_sd15_tile.bin" + }, + { + "location": "ComfyUI/models/controlnet/control_v11p_sd15_softedge.safetensors", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/control_v11p_sd15_softedge.safetensors" + }, + { + "location": "ComfyUI/models/controlnet/control_v11p_sd15s2_lineart_anime.safetensors", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/control_v11p_sd15s2_lineart_anime.safetensors" + }, + { + "location": "ComfyUI/models/controlnet/control_v11p_sd15_lineart.safetensors", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/control_v11p_sd15_lineart.safetensors" + }, + { + "location": "ComfyUI/models/controlnet/control_v11f1p_sd15_depth.safetensors", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/control_v11f1p_sd15_depth.safetensors" + }, + { + "location": "ComfyUI/models/controlnet/control_v11p_sd15_openpose.safetensors", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/control_v11p_sd15_openpose.safetensors" + }, + { + "location": "ComfyUI/models/controlnet/animatediff_controlnet.ckpt", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/animatediff_controlnet.ckpt" + }, + { + "location": "ComfyUI/models/controlnet/control_v2p_sd15_mediapipe_face.safetensors", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/control_v2p_sd15_mediapipe_face.safetensors" + }, + { + "location": "ComfyUI/models/controlnet/ControlNetHED.pth", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/ControlNetHED.pth" + }, + { + "location": "ComfyUI/models/ipadapter/ip-adapter_sd15_light.safetensors", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/ip-adapter_sd15_light.safetensors" + }, + { + "location": "ComfyUI/models/clip_vision/CLIP-ViT-H-14-laion2B-s32B-b79K.safetensors", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/model.safetensors" + }, + { + "location": "ComfyUI/custom_nodes/ComfyUI-AnimateDiff-Evolved/models/v3_sd15_mm.ckpt", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/v3_sd15_mm.ckpt" + }, + { + "location": "ComfyUI/custom_nodes/comfyui_controlnet_aux/ckpts/hr16/DWPose-TorchScript-BatchSize5/dw-ll_ucoco_384_bs5.torchscript.pt", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/dw-ll_ucoco_384_bs5.torchscript.pt" + }, + { + "location": "ComfyUI/custom_nodes/comfyui_controlnet_aux/ckpts/yzd-v/DWPose/yolox_l.onnx", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/yolox_l.onnx" + }, + { + "location": "ComfyUI/custom_nodes/comfyui_controlnet_aux/ckpts/LiheYoung/Depth-Anything/checkpoints/depth_anything_vitl14.pth", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/depth_anything_vitl14.pth" + }, + { + "location": "ComfyUI/custom_nodes/comfyui_controlnet_aux/ckpts/lllyasviel/Annotators/sk_model2.pth", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/sk_model2.pth" + }, + { + "location": "ComfyUI/custom_nodes/comfyui_controlnet_aux/ckpts/lllyasviel/Annotators/sk_model.pth", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/sk_model.pth" + }, + { + "location": "ComfyUI/custom_nodes/comfyui_controlnet_aux/ckpts/lllyasviel/Annotators/netG.pth", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/netG.pth" + }, + { + "location": "ComfyUI/custom_nodes/comfyui_controlnet_aux/ckpts/lllyasviel/Annotators/ControlNetHED.pth", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/ControlNetHED.pth" + }, + { + "location": "ComfyUI/custom_nodes/ComfyUI-Frame-Interpolation/ckpts/rife/rife47.pth", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/rife47.pth" + }, + { + "location": "ComfyUI/input/example.png", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/example.png" + }, + { + "location": "ComfyUI/custom_nodes/ComfyUI-AnimateDiff-Evolved/models/sd15_t2v_beta_motion.ckpt", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/sd15_t2v_beta_motion.ckpt" + }, + { + "location": "ComfyUI/models/loras/LCM_LoRA_Weights_SD15.safetensors", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/LCM_LoRA_Weights_SD15.safetensors" + }, + { + "location": "ComfyUI/models/controlnet/control_v11p_sd15_canny.safetensors", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/control_v11p_sd15_canny.safetensors" + }, + { + "location": "ComfyUI/models/grounding-dino/GroundingDINO_SwinT_OGC.cfg.py", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/GroundingDINO_SwinT_OGC.py" + }, + { + "location": "ComfyUI/models/grounding-dino/groundingdino_swint_ogc.pth", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/groundingdino_swint_ogc.pth" + }, + { + "location": "ComfyUI/models/vae/vae-ft-mse-840000-ema-pruned.ckpt", + "url": "https://storage.googleapis.com/vocodes-public/comfyui-deps/vae-ft-mse-840000-ema-pruned.ckpt" + } +] diff --git a/workflows/preview_server/initialize_comfy_extensions.py b/workflows/preview_server/initialize_comfy_extensions.py new file mode 100644 index 0000000..bae7c54 --- /dev/null +++ b/workflows/preview_server/initialize_comfy_extensions.py @@ -0,0 +1,46 @@ +import os +import sys +import asyncio +import threading +# Init all the nodes + +current_script_dir = os.path.dirname(os.path.realpath(__file__)) +comfy_path = os.path.dirname(os.path.abspath(__file__)) +comfy_path = os.path.join(comfy_path, 'ComfyUI') + +# change to ComfyUI directory +os.chdir(comfy_path) + +# add ComfyUI to path +sys.path.append(comfy_path) + +from server import PromptServer +from execution import PromptQueue +from main import init_custom_nodes, cuda_malloc_warning, prompt_worker, execute_prestartup_script +import folder_paths + +execute_prestartup_script() + +async def run(): + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + server = PromptServer(loop) + q = PromptQueue(server) + + init_custom_nodes() + + cuda_malloc_warning() + + server.add_routes() + + threading.Thread(target=prompt_worker, daemon=True, args=(q, server,)).start() + + folder_paths.add_model_folder_path("checkpoints", os.path.join(folder_paths.get_output_directory(), "checkpoints")) + folder_paths.add_model_folder_path("clip", os.path.join(folder_paths.get_output_directory(), "clip")) + folder_paths.add_model_folder_path("vae", os.path.join(folder_paths.get_output_directory(), "vae")) + + await server.start('127.0.0.1', 8188) + + +if __name__ == "__main__": + asyncio.run(run()) diff --git a/workflows/preview_server/install.py b/workflows/preview_server/install.py new file mode 100644 index 0000000..d83139f --- /dev/null +++ b/workflows/preview_server/install.py @@ -0,0 +1,101 @@ + +import subprocess +import json +import os +from pathlib import Path +import requests + +# set cwd to script location +os.chdir(os.path.dirname(os.path.realpath(__file__))) + +json_file_path = 'repos.json' +venv_python = os.path.join('ComfyUI', 'venv', 'Scripts' if os.name == 'nt' else 'bin', 'python') + + +def run_command(command): + process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) + + # Print stdout live + for line in iter(process.stdout.readline, ''): + print(line, end='') + + # Wait for the process to terminate and get the exit code + process.wait() + + # Check if the process exited with an error + if process.returncode != 0: + # Print any errors from stderr + for line in iter(process.stderr.readline, ''): + print(line, end='') + print(f"Error executing command: {command}") + + +def setup_repo(repo_info): + url, commit, folder = repo_info['url'], repo_info['commit'], repo_info['folder'] + # save the current working directory + original_cwd = os.getcwd() + try: + run_command(f"git clone {url} {folder}") + os.chdir(folder) + run_command(f"git checkout {commit}") + finally: + os.chdir(original_cwd) + + +def setup_venv_and_install_requirements(): + run_command("python3 -m venv ComfyUI/venv") + print('=============# Installing ComfyUI Requirements #=============') + run_command(f"{venv_python} -m pip install -r ComfyUI/requirements.txt") + print('=============# Installing extension missing requirements #=============') + run_command(f"{venv_python} -m pip install -r required_requirements.txt") + + +def run_comfyui_setup(): + run_command(f"{venv_python} initialize_comfy_extensions.py") + + +def install_dependencies(json_file_path='dependencies.json'): + # Load the dependency JSON + with open(json_file_path, 'r') as file: + dependencies = json.load(file) + + for dep in dependencies: + # Extract location and URL + location = dep['location'] + url = dep['url'] + + # Convert the location to a Path object and create parent directories if they don't exist + path = Path(location) + path.parent.mkdir(parents=True, exist_ok=True) + + if path.is_file(): + print(f"{path} is already installed") + continue + + # Download the file + response = requests.get(url) + if response.status_code == 200: + # Write the content to the file in the specified location + with open(path, 'wb') as file: + file.write(response.content) + print(f"Installed {path}") + else: + print(f"Failed to download {url}") + + +def main(): + with open(json_file_path, 'r') as file: + repos = json.load(file) + + for repo_info in repos: + print(f"installing {repo_info['url']} at commit {repo_info['commit']} to {repo_info['folder']}") + setup_repo(repo_info) + + setup_venv_and_install_requirements() + install_dependencies() + run_comfyui_setup() + + +if __name__ == "__main__": + main() + open('ALREADY_SETUP.flag', 'w').close() diff --git a/workflows/preview_server/preview_server.py b/workflows/preview_server/preview_server.py new file mode 100644 index 0000000..89ef883 --- /dev/null +++ b/workflows/preview_server/preview_server.py @@ -0,0 +1,146 @@ +import os +import signal +import subprocess +import time + +from fastapi import FastAPI, File, UploadFile, HTTPException +from fastapi.responses import FileResponse +import shutil +from pathlib import Path +import asyncio +import uuid +import os +import json +import requests +import random + +app = FastAPI() +lock = asyncio.Lock() # Create an asyncio lock + +SERVER_IP = os.environ.get("SERVER_IP", "127.0.0.1:8188") +TIMEOUT_SECONDS = os.environ.get("TIMEOUT_SECONDS", 1000) +PROMPT_ENDPOINT = f"http://{SERVER_IP}/prompt" +PROMPT_FILE = os.environ.get("PROMPT_FILE", "prompt.json") +COMFY_ROOT_DIRECTORY = os.environ.get("COMFY_ROOT_DIRECTORY", + "/home/salt/clone/storyteller/storyteller-ml/workflows/comfy/ComfyUI") +SERVER_START_TIMEOUT = int(os.environ.get("SERVER_START_TIMEOUT", 60)) + + + +def terminate_process(proc): + proc.terminate() + try: + proc.wait(timeout=10) + except subprocess.TimeoutExpired: + proc.kill() + + +def signal_handler(signum, frame): + print("Signal received, shutting down.") + terminate_process(comfyui_process) + exit(0) + + +@app.post("/preview/") +async def upload_video(video: UploadFile = File(...)): + async with lock: # Acquire the lock + try: + # Save uploaded video to a temporary directory + video_filename = f"temp_videos/{uuid.uuid4()}.mp4" # Use a unique filename + Path("temp_videos").mkdir(parents=True, exist_ok=True) # Ensure the directory exists + with open(video_filename, "wb") as buffer: + shutil.copyfileobj(video.file, buffer) + except Exception as e: + raise HTTPException(status_code=500, detail=f"Failed to save video: {str(e)}") + + # Process video and generate preview + preview_image_path = await process_video(video_filename) + + return FileResponse(preview_image_path, media_type='image/jpeg') + + +async def process_video(video_path: str) -> Path: + json_prompt = json.load(open(PROMPT_FILE)) + + # generate random seed (otherwise video will cache completely and not generate a new output) + json_prompt["173"]["inputs"]["seed"] = random.randint(0, 1000000) + + input_video_path = Path(COMFY_ROOT_DIRECTORY) / "input/input.mp4" + preview_image_path = Path(COMFY_ROOT_DIRECTORY) / "output/vid2vid/SparseImagePreview_00001_.png" + shutil.move(video_path, input_video_path) + if os.path.exists(preview_image_path): + os.remove(preview_image_path) + + response = requests.get(PROMPT_ENDPOINT, timeout=5) + if response.status_code == 200: + print("Server is healthy") + else: + print("Server is unhealthy") + print(f"Status code: {response.status_code}") + print(f"Response: {response.text}") + raise HTTPException(status_code=500, detail="Server is unhealthy") + + # make sure there are no jobs already + queue_json = response.json() + if queue_json["exec_info"]["queue_remaining"]: + print("There are jobs in the queue already. Exiting...") + raise HTTPException(status_code=500, detail="There are jobs in the queue already (this shouldn't happen)") + else: + print("Queue is empty") + + p = {"prompt": json_prompt} + data = json.dumps(p).encode('utf-8') + response = requests.post(PROMPT_ENDPOINT, data=data) + if response.status_code == 200: + print("Job enqueued successfully") + else: + print("Job failed to queue") + print(f"Status code: {response.status_code}") + print(f"Response: {response.text}") + raise HTTPException(status_code=500, detail=f"Failed to queue job") + + start_time = time.time() + while True: + response = requests.get(PROMPT_ENDPOINT, timeout=5) + queue_json = response.json() + if queue_json["exec_info"]["queue_remaining"]: + pass + else: + print("Job is done") + break + if time.time() - start_time > TIMEOUT_SECONDS: + print("Timeout reached and job didn't finish!") + raise HTTPException(status_code=500, detail="Timeout reached and job didn't finish!") + time.sleep(1) + + return preview_image_path + + +if __name__ == "__main__": + import uvicorn + + signal.signal(signal.SIGINT, signal_handler) + signal.signal(signal.SIGTERM, signal_handler) + + comfyui_process = subprocess.Popen(["venv/bin/python", "main.py"], cwd=COMFY_ROOT_DIRECTORY) + + # block until comfyUI server is up + start_time = time.time() + started = False + while time.time() - start_time < SERVER_START_TIMEOUT: + try: + response = requests.get(PROMPT_ENDPOINT, timeout=5) + if response.status_code == 200: + print("Server is healthy") + started = True + break + except requests.exceptions.ConnectionError: + print(f"Server is not up yet. Time elapsed: {time.time() - start_time:.2f}") + time.sleep(1) + if not started: + print(f"Server failed to start in {SERVER_START_TIMEOUT} seconds") + exit(1) + print("ComfyUI server running, starting FastAPI server") + uvicorn.run(app, host="127.0.0.1", port=8000) + # cleanup + terminate_process(comfyui_process) diff --git a/workflows/preview_server/repos.json b/workflows/preview_server/repos.json new file mode 100644 index 0000000..e8ad213 --- /dev/null +++ b/workflows/preview_server/repos.json @@ -0,0 +1,132 @@ +[ + { + "url": "https://github.com/comfyanonymous/ComfyUI.git", + "commit": "eda87043862f743b0a0467735f8531f7c4709b3a", + "folder": "ComfyUI" + }, + { + "url": "https://github.com/ltdrdata/ComfyUI-Manager.git", + "commit": "6c553d1228978352767f4914c4dd7787b00f6769", + "folder": "ComfyUI/custom_nodes/ComfyUI-Manager" + }, + { + "url": "https://github.com/ltdrdata/ComfyUI-Impact-Pack.git", + "commit": "e374bd304a4a5b44d0deae2b2afaf4d5faad4810", + "folder": "ComfyUI/custom_nodes/ComfyUI-Impact-Pack" + }, + { + "url": "https://github.com/Fannovel16/comfyui_controlnet_aux.git", + "commit": "33d6e86b65c40e5f97052262c6900f413684ccde", + "folder": "ComfyUI/custom_nodes/comfyui_controlnet_aux" + }, + { + "url": "https://github.com/Fannovel16/ComfyUI-Frame-Interpolation.git", + "commit": "5e11679995c68f33891c306a393915feefe234b5", + "folder": "ComfyUI/custom_nodes/ComfyUI-Frame-Interpolation" + }, + { + "url": "https://github.com/jags111/efficiency-nodes-comfyui.git", + "commit": "f6d01dc5449e2cc6e29da92b3b337e49c0dce112", + "folder": "ComfyUI/custom_nodes/efficiency-nodes-comfyui" + }, + { + "url": "https://github.com/Derfuu/Derfuu_ComfyUI_ModdedNodes.git", + "commit": "2ace4c463d5b2063de35e46ebb9bd3f10e2d34b4", + "folder": "ComfyUI/custom_nodes/Derfuu_ComfyUI_ModdedNodes" + }, + { + "url": "https://github.com/WASasquatch/was-node-suite-comfyui.git", + "commit": "6c3fed70655b737dc9b59da1cadb3c373c08d8ed", + "folder": "ComfyUI/custom_nodes/was-node-suite-comfyui" + }, + { + "url": "https://github.com/pythongosssss/ComfyUI-Custom-Scripts.git", + "commit": "b4a9cebf24b50c4b538945ae86c17a9dc24052a8", + "folder": "ComfyUI/custom_nodes/ComfyUI-Custom-Scripts" + }, + { + "url": "https://github.com/melMass/comfy_mtb.git", + "commit": "54ff6583ded0ed4054f8e5d7fadf0b2350259dce", + "folder": "ComfyUI/custom_nodes/comfy_mtb" + }, + { + "url": "https://github.com/FizzleDorf/ComfyUI_FizzNodes.git", + "commit": "2ad19c1c3ad424b732fa0bc16ffb02284676a5da", + "folder": "ComfyUI/custom_nodes/ComfyUI_FizzNodes" + }, + { + "url": "https://github.com/Kosinkadink/ComfyUI-Advanced-ControlNet.git", + "commit": "98768c7c3c45ac1e803071c5ad8e675e360e9e73", + "folder": "ComfyUI/custom_nodes/ComfyUI-Advanced-ControlNet" + }, + { + "url": "https://github.com/Kosinkadink/ComfyUI-AnimateDiff-Evolved.git", + "commit": "9ccea911a63e2119778fa91b2692a8470a48e9da", + "folder": "ComfyUI/custom_nodes/ComfyUI-AnimateDiff-Evolved" + }, + { + "url": "https://github.com/Kosinkadink/ComfyUI-VideoHelperSuite.git", + "commit": "f94597739f20dac331f9918a245149b6b00a60f2", + "folder": "ComfyUI/custom_nodes/ComfyUI-VideoHelperSuite" + }, + { + "url": "https://github.com/theUpsider/ComfyUI-Logic.git", + "commit": "fb8897351f715ea75eebf52e74515b6d07c693b8", + "folder": "ComfyUI/custom_nodes/ComfyUI-Logic" + }, + { + "url": "https://github.com/rgthree/rgthree-comfy.git", + "commit": "9021670e9ff887d40e031334fc9f3e92c599d161", + "folder": "ComfyUI/custom_nodes/rgthree-comfy" + }, + { + "url": "https://github.com/giriss/comfy-image-saver.git", + "commit": "65e6903eff274a50f8b5cd768f0f96baf37baea1", + "folder": "ComfyUI/custom_nodes/comfy-image-saver" + }, + { + "url": "https://github.com/kijai/ComfyUI-KJNodes.git", + "commit": "df86fd77ac7f832b35ddaa748e4cf421ce9bf9e1", + "folder": "ComfyUI/custom_nodes/ComfyUI-KJNodes" + }, + { + "url": "https://github.com/Ttl/ComfyUi_NNLatentUpscale.git", + "commit": "08105da31dbd7a54569661e135835e73bd8064b0", + "folder": "ComfyUI/custom_nodes/ComfyUi_NNLatentUpscale" + }, + { + "url": "https://github.com/cubiq/ComfyUI_IPAdapter_plus.git", + "commit": "6a411dcb2c6c3b91a3aac97adfb080a77ade7d38", + "folder": "ComfyUI/custom_nodes/ComfyUI_IPAdapter_plus" + }, + { + "url": "https://github.com/cubiq/ComfyUI_essentials.git", + "commit": "0283ce45272fc0737e3420c0aa2c5c30a74f7a36", + "folder": "ComfyUI/custom_nodes/ComfyUI_essentials" + }, + { + "url": "https://github.com/storyicon/comfyui_segment_anything.git", + "commit": "681d977c2cc244de729fd9e08145ff365c609262", + "folder": "ComfyUI/custom_nodes/comfyui_segment_anything" + }, + { + "url": "https://github.com/Jcd1230/rembg-comfyui-node.git", + "commit": "fac7df6c3f42e158a2829b511b37f13e4cc834eb", + "folder": "ComfyUI/custom_nodes/rembg-comfyui-node" + }, + { + "url": "https://github.com/crystian/ComfyUI-Crystools.git", + "commit": "8c257748b98f59357ac20cebd4b4b67c0a9e53fe", + "folder": "ComfyUI/custom_nodes/ComfyUI-Crystools" + }, + { + "url": "https://github.com/Fannovel16/ComfyUI-Video-Matting.git", + "commit": "178bf956ddb817d065b1b073ec04582ad60335bb", + "folder": "ComfyUI/custom_nodes/ComfyUI-Video-Matting" + }, + { + "url": "https://github.com/Suzie1/ComfyUI_Comfyroll_CustomNodes.git", + "commit": "d78b780ae43fcf8c6b7c6505e6ffb4584281ceca", + "folder": "ComfyUI/custom_nodes/ComfyUI_Comfyroll_CustomNodes" + } +] diff --git a/workflows/preview_server/required_requirements.txt b/workflows/preview_server/required_requirements.txt new file mode 100644 index 0000000..06d6657 --- /dev/null +++ b/workflows/preview_server/required_requirements.txt @@ -0,0 +1,14 @@ +numexpr +numba +opencv-python +color_matcher +mediapipe +piexif +segment_anything +scikit-image +rembg[gpu] +timm +addict +yapf +deepdiff +pynvml diff --git a/workflows/preview_server/server_requirements.txt b/workflows/preview_server/server_requirements.txt new file mode 100644 index 0000000..5ca32c7 --- /dev/null +++ b/workflows/preview_server/server_requirements.txt @@ -0,0 +1,4 @@ +requests~=2.31.0 +uvicorn~=0.29.0 +fastapi~=0.110.0 +python-multipart~=0.0.9