⌇ 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.
What Ariadne follows
- One target's ancestor path back to its root—not sibling replies or a whole tree.
- Older parents even when
--sincelimits 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
- Documentation site
- Persistent archive library
- Python API
- Source behavior
- Output schemas
- Raft handoff
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
91991a63153898410ed041cbc6e275f0cb4990ab61086b1a3d430daf84f66de9
|
|
| MD5 |
9dad719f61042fd29f34d2d78b1d1e69
|
|
| BLAKE2b-256 |
2b6e3bf3170e07d94ab5dca4470a9d3b49dab17f4a934fed269b0f80fe03f211
|
Provenance
The following attestation bundles were made for ariadne_x-0.5.0.tar.gz:
Publisher:
publish.yml on lumpenspace/ariadne
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ariadne_x-0.5.0.tar.gz -
Subject digest:
91991a63153898410ed041cbc6e275f0cb4990ab61086b1a3d430daf84f66de9 - Sigstore transparency entry: 2549268944
- Sigstore integration time:
-
Permalink:
lumpenspace/ariadne@12d2a6f5074e7dc2b70e9d9782a4a6346ce38bd1 -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/lumpenspace
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@12d2a6f5074e7dc2b70e9d9782a4a6346ce38bd1 -
Trigger Event:
release
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c40e0787b7cabe58351e9de458feeb1e15c1b4baa8a718ddede5ee6e6e710a2a
|
|
| MD5 |
c410862e0abd8dd5b1e20212c5e7be93
|
|
| BLAKE2b-256 |
b504c004ce2681b2e3e509365f1785fa8cb5d7a6d06a3e335134e37c6b927302
|
Provenance
The following attestation bundles were made for ariadne_x-0.5.0-py3-none-any.whl:
Publisher:
publish.yml on lumpenspace/ariadne
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ariadne_x-0.5.0-py3-none-any.whl -
Subject digest:
c40e0787b7cabe58351e9de458feeb1e15c1b4baa8a718ddede5ee6e6e710a2a - Sigstore transparency entry: 2549268970
- Sigstore integration time:
-
Permalink:
lumpenspace/ariadne@12d2a6f5074e7dc2b70e9d9782a4a6346ce38bd1 -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/lumpenspace
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@12d2a6f5074e7dc2b70e9d9782a4a6346ce38bd1 -
Trigger Event:
release
-
Statement type: