Nodes/OmniNodes/Model/LoRA Downloader ⬇️
ComfyUI Node

Model/LoRA Downloader ⬇️

Point It at a URL, Get a Loadable Model — No Browser Tab, No File Juggling

By TensorVizion·Created 3 months ago·Updated 21 days ago· 1
Model/LoRA Downloader ⬇️
    • file_path
    • filename
    • downloaded
    • summary
    ◄url►
    ◄model_type▾►
    ◄filename►
    ◄overwritefalse►
    ◄auth_token►
    ◄timeout_seconds60.00►

    The name is honest, which is refreshing: you give it a URL and a folder type, it streams the file into the folder ComfyUI actually loads models from. That's it. It is not a model browser, it doesn't scrape CivitAI, and it won't resume a 6GB download that died at 70%.

    What it's genuinely good for: a workflow that references a LoRA you haven't downloaded yet, a headless or remote ComfyUI box where opening a browser to grab a checkpoint is a nuisance, or any repeated setup where you'd rather not remember whether LoRAs live in models/loras or models/Lora on this particular machine.

    How it works

    A streamed HTTP GET (requests, 1MB chunks) written to <target>.part, then an atomic rename onto the real filename only after the last byte lands. If anything throws mid-stream, the partial file is deleted rather than left behind to fail confusingly three nodes downstream. Content-Length is used to report the expected size in the summary - that's a comparison you read, not a checksum that's verified.

    If the target file already exists and overwrite is False (the default), it skips the download entirely and returns the existing path. That's what makes it safe to leave in a graph you re-run nightly: you pay for the download once.

    Inputs and outputs

    Required: url, model_type (seven folders - checkpoints, loras, vae, controlnet, upscale_models, clip, embeddings), filename, overwrite. Optional: auth_token and timeout_seconds (default 60, capped at 3600).

    Outputs are file_path, filename, downloaded (BOOLEAN) and summary. The downloaded boolean is the useful one for branching - it's False on a skipped file and False on a failure, so check summary to tell which happened. Failures come back as text, not exceptions: a bad URL, a 401, a missing requests install, all return downloaded: False and an explanation, so the queue doesn't die on you.

    The file lands in the first path registered for that model type - the same place ComfyUI's own loaders look. With extra_model_paths.yaml pointing at several locations for one type, that ordering decides where your file goes.

    Installing it

    This is one of the Web API nodes, so it needs requests, which is not bundled with ComfyUI.

    cd ComfyUI/custom_nodes/
    git clone https://github.com/TensorVizion/OmniNodes
    cd OmniNodes && pip install -r requirements.txt
    # or just: pip install requests
    

    Same environment ComfyUI runs in, then restart. The node appears under TensorVizion/Web API. Skip the pip step and it still loads - it just returns a "requests not installed" message instead of downloading anything.

    Where people get burned

    Set filename yourself, always. Leave it blank and the node guesses from the last path segment of the URL. CivitAI's download links look like civitai.com/api/download/models/123456 - no extension, so you get a file literally named downloaded_model.safetensors sitting in your checkpoints folder. Good luck telling that apart from the next one.

    CivitAI's token goes in the URL, not the auth_token field. The field is sent as an Authorization: Bearer header, which is what gated Hugging Face repos want. CivitAI expects the API key as a query parameter on the download link itself (.../api/download/models/123456?token=YOUR_KEY) - that's the pattern people have been pasting into other tools for years, and without it a gated file just 401s.

    Your loader dropdowns won't show the new file. ComfyUI builds those lists when the node is added to the graph, so a file downloaded at queue time is real but invisible in an already-placed loader until you refresh the page or re-add the node.

    There's no progress bar. A multi-gigabyte checkpoint streams in silence - the UI looks hung. The terminal or the summary is where you find out it worked. The default 60-second timeout_seconds is a stall timeout, though: a slow-but-steady connection is fine, a mirror that stops sending bytes is not.

    Treat the URL like code. A .ckpt or .pth from an untrusted source is a pickle, and you're handing it to a process with your full user permissions; prefer .safetensors. And note that a token typed into that widget gets saved into the workflow JSON, so the moment you share the graph you've shared the credential. This is the one node category in the ecosystem that has already shipped malware once - pasting a link into a node is not more trustworthy than downloading it by hand.

    CategoryTensorVizion/Web API

    Inputs (6)

    NameTypeDefaultDescription
    urlSTRING—
    model_typeCOMBO7 options: checkpoints, loras, vae, controlnet, upscale_models, clip, +1
    filenameSTRING—
    overwriteBOOLEANfalse—
    auth_tokenoptSTRING—
    timeout_secondsoptFLOAT60.005–3600—

    Outputs (4)

    NameTypeDescription
    file_pathSTRING—
    filenameSTRING—
    downloadedBOOLEAN—
    summarySTRING—