Skip to main content

Export Notion pages and databases to Obsidian-friendly Markdown.

Project description

NoteShift (noteshift)

NoteShift exports Notion content to Obsidian-friendly Markdown with predictable filenames, link rewriting, and checkpoint/resume support.

CI PyPI Python Versions codecov

Why it exists

Teams migrating from Notion to Obsidian consistently report four pains:

  1. broken internal links after export
  2. inconsistent filenames and folder layout
  3. long exports failing midway without resume
  4. low confidence in migration correctness

NoteShift is focused on solving those pains first.

Current capabilities

  • Export a Notion page tree to Markdown
  • Export Notion data sources/databases through API layer
  • Rewrite internal links for Obsidian compatibility
  • Preserve and download attachments
  • Resume interrupted runs via checkpoint file
  • Emit migration report (migration_report.json + .md)
  • Optionally emit YAML frontmatter with Notion metadata in each exported page

Documentation

Installation

Install from PyPI

uv tool install noteshift
# or
pipx install noteshift

Install from source (development)

uv tool install .
uv sync --extra dev --extra test

Authentication

Set a Notion integration token in NOTION_TOKEN.

export NOTION_TOKEN="secret_xxx"

Basic usage

noteshift export \
  --page-id "<notion-page-id>" \
  --out ./export \
  --max-depth 2 \
  --overwrite

Frontmatter

Pass --frontmatter to include YAML frontmatter at the top of every exported markdown file:

noteshift export \
  --page-id "<notion-page-id>" \
  --out ./export \
  --frontmatter

Each index.md will begin with a block like:

---
notionId: "abc12345-..."
notionUrl: "https://www.notion.so/..."
createdAt: "2024-01-01T10:00:00.000Z"
updatedAt: "2024-06-15T14:30:00.000Z"
title: "My Page"
---

For pages that live inside a Notion database, supported property types are also included as additional keys (select, multi_select, date, checkbox, number, url, email, phone_number, rich_text). Property names are lowercased and spaces are replaced with underscores.

Frontmatter is off by default so existing exports are unaffected.

Output

A successful run writes:

  • Markdown files for exported pages
  • downloaded assets in the export tree
  • .checkpoint.json for resume
  • migration_report.json
  • migration_report.md

Development

uv sync --extra dev --extra test
uv run ruff format .
uv run ruff check .
uv run mypy src
uv run pytest --cov=noteshift --cov-report=term

Contract tests (pytest-vcr)

Contract tests are deterministic and replay HTTP traffic from sanitized cassettes:

uv run pytest -m contract

To re-record cassettes intentionally, set a real token in your environment and run:

VCR_RECORD_MODE=once uv run pytest -m contract

License

MIT

Project details


Download files

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

Source Distribution

noteshift-0.2.0.tar.gz (18.9 kB view details)

Uploaded Source

Built Distribution

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

noteshift-0.2.0-py3-none-any.whl (24.4 kB view details)

Uploaded Python 3

File details

Details for the file noteshift-0.2.0.tar.gz.

File metadata

  • Download URL: noteshift-0.2.0.tar.gz
  • Upload date:
  • Size: 18.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for noteshift-0.2.0.tar.gz
Algorithm Hash digest
SHA256 fdf31ad26ec947485f6b902365230d7b107b64928fdb6096668ae5445b6659fd
MD5 4234b17ade9b123f716aba267b26b783
BLAKE2b-256 1db5f9dce3c4c941560aef4cd7961ffff25e5cd26c1d05aa47fe9b8e1447f951

See more details on using hashes here.

Provenance

The following attestation bundles were made for noteshift-0.2.0.tar.gz:

Publisher: release.yml on Fragment256/noteshift

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

File details

Details for the file noteshift-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: noteshift-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 24.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for noteshift-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cede87a7170f24625235054be6ba210098f78fd2e38d6fd3276641250d71acb8
MD5 13518d6dd0f090f5dccd38df067e684e
BLAKE2b-256 3ef82e7e92d6647bb9f62eff3585b449b909162a4422e6e1fbbad9bbaf4ce193

See more details on using hashes here.

Provenance

The following attestation bundles were made for noteshift-0.2.0-py3-none-any.whl:

Publisher: release.yml on Fragment256/noteshift

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

Supported by

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