Skip to main content

twitter-username

PyPI Python License

Look up any X (Twitter) account by username or numeric id — no API key, no developer account, no browser, no login.

Convert a username to a user id, a user id back to a username, and pull the public profile: display name, bio, follower and following counts, tweet count, join date, avatar, banner and verification status.

from twitter_username import resolve

user = resolve("jack")
print(user.id, user.name, user.followers_count)
# 12 jack 11177316
$ twitter-username jack -f id -f screen_name -f followers_count
{
  "id": "12",
  "screen_name": "jack",
  "followers_count": 11177316
}

Why

The official X API costs money and rate-limits hard even on paid tiers. This library pulls the same public profile data straight from X, handles the plumbing for you, and returns clean Python objects. No token to manage, no monthly bill.

Install

pip install twitter-username

Only requests and beautifulsoup4 are required. For SOCKS proxies:

pip install "twitter-username[socks]"

Requirements

Python 3.8 or newer. Pure Python — the wheel is py3-none-any, there is nothing to compile, and no browser, JS engine or system package is involved.

Runs unchanged on Linux, macOS and Windows, and on anything else CPython supports (BSD, Android/Termux, iOS via CPython 3.13+). On a legacy Windows console (cp1252, cp437) the CLI switches to UTF-8 where the terminal allows it and otherwise emits \uXXXX-escaped JSON, so emoji and CJK display names never crash it and the output stays valid, lossless JSON.

Usage

One-off lookups

from twitter_username import resolve, resolve_raw

resolve("jack")                       # by username
resolve("@jack")                      # leading @ is fine
resolve("https://x.com/jack")         # so is a profile URL
resolve(user_id=12)                   # by numeric id

resolve_raw("jack")                   # the untouched JSON response

Many lookups — reuse a Client

Each resolve() call sets itself up from scratch. A Client keeps that setup warm, so every lookup after the first costs a single request.

from twitter_username import Client

with Client() as client:
    for handle in ["jack", "elonmusk", "python"]:
        user = client.resolve(handle)
        print(f"{user.screen_name:12} {user.followers_count:>12,}")

The User object

Populated fields only; anything X did not return stays None. The complete untouched payload is always on .raw, so nothing is lost.

id screen_name name created_at identity
description location url profile
followers_count following_count tweet_count media_count favourites_count listed_count counts
verified is_blue_verified protected possibly_sensitive flags
profile_image_url profile_banner_url media
raw the original response object

Plus created_at_datetime, profile_url, profile_image_url_original and to_dict(include_raw=False).

Errors

from twitter_username import resolve, UserNotFound, UserUnavailable, APIError

try:
    user = resolve("some_handle")
except UserNotFound:
    ...          # no such account (also covers suspended/deactivated)
except UserUnavailable as exc:
    print(exc.reason)
except APIError as exc:
    print(exc.status_code, exc.body)

All of them subclass TwitterUsernameError.

Transport failures (proxy refused, DNS, TLS, timeout) are not wrapped — they surface as the usual requests.RequestException subclasses, so existing requests error handling and retry policies keep working. The CLI catches them and prints one line instead of a traceback.

Proxies

proxies accepts a single URL applied to both schemes, or a requests-style mapping.

from twitter_username import Client, resolve

resolve("jack", proxies="http://user:pass@127.0.0.1:8080")
resolve("jack", proxies="socks5://127.0.0.1:1080")     # needs [socks] extra

with Client(proxies={"http": "http://a:8080", "https": "http://b:8080"}) as c:
    c.resolve("jack")

The proxy is set on the session, so it covers every request the library makes.

Custom headers

Headers merge in layers, each one overriding the last: library defaults → session → client → individual call. Passing None as a value removes a header the library would otherwise send.

from twitter_username import Client

with Client(
    headers={"Accept-Language": "de-DE,de;q=0.9"},
    user_agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ...",
) as client:
    client.resolve("jack")
    client.resolve("python", headers={"Referer": "https://x.com/explore"})

Bringing your own session

Pass a configured requests.Session to keep control of retries, connection pooling, adapters and cookies. The client will not close a session it did not create.

import requests
from requests.adapters import HTTPAdapter, Retry
from twitter_username import Client

session = requests.Session()
session.mount("https://", HTTPAdapter(max_retries=Retry(total=3, backoff_factor=1)))

with Client(session=session) as client:
    client.resolve("jack")

Other Client options: timeout, page_url, features, verify, cert, trust_env, bearer, guest_token.

Command line

twitter-username jack                       # parsed JSON
twitter-username jack elonmusk python       # batch, JSON array
twitter-username --user-id 12               # id to username
twitter-username jack --raw                 # full response
twitter-username jack -f id -f followers_count
twitter-username jack --compact             # one JSON object per line

twitter-username jack -x socks5://127.0.0.1:1080
twitter-username jack -H 'Accept-Language: de-DE' -H 'Referer:'

Exit codes: 0 ok, 1 error, 2 usage, 3 not found, 4 unavailable.

Pipe it into jq like any other tool:

twitter-username jack elonmusk --compact | jq -r '[.screen_name, .followers_count] | @tsv'

Development

pip install -e ".[dev]"
pytest                    # offline tests
pytest -m network         # live tests over the network

Stability

This library depends on public data whose shape X can change without notice. Pin a version, handle BootstrapError as a signal that something upstream moved, and open an issue if lookups start failing.

Use it for public profile data only, and respect X's terms and the law where you are. Rate-limit yourself; do not hammer it.

Keywords

twitter api · x api · twitter without api key · free twitter api · twitter scraper · x scraper · twitter username to id · twitter id to username · twitter user lookup · get twitter user id · twitter profile scraper · twitter follower count · twitter user info · x user lookup · python twitter library · twitter osint · x osint · snscrape alternative · tweepy alternative · no api key · twitter data · social media scraper · twitter account checker · username checker

License

MIT — see the LICENSE file included in the distribution.

Download files

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

Source Distribution

twitter_username-0.1.0.tar.gz (34.8 kB view details)

Uploaded Source

Built Distribution

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

twitter_username-0.1.0-py3-none-any.whl (26.4 kB view details)

Uploaded Python 3

File details

Details for the file twitter_username-0.1.0.tar.gz.

File metadata

  • Download URL: twitter_username-0.1.0.tar.gz
  • Upload date:
  • Size: 34.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.3

File hashes

Hashes for twitter_username-0.1.0.tar.gz
Algorithm Hash digest
SHA256 a2d9e3d1eb2ccf7e13d40314fc1e1d55ce745e4947c65eda9fd40c33ca9d191c
MD5 01105a2ffd121ff2f511a17cbc36cbd0
BLAKE2b-256 933a541ed010ea943a0e853cb8fb090c143b07dcd06e60f4d0a29014968abecb

See more details on using hashes here.

File details

Details for the file twitter_username-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for twitter_username-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d943ddfd31ce75bc4c7b980d331048ed937b858e1d6eb87d0c2b3c854dde231f
MD5 9aa76dd4ad37047222bf7ec9fb0f8b69
BLAKE2b-256 a911d03dbf8499a6d1c9d472d63f0bb8076dd61f51dfe811c3cc1a10727972de

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page