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
  • Comments: create/update comments with rich text or inline markdown, plus delete support
  • Meeting notes: query AI meeting notes through blocks.meetingNotes.query()
  • Custom emojis: customEmojis.list() support
  • Pagination status: exposes request_status on list responses
  • 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.21.tar.gz (178.2 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.21-py3-none-any.whl (115.7 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for notion_py_client-0.1.21.tar.gz
Algorithm Hash digest
SHA256 97df073b70ed71a5dd26f78fc7604f94486a76236e79125a15c1d347dfb53b6b
MD5 e678f5e2d980c88d2c43ac90e855cf0e
BLAKE2b-256 7a2bbd03de4a90fce85cacb1c02982360bdd0e68fa1ec821c5260ef5cf17027e

See more details on using hashes here.

Provenance

The following attestation bundles were made for notion_py_client-0.1.21.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.21-py3-none-any.whl.

File metadata

File hashes

Hashes for notion_py_client-0.1.21-py3-none-any.whl
Algorithm Hash digest
SHA256 8665aef4be80e56d181cc79f6212e5c076059f5f654c3ac84ad06d318a800946
MD5 f702fcb1e5a5917dbc378bf2864f41c8
BLAKE2b-256 b556aa1724d32fd76b023bed92acbf7a6c825620bcfafb89b5acf7091f352514

See more details on using hashes here.

Provenance

The following attestation bundles were made for notion_py_client-0.1.21-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