It downloads all the images and Videos from a provided Username, Model ID or Model TAG from CivitAI. Should the API not spit out all the data for all images then I'm sorry. The script can only download where data is provided.
The files are downloaded into a folder with the name of the user, ModelID or the TAG
Second Level is the Model Name with which the image was generated.
Videos without model metadata are placed in a dedicated videos/ subfolder.
- Install Python 3 Ensure you have Python 3.8 or newer installed.
install Python3
- Install Dependencies NEW requirements for users who already use the script
pip install -r requirements.txt- Migrate Existing Data
- If you are using the previous version with a
downloaded_images.jsonfile and want to continue using your data for tracking, you must use the my toolmigrate_json_to_sqlite.pyto transfer your old data to the new database. - Make sure both
migrate_json_to_sqlite.pyand your olddownloaded_images.jsonare in the same directory. - Run the migration tool from your terminal:
python migrate_json_to_sqlite.py- Follow the prompts. It will create
tracking_database.sqliteand offer to rename your old JSON file.
Run the script without any command-line arguments:
python civit_image_downloader.pythe script will ask you to:
Enter timeout value (seconds) [default: 60]:Choose image quality (1=SD, 2=HD) [default: 1]:Allow re-downloading tracked items? (1=Yes, 2=No) [default: 2]:Skip video files? (y/n) [default: n]:Choose mode (1=user, 2=model ID, 3=tag search, 4=model version ID):Enter max concurrent downloads [default: 5]:- (Mode-specific prompts):
- Mode 1:
Enter username(s) (, separated): - Mode 1:
Enter filter tag(s) (comma-separated, optional, press Enter to skip):(Optional: filter images by tags) - Mode 1:
Disable prompt check? (y/n) [default: n]:(If filter tags are provided) - Mode 2:
Enter model ID(s) (numeric, , separated): - Mode 3:
Enter tags (, separated): - Mode 3:
Disable prompt check? (y/n) [default: n]:(Check if tag words must be in the image prompt) - Mode 4:
Enter model version ID(s) (numeric, , separated): - Mode 4:
Enter filter tag(s) (comma-separated, optional, press Enter to skip):(Optional: filter by tags) - Mode 4:
Disable prompt check? (y/n) [default: n]:(If filter tags are provided)
- Mode 1:
If you just hit enter it will use the Default values of that Option if it has a default value.
Provide arguments directly on the command line. Unspecified arguments will use their defaults. --mode is required.
Available Arguments
--timeout INT(Default: 60)--quality {1,2}(1=SD, 2=HD, Default: SD)--redownload {1,2}(1=Yes, 2=No, Default: 2)--mode {1,2,3,4}(Required)--tags TAGS(Comma-separated, required for Mode 3)--disable_prompt_check {y,n}(Default: n, works with Mode 1 (with filter_tags), Mode 3 and Mode 4)--username USERNAMES(Comma-separated, required for Mode 1)--model_id IDS(Comma-separated, numeric, required for Mode 2)--model_version_id IDS(Comma-separated, numeric, required for Mode 4)--filter_tags TAGS(Comma-separated, optional for Mode 1 and Mode 4, filters images by tags)--output_dir PATH(Default: "image_downloads")--semaphore_limit INT(Default: 5)--no_sort(Disables model subfolder sorting, Default: False/Sorting enabled)--no_videos(Skip video files, download images only, Default: False)--max_path INT(Default: 240)--retries INT(Default: 2)--max_images INT(Limit total images downloaded, Default: unlimited)--max_per_model INT(Limit images per model in tag searches, Default: unlimited)--deep_scan(Enable deep scan for users with 50K+ images, Mode 1 only, Default: False)
- Download HD images for user "artist1", allowing redownloads, higher concurrency:
python civit_image_downloader.py --mode 1 --username "artist1" --quality 2 --redownload 1 --semaphore_limit 10 - Download SD images for models 123 and 456, using defaults for other options:
python civit_image_downloader.py --mode 2 --model_id "123, 456" - Download SD images for tag "sci-fi", disabling prompt check, no redownloads:
python civit_image_downloader.py --mode 3 --tags "sci-fi" --disable_prompt_check y --redownload 2 - Download images from model version 123456, filtered by tags "anime" and "portrait":
python civit_image_downloader.py --mode 4 --model_version_id "123456" --filter_tags "anime,portrait" --disable_prompt_check y
- Download only "anime" images from a specific username (Mode 1 + tag filter):
python civit_image_downloader.py --mode 1 --username "artist123" --filter_tags "anime" --max_images 50
- Download only 100 images from user "artist1" (useful for testing or sampling):
python civit_image_downloader.py --mode 1 --username "artist1" --max_images 100 - Download images from tag search with per-model limit (balanced sampling):
python civit_image_downloader.py --mode 3 --tags "landscape" --max_per_model 50 --max_images 500 - To skip all video files:
python civit_image_downloader.py --mode 1 --username "artist1" --no_videos - Download ALL images from a user (50K+ images) using deep scan:
python civit_image_downloader.py --mode 1 --username "Artist1" --deep_scan
CivitAI's API caps pagination at ~50,000 images per user. Users with more than 50K images will silently get incomplete downloads. Pass --deep_scan to run additional passes that retrieve images beyond this limit using bi-directional pagination and per-model-version queries. Only applies to Mode 1 (username search). Without this flag, the script warns when a user hits the cap. For more technical information https://github.com/Confuzu/CivitAI_Image_grabber/tree/main#21-deep-scan----50k-api-pagination-cap-bypass
If only some arguments are provided (e.g., only --mode), the script will use the provided options and prompt the user for any missing inputs.
The downloaded files will be organized within the specified --output_dir (default: image_downloads). Sorting (--no_sort flag) affects the structure inside the identifier folder.
With Sorting Enabled (Default)
image_downloads/
├── Username_Search/
│ └── [Username]/
│ ├── [Model Name Subfolder]/ # Based on image metadata 'Model' field
│ │ ├── [ImageID].jpeg # or .png, .webp
│ │ └── [ImageID]_meta.txt
│ ├── videos/ # Videos without parsable model metadata (.mp4, .webm)
│ │ ├── [ImageID].mp4 # or .webm
│ │ └── [ImageID]_no_meta.txt (or _meta.txt)
│ ├── invalid_metadata/ # For images with meta but no parsable 'Model' field
│ │ ├── [ImageID].jpeg
│ │ └── [ImageID]_meta.txt
│ └── no_metadata/ # For images (non-video) with no metadata found
│ ├── [ImageID].jpeg
│ └── [ImageID]_no_meta.txt
├── Model_ID_Search/
│ └── model_[ModelID]/
│ ├── [Model Name Subfolder]/
│ │ ├── [ImageID].jpeg
│ │ └── [ImageID]_meta.txt
│ ├── videos/ # Videos without parsable model metadata (.mp4, .webm)
│ │ ├── [ImageID].mp4
│ │ └── [ImageID]_no_meta.txt (or _meta.txt)
│ ├── invalid_metadata/
│ │ ├── [ImageID].jpeg
│ │ └── [ImageID]_meta.txt
│ └── no_metadata/
│ ├── [ImageID].jpeg
│ └── [ImageID]_no_meta.txt
│
├── Model_Version_ID_Search/
│ └── modelVersion_[VersionID]/
│ ├── [Model Name Subfolder]/
│ │ ├── [ImageID].jpeg
│ │ └── [ImageID]_meta.txt
│ ├── videos/ # Videos without parsable model metadata (.mp4, .webm)
│ │ ├── [ImageID].mp4
│ │ └── [ImageID]_no_meta.txt (or _meta.txt)
│ ├── invalid_metadata/
│ │ ├── [ImageID].jpeg
│ │ └── [ImageID]_meta.txt
│ └── no_metadata/
│ ├── [ImageID].jpeg
│ └── [ImageID]_no_meta.txt
└── Model_Tag_Search/
└── [Sanitized_Tag_Name]/ # e.g., sci_fi_vehicle
├── model_[ModelID]/ # Folder for each model found under the tag
│ ├── [Model Name Subfolder]/
│ │ ├── [ImageID].jpeg
│ │ └── [ImageID]_meta.txt
│ ├── videos/ # Videos without parsable model metadata (.mp4, .webm)
│ │ ├── [ImageID].mp4
│ │ └── [ImageID]_no_meta.txt (or _meta.txt)
│ ├── invalid_metadata/
│ │ ├── [ImageID].jpeg
│ │ └── [ImageID]_meta.txt
│ └── no_metadata/
│ ├── [ImageID].jpeg
│ └── [ImageID]_no_meta.txt
└── summary_[Sanitized_Tag_Name]_[YYYYMMDD].csv
With Sorting Disabled (--no_sort)
All images, videos and metadata files for a given identifier (username, model ID, model version ID, or model ID within a tag) are placed directly within that identifier's folder, without the [Model Name Subfolder], videos/, invalid_metadata, or no_metadata subdirectories.
image_downloads/
├── Username_Search/
│ └── [Username]/
│ ├── [ImageID].jpeg # or .png, .webp
│ ├── [ImageID].mp4 # or .webm (videos)
│ ├── [ImageID]_meta.txt
│ └── [ImageID]_no_meta.txt
├── Model_ID_Search/
│ └── model_[ModelID]/
│ ├── [ImageID].jpeg
│ ├── [ImageID].mp4
│ └── ...
├── Model_Version_ID_Search/
│ └── modelVersion_[VersionID]/
│ ├── [ImageID].jpeg
│ ├── [ImageID].mp4
│ └── ...
└── Model_Tag_Search/
└── [Sanitized_Tag_Name]/
├── model_[ModelID]/
│ ├── [ImageID].jpeg
│ ├── [ImageID].mp4
│ ├── [ImageID]_meta.txt
│ └── [ImageID]_no_meta.txt
└── summary_[Sanitized_Tag_Name]_[YYYYMMDD].csv
This file replaces the old JSON file. It stores a record of each downloaded image/video, including its path, quality, download date, associated tags (from Mode 3), original URL, and extracted checkpoint name (from metadata). You can explore this file using tools like "DB Browser for SQLite".
Migration Tool (migrate_json_to_sqlite.py)
If you are updating from a version using downloaded_images.json, run this separate Python script once in the same directory as your JSON file before using the main downloader. It will read the JSON and populate the new tracking_database.sqlite file.
python migrate_json_to_sqlite.pyNew --deep_scan flag for Mode 1 (username search) that retrieves images beyond the CivitAI API's 50K pagination cap.
CivitAI's /api/v1/images endpoint uses cursor-based pagination that caps at ~50,000 items (250 pages x 200 items per page). After that, nextPage becomes null and pagination silently stops. For users with more than 50K images, this means a standard download only retrieves a fraction of their gallery. A user with 148,208 images would only get ~50,000 without deep scan.
Deep scan uses a 5-pass strategy to retrieve images beyond the 50K cap:
| Pass | Strategy | Purpose |
|---|---|---|
| 1 | sort=Newest, nsfw=X |
Initial pass (NSFW images, newest first) |
| 2 | sort=Oldest, nsfw=X |
NSFW images from the other end |
| 3 | sort=Newest, no nsfw param |
SFW images, newest first |
| 4 | sort=Oldest, no nsfw param |
SFW images from the other end |
| 5 | Per-modelVersionId queries |
Targeted gap-filling for specific models |
Each pass paginates until the API stops returning results. The SQLite tracking database prevents duplicate downloads across all passes.
Pass 5 collects modelVersionId values discovered during passes 1-4 and queries each one individually. This catches images that fall in the "middle" between what Newest and Oldest pagination can reach. It stops after 50 consecutive model versions yield zero new images.
The API treats NSFW and SFW images as entirely separate pagination streams, each with its own independent 50K cap. This effectively doubles the maximum reachable images to ~200K (100K NSFW + 100K SFW) before model-version fill is needed.
Coverage depends on how many images the user has and how they're distributed:
| User's Total Images | Expected Coverage | Notes |
|---|---|---|
| 50K - 100K | 90-100% | Bi-directional pagination usually covers everything |
| 100K - 200K | 60-95% | Depends on SFW/NSFW split and model diversity |
| 200K - 500K | 30-60% | Middle images may be unreachable via any API path |
| 500K+ | 10-30% | API limitations make full retrieval unlikely |
The 50K cap is a hard API limitation. Deep scan maximizes what's retrievable but cannot guarantee 100% for very large galleries.
# Basic deep scan
python civit_image_downloader.py --mode 1 --username "user" --deep_scan
# Multiple users -- deep scan applies to all that hit the cap
python civit_image_downloader.py --mode 1 --username "user1,user2,user3" --deep_scanWithout --deep_scan, the script warns when a user hits the cap:
WARNING: username appears to have hit the 50K API pagination cap (49863 items).
Use --deep_scan to retrieve additional images beyond this limit.
Video Download Support
- The script now detects and downloads video files automatically — no configuration required.
- Detects
type: "video"items in API responses and downloads them as.mp4or.webm - Videos are routed to a dedicated
videos/subfolder inside the identifier folder (all modes)
Skip videos (--no_videos):
Users who only want images can pass --no_videos to skip all video files returned by the API. Skipped videos appear in the end-of-run skip summary.
python civit_image_downloader.py --mode 1 --username "artist1" --no_videosin the Interactive Mode it will ask you
4. Skip video files? (y/n) [default: n]:
Fix 1 — SSRF protection (_validate_next_page()):
- Any nextPage URL from the API now passes three checks before being followed: must be https://, must be
civitai.com or www.civitai.com,must start with /api/ - Applied to both pagination loops (_run_paginated_download and _search_models_by_tag)
- Invalid URLs log a warning and stop pagination gracefully rather than raising
Fix 2 — URL encoding (quote()):
- username in Mode 1: quote(ident, safe='') — handles any special character a CivitAI username could contain
- Tag in _search_models_by_tag: replaces the partial .replace(" ", "%20") with proper RFC 3986 encoding
Mode 1 now supports --filter_tags, allowing you to download only images from a specific user that match certain tags. Previously, username search and tag filtering were completely separate modes.
New Interactive Prompts for Mode 1:
Enter filter tag(s) (comma-separated, optional, press Enter to skip):
Disable prompt check? (y/n) [default: n]:
Example Scenarios:
- Download only "anime" images from a specific artist
python civit_image_downloader.py --mode 1 --username "artist123" --filter_tags "anime" --max_images 50- Multiple tags (image must match ALL tags)
python civit_image_downloader.py --mode 1 --username "artist123" --filter_tags "woman,photorealistic" --max_images 30- Disable prompt check for faster (less strict) filtering
python civit_image_downloader.py --mode 1 --username "photographer_xyz" --filter_tags "portrait" --disable_prompt_check yThe --redownload 1 option has been enhanced to support selective clearing of database history. When re-downloading, the script now automatically clears only the specific target being processed, leaving all other download records untouched.
- Each download is now tagged with its target type and value (
username:artist1,model:12345, etc.) - Database migration automatically adds target tracking columns on first run (non-destructive, preserves all existing data)
- When
--redownload 1is used, the script clears only the current target's records before redownloading.
Example Scenarios:
- Scenario 1: Re-download one user
python civit_image_downloader.py --mode 1 --username "artist1" --redownload 1 --quality 1Output: Cleared 150 previous downloads for username: artist1 Result: Only artist1's records cleared, other users untouched
- Scenario 2: Multiple users in one run
python civit_image_downloader.py --mode 1 --username "Bob,Alice,Charlie" --redownload 1 --quality 1Result: Bob cleared → Bob downloaded → Alice cleared → Alice downloaded → Charlie cleared → Charlie downloaded
- Scenario 3: Normal download (no clearing)
python civit_image_downloader.py --mode 1 --username "artist1" --redownload 2 --quality 1Result: No clearing, skips already-downloaded images (default behavior unchanged)
- Database Schema:
- Added
target_typecolumn (stores:username,model,tag,modelVersion) - Added
target_valuecolumn (stores: actual username, model ID, tag name, or version ID) - Created index for fast queries by target
- Fully backwards compatible (old records with NULL targets preserved and functional)
New Parameters:
--max_images- Limit total images downloaded--max_per_model- Limit images per model in tag searches
Features:
- Stops pagination early when limit reached (saves API calls)
- Only counts successful downloads (skipped images don't count toward limit)
- Clear progress reporting showing limit status
- Works with all modes (user, model, tag, model version)
- Fully backwards compatible (unlimited by default)
-
Fixed Model Name Extraction (Bug #38):
Images now correctly sort into model-specific folders instead of being incorrectly placed ininvalid_metadata. The script now extracts model names from the CivitAI API'scivitaiResourcesfield when the legacyModelfield is not present.
Extraction Priority: Existing Model field → civitaiResources checkpoint → baseModel → invalid_metadata -
Fixed Download Tracking Cross-Contamination (Bug #47):
Database tracking keys now include query context (mode + target identifier) to prevent false "already downloaded" detections across different query types. Previously, an image downloaded via model search would be incorrectly skipped when downloading that same image via username search.
New Key Format:{mode}:{target}_{image_id}_{quality}(e.g.,username:Exorvious_12345_SD)
Users can now collect complete image sets for each query type without cross-contamination. -
Fixed URN-Format Model Names (Bug #42):
Images containing URN-format resource identifiers (e.g.,urn_air_sdxl_checkpoint_civitai_101055@128078) in the Model field are now properly detected and replaced with human-readable model names extracted fromcivitaiResources. -
Enhanced Progress Visibility (Bug #50 - UX Improvement):
Added status messages to clarify progress when downloading multiple identifiers concurrently. Previously, the progress bar appeared to "jump" between users/models, causing confusion about whether downloads were stuck.
Users now have clear visibility into which identifier is being processed, progress per page, and completion status. No more confusion about "stuck" downloads when multiple identifiers run concurrently
-
Mode 4 Tag Filtering (New Feature):
Added--filter_tagsargument: Mode 4 (model version ID downloads) now supports filtering images by tags, similar to Mode 3. Users can specify one or more tags to only download images that match those tags.
Prompt Check Support: The--disable_prompt_checkoption now works with Mode 4 -
HTTP 429 Rate Limit Handling:
Added proper handling for HTTP 429 (Too Many Requests) responses from the CivitAI API. The script now automatically retries with exponential backoff when rate limits are encountered, preventing failed downloads due to API throttling. -
Fixed Dynamic Retry Configuration:
Fixed a bug where the--retriesargument was not being properly respected due to static decorator evaluation. The retry count is now dynamically determined at runtime, allowing users to customize the number of retry attempts via command-line arguments. -
Enhanced Database Thread Safety:
Enabled async locking in database read operations to prevent race conditions when multiple concurrent downloads check if an image has already been downloaded. This ensures data consistency in high-concurrency scenarios. -
Performance Optimization:
Optimized debug logging to only execute expensive operations (metadata extraction, JSON parsing) when debug level logging is actually enabled, improving performance in production use.
-
Code Structure (Major Refactoring):
The entire script has been refactored into an object-oriented structure using theCivitaiDownloaderclass. This encapsulates state (configuration,tracking data, statistics) and logic (downloading, sorting, API interaction) within the class, eliminating reliance on global variables. -
Scalable Tracking (SQLite Migration):
Replaced JSON: The previousdownloaded_images.jsontracking file has been replaced with an SQLite database (tracking_database.sqlite).
Relational Tags: Image tags (for Mode 3 summaries) are now stored relationally in a separateimage_tagstable, linked to the maintracked_imagestable. This allows for efficient querying.
Migration: A separatemigrate_json_to_sqlite.pyscript is provided for users to perform a one-time migration of their existingdownloaded_images.jsondata into the new SQLite database format. -
Robust Error Handling & Retries:
Automatic Retries: Integrated thetenacitylibrary to automatically retry failed network operations (image downloads, API page fetches, model searches) caused by common transient issues like timeouts, connection errors, or specific server-side errors (500, 502, 503, 504).
File Operations: Implemented a_safe_movefunction with retries to handle potential file locking issues during sorting (especially on Windows). Added checks to verify move operations. -
Improved Tag Search (Mode 3) Validation:
Invalid Tag Detection: When searching by tag, the script now fetches the first page of results and checks if any of the returned models actually contain the searched tag in their own metadata tags. -
Detailed Per-Identifier Statistics:
Granular Reporting: The final statistics summary now provides a detailed breakdown for each identifier (username, model ID, tag, version ID) processed during the run. -
Improved User Interface & Experience:
Input Validation: Added/improved validation loops for interactive inputs (e.g., ensuring numeric IDs, positive numbers). Handles invalid CLI arguments more gracefully (logs errors, exits).
Clearer Output: Refined console and log messages. Added specific warnings for invalid tags or identifiers that yield no results. Reduced console noise by logging successful per-file downloads only at the DEBUG level. Added a final summary note listing identifiers that resulted in no downloads.
This update introduces support for three different startup modes.
Fully Interactive Mode: If no command-line arguments are provided, the script will prompt the user for all required inputs interactively, as before.
Fully Command-Line Mode: If all necessary arguments are supplied via the command line, the script will execute without any prompts, offering a streamlined experience for advanced users.
Mixed Mode: If only some arguments are provided, the script will use the provided options and prompt the user for any missing inputs. This allows for a flexible combination of both modes.
The new Feature includes a check for mismatched arguments. If you provide arguments that don't match the selected mode, you will receive a warning message, but the script will continue to run,
ignoring the mismatched arguments and prompting for the required information if necessary.
Warning: --Argument is not used in ... mode. This argument will be ignored.
All images with no_meta_data are now moved to their own folder named no_meta_data.
They also have a text file containing the URL of the image, rather than any metadata.
No metadata available for this image.
URL: https://civitai.com/images/ID?period=AllTime&periodMode=published&sort=Newest&view=feed&username=Username&withTags=false
A bug was fixed where the script sometimes did not download all the images provided by the API.
The logging function was also enhanced. You can now see how many image links the API provided and what the script has downloaded.
A short version is displayed in your terminal.
Number of downloaded images: 2
Number of skipped images: 0
While more detailed information is available in the log file.
Date Time - INFO - Running in interactive mode
Date Time - WARNING - Invalid timeout value. Using default value of 60 seconds.
Date Time - WARNING - Invalid quality choice. Using default quality SD.
Date Time - INFO - Received 2 items from API for username Example
Date Time - INFO - Attempting to download: https://image.civitai.com/247f/width=896/b7354672247f.jpeg
Date Time - INFO - Attempting to download: https://image.civitai.com/db84/width=1024/45757467b84.jpeg
Date Time - INFO - Successfully downloaded: image_downloads/Username_Search/Example/2108516.jpeg
Date Time - INFO - Successfully downloaded: image_downloads/Username_Search/Example/2116132.jpeg
Date Time - INFO - Marked as downloaded: 21808516 at image_downloads/Username_Search/Example/2108516.jpeg
Date Time - INFO - Marked as downloaded: 21516132 at image_downloads/Username_Search/Example/2116132.jpeg
Date Time - INFO - Total items from API: 2, Total downloaded: 2
Date Time - INFO - 2 images have no meta data.
Date Time - INFO - Total API items: 2, Total downloaded: 2
Date Time - INFO - Image download completed.
The script can now selectively download images that belong to a specific model version ID. Option 4
This saves disk space and in addition, the Civit AI Server API is used less, which leads to a more efficient use of resources.
The Script will download the Images to this new Folder --> Model_Version_ID_Search
Updated the Folder Structure
i have noticed that the timeout of 20 seconds is too short for model ID and version ID and that i get more network errors than downloads,
so i have set it to 60 seconds for now.
But if you want to be on the safe side, then enter the following: 120 for the option: Enter timeout value (in seconds):
this has always worked up to now
Updated Folder Structure.
The script creates a Folder for each Option you can choose.
This new structure ensures better organization based on the search type, making image management more efficient.
New Feature
Redownload of images. The new option allows the tracking file to be switched off. So that already downloaded images can be downloaded again.
Allow re-downloading of images already tracked (1 for Yes, 2 for No) [default: 2]:
If you choose 2 or just hit enter the Script will run with Tracking as Default like always.
New Update
When the script is finished, a summary of the usernames or Model IDs that could not be found is displayed.
Failed identifiers:
username: 19wer244rew
Failed identifiers:
ModelID: 493533
With this Script you can search locally in txt a file if your TAG is searchable.
Just launch tagnames.py and it creates a txt File with all the Tags that the API gives out for the Model TAG search Option 3
But there are some entrys that are cleary not working. I dont kow why they are in the API Answer.
It has an function to add only new TAGS to he txt File if you run it again.
Features:
Model Tag Based Image download in SD or HD with Prompt Check Yes or NO
Prompt Check YES means when the TAG is also present in the Prompt, then the image will be Downloaded. Otherwise it will be skipped.
Prompt Check NO all Images with the searched TAG will be Downloaded. But the chance for unrelated Images is higher.
CSV File creation within Option 3 TAG Seach
The csv file will contain the image data that, according to the JSON file, has already been downloaded under a different TAG in this format:
"Current Tag,Previously Downloaded Tag,Image Path,Download URL"
Litte Statistc how many images have just been downloaded and skipped with a why reasons.
Updates:
Use of Multiple Entrys in all 3 Options comma-separated
New Folder Structure for Downloaded Images in all Options First Folder is named after what you searched Username, ModelID, TAG. Second is the Model that was used to generate the image
Performance:
Code optimizations now the script runs smoother and faster.
Better Error Handling for some Cases
Rate Limiting set to 20 simultaneous connections. Download Date Format changend in the JSON Tracking File
Option for Downloading SD (jpeg) Low Quality or HD (PNG) High Quality Version of Images
Better Tracking of images that already downloaded, with a JSON File called downloaded_images.json in the same Folder as the script. The Scripts writes for SD Images with jpeg Ending
"ImageID_SD":
"path": "image_downloads/civitAIuser/image.jpeg",
"quality": "SD",
"download_date": "YYYY-MM-DD - H:M"
For HD Images with PNG Ending
"ImageID_HD": {
"path": "image_downloads/civitAIuser/Image.png",
"quality": "HD",
"download_date": "YYYY-MM-DD- H:M"
into it and checks before Downloading a Image. For Both Option, Model ID or Username
Image Download with Model ID. Idea for it came from bbdbby The outcome looks sometimes chaotic a lot of folders with Modelnames you cant find on CivitAI. Because of renaming or Deleting the Models. But older Images have the old Model Names in the META data.
Sort function to put the images and meta txt files into the right Model Folder. The sort Function relies on the Meta Data from the API for the images. Sometimes Chaos. Especially for models that have a lot of images.
Tracking of images that already downloaded with a text file called downloaded_images.txt in the same Folder as the script. The Scripts writes the Image ID into it and checks before Downloading a Image. For Both Option, Model ID or Username
Increased the timeout to 20
It is writing the Meta Data for every image into a separate text file with the ID of the image: ID_meta.txt. If no Meta Data is available, the text file will have the URL to the image to check on the website.
Increased the timeout to 10
Added a delay between requests
