Skip to content

InstaZDLL/plume-tui

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Plume

Python 3.10+ License: BSL 1.0 Built with Textual Platforms: Instagram and X

Plume logo

Multi-platform social TUI client for Instagram and X.com / Twitter. Browse your feed, like posts, and download media without leaving the terminal.

Warning: instagrapi and twikit are unofficial clients and may violate platform terms of service. Use burner accounts, not your primary accounts.

Install

Python 3.11 is recommended. twikit depends on Js2Py, which currently breaks on Python 3.12+.

cd <repo-dir>
python3.11 -m venv .venv && source .venv/bin/activate
pip install -e .

# for image rendering in the terminal:
sudo dnf install chafa     # Fedora
# or: sudo apt install chafa

Run

plume
# or: python -m plume

On launch, Plume opens a home screen where you can choose Instagram or X.com. After login, the session is persisted in a local SQLite database so the next launch returns directly to the feed.

Login

Instagram

Username and password, with 2FA if enabled. instagrapi emulates the mobile app, so the first login can take 10 to 20 seconds.

X.com: cookie login (recommended)

The username and password flow in twikit is currently broken because X changed their JS bundle layout. Cookie login is the reliable path:

  1. Log in normally on x.com in your browser.
  2. Export cookies to a file, for example with Cookie-Editor on Chrome or Firefox.
  3. In the X login screen, press Ctrl+K or click Cookies....
  4. Paste the cookie payload into the text area, or preferably paste a file path and click Load file for large JSON exports.
  5. Click Sign in. auth_token and ct0 are required; everything else is optional.

Accepted formats: Cookie-Editor JSON array, JSON key/value object, or a raw Cookie: header like auth_token=...; ct0=....

Long pastes are often truncated by terminal bracketed paste mode. Prefer a file path when importing Cookie-Editor JSON.

Persistence

All local state is stored in a single SQLite database:

~/.local/share/plume/plume.db

Tables:

table content
session Per-platform cookies and session settings
proxy Per-platform proxy configuration
setting Generic key/value settings such as last platform

Downloads are written to ~/Downloads/plume/<platform>/.

Keybindings

Home

key action
↑ / ↓ + Enter Choose platform
Esc Quit

Auth screen

key action
Tab Move between fields
Enter Submit
Ctrl+P Open proxy settings
Ctrl+K Open cookie login for X
Esc Back to home

Feed

key action
j / k or arrows Navigate
l Like or unlike
d Download media
r Reload
Esc Back to home
q Quit

Proxy

Supported schemes: HTTP, HTTPS, SOCKS4, and SOCKS5 with optional authentication.

Proxy settings are stored per platform, so Instagram can use SOCKS5 while X uses HTTP, for example. Access proxy settings from the login screen with Ctrl+P or the Proxy... button.

X.com compatibility patches

twikit expects a JS bundle structure that no longer exists on x.com. Plume installs two runtime patches from plume/x/client.py:

  • _StubClientTransaction replaces ClientTransaction, which fails with "Couldn't get KEY_BYTE indices", and returns an empty X-Client-Transaction-Id. Read endpoints accept it.
  • _install_twikit_compat_patches makes User.__init__ defensive by pre-filling about 30 legacy.* fields that X removed or renamed.

When upstream twikit catches up, these patches should become no-ops and can be removed.

Limitations

  • Instagram rate limits are aggressive. The client throttles 1 to 3 seconds, but you should still avoid spamming actions.
  • X username/password login is unreliable. Use cookies.
  • Not implemented yet: DMs, stories, search, profile pages, posting, retweets.
  • Image rendering uses chafa ANSI symbols. For true inline images, extend the renderer for kitty or ghostty graphics protocols.

Troubleshooting

"change your IP address, because it is added to the blacklist" on Instagram

Your IP or account was flagged by Instagram. Try this:

  1. Log in first on instagram.com or the mobile app from the same network.
  2. Wait 15 to 30 minutes.
  3. Configure a residential proxy with Ctrl+P.
  4. Use an account with some real history instead of a fresh one.

"Couldn't get KEY_BYTE indices" during X username/password login

This is a structural upstream issue. See the X compatibility patch section above. Use cookie login with Ctrl+K.

'ClientTransaction' object has no attribute 'key'

Same root cause as above. The stub fixes it automatically, but if the error returns then the patch likely was not installed. Make sure XClient() is instantiated before any call into twikit.

"missing required cookies: auth_token, ct0"

The terminal likely truncated your paste. Try this instead:

  1. Save the cookies to a file and use Load file.
  2. Use the raw Cookie: header format, which is shorter and more tolerant.

Image 403 / "failed to download"

The Twitter and Instagram CDNs reject non-browser user agents. plume/image_render.py already sends a Firefox user agent, so if it still fails then the CDN is likely rate limiting you. Wait a few minutes.

Session expirée

sqlite3 ~/.local/share/plume/plume.db \
  "DELETE FROM session WHERE platform = 'instagram';"
# ou platform = 'x'

Then log in again.

Images render as raw ANSI codes (3;93;48;2;...)

chafa outputs real ANSI sequences, but your terminal or Textual layer is not rendering them. The renderer already converts through rich.text.Text.from_ansi(...). If it still breaks, update your checkout and reinstall with pip install -e ..

Rate limit / "feedback_required"

Stop all activity for about 30 minutes. If it persists, the account is likely restricted and may need 24 hours to cool down.

Project structure

plume/
├── app.py                 # boot
├── config.py              # path helpers
├── storage.py             # SQLite session/proxy/setting store
├── proxy.py               # ProxyConfig load/save helpers
├── format.py              # compact_number, truncate
├── image_render.py        # chafa → rich.text.Text
├── screens/
│   ├── home.py            # Instagram / X platform picker
│   └── proxy.py           # generic proxy screen per platform
├── instagram/
│   ├── client.py          # wrapper instagrapi
│   └── screens/
│       ├── login.py
│       └── feed.py
└── x/
    ├── client.py          # wrapper twikit + compat patches
    └── screens/
        ├── login.py       # user/password path
        ├── cookies.py     # recommended cookie login
        └── feed.py

Dev

pip install -e .
python -m plume                     # run from local sources
python -m compileall plume          # quick syntax check

# inspect the database:
sqlite3 ~/.local/share/plume/plume.db
sqlite> .tables
sqlite> SELECT platform, updated_at FROM session;
sqlite> SELECT platform, host, port FROM proxy;

License

Plume is distributed under the Boost Software License 1.0. See LICENSE for the full text.

About

Terminal-first social client for Instagram and X with browsing, likes, downloads, cookie login, and proxy support.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages