Skip to main content

🌊 Nami

An open-source CLI media downloader for Instagram, TikTok, Facebook, and X

CI PyPI Version Python Version License: MIT GitHub Stars

Nami is a lightweight, open-source media downloader designed for seamless batch extraction across social platforms. Combining gallery-dl and yt-dlp with an interactive Rich terminal interface and scriptable CLI workflows, Nami automates deduplication, rate-limit retries, and browser cookie handling.

InstallationQuickstartSupported PlatformsCLI CommandsConfigurationDiagnosticsTroubleshooting


Features

  • Multi-Platform Batch Downloads: Extract high-resolution photos, videos, reels, posts, stories, and highlights.
  • Dual-Engine Architecture: Intelligently routes tasks between gallery-dl and yt-dlp with automatic fallback on extractor failures.
  • Interactive & Headless Modes: Run interactively with an intuitive terminal UI or integrate into headless pipelines with dedicated CLI subcommands and --json output.
  • Smart Anti-Duplicate Archiving: Maintains per-target archive.txt records to avoid redundant re-downloads, with safe archive reset management.
  • Flexible Authentication: Supports Netscape cookie files, anonymous fallbacks, and direct browser cookie extraction (--cookies-from-browser).
  • Resilient Retry & Failure Classification: Classifies auth, cookie, rate-limit, network, dependency, not-found, extractor, and timeout failures with exponential jittered backoff.
  • Built-in System Doctor: Run nami doctor to verify local binaries, browser installations, cookie permissions, and workspace health without network calls.

Supported Platforms

Platform Photos / Posts Videos / Reels Stories Highlights Auth Support Primary Engine
Instagram Included Included Included Included Netscape Cookie / Anonymous gallery-dl / yt-dlp
TikTok Limited by upstream Included N/A N/A Browser DB / Netscape Cookie yt-dlp / gallery-dl
Facebook Limited by upstream Included N/A N/A Netscape Cookie / Anonymous gallery-dl / yt-dlp
X (Twitter) Limited by upstream Included N/A N/A Netscape Cookie / Anonymous gallery-dl / yt-dlp

[!NOTE] Unsupported media combinations are reported as unsupported operations instead of silently failing or being treated as successful downloads.


Installation

Install nami directly via pip:

python -m pip install nami

Runtime dependencies (rich, gallery-dl, yt-dlp) are automatically installed.

To upgrade to the latest release:

python -m pip install --upgrade nami

Nami requires Python 3.10 or newer.


Quickstart

1. Interactive Mode

Run nami without arguments to launch the interactive terminal UI:

nami
┌──────────────────────── Nami ────────────────────────┐
│ What do you want to download?                        │
│                                                      │
│  1  Photos only                                      │
│  2  Videos only                                      │
│  3  Stories only                                     │
│  4  Highlights only                                  │
│  5  Photos + Videos                                  │
│  6  Stories + Highlights                             │
│  7  All                                              │
│  8  Settings                                         │
│  0  Exit                                             │
│                                                      │
│  Save: ~/Nami/downloads                              │
└──────────────────────────────────────────────────────┘

On first launch, Nami guides you through workspace initialization. Workspace setup is explicit and never creates files as hidden import-time side effects.

2. Workspace Layout

Nami organizes downloads, cookie files, and target profile lists cleanly:

Nami/
├── downloads/      # Extracted media organized by platform, account & kind
├── cookies/        # Optional Netscape cookie files (*_cookies.txt)
└── profiles/       # Target profile URLs (*_profiles.txt)
    ├── facebook_profiles.txt
    ├── instagram_profiles.txt
    ├── tiktok_profiles.txt
    └── x_profiles.txt

CLI Commands Reference

Nami provides a full suite of scriptable subcommands for headless pipelines and automation:

nami setup

Initialize a Nami workspace directory structure and configuration:

# Initialize workspace under current directory
nami setup --root .

# Initialize with template cookie files
nami setup --root /path/to/workspace --cookie-templates

# Output JSON report
nami setup --root . --json

nami download

Download specific target URLs or batch profiles:

# Download direct URLs
nami download https://www.instagram.com/p/DAEXAMPLE123/ https://x.com/OpenAI/status/123456

# Filter by media kinds (photos, videos, stories, highlights, all)
nami download https://www.instagram.com/example/ --media photos,videos

# Force platform inference when URL is ambiguous
nami download https://x.com/example --platform x --media videos

# Batch download all configured profile files
nami download --profiles

# Filter profile downloads by platform and media kinds
nami download --profiles --platform instagram --media stories,highlights

# Machine-readable JSON output
nami download --profiles --media all --json

nami doctor

Inspect system health, engine availability, browser installations, and workspace configuration without network calls:

nami doctor
nami doctor --json

nami config

Inspect and update persistent configuration settings:

# Show all active settings
nami config show

# Get a specific setting value
nami config get browser
nami config get base_dir

# Set a setting value
nami config set browser chrome
nami config set timeout_seconds 600

# Reset a setting to its default/derived value
nami config unset browser

# Machine-readable JSON output
nami config show --json

nami archive reset

Safely manage download tracking archives to enable re-downloading media without deleting archives implicitly:

# Preview archives that would be reset (dry run)
nami archive reset --all --dry-run

# Back up archives for a specific target (creates timestamped .bak files)
nami archive reset --platform instagram --target example --yes

# Filter reset by media kind
nami archive reset --platform instagram --target example --media stories --yes

# Permanently delete matching archives only when intentional
nami archive reset --all --delete --yes

Authentication & Cookies

To access private content, high-resolution stories, or avoid login restrictions:

1. Netscape Cookie Files

Place Netscape-formatted cookie files inside your configured cookies_dir. Nami validates that files contain at least one valid seven-column Netscape cookie row; placeholder files and headers alone are rejected.

Nami recognizes platform-specific cookie filenames such as:

  • instagram_cookies.txt or instagram.com_cookies.txt
  • tiktok_cookies.txt or tiktok.com_cookies.txt
  • facebook_cookies.txt or facebook.com_cookies.txt
  • x_cookies.txt, x.com_cookies.txt, twitter_cookies.txt, or twitter.com_cookies.txt

2. Browser Session Extraction

TikTok can fall back to browser cookie extraction when no valid cookie file is available. Configure your browser via:

nami config set browser brave   # Options: brave, chrome, edge, firefox

Note: If the configured browser is currently running, its database may be locked; nami doctor will report this as a warning.


Configuration & Environment Variables

Nami loads configuration in the following order of precedence:

  1. Environment variables
  2. ~/.nami/nami_config.json
  3. Default values based on the user's home directory
Configuration Key Environment Variable Description Default
base_dir NAMI_BASE_DIR Download output root directory ~/Nami/downloads
cookies_dir NAMI_COOKIES_DIR Netscape cookie files directory ~/Nami/cookies
profiles_dir NAMI_PROFILES_DIR Target profile text files directory ~/Nami/profiles
browser NAMI_BROWSER Browser for automated cookie extraction (brave, chrome, edge, firefox) brave
user_agent NAMI_USER_AGENT Custom HTTP User-Agent string Standard Chrome string
timeout_seconds NAMI_TIMEOUT_SECONDS / NAMI_TIMEOUT Child engine process execution timeout (seconds) 900
NAMI_THEME Terminal UI theme styling (dark, light, auto) dark
NAMI_SKIP_ENV_CHECK Set to 1 to bypass startup binary verification 0

Diagnostics

Run local, read-only system diagnostics:

nami doctor

Doctor checks include:

  • Configuration validity and integrity
  • Python version compatibility (>= 3.10)
  • Importability and versions of runtime dependencies (rich, gallery-dl, yt-dlp)
  • Workspace readability and writability
  • Configured browser installation and process lock state
  • Netscape cookie file validity (detects placeholder/empty files)
  • Profile file readability and syntax validation
  • Potential urllib3 namespace conflicts
  • Stale archive lock detection

Exit Codes

Nami returns deterministic exit codes for CI/CD and scripting pipelines:

Exit Code Meaning Description
0 Success All requested download or management operations completed successfully
1 Failure One or more download operations failed after retry/fallback attempts
2 Invalid Input Invalid CLI argument, unparseable profile URL, or corrupt configuration
3 Partial / Unsupported Partial results, warnings, or unsupported platform/media combinations
4 No Results Extractor completed successfully but found 0 downloadable items
130 Cancelled Execution interrupted via SIGINT (Ctrl+C)

Development & Testing

Clone the repository and install development dependencies in an editable environment:

git clone https://github.com/OpenSelena/nami.git
cd nami
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"

Running Checks & Tests

# Run test suite with pytest
PYTHONPATH=src python -m pytest -q

# Run Ruff lint and format checks
python -m ruff check src tests
python -m ruff format --check src tests

# Build and verify distribution package
python -m build
python -m twine check dist/*
check-wheel-contents dist/*.whl

The test suite runs completely offline without making external network calls.


Troubleshooting

  • Check diagnostics first: Run nami doctor to get immediate actionable remediation steps.
  • Import issues during testing: If pytest imports an old installed copy of Nami, run with PYTHONPATH=src or reinstall editable with python -m pip install -e ".[dev]".
  • Cookie authentication failures: Ensure exported Netscape cookie files contain genuine 7-column rows and not just headers/comments.
  • Browser database locked: If TikTok browser cookie extraction fails, close all running instances of your configured browser and retry.
  • Download timeouts: If downloads of large profiles or playlists time out, increase the timeout limit via nami config set timeout_seconds 3600.
  • Re-downloading existing media: Use nami archive reset to clear or back up tracking archives rather than deleting files manually.

License

Distributed under the MIT License. Developed and maintained by Igect under OpenSelena.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nami-5.0.1.tar.gz (68.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nami-5.0.1-py3-none-any.whl (54.1 kB view details)

Uploaded Python 3

File details

Details for the file nami-5.0.1.tar.gz.

File metadata

  • Download URL: nami-5.0.1.tar.gz
  • Upload date:
  • Size: 68.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for nami-5.0.1.tar.gz
Algorithm Hash digest
SHA256 5c60f4e214ecd633487495072d1a9dba5b9126f19b8190b2c4a13d4ec3070dfe
MD5 38b2248a8ea97f07c9395ec1725fefc0
BLAKE2b-256 26f3b00090521ff4f8a8f1d1d9e08f1591630e2eaa6f4e7de27dc40b3d9b8bac

See more details on using hashes here.

Provenance

The following attestation bundles were made for nami-5.0.1.tar.gz:

Publisher: publish.yml on OpenSelena/nami

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nami-5.0.1-py3-none-any.whl.

File metadata

  • Download URL: nami-5.0.1-py3-none-any.whl
  • Upload date:
  • Size: 54.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for nami-5.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 737b5ac3cb2c311c4ee1641d14c2257f6002eb01e06f59391b8d0a05d78961cd
MD5 fef70e0fe12db6f42a093b486ac37273
BLAKE2b-256 feb029d5345324a77ab29a6e5639ac6398fef5fe046e82fe4f778e0d1ab18613

See more details on using hashes here.

Provenance

The following attestation bundles were made for nami-5.0.1-py3-none-any.whl:

Publisher: publish.yml on OpenSelena/nami

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

5.0.6

2 files

5.0.4

2 files

5.0.3

2 files

5.0.2

2 files

This release

5.0.1 This release

2 files

5.0.0

2 files

4.0.0

2 files

3.0.4

2 files

3.0.3

2 files

3.0.2

2 files

3.0.1

2 files

3.0.0

2 files

2.5.2

2 files

2.5.1

2 files

2.5.0

2 files

2.4.1

2 files

2.4.0

2 files

2.3.9

2 files

2.3.8

2 files

2.3.7

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page