This guide is for people who want to use parth-dl inside another project, contribute
code, debug extraction problems, or ship a release.
- Python 3.9 or newer
- Git
- A terminal with internet access
- No runtime dependencies are required by the package itself
Development dependencies are installed through the dev extra:
pip install -e ".[dev]"That currently installs pytest and ruff.
Clone the repository:
git clone https://github.com/parthmax2/parth-dl.git
cd parth-dlCreate a virtual environment:
python -m venv .venvActivate it on Windows PowerShell:
.\.venv\Scripts\Activate.ps1Activate it on macOS/Linux:
source .venv/bin/activateInstall the package in editable mode:
pip install -e ".[dev]"Check the CLI:
parth-dl --version
parth-dl --helpIf the parth-dl command is not found, use:
python -m parth_dl.cli --versionor make sure the virtual environment is activated.
Run tests:
python -m pytestRun one test file:
python -m pytest tests/test_cli.pyRun lint:
python -m ruff check .Run the CLI from the working tree:
python -m parth_dl.cli https://www.instagram.com/reel/Cxyz123AbCd/Run the local HTTP API and web UI:
parth-dl serve --dir ./downloads --port 8000Open:
http://127.0.0.1:8000
Use verbose mode when checking an Instagram behavior change:
parth-dl -v -P ./downloads https://www.instagram.com/reel/Cxyz123AbCd/Use JSON mode when you only want extraction metadata:
parth-dl --json https://www.instagram.com/reel/Cxyz123AbCd/Use format listing when debugging rendition selection:
parth-dl --list-formats https://www.instagram.com/reel/Cxyz123AbCd/Notes:
- Test with public content that works in a logged-out browser.
- Keep the default rate limiter on.
- Do not commit downloaded media,
.partfiles, or local debug scripts. - Direct CDN URLs from metadata are signed and expire quickly.
parth_dl/
__init__.py Public package exports: download(), get_info(), InstagramDownloader
cli.py CLI parser, banner, JSON mode, exit-code mapping
core.py Download orchestration, output paths, resume handling
extractors.py Instagram extraction methods and fallback order
server.py Loopback HTTP API, job queue, web UI serving
utils.py URL checks, retry, rate limiter, file safety, output helpers
web/index.html Single-file browser UI
High-level flow:
URL
-> validate Instagram URL
-> extract metadata through fallback methods
-> select best/worst format
-> validate CDN URL and redirects
-> download to .part
-> verify byte count
-> promote to final filename
The extraction layer is intentionally separated from download orchestration. Instagram changes often, so extractor fixes should be small, testable, and isolated whenever possible.
Keep these stable unless the version is intentionally breaking:
- CLI flags in cli.md
- CLI exit codes in cli.md
- Python exports in
parth_dl.__all__ - Metadata fields in schema.md
- HTTP endpoints and status codes in http-api.md
- File safety behavior: no path traversal, no unsafe media hosts, no partial promoted as complete
When changing any public behavior, update the matching doc page and tests in the same change.
- Decide the surface area: CLI, Python API, HTTP API, or internal only.
- Add tests near the layer being changed.
- Keep runtime dependencies at zero unless there is a strong reason.
- Update docs for every public surface affected.
- Run
python -m pytestandpython -m ruff check ..
Feature examples:
- CLI-only flag: update
parth_dl/cli.py,docs/cli.md, andtests/test_cli.py. - New metadata field: update extractor/core tests,
docs/schema.md, and any API docs. - Server endpoint: update
parth_dl/server.py,docs/http-api.md, andtests/test_server.py.
Start with:
parth-dl -v --json "https://www.instagram.com/reel/Cxyz123AbCd/"Check these possibilities:
| Problem | What it usually means |
|---|---|
| Works in browser only when logged in | The content is login-walled; anonymous download may not be possible |
| Browser says content unavailable | Deleted, region blocked, or private |
| CLI says rate limited | Instagram is throttling the IP; wait and retry later |
| Embed has only a thumbnail | The fallback extractor should try the logged-out Polaris flow |
| CDN URL returns 403 later | Signed CDN URL expired; extract fresh metadata |
| Video has no audio | Instagram may have returned a DASH/video-only rendition; choose combined H.264/AAC when available |
Useful checks:
parth-dl --list-formats URL
parth-dl --json URL
parth-dl -v URLDo not add cookie-based flows unless the project explicitly decides to support authenticated downloads. The current contract is public logged-out content only.
Python callers should catch specific exceptions first:
from parth_dl import DownloadError, NetworkError, RateLimitError, ValidationError
try:
path = download(url)
except ValidationError:
...
except RateLimitError:
...
except NetworkError:
...
except DownloadError:
...Shell callers should branch on exit codes:
parth-dl --quiet "$url"
case $? in
0) echo "ok" ;;
3) echo "network error" ;;
4) echo "rate limited" ;;
5) echo "invalid url" ;;
*) echo "download failed" ;;
esacHTTP callers should branch on status codes, not message text. See http-api.md.
Write docs for the person trying to build something quickly:
- Start with the command or code they can run.
- State whether the example is CLI, Python, or HTTP.
- Link to the schema instead of repeating every field.
- Mention public-content limitations clearly.
- Keep examples copy-pasteable.
- Avoid depending on a specific real Instagram URL in permanent docs.
When docs mention the CLI caption, use:
parth-dl v1.2.0
Instagram Media Downloader · public content
Developed by Parthmax
Before publishing:
- Update
parth_dl/__init__.pyversion. - Update
CHANGELOG.md. - Run
python -m pytest. - Run
python -m ruff check .. - Build and inspect the package.
- Install the built wheel in a clean environment.
- Smoke test
parth-dl --help,parth-dl --version, andparth-dl serve --no-open. - Publish to PyPI.
- Verify the PyPI page renders the README correctly.
Build commands:
python -m pip install build twine
python -m build
python -m twine check dist/*Before opening a PR:
- Tests pass locally.
- Ruff passes locally.
- New public behavior is documented.
- New errors use existing exception types or documented HTTP statuses.
- No downloaded media, credentials, cookies, or local debug files are committed.
- The change keeps Windows, macOS, and Linux behavior in mind.
For extractor PRs, include the failing public URL only if it is safe to share.