CurseForge modpack downloader — download mods, resource packs, and shader packs from CurseForge.
Project description
curseforge-dl
A Python package to download mods, resource packs, and shader packs from CurseForge. Replicates the download logic used by HMCL.
Installation
pip install curseforge-dl
Usage
CLI
# Set your CurseForge API key (choose one method):
# Method 1: Create a .env file (recommended)
cp .env.example .env
# Edit .env and set CURSEFORGE_API_KEY=your-key
# Method 2: Environment variable
export CURSEFORGE_API_KEY="your-api-key"
# Method 3: Pass directly via CLI
curseforge-dl --api-key "your-api-key" install modpack.zip ./output
# Fetch modpack info by slug
curseforge-dl fetch all-the-mods-10
# Download latest modpack zip by slug
curseforge-dl download all-the-mods-10 --output-dir ./downloads
# Download with Minecraft version filter
curseforge-dl download all-the-mods-10 -g 1.21.1 -o ./downloads
# Install a CurseForge modpack
curseforge-dl install modpack.zip ./output
# Search for mods
curseforge-dl search "JEI" --game-version 1.21.1
# Get mod info
curseforge-dl info 238222
# Parse modpack info (no API key / download needed)
curseforge-dl modpack-info modpack.zip
# Parse modpack info with full mod list
curseforge-dl modpack-info modpack.zip --show-mods
Python API
import asyncio
from curseforge_dl import CurseForgeAPI, ModpackInstaller
async def main():
async with CurseForgeAPI(api_key="your-key") as api:
# Search mods
results = await api.search_mods("JEI", game_version="1.21.1")
for mod in results:
print(mod.name)
# Find a modpack by slug
modpack = await api.get_mod_by_slug("all-the-mods-10", class_id=4471)
if modpack:
print(f"{modpack.name} — {modpack.download_count:,} downloads")
# Download latest modpack zip by slug
installer = ModpackInstaller(api)
zip_path, addon, file = await installer.download_modpack_by_slug(
"all-the-mods-10", output_dir="./downloads"
)
print(f"Downloaded {addon.name} to {zip_path}")
# Install a modpack from zip
await installer.install("modpack.zip", "./output")
asyncio.run(main())
Parse modpack info (no API key needed)
from curseforge_dl import ModpackInstaller
manifest = ModpackInstaller.parse_modpack_info("modpack.zip")
print(manifest.name) # "All the Mods 10"
print(manifest.version) # "5.5"
print(manifest.author) # "ATMTeam"
print(manifest.minecraft.version) # "1.21.1"
for loader in manifest.minecraft.mod_loaders:
print(loader.id) # "neoforge-21.1.219"
print(f"Total mods: {len(manifest.files)}") # 480
Features
- Modpack fetch by slug: Look up any modpack by its slug and view latest version info
- Modpack download by slug: Download the latest modpack zip directly by slug
- Modpack installation: Parse CurseForge modpack zips and download all mods
- Modpack info: Parse modpack metadata (MC version, loader, mod list) without downloading
- Smart URL construction: Falls back to CDN URL when API doesn't provide download links
- File fingerprinting: MurmurHash2-based local file matching
- Async downloads: Parallel downloads with configurable concurrency
- Download retry: Automatic retry with exponential backoff on failure (default 3 attempts)
- Progress reporting: Built-in tqdm progress bars
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file curseforge_dl-1.2.0.tar.gz.
File metadata
- Download URL: curseforge_dl-1.2.0.tar.gz
- Upload date:
- Size: 40.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
968fd3dd0161f9dd0821e2232ff88c4093b0ea8138bd19c7a69ab22380af7f69
|
|
| MD5 |
0ce0a6187629af11f43ca71620a7ee34
|
|
| BLAKE2b-256 |
88faa204f240d00853448657eea5e8a6103fa5bc47fe554e274ac25e46ca2356
|
Provenance
The following attestation bundles were made for curseforge_dl-1.2.0.tar.gz:
Publisher:
publish.yml on zack-zzq/curseforge-dl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
curseforge_dl-1.2.0.tar.gz -
Subject digest:
968fd3dd0161f9dd0821e2232ff88c4093b0ea8138bd19c7a69ab22380af7f69 - Sigstore transparency entry: 991024747
- Sigstore integration time:
-
Permalink:
zack-zzq/curseforge-dl@e4c5a541242e7636ee9fa359699dc4b76f3e6a14 -
Branch / Tag:
refs/tags/v1.2.0 - Owner: https://github.com/zack-zzq
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e4c5a541242e7636ee9fa359699dc4b76f3e6a14 -
Trigger Event:
push
-
Statement type:
File details
Details for the file curseforge_dl-1.2.0-py3-none-any.whl.
File metadata
- Download URL: curseforge_dl-1.2.0-py3-none-any.whl
- Upload date:
- Size: 18.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8a99e95f350dc8145a49de43e8fdfbb3a24b16067e3710da9d486701e8f2c55a
|
|
| MD5 |
23e52625a858ec8652bccf7d905390e0
|
|
| BLAKE2b-256 |
b55ac20efec781c9758fd06366d25e1bb4bd47cfa9568e2af9279cfe31f92a10
|
Provenance
The following attestation bundles were made for curseforge_dl-1.2.0-py3-none-any.whl:
Publisher:
publish.yml on zack-zzq/curseforge-dl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
curseforge_dl-1.2.0-py3-none-any.whl -
Subject digest:
8a99e95f350dc8145a49de43e8fdfbb3a24b16067e3710da9d486701e8f2c55a - Sigstore transparency entry: 991024759
- Sigstore integration time:
-
Permalink:
zack-zzq/curseforge-dl@e4c5a541242e7636ee9fa359699dc4b76f3e6a14 -
Branch / Tag:
refs/tags/v1.2.0 - Owner: https://github.com/zack-zzq
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e4c5a541242e7636ee9fa359699dc4b76f3e6a14 -
Trigger Event:
push
-
Statement type: