Skip to main content

A Python client for Notion API

Project description

notion-py-client

A type-safe Python client library for the Notion API, built with Pydantic v2.

PyPI version Downloads Monthly Downloads Python Version License: MIT

Features

  • Type-Safe: Complete type definitions using Pydantic v2
  • Async-First: Built on httpx for async/await support
  • API 2026-03-11: Latest Notion API with position, in_trash, and meeting_notes
  • Comprehensive: All blocks, properties, filters, and request types
  • Domain Mapping: Built-in mapper for converting to domain models

Installation

pip install notion-py-client

Quick Start

import asyncio
from notion_py_client import NotionAsyncClient

async def main():
    client = NotionAsyncClient(auth="your_NOTION_API_TOKEN")

    # Query a data source (API 2026-03-11)
    response = await client.dataSources.query(
        data_source_id="your_data_source_id"
    )

    for page in response.results:
        print(page.id, page.properties)

asyncio.run(main())

Notion API 2026-03-11

This library supports the latest Notion API version 2026-03-11, including:

  • Current breaking changes: position, in_trash, and meeting_notes
  • Markdown APIs: create, read, and update page content as markdown
  • Custom emojis: customEmojis.list() support
  • DataSources: Continued support for the 2025-09-03 data model split

DataSources vs Databases

# New DataSources API (recommended)
await client.dataSources.query(data_source_id="...")

# Legacy Databases API (only for older Notion-Version headers)
await client.databases.query(database_id="...")

Both endpoints work identically, but dataSources is the future-proof choice.

Documentation

Full documentation is available at: https://higashi-masafumi.github.io/notion-py/

Core Capabilities

Pages

# Create a page
from notion_py_client.requests import CreatePageParameters, TitlePropertyRequest

await client.pages.create(
    params=CreatePageParameters(
        parent={"type": "data_source_id", "data_source_id": "your_data_source_id"},
        properties={
            "Name": TitlePropertyRequest(
                title=[{"type": "text", "text": {"content": "New Page"}}]
            )
        }
    )
)

Filters

from notion_py_client import NotionAsyncClient
from notion_py_client.filters import create_and_filter, create_or_filter

client = NotionAsyncClient(auth="your_NOTION_API_TOKEN")

# Simple filter (直接辞書 - IDE補完が効く)
response = await client.dataSources.query(
    data_source_id="your_data_source_id",
    filter={"property": "Status", "status": {"equals": "Active"}}
)

# AND filter with helper function (型安全 - IDE補完が効く)
filter = create_and_filter(
    {"property": "Name", "rich_text": {"contains": "urgent"}},
    {"property": "Status", "status": {"equals": "In Progress"}}
)

# OR filter with helper function
filter = create_or_filter(
    {"property": "Priority", "select": {"equals": "High"}},
    {"property": "Priority", "select": {"equals": "Medium"}}
)

# Nested filters (AND + OR)
filter = create_and_filter(
    {"property": "Team", "select": {"equals": "Engineering"}},
    create_or_filter(
        {"property": "Status", "status": {"equals": "Active"}},
        {"property": "Status", "status": {"equals": "Pending"}}
    )
)

await client.dataSources.query(
    data_source_id="your_data_source_id",
    filter=filter
)

Key Benefits:

  • IDE Completion: Type hints work correctly with dictionary literals
  • Type Safety: TypedDict definitions match official TypeScript SDK
  • No .model_dump(): Use filters directly without conversion
  • Public API Compatible: Follows official Notion API specification

Domain Mapping

from notion_py_client.helper import NotionMapper, NotionPropertyDescriptor, Field
from notion_py_client.requests.property_requests import (
    TitlePropertyRequest,
    StatusPropertyRequest,
)
from notion_py_client.responses.property_types import TitleProperty, StatusProperty
from pydantic import BaseModel

class Task(BaseModel):
    id: str
    name: str
    status: str

class TaskMapper(NotionMapper[Task]):
    # Define field descriptors with type annotations
    name_field: NotionPropertyDescriptor[TitleProperty, TitlePropertyRequest, str] = Field(
        notion_name="Name",
        parser=lambda p: p.title[0].plain_text if p.title else "",
        request_builder=lambda v: TitlePropertyRequest(
            title=[{"type": "text", "text": {"content": v}}]
        )
    )

    status_field: NotionPropertyDescriptor[StatusProperty, StatusPropertyRequest, str] = Field(
        notion_name="Status",
        parser=lambda p: p.status.name if p.status else "",
        request_builder=lambda v: StatusPropertyRequest(
            status={"name": v}
        )
    )

    def to_domain(self, notion_page):
        """Convert Notion page to domain model."""
        props = notion_page.properties
        return Task(
            id=notion_page.id,
            name=self.name_field.parse(props["Name"]),
            status=self.status_field.parse(props["Status"]),
        )

# Use the mapper
mapper = TaskMapper()
tasks = [mapper.to_domain(page) for page in response.results]

Requirements

  • Python >= 3.10
  • Pydantic >= 2.11.10

License

MIT License - see LICENSE for details.

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

notion_py_client-0.1.20.tar.gz (172.6 kB view details)

Uploaded Source

Built Distribution

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

notion_py_client-0.1.20-py3-none-any.whl (112.9 kB view details)

Uploaded Python 3

File details

Details for the file notion_py_client-0.1.20.tar.gz.

File metadata

  • Download URL: notion_py_client-0.1.20.tar.gz
  • Upload date:
  • Size: 172.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for notion_py_client-0.1.20.tar.gz
Algorithm Hash digest
SHA256 8a87bc333d8373d78efeec473c5a65e60a3689ccfddbe847b73f4d9adda35769
MD5 fc86192901cb70197a6e3ed785f3d9bc
BLAKE2b-256 19f398bc28d456e3472455f436987953d681d2bc7839e536b35b3d92cf024890

See more details on using hashes here.

Provenance

The following attestation bundles were made for notion_py_client-0.1.20.tar.gz:

Publisher: publish-to-pypi.yml on Higashi-Masafumi/notion-py

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

File details

Details for the file notion_py_client-0.1.20-py3-none-any.whl.

File metadata

File hashes

Hashes for notion_py_client-0.1.20-py3-none-any.whl
Algorithm Hash digest
SHA256 1ff28fdb089283e1000993feace5041e24bf7b2edab65fbc6dd55ed25228e72c
MD5 11d9a8835906eadba89b5ae554e68a06
BLAKE2b-256 b325980041ab9fca14ae6da943d39d09ec96ec6e94feaf34115f13748d7980c4

See more details on using hashes here.

Provenance

The following attestation bundles were made for notion_py_client-0.1.20-py3-none-any.whl:

Publisher: publish-to-pypi.yml on Higashi-Masafumi/notion-py

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