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

Uploaded Python 3

File details

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

File metadata

  • Download URL: ariadne_x-0.5.0.tar.gz
  • Upload date:
  • Size: 89.3 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.0.tar.gz
Algorithm Hash digest
SHA256 91991a63153898410ed041cbc6e275f0cb4990ab61086b1a3d430daf84f66de9
MD5 9dad719f61042fd29f34d2d78b1d1e69
BLAKE2b-256 2b6e3bf3170e07d94ab5dca4470a9d3b49dab17f4a934fed269b0f80fe03f211

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: ariadne_x-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 65.5 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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c40e0787b7cabe58351e9de458feeb1e15c1b4baa8a718ddede5ee6e6e710a2a
MD5 c410862e0abd8dd5b1e20212c5e7be93
BLAKE2b-256 b504c004ce2681b2e3e509365f1785fa8cb5d7a6d06a3e335134e37c6b927302

See more details on using hashes here.

Provenance

The following attestation bundles were made for ariadne_x-0.5.0-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

0.5.1

2 files

This release

0.5.0 This release

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