Code Monkey home page Code Monkey logo

notion-sdk-py's Issues

Images url not included

Yesterday it was working well. But now the image columns are returned as only name of image but not the url, for both external and uploads.

Missing examples of creating databases

Hello,
I'm having problems creating a database, mostly due to lack of any examples.
I can create a page just fine, but am having problems with databases.
I think I just get type/format of the title and properties wrong.

Would be great to have an example of how to create a database with a title and a text property.

Thanks for your great work!

vscode jupyter os.environ key error

Hi guys, when using vs code with conda envs, I get a key error for loading the Client with my key via
notion = Client(auth=os.environ['TOKEN']
i get this output

KeyError: 'TOKEN'
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
/var/folders/cq/tw7v96zx0sx59ptff9z4d6hw0000gn/T/ipykernel_14685/1136862354.py in <module>
----> 1 notion = Client(auth=os.environ["TOKEN"])

~/miniforge3/envs/pipeline/lib/python3.8/os.py in __getitem__(self, key)
    673         except KeyError:
    674             # raise KeyError with the original key value
--> 675             raise KeyError(key) from None
    676         return self.decodevalue(value)
    677 

KeyError: 'TOKEN'

anybody came across the same issue, or knows how to fix it?

Defining Data Transfer Objects (in terms of `@dataclass`) for easier development

Hello, thank you for creating such a great project.

I was wondering if there is a plan to add pre-defiend DTOs for API request / response since the official API is out of beta.

Currently, API endpoint invocations return generic SyncAsync[T] types, which makes development a bit cumbersome.

From what I am aware of, the following libs are options for defining DTOs:

  • dataclasses is built-in from 3.7, but cannot serialize / deserialize nested object (dataclasses-json).
  • pydantic has good serialization / deserialization features, but a bit heavier than the other.

Implement all endpoints

  • blocks.children.append()
  • blocks.children.list()
  • databases.list()
  • databases.query()
  • databases.retrieve()
  • pages.create()
  • pages.retrieve()
  • pages.update()
  • search()
  • users.list()
  • users.retrieve()

Trying to create a page with an icon, but I get a page...without an icon

Hi!

Just as the title says, I'm trying to create a page with an icon, but I fail to see where I'm going wrong about it. Here's my code:

notion.pages.create(parent={"database_id": projects_db},
                           icon={"emoji": "⚜️", "type":"emoji"},
                           properties={"Nom": {"title": [{"text": {"content": "Blabla"}}]}})

What I get is a page, in the right database, with the right name, but no icon. Am I missing something?

Thanks!

How can I create new page with some contents of text

Hi!

I use the script in the example and success to add one new page with my database.
But I want to add some text on page creating like below.

image

My code shows below.

# Initialize the client
notion = Client(auth=NOTION_TOKEN)

# Create a new page
properties = {
    "Name": {"title": [{"text": {"content": "test_title"}}]},
    "Created": {"date": {"start": "2022-03-28"}},
    "Tags": {
      "type": "multi_select",
      "multi_select": [{"name": "Daily"}]
    },
    "Property": {
        "type": "rich_text",
        "rich_text": [
            {
                "type": "text",
                "text": {"content": ""},
            },
        ], 
    }
}

test_ = notion.pages.create(parent={"database_id": DATABASE_ID}, properties=properties)

Thanks for helping.

I'm confuse with the official documentation when I use a method with requests. :'(

TimeoutException should handled during `send()` not in `_parse_reponse`

def _parse_response(self, response: Response) -> Any:
        try:
            response.raise_for_status()
        except httpx.TimeoutException as error:
            if is_timeout_error(error):
                raise RequestTimeoutError()
            raise
        except httpx.HTTPStatusError as error:
            body = error.response.json()
            code = body.get("code")
            if is_api_error_code(code):
                body = APIErrorResponseBody(code=code, message=body["message"])
                raise APIResponseError(error.response, body)
            raise HTTPResponseError(error.response)

        return response.json()

Timeout exception handling logic above in BaseClient._parse_response() would never run, becuase raise_for_status() won't raise TimeoutException.

JSONDecodeError when server return 502

This line will cause JSONDecodeError when server return 502

    def _parse_response(self, response: Response) -> Any:
        try:
            response.raise_for_status()
        except httpx.HTTPStatusError as error:
            body = error.response.json()   # <<< This line
            code = body.get("code")
            if code and is_api_error_code(code):
                raise APIResponseError(response, body["message"], code)
            raise HTTPResponseError(error.response)

It would be better try it first

    def _parse_response(self, response: Response) -> Any:
        try:
            response.raise_for_status()
        except httpx.HTTPStatusError as error:
            try:
                body = error.response.json()
            except:
                raise HTTPResponseError(error.response)
            code = body.get("code")
            if code and is_api_error_code(code):
                raise APIResponseError(response, body["message"], code)
            raise HTTPResponseError(error.response)

Detail: the 502 response content is html, basically saying server error, try again.

in query empty start_cursor option throws error

hi,

I try to make a query:

next_cursor = None
results = notion.databases.query(
        **{
            "database_id": DB_GMB_ID,
            "start_cursor": next_cursor
        }
    )

I receive the error:

APIResponseError: body failed validation: body.start_cursor should be a string or `undefined`, instead was `null`.

"" produces the same result.

What value should be used to satisfy undefined start_cursor?

Can't create a page using parent='page_id'

Hi!

I am trying to create a page inside a page but it seems imposible to me. ¿Is it supported?

notion.pages.create(parent={"page_id": PAGE_ID},
                   icon={"emoji": "🧪", "type":"emoji"},
                   title={"text": {"content": "Blabla"}})

The output is:

Traceback (most recent call last):
  File "c:\Codigo\Notion-API\Notion-sdk-client-VTC-v1.0.py", line 62, in <module>
    notion.pages.create(parent={"page_id": PAGE_ID},
  File "c:\Codigo\Notion-API\venv\lib\site-packages\notion_client\api_endpoints.py", line 197, in create
    return self.parent.request(
  File "c:\Codigo\Notion-API\venv\lib\site-packages\notion_client\client.py", line 188, in request
    return self._parse_response(response)
  File "c:\Codigo\Notion-API\venv\lib\site-packages\notion_client\client.py", line 120, in _parse_response
    raise APIResponseError(response, body["message"], code)
notion_client.errors.APIResponseError: body failed validation: body.parent.database_id should be defined, instead was `undefined`.

Thanks!

Cannot update icon and cover

The problem

In the new version, Notion added an icon and image cover support and consequently fields in API, but the SDK doesn't support this feature (and fields) yet.

Possible solution

I suppose the problem is here in line 147:

def create(self, **kwargs: Any) -> SyncAsync[Any]:
"""Create a new page in the specified database or as a child of an existing page.
If the parent is a database, the `properties` parameter must conform to the
parent database's property schema.
If the parent is a page, the only valid property is `title`. The new page may
include page content, described as blocks in the `children` parameter.
"""
return self.parent.request(
path="pages",
method="POST",
body=pick(kwargs, "parent", "properties", "children"),
auth=kwargs.get("auth"),
)

I guess It should be changed like that:

# "icon" and "cover" fields were added
body=pick(kwargs, "parent", "properties", "children", "icon", "cover"),

Search inside Client

Is there a reason the client.search doesn't use the Client?

The async client could also implements the search in async Fashion

Data structures

Hi Ramnes,

I love the work you've done so far on the Notion SDK for python. I had a couple ideas to implement in the SDK if you thought they'd be of value:

  • Simple data classes on top of the various API objects for Typing and abstraction.
  • Implementing natural pythonic pagination and iteration

I'll fork the repo and start work on these. Let me know what you think of these and I can make a PR when I'm done.

Cheers,
Jeadie

Documentation links broken

The given examples have been really helpful. However, most of the links in docs/SUMMARY.md are broken. Is there a link to the full documentation anywhere else?

I would be happy to contribute as well if needed.

notion_client.errors.APIResponseError: Value is expected to be rich_text. Link is expected to be files.

Issue: when I try to add data to a database, I get errors because of the properties that are expected are incorrectly setup in the database, and the error returned doesn't helps.

The Following an example from: https://github.com/ramnes/notion-sdk-py/wiki/Examples#crud

I have had incorrectly created/setup the following properties in my db:

(Property Name: Type)
Name: Text
Tags: Multi-Select
Value: Text
Link: Files

Therefore the APIResponseError returned:
Value is expected to be rich_text. Link is expected to be files.
but this is wrong, since what's the error is saying is that the type that Value is supposed to be expecting is "rich_text", but it's actually telling me the actual property type... instead it should have returned something like this:

notion_client.errors.APIResponseError: Value is expected to be Number. Link is expected to be URL.

This took me a while to understand, because I hadn't look at the schema that it's already setup:

new_page_props = {
        'Name': {'title': [{'text': {'content': f"My Page of {rand_page_type} {page_id}"}}]},
        'Value': {'number': page_id},
        'Link': {'type': 'url', 'url': f"http://examples.org/page/{page_id}"},
        'Tags': {'type': 'multi_select', 'multi_select': [{'name': rand_page_type}]}
    }

Stack Trace:

Traceback (most recent call last):
  File "C:\Users\user\Documents\project\bots\test_notion_api.py", line 44, in <module>
    notion_page = notion.pages.create(
  File "C:\Users\maris\miniconda3\envs\an_env\lib\site-packages\notion_client\api_endpoints.py", line 197, in create
    return self.parent.request(
  File "C:\Users\maris\miniconda3\envs\an_env\lib\site-packages\notion_client\client.py", line 192, in request
    return self._parse_response(response)
  File "C:\Users\maris\miniconda3\envs\an_env\lib\site-packages\notion_client\client.py", line 124, in _parse_response
    raise APIResponseError(response, body["message"], code)
notion_client.errors.APIResponseError: Value is expected to be rich_text. Link is expected to be files.

Process finished with exit code 1

Solution: Be able to get a proper error message with the actual type that's expected by the read values, and not the ones that are setup in the database.

Missing requirements.txt

notion-sdk-py/setup.py

Lines 20 to 21 in 93f3ca9

install_requires=[
"httpx >= 0.15.0, < 0.18.0",

Install requires httpx, so I think, the project requirements.txt for that.

The best point for using poetry is that we don't need to write the deps twice. Once in requirements.txt, and once in setup.py.

Examples on how to use async client

Hi - totally understand if this is super low priority, but would be awesome to see some async client examples in action.

I am not an Async expert but I was trying to get familiar with the AsyncClient but i am unable to do so.

Below my beginners attempt:

async_notion = AsyncClient(auth=NOTION_TOKEN)
async def main():
    await asyncio.gather(async_notion.databases.retrieve(**{"database_id": "123"})), async_notion.databases.retrieve(**{"database_id": "123"}))

asyncio.run(main())

I am getting the following exception:

_asyncio.py in receive(self, max_bytes)

   1091             except IndexError:
   1092                 if self._closed:
-> 1093                     raise ClosedResourceError from None
   1094                 elif self._protocol.exception:
   1095                     raise self._protocol.exception

ClosedResourceError: 

Cheers!

🐛 Boolean always evaluated to `True`

I'm trying to generate text with styling.

For example, if I want bold + italic text on a blue background, I do the following :

from notion_client import Client

text = {
    "object": "block",
    "type": "paragraph",
    "paragraph": {
        "text": [
            {
                "type": "text",
                "text": {"content": "Test"},
                "annotations": {
                    "bold": True,
                    "italic": True,
                    "strikethrough": False,
                    "underline": False,
                    "code": False,
                    "color": "blue_background",
                },
            }
        ]
    },
}

notion = Client(auth=AUTH_TOKEN)
notion.blocks.children.append(block_id=BLOCK_ID, children=[text])

Expected result :
image

Actual result :
image

Every boolean annotations are set to True, I don't know why...


It works properly if simply remove the annotations I want to set to False :

text = {
    "object": "block",
    "type": "paragraph",
    "paragraph": {
        "text": [
            {
                "type": "text",
                "text": {"content": "Test"},
                "annotations": {
                    "bold": True,     # Note : I can set this to False, the result is the same
                    "italic": True,     # Note : I can set this to False, the result is the same
                    "color": "blue_background",
                },
            }
        ]
    },
}

Search does not return root page, when root is not a workpace parent level page

This is weird. I think this is a problem with Notion API and not this library. But opening this issue, so that it can be closed when this is solved.

Problem

Suppose I create a page "my page name", and add my integration to this page, then

notion.search(query="my page name")

will not give this page.

If I query for any subpage/database in this page/page within a database on this page, I will get it successfully.

Steps to reproduce

Create a new integration named "Issue32Inti".

Duplicate this page https://www.notion.so/aahnik/notion-sdk-py-540f8e2b79914654ba103c5d8a03e10e and [update]* put it inside a parent level page .share this with your integration.

Note: the page should be a subpage. Not a parent-level page. ie, it should be inside a parent page.

Now, Initialize your client object notion.

Root page

obj = notion.search(query="notion-sdk-py") # root page
Result ❌
   { 'object': 'list',
      'results': [],
      'next_cursor': None,
      'has_more': False,
    } 

Database

obj = notion.search(query="People") # database
Result ✅
{ 'object': 'list',
 'results': [{'object': 'database',
   'id': '99572135-4646-49bd-95a1-4ff08f79c7a5',
   'created_time': '2021-05-19T04:50:21.634Z',
   'last_edited_time': '2021-05-19T04:57:00.000Z',
   'title': [{'type': 'text',
     'text': {'content': 'People', 'link': None},
     'annotations': {'bold': False,
      'italic': False,
      'strikethrough': False,
      'underline': False,
      'code': False,
      'color': 'default'},
     'plain_text': 'People',
     'href': None}],
   'properties': {'Tags': {'id': 'EcDa',
     'type': 'multi_select',
     'multi_select': {'options': [{'id': '2cd67f95-2f58-4223-bc0a-de03bf87c1e2',
        'name': 'python',
        'color': 'default'},
       {'id': 'f2ae0eef-5611-4da8-97e0-9208ecec44c1',
        'name': 'expert',
        'color': 'blue'},
       {'id': '573d40b5-42bd-4035-815d-73fc4aa7d208',
        'name': 'learner',
        'color': 'purple'}]}},
    'Website': {'id': 'Z{nX', 'type': 'url', 'url': {}},
    'GitHub': {'id': '`<Mi', 'type': 'rich_text', 'rich_text': {}},
    'Name': {'id': 'title', 'type': 'title', 'title': {}}}}],
 'next_cursor': None,
 'has_more': False}

Subpage

obj = notion.search(query="Subpage 1") # subpage
Result ✅
{ 'object': 'list',
 'results': [{'object': 'page',
   'id': '4e8705d7-e6a5-4b23-853f-3b2fcc9f18fe',
   'created_time': '2021-05-19T04:45:47.349Z',
   'last_edited_time': '2021-05-19T04:49:00.000Z',
   'parent': {'type': 'page_id',
    'page_id': '540f8e2b-7991-4654-ba10-3c5d8a03e10e'},
   'archived': False,
   'properties': {'title': {'id': 'title',
     'type': 'title',
     'title': [{'type': 'text',
       'text': {'content': 'Subpage 1', 'link': None},
       'annotations': {'bold': False,
        'italic': False,
        'strikethrough': False,
        'underline': False,
        'code': False,
        'color': 'default'},
       'plain_text': 'Subpage 1',
       'href': None}]}}}],
 'next_cursor': None,
 'has_more': False}

[update] means that portion was later edited.

Add documentation to source with examples

Although it is possible to translate the examples on the Notion API page or the examples on the JS SDK to methods and attributes on this SDK, it would be nice to reduce this "mental work" by adding documentation and examples to python source code.

Adding one example for each action bellow is a good start point:

  • listing databases
  • listing pages
  • searching databases
  • searching pages
  • creating pages
  • updating pages

httpx.HTTPStatusError: Client error '400 Bad Request' for url 'https://api.notion.com/v1/databases/897e5a76-ae52-4b48-9fdf-e71f5945d1af/query' when running example

This minimal example from the documentation fails for me:

import os
from notion_client import Client

notion = Client(auth=os.environ["NOTION_TOKEN"])
my_page = notion.databases.query(
    **{
        "database_id": "897e5a76-ae52-4b48-9fdf-e71f5945d1af",
        "filter": {
            "property": "Landmark",
            "text": {
                "contains": "Bridge",
            },
        },
    }
)

Other lookups work, it's specifically this filtering down to get an item using the databases.query endpoint. Do you know what might be happening?

Testing notion-sdk-py when part of another project

Hello,
I am using notion-sdk-py for a project, I would like to write tests in order to see if the different functions that are using some modules from notion-sdk-py are working in order to enhance the workflow/stability of my project. However I am not sure how it is possible to test this API as it is linked to a notion database/account.
Do you have recommendation on how to do so ?
Thanks!

SSL Certificate validation failed.

I am running the package for the first time.
Nice work with this! Interfaces are super pleasant to use.

Unfortunately my socket connection can't be established due to SSL certificate issue.
Any idea how to fix this?

>>> notion = Client(auth="...")
>>> notion.users.list()
Traceback (most recent call last):
  File "/mnt/c/Users/MeillieA/PycharmProjects/notion-code-legacy/.venv/lib/python3.8/site-packages/httpx/_transports/default.py", line 61, in map_httpcore_exceptions
    yield
  File "/mnt/c/Users/MeillieA/PycharmProjects/notion-code-legacy/.venv/lib/python3.8/site-packages/httpx/_transports/default.py", line 180, in handle_request
    status_code, headers, byte_stream, extensions = self._pool.handle_request(
  File "/mnt/c/Users/MeillieA/PycharmProjects/notion-code-legacy/.venv/lib/python3.8/site-packages/httpcore/_sync/connection_pool.py", line 234, in handle_request
    response = connection.handle_request(
  File "/mnt/c/Users/MeillieA/PycharmProjects/notion-code-legacy/.venv/lib/python3.8/site-packages/httpcore/_sync/connection.py", line 136, in handle_request
    self.socket = self._open_socket(timeout)
  File "/mnt/c/Users/MeillieA/PycharmProjects/notion-code-legacy/.venv/lib/python3.8/site-packages/httpcore/_sync/connection.py", line 163, in _open_socket
    return self._backend.open_tcp_stream(
  File "/mnt/c/Users/MeillieA/PycharmProjects/notion-code-legacy/.venv/lib/python3.8/site-packages/httpcore/_backends/sync.py", line 144, in open_tcp_stream
    return SyncSocketStream(sock=sock)
  File "/usr/lib/python3.8/contextlib.py", line 131, in __exit__
    self.gen.throw(type, value, traceback)
  File "/mnt/c/Users/MeillieA/PycharmProjects/notion-code-legacy/.venv/lib/python3.8/site-packages/httpcore/_exceptions.py", line 12, in map_exceptions
    raise to_exc(exc) from None
httpcore.ConnectError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1131) 

Update to the 2022-02-22 version

Hi!
I see that the API has been updated to the new version, which has a couple of cool features: one I'm interested in is the chance to add advanced types of block like toggles to the BlocksChildrenEndpoint, which is not working with the current version of the library.

If I try to append a children to an existing page with the example code for a toggle provided by Notion I get an error saying to update the API version.

I think that it's solvable by upgrading the version here, but since it's not backward compatible I'm asking here if there's something to be aware of before proceeding.

Impossible to clear a field

According to notion support, to clear a field (reset its value), you should do:
{
"properties": {
"Sponsor": { "select": null }
}

This is not possible with the current version. The best that we can do is:
{
"properties": {
"Sponsor": { "select": None }
}

but it is not accepted by notion.

Object of type Decimal is not JSON serializable notion api

Hi 👋,
I get this error TypeError: Object of type Decimal is not JSON serializable notion api while trying to create a page with a "number" property type and a decimal number as the input.

I think the error is in "_content.py" line 175.

def encode_json(json: Any) -> Tuple[Dict[str, str], ByteStream]:
    body = json_dumps(json).encode("utf-8")
    content_length = str(len(body))
    content_type = "application/json"
    headers = {"Content-Length": content_length, "Content-Type": content_type}
    return headers, ByteStream(body)`

I don't know how to solve this problem.
Thank you. 😁

Client-side validation

I am now using this sdk to do some develop. But usually i get the APIResponseError error.

APIResponseError: body failed validation.

I plan to write a simple validator in my code, and I'm curious if this feature will be added in the future.

Upload to database w/ external source

Hello,
I am struggling to upload to database from an external source, is there an issue with the object that I send? (I tried w/ and w/out [])

from notion_client import Client


token = ""
database_id = ""
url = ""

client = Client(auth=token)
client.pages.create(
    parent={'database_id': database_id},
    properties={
        'Title': [{'text': {'content': 'Testing upload'}}],
        "File": [{
            "files": [
                {
                    "type": "external",
                    "name": "pdf",
                    "external": url
                }
            ]
        }]
    },
)

File and Title exist, but it still doesn't work :/

Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\lib\site-packages\notion_client\client.py", line 115, in _parse_response
    response.raise_for_status()
  File "C:\ProgramData\Anaconda3\lib\site-packages\httpx\_models.py", line 1508, in raise_for_status
    raise HTTPStatusError(message, request=request, response=self)
httpx.HTTPStatusError: Client error '400 Bad Request' for url 'https://api.notion.com/v1/pages'
For more information check: https://httpstatuses.com/400

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "D:/Thomas/GitHub/notion-scholar/excluded/upload.py", line 12, in <module>
    client.pages.create(
  File "C:\ProgramData\Anaconda3\lib\site-packages\notion_client\api_endpoints.py", line 202, in create
    return self.parent.request(
  File "C:\ProgramData\Anaconda3\lib\site-packages\notion_client\client.py", line 187, in request
    return self._parse_response(response)
  File "C:\ProgramData\Anaconda3\lib\site-packages\notion_client\client.py", line 122, in _parse_response
    raise APIResponseError(response, body["message"], code)
notion_client.errors.APIResponseError: body failed validation. Fix one: body.properties.File[0].text should be defined, instead was `undefined`. body.properties.File[0].mention should be defined, instead was `undefined`. body.properties.File[0].equation should be defined, instead was `undefined`. body.properties.File[0].id should be defined, instead was `undefined`. body.properties.File[0].name should be defined, instead was `undefined`. body.properties.File[0].person should be defined, instead was `undefined`. body.properties.File[0].bot should be defined, instead was `undefined`. body.properties.File[0].file should be defined, instead was `undefined`. body.properties.File[0].external should be defined, instead was `undefined`.

Process finished with exit code 1

I got what to put for File here https://developers.notion.com/reference/property-value-object#files-property-values

If I do that:

    client = Client(auth=token)
    client.pages.create(
        parent={'database_id': database_id},
        properties={
            'Title': [{'text': {'content': 'Testing upload'}}],
        }
    )

It works just fine

Thanks!

Update method of PagesEndpoint class never handles archived pages

Calling something like
archivedpage = notion.pages.update(page_id, **{"archived":True, "properties":properties})
will never result in the page being archived. Tested calling the same route on curl and it works

Did some digging and i think i figured out where the bug is from,

def update(self, page_id: str, **kwargs: Any) -> SyncAsync[Any]:
        return self.parent.request(
            path=f"pages/{page_id}",
            method="PATCH",
            body=pick(kwargs, "properties"),
            auth=kwargs.get("auth"),
        )

The line body=pick(kwargs, "properties") in the update method doesn't pick up the archived keyword from kwargs, resulting in only the properties item being added to body

Question: the struggle is real

Hi Guys,

this is more of a question i have. I got started and tried the one example to display the users.
That worked fine. However, after that i tried to find a notion page by it's id.
So my first question, where to find that page_id ? I thought about it's the hash value on the link
of the notion page (however, in the example it includes - and in the hash not.

After that, i just wanted to list all pages that are available, how to do that?
I could not find anything like notion.pages.list() .

Last but not least, and more of a general understanding question what are blocks?
How to see what blocks are saved?

Sorry if this questions are to simple for you, peeps.

Cheers
Chris

Adding A Formatting Option

I would like to add a formatter that will automatically create the dictionaries in their correct format based on the property. I think this will help make the code just more readable since without it there are just extremely large dictionaries and a whole bunch of curly braces. I personally use this formatter for my own scripts that I use to automate some things on Notion.

For example:

Before using a formatter:

create_details = {
    "parent": DB_ID,
    "properties": {
        "some date property": {
            "date": {
                "start": "starting date",
                "end": "ending date",
            }
        },
        "some multi select property": {
            "multi_select": [
                {
                    "name": "option name"
                },
                {
                    "name": "option name",
                    "color": "option color"
                }
            ]
        },
        "some select property": {
            "select": {
                "option": "option name",
                "color": "option color"
            }
        }
    }
}

After using a formatter:

# this is needed because `formatter.multi_select` takes a dictionary
# as the input
multi_select_options = {
    "option one": "default",
    "option two": "color"
}
# the same dictionary, but using the formatter
create_details = {
    "parent": DB_ID,
    "properties": {
        "some date property": formatter.date("start date", "end date"),
        "some multi select property": formatter.multi_select(multi_select_options),
        "some select property": formatter.select("option name", "option color")
    }
}

ORM for notion databases

Django ORM, sqlalchemy etc, are examples where you write python classes and call python functions, but under the hood SQL queries get carried out.

It would be great to have an ORM, that under the hood would carry out various interactions using Notion API. For the end user, it will be a high level experience.

Example usage

# a vague example usage

class Student(NotionBaseModel):
    name: Title
    address: Text
    last_edited: LastEditedTime

student = Student("Aahnik","India") # will add a row to the table

Feature Request: log full request data

When debugging, it would be helpful to view the entire payload being sent to / from the Notion API. That's a lot of information to consume for DEBUG, but perhaps there would be a "special" named logger that could be configured to dump the request and response data?

notion_client.errors.APIResponseError: This API is deprecated when trying to fetch databases

When trying to list databases I get notion_client.errors.APIResponseError: This API is deprecated when trying to fetch databases exception:

import os
from notion_client import Client

notion = Client(auth=os.getenv("NOTION_SECRET"))
databases = notion.databases.list()  # raises notion_client.errors.APIResponseError exception

pytest log:

self = <notion_client.client.Client object at 0x10a38ce80>, response = <Response [400 Bad Request]>

    def _parse_response(self, response: Response) -> Any:
        try:
            response.raise_for_status()
        except httpx.HTTPStatusError as error:
            try:
                body = error.response.json()
                code = body.get("code")
            except json.JSONDecodeError:
                code = None
            if code and is_api_error_code(code):
>               raise APIResponseError(response, body["message"], code)
E               notion_client.errors.APIResponseError: This API is deprecated.
  • Python: 3.9.9
  • notion-client version: 1.0.0

Library was installed using poetry with:

$ poetry add notion-client

Leverage type hints

  • Add complete type hints for all signatures
  • Bundle a py.typed file
  • Make Mypy run in the CI

Querying databases and pages provide limited properties

This is ultimately 2 issues I believe.

  1. Listing a database where I have 23 properties, the results returned provides only 16
  2. Querying a database to retrieve pages provided only 14 properties where again, there should be 23 properties.
class Test:
    def __init__(self):
        self.notion = None
        self.databases = {}
        self.pageIds = []
        self.pages = {}

    def initialize(self):
        #NOTION_TOKEN = os.getenv("NOTION_TOKEN", "")
        with open('Notion_Config.YAML') as f:
            data = yaml.load(f, Loader=yaml.FullLoader)
            print(data)
        NOTION_TOKEN = data["Token"]

        while NOTION_TOKEN == "":
            print("NOTION_TOKEN not found.")
            NOTION_TOKEN = input("Enter your integration token: ").strip()

        self.notion = Client(auth=NOTION_TOKEN)

    def list_db(self):
        results = self.notion.databases.list()
        print("Listing databases: ")
        for item in results["results"]:
            print(item["title"][0]["plain_text"])
            self.databases.update({item["title"][0]["plain_text"] : item["id"]})

    def query_db(self, database_name):
        #while db["more"] == True:
        db = self.notion.databases.query(database_id=self.databases.get(database_name))
        for item in db["results"]:
            print(item)
            self.pageIds.append(item["id"])

    def query_pages(self):
        for item in self.pageIds:
            page = self.notion.pages.retrieve(page_id=item)
            print(page)

Calling list_db. You can see the number of properties retrieved is 16
image

Calling query_db. You can see the number of properties retrieved is 14
image

This screenshot shows the list of properties for my database
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.