Nodes/ComfyUI-Model_Downloader/Model Downloader from INI
ComfyUI Node

Model Downloader from INI

Stop downloading models by hand — batch them from an INI file

By tori29umai0123·Created 10 months ago·Updated 10 months ago· 4
Model Downloader from INI
    • status
    • summary
    ini_file_path
    max_retries3
    skip_existingtrue

    If you run ComfyUI long enough, the pain stops being the generation and starts being the setup: a workflow you want is missing three LoRAs, a controlnet, and a checkpoint, and you spend the afternoon hunting URLs. Model Downloader from INI is the answer to exactly that. It's the batch node from tori29umai0123's Model_Downloader pack: you point it at an INI file, and it downloads every model listed in there in one run. Do the click-and-wait once, replay it forever.

    How it works

    The mechanism is almost embarrassingly simple, which is why it works. Each [section] in the INI file is one model with its URL, target folder, and (optionally) a SHA-256 hash for verification. The node loops through the sections, calls the pack's underlying downloader for each one, retries failures up to max_retries, and reports a count at the end.

    The clever part: the sibling Model Downloader node auto-appends every file you grab with it to a models.ini sitting in the pack folder (ComfyUI/custom_nodes/model_downloader/models.ini). So you don't have to write the file by hand at all - download what you need once, and this node replays your exact download history. It even understands type = huggingface_directory sections written by the HuggingFace Directory Downloader node and hands those off to that downloader automatically.

    [sdxl_turbo_safetensors]
    url = https://huggingface.co/stabilityai/sdxl-turbo/resolve/main/sd_xl_turbo_1.0.safetensors
    subdirectory = checkpoints/sdxl
    filename = sdxl_turbo.safetensors
    hash = <optional sha256>
    

    The inputs that matter

    • ini_file_path - the only required input. Leave it empty to use the default models.ini in the pack folder, or point it at any file. It tolerates Windows paths, quoted paths, and paths relative to the pack directory.
    • skip_existing - default on, so reruns don't re-download files you already have. This is what makes the node safe to hammer repeatedly.
    • max_retries - default 3, up to 10.

    The two outputs are both strings: status gives the human-readable summary ("3 downloaded, 1 skipped"), and summary gives the machine-friendly Total/Success/Skipped/Failed line.

    Install

    Via ComfyUI Manager (search for "ComfyUI Model_Downloader"), or manually:

    cd ComfyUI/custom_nodes
    git clone https://github.com/tori29umai0123/ComfyUI-Model_Downloader
    

    then restart ComfyUI. The pack has no requirements.txt - it only needs requests, which you already have - so there's no dependency install step. If you plan to fetch CivitAI models, copy config.ini.example to config.ini and drop in an API key from civitai.com/user/account; a HuggingFace token goes in the same file for gated or private repos. config.ini is gitignored on purpose - don't commit your keys.

    Where people get burned

    The usual suspects: a 401 Unauthorized from CivitAI means the API key is missing or wrong; a 403 from HuggingFace means the repo is gated and you haven't accepted its terms or set a token. Both are config.ini problems, not node problems. If you hand-write an INI and a section is missing a url, the node skips it and counts it failed, so check the console output for which section broke. And the "skip existing" behavior means if you want to force a re-download of one model, you have to delete the file first - there's no force flag.

    Where it genuinely shines is reproducibility: copy models.ini to a new machine (or a fresh install) and one run rebuilds your entire model setup. For a team sharing a workflow, that's a lot closer to "it just works" than "here are eight URLs, good luck."

    Categoryutils

    Inputs (3)

    NameTypeDefaultDescription
    ini_file_pathSTRING
    max_retriesoptINT31–10
    skip_existingoptBOOLEANtrue

    Outputs (2)

    NameTypeDescription
    statusSTRING
    summarySTRING