Skip to content

Instantly share code, notes, and snippets.

@RupertAvery
Created May 2, 2025 22:37
Show Gist options
  • Save RupertAvery/2313682fecb430268cd0810f73a71556 to your computer and use it in GitHub Desktop.
Save RupertAvery/2313682fecb430268cd0810f73a71556 to your computer and use it in GitHub Desktop.
Script to download Checkpoint (model/LORA) metadata from CivitAI based on the models in your local machine
import os
import hashlib
import requests
import json
import argparse
# Config
BASE_URL = "https://civitai.com/api/v1"
EXTENSION = ".safetensors"
def get_sha256(file_path):
"""Compute the SHA-256 hash of a file."""
sha256_hash = hashlib.sha256()
with open(file_path, "rb") as f:
for byte_block in iter(lambda: f.read(4096), b""):
sha256_hash.update(byte_block)
return sha256_hash.hexdigest()
def fetch_model_version_by_hash(file_hash):
"""Query Civitai for a model version using the file hash."""
url = f"{BASE_URL}/model-versions/by-hash/{file_hash}"
response = requests.get(url)
if response.status_code == 200:
return response.json()
else:
print(f"[ERROR] Failed to fetch model version for hash {file_hash} - {response.status_code}")
return None
def fetch_model_details(model_id):
"""Query Civitai for model details using the model ID."""
url = f"{BASE_URL}/models/{model_id}"
response = requests.get(url)
if response.status_code == 200:
return response.json()
else:
print(f"[ERROR] Failed to fetch model for ID {model_id} - {response.status_code}")
return None
def save_model_info(file_path, data):
"""Save JSON data next to the original file."""
json_path = os.path.splitext(file_path)[0] + ".json"
try:
with open(json_path, "w", encoding="utf-8") as f:
json.dump(data, f, indent=4, ensure_ascii=False)
print(f"[INFO] Saved model info to {json_path}")
except Exception as e:
print(f"[ERROR] Failed to save JSON for {file_path} - {e}")
def main(search_dir):
for root, dirs, files in os.walk(search_dir):
for file in files:
if file.endswith(EXTENSION):
file_path = os.path.join(root, file)
print(f"\n[PROCESSING] {file_path}")
file_hash = get_sha256(file_path)
print(f"[HASH] {file_hash}")
model_version = fetch_model_version_by_hash(file_hash)
if not model_version:
continue
model_id = model_version.get("modelId")
model_info = {
"modelVersion": model_version
}
if model_id:
model_details = fetch_model_details(model_id)
if model_details:
model_info["model"] = model_details
save_model_info(file_path, model_info)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Scan .safetensors files and fetch Civitai metadata.")
parser.add_argument("search_dir", help="Path to directory containing .safetensors files")
args = parser.parse_args()
main(args.search_dir)
@RupertAvery
Copy link
Author

Prompt 1:

Create a python script that will enumerate files with extension .safetensors from a location e.g. a network location "\192.168.1.71\ComfyUI\models\loras\Pony"

Then for each file, I want to calculate the SHA-256 of the file.

The, using the hash, I want to fetch from an api "{baseUrl}/model-versions/by-hash/{hash}" where baseUrl will be stored as https://civitai.com/api/v1 and hash is the hash of the file.

The result should return something that matches this class:

public class ModelVersion
{
    public int Id { get; set; }
    public int ModelId { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public DateTime CreatedAt { get; set; }
    public DateTime UpdatedAt { get; set; }
    public string DownloadUrl { get; set; }
    public List<string> TrainedWords { get; set; }
    public List<ModelFile> Files { get; set; }
    public List<ModelImage> Images { get; set; }
    public Stats Stats { get; set; }
    public string BaseModel { get; set; }

    // Additional properties
    //"trainingStatus": null,
    //"trainingDetails": null,
    //"baseModel": "SD 1.5",
    //"baseModelType": "Standard",
    //"earlyAccessTimeFrame": 0,
    //"description": null,
    //"vaeId": null,
}


/// <summary>
/// Used by model-versions api
/// </summary>
public class ModelVersion2 : ModelVersion
{
    public ModelVersionModel? Model { get; set; }
}



public class ModelVersionModel
{
    public string Name { get; set; }
    public ModelType Type { get; set; }
    public bool Nsfw { get; set; }
    public bool Poi { get; set; }
    public ModelMode? Mode { get; set; }
}

using that information, I want to fetch from the following url:

{baseUrl}/models/{modelVersion.ModelId}

Prompt 2:

I want to store it as json matching the input file

Prompt 3:

change SEARCH_DIR to be taken from the command line args

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment