Skip to content

Instantly share code, notes, and snippets.

@yosun
Last active August 30, 2025 10:16
Show Gist options
  • Select an option

  • Save yosun/52af79b571cd106166ddd3c20443077b to your computer and use it in GitHub Desktop.

Select an option

Save yosun/52af79b571cd106166ddd3c20443077b to your computer and use it in GitHub Desktop.
python ~/ComfyUI/_install.models.etc.py [path to workflow.json] <br> installs all missing models and lets you insert civitai key if needed <br> extract workflow from image using https://absurdity.ai/comfyui/image2workflowjson.html
import json
import os
import sys
import requests
MODELS_BASE_DIR = os.path.join("ComfyUI", "models")
def download_file(url, directory, filename, civitai_key=None, hf_token=None):
target_dir = os.path.join(MODELS_BASE_DIR, directory)
os.makedirs(target_dir, exist_ok=True)
target_path = os.path.join(target_dir, filename)
if os.path.exists(target_path):
print(f"βœ… Already exists: {target_path}")
return
print(f"⬇️ Downloading {filename} β†’ {directory}")
headers = {}
if civitai_key and "civitai.com" in url:
headers["Authorization"] = f"Bearer {civitai_key}"
if hf_token and "huggingface.co" in url:
headers["Authorization"] = f"Bearer {hf_token}"
try:
with requests.get(url, stream=True, headers=headers) as r:
r.raise_for_status()
with open(target_path, "wb") as f:
for chunk in r.iter_content(chunk_size=8192):
if chunk:
f.write(chunk)
print(f"βœ… Saved: {target_path}")
except Exception as e:
print(f"❌ Failed to download {url}: {e}")
def download_models_from_list(models, civitai_key=None, hf_token=None):
for m in models:
name = m.get("name")
url = m.get("url")
directory = m.get("directory", "")
if name and url and directory:
download_file(url, directory, name, civitai_key, hf_token)
else:
print(f"⚠️ Missing info for model: {m}")
def main(workflow_path):
if not os.path.isfile(workflow_path):
print(f"❌ File not found: {workflow_path}")
sys.exit(1)
with open(workflow_path, "r", encoding="utf-8") as f:
workflow_data = json.load(f)
# Collect all model URLs from root models and node properties
all_urls = set()
for m in workflow_data.get("models", []):
url = m.get("url", "")
if url:
all_urls.add(url)
for node in workflow_data.get("nodes", []):
props = node.get("properties", {})
models = props.get("models", [])
for m in models:
url = m.get("url", "")
if url:
all_urls.add(url)
civitai_key = None
if any("civitai.com" in url for url in all_urls):
civitai_key = input("πŸ”‘ Enter your Civitai API key (or leave empty to skip): ").strip() or None
hf_token = None
if any("huggingface.co" in url for url in all_urls):
hf_token = input("πŸ”‘ Enter your Huggingface API token (or leave empty to skip): ").strip() or None
print("⏳ Downloading models listed at root...")
download_models_from_list(workflow_data.get("models", []), civitai_key, hf_token)
print("⏳ Downloading models listed inside nodes...")
for node in workflow_data.get("nodes", []):
props = node.get("properties", {})
models = props.get("models", [])
download_models_from_list(models, civitai_key, hf_token)
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python download_comfyui_models.py <workflow.json>")
sys.exit(1)
main(sys.argv[1])
import json
import os
import sys
import requests
WORKSPACE_MODELS_DIR = "/workspace/models"
COMFYUI_MODELS_DIR = os.path.join("ComfyUI", "models")
def ensure_symlink(src_path, dest_path):
try:
if os.path.islink(dest_path) or os.path.exists(dest_path):
os.remove(dest_path)
os.symlink(os.path.relpath(src_path, os.path.dirname(dest_path)), dest_path)
print(f"πŸ”— Symlinked {dest_path} β†’ {src_path}")
except Exception as e:
print(f"❌ Failed to create symlink from {src_path} to {dest_path}: {e}")
def find_model_in_workspace(filename):
for root, _, files in os.walk(WORKSPACE_MODELS_DIR):
if filename in files:
return os.path.join(root, filename)
return None
def download_file(url, subdir, filename, civitai_key=None, hf_token=None):
target_dir = os.path.join(WORKSPACE_MODELS_DIR, subdir)
os.makedirs(target_dir, exist_ok=True)
workspace_path = os.path.join(target_dir, filename)
if not os.path.exists(workspace_path):
print(f"⬇️ Downloading {filename} β†’ {target_dir}")
headers = {}
if civitai_key and "civitai.com" in url:
headers["Authorization"] = f"Bearer {civitai_key}"
if hf_token and "huggingface.co" in url:
headers["Authorization"] = f"Bearer {hf_token}"
try:
with requests.get(url, stream=True, headers=headers) as r:
r.raise_for_status()
with open(workspace_path, "wb") as f:
for chunk in r.iter_content(chunk_size=8192):
if chunk:
f.write(chunk)
print(f"βœ… Downloaded to: {workspace_path}")
except Exception as e:
print(f"❌ Download failed: {url} β€” {e}")
return None
else:
print(f"βœ… Already exists in workspace: {workspace_path}")
return workspace_path
def ensure_model_symlink(url, subdir, filename, civitai_key=None, hf_token=None):
comfy_dir = os.path.join(COMFYUI_MODELS_DIR, subdir)
os.makedirs(comfy_dir, exist_ok=True)
comfy_path = os.path.join(comfy_dir, filename)
if os.path.exists(comfy_path):
print(f"βœ… ComfyUI path exists: {comfy_path}")
return
existing = find_model_in_workspace(filename)
if not existing:
existing = download_file(url, subdir, filename, civitai_key, hf_token)
if existing:
ensure_symlink(existing, comfy_path)
else:
print(f"❌ Model not found or downloaded: {filename}")
def download_models_from_list(models, civitai_key=None, hf_token=None):
for m in models:
name = m.get("name")
url = m.get("url")
directory = m.get("directory", "")
if name and url and directory:
ensure_model_symlink(url, directory, name, civitai_key, hf_token)
else:
print(f"⚠️ Missing fields in model entry: {m}")
def main(workflow_path):
if not os.path.isfile(workflow_path):
print(f"❌ File not found: {workflow_path}")
sys.exit(1)
with open(workflow_path, "r", encoding="utf-8") as f:
workflow_data = json.load(f)
# Get all URLs
all_urls = set()
for m in workflow_data.get("models", []):
url = m.get("url", "")
if url:
all_urls.add(url)
for node in workflow_data.get("nodes", []):
props = node.get("properties", {})
models = props.get("models", [])
for m in models:
url = m.get("url", "")
if url:
all_urls.add(url)
civitai_key = None
if any("civitai.com" in url for url in all_urls):
civitai_key = input("πŸ”‘ Enter your Civitai API key (or leave empty): ").strip() or None
hf_token = None
if any("huggingface.co" in url for url in all_urls):
hf_token = input("πŸ”‘ Enter your Huggingface token (or leave empty): ").strip() or None
print("πŸ“¦ Processing root models...")
download_models_from_list(workflow_data.get("models", []), civitai_key, hf_token)
print("πŸ“¦ Processing node models...")
for node in workflow_data.get("nodes", []):
props = node.get("properties", {})
models = props.get("models", [])
download_models_from_list(models, civitai_key, hf_token)
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python download_comfyui_models.py <workflow.json>")
sys.exit(1)
main(sys.argv[1])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment