Export a Confluence space to PDF/DOCX/Markdown/HTML with attachments, merging, and an interactive UI.
Project description
Confluence Exporter
Export an entire Confluence space to PDF, DOCX, Markdown or HTML โ with attachments embedded, optional consolidated volumes, and an interactive terminal UI.
Built for teams that need to archive, migrate, or feed their wiki into an LLM (NotebookLM, RAG pipelines, LLM fine-tuning). The tool produces clean, self-contained PDFs with embedded images and merged attachment appendices โ no missing links, no 0 KB files, no orphaned binary blobs.
Highlights
- ๐ Three auth strategies: API token (Basic), Personal Access Token (Bearer), or browser-cookie paste โ works on SSO-locked tenants where API tokens are disabled. Cookie parser is generic: paste the full
Cookie:header from DevTools and any session-cookie name (cloud.session.token,tenant.session.token, โฆ) works. - ๐จ๏ธ Pluggable PDF engines with automatic fallback: Playwright โ WeasyPrint โ xhtml2pdf. Pick one explicitly or let the tool auto-detect the best one you have installed.
- ๐ Attachments really embedded: PDFs get merged as appendix pages into each document; images are inlined; others are listed with links.
- ๐ Consolidated volumes: merge the per-page PDFs of a space into a few big PDFs with a generated Table of Contents and a hierarchical PDF bookmark outline โ upload-ready for NotebookLM.
- ๐ช Windows long-path safe: deep Confluence hierarchies that exceed
MAX_PATH(260 chars) are handled via\\?\prefixing and a_flatfallback bucket. - โก Resumable: a per-space lockfile skips pages that haven't changed, so re-runs take seconds.
- ๐จ Nice terminal UI: colored prompts, progress bars, summary tables (powered by Rich + Typer).
Installation
pip install confluence-space-exporter
For best-quality PDFs (recommended), also install Playwright:
pip install "confluence-space-exporter[playwright]"
playwright install chromium
All engines in one shot:
pip install "confluence-space-exporter[all]"
playwright install chromium
Requires Python 3.10+.
Three ways to use it
The same codebase ships with three entry surfaces โ the business logic lives in the library; CLI and GUI are thin adapters on top.
| Mode | When to use it | Launch |
|---|---|---|
| ๐ฑ๏ธ Desktop app | Prefer a window with forms, file pickers and a live log pane | confluence-exporter-gui (alias: cfx-gui) |
| ๐ป CLI / TUI | SSH sessions, scripts, CI pipelines, or a rich terminal UI | confluence-exporter (alias: cfx) |
| ๐ฆ Library | Embed the export inside your own Python code / data pipeline | from confluence_exporter import SpaceExporter, โฆ |
Desktop app
confluence-exporter-gui
A Tkinter window with tabs for Connection โ Export โ Convert โ Merge โ Diagnose, a progress bar, and a live log pane. All long tasks run on a background thread so the UI stays responsive. No extra dependencies โ Tkinter ships with Python. (On some Linux distros you may need sudo apt install python3-tk.)
The status bar has a โน Stop button that cancels the current task gracefully โ the runner finishes the page it's on, saves the lockfile, and shuts down cleanly (no torn HTTP connections, no half-written PDFs). Run buttons disable while a task is running and re-enable when it finishes or cancels. Window geometry is remembered between sessions in ~/.confluence-exporter-gui.json.
The Connection tab shows a welcome banner while config is incomplete (it disappears once you've set base URL + space key + credentials), and the cookie textbox parses cookies live as you paste โ you'll see "โ 12 cookie(s) parsed โ session token: cloud.session.token" before you even click Test connection.
CLI
# Interactive menu (recommended first run)
confluence-exporter
# Short alias
cfx
The tool walks you through auth setup, target space, and format, and saves your choices to config.json. Subsequent runs re-use it.
Non-interactive / scripted:
cfx export --space MYKEY --format pdf --output ./out -y
cfx convert ./out --engine playwright --merge -y
cfx merge ./out_converted ./out_volumes --mode per_section -y
cfx diagnose # check installed engines + credentials
cfx init-config # edit / (re)create config.json
Press Ctrl+C during an export to cancel gracefully โ the current page finishes, the lockfile is saved, and the next run picks up where you left off.
Run cfx <command> --help for all options.
Library
from pathlib import Path
from confluence_exporter import (
AppConfig, ConfluenceClient, SpaceExporter, OutputConverter, PDFMerger,
)
cfg = AppConfig()
cfg.confluence.base_url = "https://your-tenant.atlassian.net"
cfg.confluence.space_key = "ABC"
cfg.confluence.auth_mode = "api_token"
cfg.confluence.email = "you@example.com"
cfg.confluence.api_token = "โฆ"
client = ConfluenceClient.from_config(cfg.confluence)
SpaceExporter(cfg, client).run()
OutputConverter(
output_root=Path(cfg.export.output_path),
target_format="pdf",
engine="auto",
).run()
PDFMerger(
source_root=Path(cfg.export.output_path + "_converted"),
dest_root=Path("./volumes"),
mode="per_section",
).run()
A full worked example โ including progress callbacks and all three auth modes โ is in examples/use_as_library.py.
Programmatic cancellation โ pass any threading.Event and set it from another thread (or a signal handler) to bail out gracefully:
import threading
cancel = threading.Event()
# Cancel after 30s if it isn't done by then
threading.Timer(30, cancel.set).start()
SpaceExporter(cfg, client, cancel_event=cancel).run()
# OutputConverter(..., cancel_event=cancel)
# PDFMerger(..., cancel_event=cancel)
Cancellation is cooperative: the runner checks the event between pages/files/groups and stops cleanly โ no torn HTTP requests, no half-written PDFs.
Three modes, end to end
1. Export โ download a Confluence space
cfx export
Writes pages + attachments to the output folder:
output/
โโโ MySpace/
โโโ Overview/
โ โโโ Introduction.html
โ โโโ Architecture.html
โโโ attachments/
โ โโโ Introduction/
โ โ โโโ diagram.png
โ โโโ _flat/
โ โโโ 12345_long-attachment-name.pdf
โโโ _flat/ # pages whose path was too long for Windows
โโโ Nested_Deep_Page_9999.html
Incremental updates
Re-running export is safe and fast: it compares the live Confluence space against the per-space lockfile and only downloads what actually changed. Each page falls into one of four buckets:
| State | Meaning | Action |
|---|---|---|
| NEW | Page exists in Confluence, not in the lockfile | Download |
| UPDATED | Newer version on Confluence (or local file is missing) | Re-download |
| UNCHANGED | Same version, file still on disk | Skip |
| DELETED-UPSTREAM | In the lockfile but no longer in Confluence | Optionally remove (cleanup_stale: true) |
To preview what an export would do โ without downloading anything โ use the status command:
cfx status # summary only
cfx status --titles # also list the actual page titles
cfx status --titles -n 50 # bump the per-bucket cap from 20 to 50
Sample output:
Diff
โโโโโโโโโโโโโโโโโโโโโโโโโณโโโโโโโ
โ Status โ # โ
โกโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฉ
โ New โ 3 โ
โ Updated โ 12 โ
โ Unchanged โ 247 โ
โ Deleted upstream โ 1 โ
โ Total in Confluence โ 262 โ
โโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโ
โ Running export would download 3 new + 12 updated page(s).
The GUI exposes the same thing as a "๐ Check status" button on the Export tab.
Tip: if you delete a PDF on disk, the next run notices and re-downloads it (the lockfile alone isn't trusted โ we also check the file is actually there).
2. Convert โ HTML โ PDF / DOCX with embedded attachments
cfx convert ./output
Produces ./output_converted/ mirroring the source tree. Each PDF has its page's PDF attachments merged as appendix pages. The conversion tolerates deep Windows paths (renders via %TEMP% and moves into place) and validates every output via magic-byte + size checks โ no 0 KB files slip through.
3. Merge โ consolidated volumes for NotebookLM / archival
cfx merge ./output_converted ./output_volumes
Three grouping modes:
| Mode | Output | Best for |
|---|---|---|
per_section |
One PDF per top-level folder of each space | NotebookLM sources (smaller, focused) |
per_space |
One PDF per Confluence space | Sharing a whole space as a single file |
single |
One PDF for everything | Archival / grep-friendly single file |
Each volume contains a generated Table of Contents page (page numbers + nesting) and a PDF outline that every reader (Acrobat, Edge, Chrome, Foxitโฆ) shows as a navigation sidebar.
Authentication
Option 1 โ Atlassian API token (easiest, if your admin allows it)
"auth_mode": "api_token",
"email": "you@company.com",
"api_token": "ATATT3xโฆ"
Get a token at https://id.atlassian.com/manage-profile/security/api-tokens.
Option 2 โ Browser cookie (for SSO-only tenants)
"auth_mode": "browser_cookie",
"cookies": {
"cloud.session.token": "eyJโฆ",
"atlassian.xsrf.token": "โฆ"
}
Easiest way to set this up:
cfx init-config # or choose menu option 5
The tool walks you through copying the full Cookie: header from DevTools โ it then parses and forwards every cookie the browser would send, so it doesn't matter whether your tenant uses cloud.session.token, tenant.session.token, JSESSIONID or something else.
Option 3 โ Personal Access Token (Server / Data Center)
"auth_mode": "pat",
"personal_access_token": "NjAxMโฆ"
Sent as Authorization: Bearer โฆ.
Configuration
A full config.json looks like examples/config.example.json. All fields have sane defaults and are overridable via CLI flags.
Keys starting with _ are treated as inline documentation and ignored at load time.
Standalone executable (no Python required for end users)
If you want to ship a double-clickable .exe / .app for users who don't have Python installed, bundle it with PyInstaller:
pip install "confluence-space-exporter[all]" pyinstaller
# Windows / macOS / Linux (run on the target OS):
pyinstaller --name ConfluenceExporter --windowed --onefile ^
--collect-all confluence_exporter ^
-m confluence_exporter.gui
The resulting dist/ConfluenceExporter.exe (or .app on macOS) embeds Python and all dependencies. For the Playwright engine specifically, Chromium binaries are large and best installed separately after first launch โ in a bundled build, prefer weasyprint or xhtml2pdf out of the box.
Troubleshooting
| Symptom | Likely cause / fix |
|---|---|
HTTP 401 Unauthorized |
API token disabled by admin โ switch to browser_cookie mode. |
HTTP 403 Forbidden when exporting PDFs |
Confluence's native PDF endpoint is disabled; the tool will fall through to local rendering automatically. |
Playwright Chromium binary not installed |
python -m playwright install chromium. |
[Errno 2] No such file or directory (Windows) |
Path exceeds MAX_PATH. The tool falls back to _flat/ automatically โ enable it in your run. |
| 0 KB PDFs | The older engine couldn't render a page. Install Playwright and rerun: cfx convert --engine playwright. |
Run cfx diagnose any time to see what's installed and confirm your credentials.
Contributing
See CONTRIBUTING.md. PRs welcome!
License
MIT โ see LICENSE.
Project details
Release history Release notifications | RSS feed
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 confluence_space_exporter-0.1.0.tar.gz.
File metadata
- Download URL: confluence_space_exporter-0.1.0.tar.gz
- Upload date:
- Size: 59.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3465489919ea73331f3bfa00c0d5e5585c9f5c63bf3c0547187c1b7caa1aa09e
|
|
| MD5 |
4dd968ba5dc089fbe71633407b34f24c
|
|
| BLAKE2b-256 |
5f8f49b4ceb221ba9f3affae056ba16b282928c5f591567146ce6c2651e8f919
|
Provenance
The following attestation bundles were made for confluence_space_exporter-0.1.0.tar.gz:
Publisher:
publish.yml on LeoChi/confluence-exporter
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
confluence_space_exporter-0.1.0.tar.gz -
Subject digest:
3465489919ea73331f3bfa00c0d5e5585c9f5c63bf3c0547187c1b7caa1aa09e - Sigstore transparency entry: 1915275539
- Sigstore integration time:
-
Permalink:
LeoChi/confluence-exporter@f10f0822a208f6a299056a7a46bab5335f1c27cb -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/LeoChi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f10f0822a208f6a299056a7a46bab5335f1c27cb -
Trigger Event:
push
-
Statement type:
File details
Details for the file confluence_space_exporter-0.1.0-py3-none-any.whl.
File metadata
- Download URL: confluence_space_exporter-0.1.0-py3-none-any.whl
- Upload date:
- Size: 60.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
979878057a938bc07591636e30e1c0a85040c45e9601facf5c3e6716f39c63c3
|
|
| MD5 |
90bb34853be46e7a307ea4dead5296f3
|
|
| BLAKE2b-256 |
6b70064ff063049b0aef6205fbbf8605b85aead811ce52cfd2dc16d1add2c600
|
Provenance
The following attestation bundles were made for confluence_space_exporter-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on LeoChi/confluence-exporter
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
confluence_space_exporter-0.1.0-py3-none-any.whl -
Subject digest:
979878057a938bc07591636e30e1c0a85040c45e9601facf5c3e6716f39c63c3 - Sigstore transparency entry: 1915275629
- Sigstore integration time:
-
Permalink:
LeoChi/confluence-exporter@f10f0822a208f6a299056a7a46bab5335f1c27cb -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/LeoChi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f10f0822a208f6a299056a7a46bab5335f1c27cb -
Trigger Event:
push
-
Statement type: