No description
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-10-11 13:32:27 +02:00
humanizer initial commit 2026-10-11 13:32:27 +02:00
tests initial commit 2026-10-11 13:32:27 +02:00
.gitignore initial commit 2026-10-11 13:32:27 +02:00
README.md initial commit 2026-10-11 13:32:27 +02:00

ChatGPT-Export-humanizer

Turn a ChatGPT data export into a browsable static website: one directory per chat with images inlined, and a searchable index page at the top level.

No dependencies beyond the Python 3.10+ standard library.

What it does

Given an unpacked ChatGPT export directory (the folder containing conversations-*.json, conversation_asset_file_names.json and a pile of file-*.dat blobs), it produces:

sites/
├── index.html              # searchable list of every conversation
├── identify-edible-mushroom/
│   ├── index.html          # the chat, rendered as HTML
│   └── assets/
│       └── untitled.jpg    # images/files referenced by this chat
├── ipv6-intro-presentation/
│   └── ...
└── ...

Each chat page is self-contained (styles are inlined), and every generated page links back to the index.

Usage

# Generate a site from an export directory
python3 -m humanizer /path/to/chatgpt-export -o sites --title "My ChatGPT Archive"

# Just see what is inside an export
python3 -m humanizer /path/to/chatgpt-export --list

# Only render the 20 most recently updated conversations
python3 -m humanizer /path/to/chatgpt-export -o sites --limit 20

Then open sites/index.html in a browser. Because it is plain static files, you can also serve it with any web server, e.g.:

python3 -m http.server 8000 --directory sites

Options

Option Description
export_dir Path to the unpacked export directory (required).
-o, --output Output directory (default: sites).
--title Title shown on the index page (default: ChatGPT Export).
--no-clean Keep the existing output directory instead of replacing it.
--list Print the conversations found and exit.
--limit N Only process the first N conversations (newest first).

How it handles an export

  • Conversation branches. ChatGPT stores each chat as a tree of nodes; edits and regenerations create sibling branches. The tool reconstructs the exact branch that is active in the export (current_node), matching what the ChatGPT UI shows.
  • Split exports. All conversations-*.json files are read and merged.
  • Images and files. Messages reference blobs as file-service://file-… (or via attachment metadata). The tool resolves those to the file-….dat blobs, recovers the original extension from conversation_asset_file_names.json (falling back to sniffing the file's magic bytes), and copies them next to each chat's page. Images render inline; other attachments (PDFs, text, …) become download links.
  • Markdown. Assistant/user text is ChatGPT-style Markdown, rendered by a small built-in renderer (headings, emphasis, code, lists, tables, quotes, links). All HTML is escaped, so untrusted export content cannot inject script.
  • Citations. ChatGPT's hidden citation control characters are stripped.

Referenced blobs that are absent from the export are shown as a small missing attachment placeholder and counted in the summary.

Development

python3 -m unittest discover -s tests

The package layout:

File Responsibility
humanizer/export.py Load and normalise an export directory.
humanizer/markdown.py Dependency-free Markdown → HTML.
humanizer/render.py Build the HTML pages and copy assets.
humanizer/cli.py Command-line interface.