Upload local Zotero PDFs to matching Notion pages managed by Notero
Project description
NoteroPDF
NoteroPDF adds your local Zotero PDF files to the matching pages in a Notion database managed by Notero.
Use it if you already sync Zotero items to Notion with Notero and want the actual PDF files to appear in a Notion files property, usually named PDF.
NoteroPDF is preview-first. It reads from Zotero, shows what would change, and only updates Notion after you turn preview mode off.
What You Need
- Zotero installed on your computer
- a local personal Zotero library
- Notero already syncing Zotero items to a Notion database
- Python 3.10, 3.11, 3.12, or 3.13 for the PyPI install
- a Notion integration token
- your Notion database shared with that integration
- a Notion files property for PDFs, usually named
PDF
Supports Windows, macOS, and Linux. Zotero group libraries are not supported yet.
Quick Start
- Install NoteroPDF:
python -m pip install noteropdf
- Run the guided setup:
noteropdf setup
- Check that Zotero and Notion are connected:
noteropdf doctor
- Preview the first sync:
noteropdf sync
- If the preview looks right, open
config.yamland change:
dry_run: true
to:
dry_run: false
- Run the real sync:
noteropdf sync
After that, run noteropdf sync whenever you want to update Notion with PDFs from Zotero.
Useful Commands
| Command | What it does |
|---|---|
noteropdf setup |
Creates config.yaml with guided prompts. |
noteropdf doctor |
Checks Zotero, Notion, config, logs, and reports. |
noteropdf sync |
Uploads missing or changed PDFs. Respects dry_run in config.yaml. |
noteropdf sync --force |
Re-uploads PDFs even when they appear unchanged. |
noteropdf cleanup |
Previews stale or duplicate Notion rows. |
noteropdf cleanup --apply |
Moves strongly classified cleanup rows to Notion trash after confirmation. |
What Changes
synconly updates the configured Notion files property, usuallyPDF.cleanup --applyonly moves strongly classified stale or duplicate rows to Notion trash.- Unclear matches are skipped for manual review.
- Zotero is never modified.
Common Problems
| Message | What to check |
|---|---|
NOTION_AUTH_ERROR |
Check your Notion token and make sure the database is shared with the integration. |
NOTION_SCHEMA_ERROR |
Check the Notion database properties, especially the PDF files property. |
NO_NOTION_MATCH |
The Zotero item could not be matched to a Notion row. |
MULTIPLE_NOTION_MATCHES |
More than one Notion row matched the same Zotero item. |
NO_PDF |
The Zotero item does not have a PDF attachment. |
MULTIPLE_PDFS |
The Zotero item has more than one PDF attachment. |
FILE_TOO_LARGE |
The PDF is larger than Notion accepts for your workspace. |
For more detail, rerun the command with --verbose:
noteropdf --verbose sync
NoteroPDF also writes logs and reports after each run. The terminal output shows where those files are saved.
Install Options
Upgrade from PyPI
python -m pip install --upgrade noteropdf
App Bundle
If you do not want to install with Python, download a bundle from the releases page, extract it, and run the included noteropdf program.
On macOS, if the downloaded app is blocked, this may help:
xattr -dr com.apple.quarantine /path/to/noteropdf
Source Install
Use this if you want to install from a local checkout.
python -m venv .venv
# Windows PowerShell
.venv\Scripts\Activate.ps1
# macOS/Linux
source .venv/bin/activate
python -m pip install -U pip
python -m pip install .
python -m noteropdf setup
Details
Matching
NoteroPDF matches Zotero items to Notion rows in this order:
- Notero page link
- Zotero URI
- DOI
An item must have exactly one usable PDF attachment. If the match or PDF choice is unclear, the item is skipped.
Uploads and Reports
- Files up to 20 MB use Notion's normal upload flow.
- Larger files use Notion multi-part upload when the workspace supports it.
- Files over the workspace upload limit are skipped.
- Each run writes a log, JSON report, CSV report, and summary JSON file.
Development
Most users do not need this section.
python -m venv .venv
# Windows PowerShell
.venv\Scripts\Activate.ps1
# macOS/Linux
source .venv/bin/activate
python -m pip install -U pip
python -m pip install -e ".[dev]"
Additional project docs:
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 noteropdf-0.3.1.tar.gz.
File metadata
- Download URL: noteropdf-0.3.1.tar.gz
- Upload date:
- Size: 50.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f8694ff2e092537e431c6e41e659223e1bdf3ef31aae5b89a3ab23651a212bec
|
|
| MD5 |
45220bd775c6b05c943e6646de15854f
|
|
| BLAKE2b-256 |
9f77b0f17f14cd0a1c1c9a4173a210106cea44156576c3af0a7e7dca27f7e97d
|
Provenance
The following attestation bundles were made for noteropdf-0.3.1.tar.gz:
Publisher:
release.yml on diyanko/NoteroPDF
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
noteropdf-0.3.1.tar.gz -
Subject digest:
f8694ff2e092537e431c6e41e659223e1bdf3ef31aae5b89a3ab23651a212bec - Sigstore transparency entry: 1547272943
- Sigstore integration time:
-
Permalink:
diyanko/NoteroPDF@2bfe482d4fa43a1c1d3e46bc936ffa2aa66f2e3b -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/diyanko
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2bfe482d4fa43a1c1d3e46bc936ffa2aa66f2e3b -
Trigger Event:
push
-
Statement type:
File details
Details for the file noteropdf-0.3.1-py3-none-any.whl.
File metadata
- Download URL: noteropdf-0.3.1-py3-none-any.whl
- Upload date:
- Size: 38.8 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 |
f4e2389b42206eee9d4fe4cf686066cc9d5bbc268c94a68935258d7b71e9e1c5
|
|
| MD5 |
213d573094ef7963d80c442c0475bbcb
|
|
| BLAKE2b-256 |
514d243b779ebedf4dfe5dc615c966a5651003348ca179a45f0f7a4ebd726357
|
Provenance
The following attestation bundles were made for noteropdf-0.3.1-py3-none-any.whl:
Publisher:
release.yml on diyanko/NoteroPDF
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
noteropdf-0.3.1-py3-none-any.whl -
Subject digest:
f4e2389b42206eee9d4fe4cf686066cc9d5bbc268c94a68935258d7b71e9e1c5 - Sigstore transparency entry: 1547272968
- Sigstore integration time:
-
Permalink:
diyanko/NoteroPDF@2bfe482d4fa43a1c1d3e46bc936ffa2aa66f2e3b -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/diyanko
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2bfe482d4fa43a1c1d3e46bc936ffa2aa66f2e3b -
Trigger Event:
push
-
Statement type: