Created
May 2, 2025 22:37
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
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
This will scan the models and calculate their SHA-256 to search in Civitai, then download the model information (trigger words, author comments) in json format, in the same folder as the model, using the name of the model with .json extension.
Usage:
Disclaimer: This was 100% coded with ChatGPT (I could have done it, but ChatGPT is faster at typing)