Skip to main content

A maintained fork of twikit — Twitter/X API scraper for Python, no API key required.

Project description

twifork

A Twitter / X API scraper for Python — no API key required.
A maintained fork of d60/twikit, fixed for the 2026 breakages that make the upstream release unusable.

PyPI Python 3.8+ MIT License Stars

[English] · [日本語] · [中文]

Drop-in replacement — the package still imports as twikit, so existing code (from twikit import Client) keeps working unchanged.


Install

pip install twifork

With optional browser-TLS impersonation (gets past some 403 walls):

pip install "twifork[impersonate]"

Or grab the latest straight from git:

pip install git+https://github.com/PawiX25/twifork.git

Why this fork?

The upstream PyPI release (twikit==2.3.3) is broken in several ways as of 2026. twifork fixes them — each item links to the upstream issue it resolves:

  • ClientTransaction / Couldn't get KEY_BYTE indices — updated ondemand.s.js parsing for the new X webpack bundle, so GraphQL requests work again. (#408, #409, #304)
  • Intermittent / sticky 404 on SearchTimeline and friends/list — the x-client-transaction-id animation key was missing X's frame_time rounding step, so on some Client sessions every strict request 404'd until the client was recreated. Restored, so the semi-random 404s are gone. (#357, #397)
  • KeyError on missing optional fields in User.__init__ and Client.request — defensive .get() parsing. (#417)
  • Empty user name / screen_name (e.g. in search results) — X moved name, screen_name, created_at, avatar, location, and more out of legacy into new sub-objects; these are now read with a legacy fallback.
  • get_tweet_by_id KeyError: 'itemContent' — handles both the legacy and the new trailing-cursor shapes. (#332, #363)
  • KeyError: 'entries' / IndexError on get_user_tweets for accounts with no visible tweets — empty / cursor-less timelines return an empty result instead of crashing. (#361, #216)
  • get_trends deprecated / returns nothing — rebuilt on top of GenericTimelineById; also adds get_explore_page(). (#389)
  • RecursionError on rate-limit — the 429 recovery path no longer recurses.
  • GuestClient.activate() 404 — the guest client now sends a User-Agent header and parses user fields defensively. (#402, #385)
  • get_latest_friends 404 — routed through the GraphQL Following endpoint after the v1.1 endpoint was retired. (#397)
  • 'Client' object has no attribute '_ui_metrix' — fixed the captcha unlock path. (#333)
  • get_bookmark_folders().next() infinite loop — fixed malformed pagination variables. (#334, #335)
  • get_latest_timeline / get_list_tweets dropping conversation entries — home- and list-conversation entries are now unpacked. (#336, #337, #340)
  • Media.source_url for the full-resolution image (#376), and Tweet.quoted_status_id for the quoted tweet id (#222).

Issues that stem from X-side restrictions (account suspension, Cloudflare/IP blocks, captcha, automation limits) aren't fixable in the library and are out of scope.

Browser TLS impersonation (optional)

Some X endpoints reject the default httpx TLS fingerprint with a 403 (HTML) response even when the request is valid. Installing the optional curl_cffi backend and passing impersonate= routes requests through a real browser TLS fingerprint, which avoids those 403s:

client = Client('en-US', impersonate='chrome124')

Quick start

Define a client and log in.

import asyncio
from twikit import Client

client = Client('en-US')

async def main():
    await client.login(
        auth_info_1='example_user',
        auth_info_2='email@example.com',
        password='password0000',
        cookies_file='cookies.json'
    )

asyncio.run(main())

Post a tweet with media attached.

media_ids = [
    await client.upload_media('media1.jpg'),
    await client.upload_media('media2.jpg'),
]
await client.create_tweet(text='Example Tweet', media_ids=media_ids)

Search the latest tweets for a keyword.

tweets = await client.search_tweet('python', 'Latest')
for tweet in tweets:
    print(tweet.user.name, tweet.text, tweet.created_at)

A few more common calls.

await client.get_user_tweets('123456', 'Tweets')   # a user's tweets
await client.send_dm('123456789', 'Hello')          # send a DM
await client.get_trends('trending')                 # trending topics

More examples (upstream, still apply): https://github.com/d60/twikit/tree/main/examples

Features

  • No API key — works by scraping the web client.
  • Free & open source (MIT).
  • Drop-in twikit replacement — same import, your code doesn't change.
  • Tweets, search, timelines, trends, users, DMs, media, bookmarks, and more.

Documentation

Full API reference (upstream — the package surface is the same): https://twikit.readthedocs.io/en/latest/twikit.html

Community

Discord

Contributing

Found a bug or have a fix? Open an issue or PR on twifork issues.

If twifork saved you a headache, consider leaving a ⭐.

Credits

twifork is a fork of d60/twikit by @d60 — all upstream credit goes to the original authors. Licensed under the MIT License.

Disclaimer

twifork is an independent, unofficial project. It is not affiliated with, endorsed by, or sponsored by X Corp. "X" and "Twitter" are trademarks of X Corp. Use it in accordance with applicable terms and laws.

Project details


Download files

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

Source Distribution

twifork-2.3.4.tar.gz (42.0 kB view details)

Uploaded Source

Built Distribution

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

twifork-2.3.4-py3-none-any.whl (53.7 kB view details)

Uploaded Python 3

File details

Details for the file twifork-2.3.4.tar.gz.

File metadata

  • Download URL: twifork-2.3.4.tar.gz
  • Upload date:
  • Size: 42.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for twifork-2.3.4.tar.gz
Algorithm Hash digest
SHA256 990c915a94b974413e78fa9062e0570455b726f697659345b07b6cb7b39297d5
MD5 34c8e1987eb4c48aa440688691cccb2a
BLAKE2b-256 891550324acd1635fdb086462619bf09d63b836e8107fdb77a91b5941c102173

See more details on using hashes here.

File details

Details for the file twifork-2.3.4-py3-none-any.whl.

File metadata

  • Download URL: twifork-2.3.4-py3-none-any.whl
  • Upload date:
  • Size: 53.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for twifork-2.3.4-py3-none-any.whl
Algorithm Hash digest
SHA256 326fead1526b0d71ab3023e71732e1ed63166e9bd32de9c13b400c87fa446546
MD5 04eed1cf36bb6100d105689b5230ec2b
BLAKE2b-256 06c0f6e7b3d0e5c3ed1017f708f3ff3be01f7f03c064580356fb3a41450a42bf

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 Pingdom Monitoring Sentry Error logging StatusPage Status page