Skip to main content

Nami

Nami is an open-source Python CLI for downloading media from Instagram, TikTok, Facebook, and X. It wraps gallery-dl and yt-dlp with safer target parsing, per-media archives, retry/fallback logic, workspace configuration, diagnostics, and an optional Rich-powered interactive UI.

Use Nami only for content you are allowed to access and download. Platform availability can change when upstream sites or extractors change.

Highlights

  • Interactive no-argument menu for guided setup and downloads.
  • Noninteractive CLI for scripts, CI, and automation.
  • Downloads explicit URLs or profile lists from a workspace.
  • Supports photos, videos, stories, and highlights where upstream extractors support them.
  • Uses per-target archives to avoid duplicate downloads without deleting archives implicitly.
  • Validates target names and proves output paths stay inside the configured workspace.
  • Supports Netscape cookie files and TikTok browser-cookie fallback.
  • Classifies auth, cookie, rate-limit, network, dependency, not-found, extractor, timeout, and unknown failures.
  • Provides JSON output for download, doctor, setup, config, and archive reset workflows.
  • Includes a read-only doctor command for local diagnostics.

Platform support

Platform Photos/posts Videos/reels Stories Highlights Authentication
Instagram Yes Yes Yes Yes Optional Netscape cookies
TikTok Limited by upstream extractor Yes No No Netscape cookies or configured browser cookies
Facebook Limited by upstream extractor Yes No No Optional Netscape cookies
X / Twitter Limited by upstream extractor Yes No No Optional Netscape cookies

Unsupported combinations are reported as unsupported operations instead of being silently treated as successful downloads.

Installation

python -m pip install nami

Upgrade an existing installation:

python -m pip install --upgrade nami

Nami requires Python 3.10 or newer. Runtime dependencies are installed automatically: rich, gallery-dl, and yt-dlp.

Quick start

Interactive mode

Run Nami without arguments:

nami

The interactive UI guides you through workspace setup, settings, profile-file downloads, and media selection. Nami no longer creates a workspace as a hidden import-time side effect; setup is explicit through the interactive prompt or the setup command.

Noninteractive setup

Create a workspace under a chosen root directory:

nami setup --root .

This creates:

Nami/
├── downloads/
├── cookies/
└── profiles/
    ├── facebook_profiles.txt
    ├── instagram_profiles.txt
    ├── tiktok_profiles.txt
    └── x_profiles.txt

Create optional cookie templates too:

nami setup --root . --cookie-templates

Download explicit URLs

nami download https://www.instagram.com/example/ --media photos,videos

Multiple URLs are supported:

nami download URL1 URL2 URL3 --media all

Force platform inference when a URL is ambiguous:

nami download https://x.com/example --platform x --media videos

Download from profile files

Add one profile URL per line in the appropriate file under Nami/profiles/, then run:

nami download --profiles --media photos,videos

Limit profile loading to one platform:

nami download --profiles --platform instagram --media stories,highlights

JSON output

Use --json for machine-readable output:

nami download --profiles --media all --json
nami doctor --json
nami config show --json

CLI reference

nami setup --root PATH [--cookie-templates] [--json]
nami download [URL ...] [--profiles] [--platform instagram|tiktok|facebook|x] [--media KINDS] [--json]
nami doctor [--json]
nami config show|get|set|unset ... [--json]
nami archive reset (--all | selectors...) [--dry-run] [--yes] [--delete] [--json]

Media kinds are photos, videos, stories, highlights, or all. Comma-separated values are accepted, for example photos,videos.

Configuration

Nami loads configuration in this order:

  1. Environment variables
  2. ~/.nami/nami_config.json
  3. Defaults based on the current user's home directory

The config file is written atomically and avoids world-readable permissions where the platform supports it.

Config commands

nami config show
nami config get base_dir
nami config set browser firefox
nami config unset browser

Supported keys:

Key Environment variable Description
base_dir NAMI_BASE_DIR Download output directory
cookies_dir NAMI_COOKIES_DIR Netscape cookie file directory
profiles_dir NAMI_PROFILES_DIR Profile text-file directory
browser NAMI_BROWSER Browser for TikTok browser-cookie fallback (brave, chrome, edge, firefox)
user_agent NAMI_USER_AGENT User-Agent sent to extractors
timeout_seconds NAMI_TIMEOUT_SECONDS or NAMI_TIMEOUT Per-attempt subprocess timeout

Authentication and cookies

Place Netscape-format cookie files in the configured cookie directory. Nami validates that files contain at least one real seven-column Netscape cookie row; placeholder files and headers alone are rejected.

Common cookie candidate names include platform-specific files such as:

instagram_cookies.txt
tiktok_cookies.txt
facebook_cookies.txt
x_cookies.txt

TikTok can fall back to browser cookie extraction when no valid cookie file is available. If the configured browser is running, its database may be locked; nami doctor reports this as a warning.

Archives

Each target/media operation uses an archive file to avoid duplicate downloads. Archives are never deleted implicitly.

Preview archive reset actions:

nami archive reset --all --dry-run

Back up matching archives after confirmation:

nami archive reset --platform instagram --target example --yes

Permanently delete matching archives only when intentional:

nami archive reset --all --delete --yes

Without --yes, archive reset reports a dry run only.

Diagnostics

Run local, read-only diagnostics:

nami doctor

Doctor checks include:

  • configuration validity
  • Python version
  • importability of runtime dependencies
  • workspace readability/writability
  • configured browser state
  • cookie-file validity
  • profile-file readability
  • potential urllib3 namespace conflicts
  • stale archive locks

Doctor does not make network requests and does not mutate the workspace.

Exit codes

Code Meaning
0 Success
1 Failure
2 Invalid input or configuration
3 Partial result, warning, or unsupported-only result
4 No results
130 Cancelled

Development

Clone the repository, create an environment, and install development dependencies:

python -m pip install --upgrade pip
python -m pip install -e .[dev]

Run tests and quality checks:

PYTHONPATH=src python -m pytest -q
python -m ruff check src tests
python -m ruff format --check src tests
python -m build
python -m twine check dist/*
check-wheel-contents dist/*.whl

The test suite is designed to avoid network calls.

Troubleshooting

  • Run nami doctor first; it provides targeted remediation messages.
  • If pytest imports an installed old copy of Nami, run with PYTHONPATH=src or install the package editable with python -m pip install -e .[dev].
  • If cookie authentication fails, export fresh Netscape cookies and ensure the file has real cookie rows, not just template comments.
  • If TikTok browser-cookie extraction fails, close the configured browser and retry.
  • If downloads repeatedly time out, increase timeout_seconds with nami config set timeout_seconds 3600.
  • If you intentionally want to re-download content, use nami archive reset instead of deleting files manually.

License

Nami is distributed under the MIT License. See LICENSE.

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.0.tar.gz (65.7 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.0-py3-none-any.whl (53.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: nami-5.0.0.tar.gz
  • Upload date:
  • Size: 65.7 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.0.tar.gz
Algorithm Hash digest
SHA256 fbaad73b4795d337f7acd3c6eb15aeba421c586e03e4f71abd837a22a003578b
MD5 1d1d332a201600c4f05c4165813bfcae
BLAKE2b-256 b6844a9342bd71320babf3c49b58eb4cc18877e193eb57eb195f17416f36e727

See more details on using hashes here.

Provenance

The following attestation bundles were made for nami-5.0.0.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.0-py3-none-any.whl.

File metadata

  • Download URL: nami-5.0.0-py3-none-any.whl
  • Upload date:
  • Size: 53.4 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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6797ff0c13b68bf255ee2c2f4fa9e6883bd194ec4c2cdb24e8675ee01c7d1819
MD5 1f1282c2a8b625a7d00fee2e77f1054f
BLAKE2b-256 f5bf7ab9f3224a46d51fcada17bbdf7be28b40297e46cfa5cb53bd1d8a8fb2b4

See more details on using hashes here.

Provenance

The following attestation bundles were made for nami-5.0.0-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

5.0.1

2 files

This release

5.0.0 This release

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