altvod / basic-notion

Client-agnostic model wrapper for Notion API
MIT License
7 stars 1 forks source link

type object 'PageBlock' has no attribute 'BLOCK_TYPE_STR'. Did you mean: 'OBJECT_TYPE_STR'? #3

Open vispar-tech opened 2 years ago

vispar-tech commented 2 years ago

how to fix it?

i tried to put page to the table with to do blocks

from notion_client import Client
from basic_notion.query import Query
from basic_notion.page import NotionPage, NotionPageList
from basic_notion.block import NotionBlock, ToDoBlock, TextListField
from basic_notion.field import SelectField, TitleField, MultiSelectField, UrlField

class PageBlock(NotionBlock):
    to_do = ToDoBlock()

class MyRow(NotionPage):
    name = TitleField(property_name='Задача | Проект')
    doing = SelectField(property_name='Выполнение')
    tags = MultiSelectField(property_name='Tags')
    link = UrlField(property_name='Ссылка')

class MyData(NotionPageList[MyRow]):
    ITEM_CLS = MyRow

def get_data(database_id: str) -> MyData:
    client = Client(auth=NOTION_TOKEN)
    data = client.databases.query(
        **Query(database_id=database_id).filter(
            MyRow.name.filter.is_not_empty(True)
        ).serialize()
    )
    return MyData(data=data)

def create_page(database_id: str) -> MyRow:
    client = Client(auth=NOTION_TOKEN)
    page = MyRow.make(
        parent={'database_id': database_id},
        children = PageBlock.make(
            to_do = 'Сделать тест'
        ),
        name = ['TestPage'],
        doing = 'Слежу',
        tags = ['На проверке'],
        link = 'wildberries.com'
    )
    response = client.pages.create(**page.data)
    item = MyRow(data=response)
    return item

create_page(DATABASE_ID)
altvod commented 2 years ago

First, block creation like that isn't supported (at least for now). You have to append them to a page or a parent block in a separate request. Second, you can't nest blocks by defining them as fields in another block - it doesn't work like that. You shouldn't inherit block classes at all (unless you want to change their behavior somehow). And third - you can't add blocks to database pages - that is a limitation of Notion.

So If you want to create a page with blocks, it would look something like this (note again that you can't use database pages here):

# Create the page
raw_page = MyPageCls.make(...)
response = client.pages.create(**raw_page.data)
page = MyPageCls(data=response)

# Add the block (use page.id as the parent block_id)
children_data = client.blocks.children.append(
    **ToDoBlock.make_as_children_data(
        block_id=page.id,
        text=['todo item block'],
        checked=False,
    )
)
append_response = sync_client.blocks.children.append(**children_data)

# Instantiate the appended block as an object if you need it
block_data = append_response['results'][0]
block = ToDoBlock(data=block_data)

For nested blocks you can use the parent block's ID as the block_id in append.

If you do need to use database pages, then you can only work with the fields that you have defined in the schema. No blocks.

For usage of blocks see tests: https://github.com/altvod/basic-notion/blob/main/tests/test_block.py#L13 Hopefully, I will add all of this to the doc in the not so distant future.