Skip to main content

A golden conversation thread crossing several archives

⌇ ariadne

Find the conversation.
Turn scattered X/Twitter archives and tweet datasets into readable, attributable reply branches.

documentation · PyPI · Python API · MIT


A social export remembers posts. The conversation around them is often somewhere else: a parent in another archive, a quote in a community dataset, an older post in the cache.

Ariadne merges those sources, selects the posts you care about, follows every known reply-parent chain toward its root, attaches quote context, and renders the result root → target.

It does not pretend sparse data is complete. Missing posts stay visible as placeholders and warnings unless you ask for --strict.

Start here

Requires Python 3.11 or newer. The distribution is ariadne-x; the command and import are both ariadne.

uv tool install ariadne-x
ariadne interactive

Or build directly from a personal archive:

ariadne build \
  --archive ~/Downloads/twitter-archive.zip \
  --for-user alice \
  --since 2024-01-01 \
  --format markdown \
  --output conversations.md

That is the whole basic loop:

archives + dumps + cache
          ↓
     choose targets
          ↓
follow known parent IDs
          ↓
 quotes + root-to-target branches

Choose your path

You have… Use…
One X/Twitter export ariadne build --archive PATH …
CSV, JSON, JSONL, or NDJSON ariadne build --tweets-file PATH …
Tweet IDs or X URLs Pass them after ariadne build
Archives you will reuse ariadne dumps import PATH
A public X account ariadne build --target-user USER …
A Bluesky handle ariadne bluesky HANDLE …

Imported archives form a local, searchable library:

ariadne dumps import ~/Downloads/twitter-archive.zip --name personal
ariadne dumps search "remembered phrase" --user alice
ariadne dumps show https://x.com/alice/status/1234567890123456789

# Imported dumps join ordinary builds automatically.
ariadne build --for-user alice --since 2024-01-01 --format raft -o alice.jsonl

Each import becomes a self-contained SQLite database under ~/.ariadne/dumps. The source is never modified, and removing an import never removes the source. Parquet imports additionally need DuckDB:

uv tool install 'ariadne-x[parquet]'

Read the archive library guide →

From Python

The CLI is a thin front end over a typed synchronous API:

from pathlib import Path
import ariadne

options = ariadne.BuildOptions(
    archive=Path.home() / "Downloads" / "twitter-archive.zip",
    for_user="alice",
    since="2024-01-01",
)

result = ariadne.build(options)

for conversation in result:
    print(conversation.target_id)

documents = result.raft_documents()
result.save("out/branches.jsonl", "raft")

Use no_dumps=True when a build must ignore the persistent archive library. Named failures derive from AriadneError, including ConfigurationError, NoTargetsError, ReconstructionError, and SourceError.

Read the Python API reference →

Pick an output

Format Shape Good for
messages enriched JSON conversations chat-like data with tweet metadata; the CLI default
openai reduced JSON conversations nested role, name, and content messages
json normalized graph + tweets analysis, provenance, and custom rendering
markdown text humans, notebooks, and review
raft one JSON object per line retrieval, chunking, and embedding

The openai renderer keeps Ariadne's conversation envelope; consumers extract conversations[i].messages. Role names describe position in the branch, not the speaker's intent.

Inspect the schemas →

What Ariadne follows

  • One target's ancestor path back to its root—not sibling replies or a whole tree.
  • Older parents even when --since limits the starting targets.
  • Reply and quote edges across different imported dumps.
  • Quote context, with root quote-tweets spliced onto their quoted post by default.

Ordinary archive builds stay local. --target-user is the convenience exception: it tries unofficial RSS and oEmbed unless disabled. Those sources can recover recent text but usually cannot prove reply edges. X API reads are separately opt-in through --fetch and --fetch-user-timeline and may be billable.

Read the source and network policy →

A few useful commands

ariadne inspect-archive ~/Downloads/twitter-archive.zip
ariadne dumps interactive
ariadne build --help

# Bluesky uses its public API and the same renderers.
ariadne bluesky alice.bsky.social --since 2024-01-01 --format raft

Reference

Development

uv sync --extra dev --extra parquet
uv run pytest
uv run ruff check .
uv run mypy src

MIT licensed. The thread was there all along.

Download files

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

Source Distribution

ariadne_x-0.5.1.tar.gz (89.8 kB view details)

Uploaded Source

Built Distribution

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

ariadne_x-0.5.1-py3-none-any.whl (65.7 kB view details)

Uploaded Python 3

File details

Details for the file ariadne_x-0.5.1.tar.gz.

File metadata

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

File hashes

Hashes for ariadne_x-0.5.1.tar.gz
Algorithm Hash digest
SHA256 32e33dc93750eeac6612a9baf84fd8bf737c151fea794b723008b502ae0e27f2
MD5 88a53fd38370a376a4a02283a494f269
BLAKE2b-256 42a18642446c562af7159ce3e16d3bf6114442731b214f3a080785b4cc900a14

See more details on using hashes here.

Provenance

The following attestation bundles were made for ariadne_x-0.5.1.tar.gz:

Publisher: publish.yml on lumpenspace/ariadne

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

File details

Details for the file ariadne_x-0.5.1-py3-none-any.whl.

File metadata

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

File hashes

Hashes for ariadne_x-0.5.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b60bcbf731faaa8975a963893c76ebdc0618b38659e41a73e48ad321823c2978
MD5 1930d5ef85358ce478520f43435eb034
BLAKE2b-256 9289ed992cfd42f88d56cd20235660e93e80daff49e51bc93527bb636a2d525a

See more details on using hashes here.

Provenance

The following attestation bundles were made for ariadne_x-0.5.1-py3-none-any.whl:

Publisher: publish.yml on lumpenspace/ariadne

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

Release history Release notifications | RSS feed

0.6.0

2 files

This release

0.5.1 This release

2 files

0.5.0

2 files

Supported by

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