---
name: notionhelper
description: "Use for Python tasks that use the notionhelper package to work with the Notion API: authentication, NotionHelper or MLNotionHelper usage, Notion databases/data sources/pages, page markdown import/export/update, block appends, file uploads, Notion data source queries, pandas DataFrame conversion, retries, structured errors, or ML experiment tracking in Notion. Triggers: notionhelper, NotionHelper, MLNotionHelper, Notion API, data_source_id, get_page_markdown, update_page_markdown, append_page_body, new_page_to_data_source, Notion file uploads, Notion pandas dataframe."
---

# NotionHelper
This is a routing skill for using the `notionhelper` Python package with the Notion API.

## Workflow
```
Step 1: Locate the caller code and credentials pattern
    v
Step 2: Identify the Notion task and load the matching reference(s)
    v
Step 3: Use package helpers before raw HTTP
    v
Step 4: Validate with mocked tests or a dry-run shape check
```

### Step 1: Locate Caller Code
Skip this step if the target file is already clear.

Search for package usage:
```bash
rg -n "NotionHelper|MLNotionHelper|notionhelper|NOTION_TOKEN|data_source_id|database_id" .
```

Prefer the package API from `notionhelper` over hand-written `requests` calls. Use raw HTTP only for Notion endpoints not exposed by the package.

### Step 2: Route to References
Always read the relevant reference before coding.

| User Need | Reference to Read |
|-----------|-------------------|
| Setup, auth, token handling, package imports, ID extraction, and integration sharing assumptions | `references/setup-and-auth.md` |
| Databases, data sources, schemas, creating rows/pages, updating schemas, and the 2025-09-03 API split | `references/databases-data-sources-pages.md` |
| Reading page content, appending blocks, markdown-backed page creation, native markdown export/update, child page expansion, and markdown limitations | `references/markdown-and-content.md` |
| Uploading files, embedding images, attaching files to page body or Files & Media properties | `references/files-and-media.md` |
| Querying data sources, pagination, JSON rows, flattened records, pandas DataFrames, dates, and page IDs | `references/retrieval-and-dataframes.md` |
| Retry settings, timeouts, structured exceptions, debugging failed requests, and validation/rate-limit handling | `references/errors-retries-debugging.md` |
| ML experiment tracking, creating experiment databases, logging metrics, plots, and artifacts with `MLNotionHelper` | `references/ml-experiment-tracking.md` |

### Quick Defaults
- Initialize with `helper = NotionHelper(os.environ["NOTION_TOKEN"])`; never hard-code tokens.
- Use `database_id` only for database containers. Use `data_source_id` for schemas, queries, and creating pages in a table.
- Use `new_page_to_data_source(...)`, not older `new_page_to_db` naming.
- Use `get_page(..., return_markdown=True)` for normal markdown exports. Use `get_page_markdown(...)` only when native metadata such as `truncated` or `unknown_block_ids` is needed.
- Use `append_page_body(page_id, markdown_or_blocks)` for incremental content appends.
- Use `RetryPolicy` or constructor retry arguments for rate limits, 5xx responses, timeouts, and connection errors.
- Catch `AuthError`, `RateLimitError`, `NotFoundError`, `ValidationError`, `TimeoutError`, or `NotionAPIError` when user-facing behavior needs clear recovery.

### Step 3: Apply Package Patterns
Use compact, explicit examples. Keep Notion property payloads faithful to the API shape:

```python
import os
from notionhelper import NotionHelper

helper = NotionHelper(os.environ["NOTION_TOKEN"])

page = helper.new_page_to_data_source(
    data_source_id,
    {
        "Name": {"title": [{"text": {"content": "Roadmap review"}}]},
        "Status": {"select": {"name": "In Progress"}},
    },
    markdown="# Notes\n\n- Draft agenda\n- Invite reviewers",
)
```

### Step 4: Validate
Prefer mocked tests for package behavior and payload shapes. Do not call live Notion from tests unless the user explicitly requests an integration test and supplies safe credentials.

Useful checks:
```bash
python -m pytest tests
python -m pytest tests/test_append_and_requests.py tests/test_error_retry_and_streaming.py
```

When debugging a live failure, inspect the exception metadata (`status_code`, `request_path`, `notion_code`) and the Notion error message before changing payloads.
