diff --git a/examples/intro_to_notion_api/.env.example b/examples/intro_to_notion_api/.env.example new file mode 100644 index 00000000..50b0ecb7 --- /dev/null +++ b/examples/intro_to_notion_api/.env.example @@ -0,0 +1,2 @@ +NOTION_API_KEY= +NOTION_PAGE_ID= diff --git a/examples/intro_to_notion_api/README.md b/examples/intro_to_notion_api/README.md new file mode 100644 index 00000000..ce6efcb6 --- /dev/null +++ b/examples/intro_to_notion_api/README.md @@ -0,0 +1,157 @@ +# Introduction to using Notion's SDK for Python + +## Learn how to make Public API requests + +Use this sample code to learn how to make Public API requests with varying +degrees of difficulty. + +The sample code is split into two sections: + +1. `basic` +2. `intermediate` + +(An `advanced` section will soon be added, as well.) + +If you are new to Notion's SDK for Python, start with the code samples in the +`/basic` directory to get more familiar to basic concepts. + +The files in each directory will build on each other to increase in complexity. +For example, in `/intermediate`, first you will see how to create a database, +then how to create a database and add a page to it, and finally create a +database, add a page, and query/sort the database. + +## Table of contents + +In case you are looking for example code for a specific task, the files are +divided as follows: + +- `basic/1_add_block.py`: Create a new block and append it to an existing + Notion page. +- `basic/2_add_linked_block.py`: Create and append new blocks, and add a link + to the text of a new block. +- `basic/3_add_styled_block.py`: Create and append new blocks, and apply text + styles to them. +- `intermediate/1_create_a_database.py`: Create a new database with defined + properties. +- `intermediate/2_add_page_to_database.py`: Create a new database and add new + pages to it. +- `intermediate/3_query_database.py`: Create a new database, add pages to it, + and filter the database entries (pages). +- `intermediate/4_sort_database.py`: Create a new database, add pages to it, + and filter/sort the database entries (pages). +- `intermediate/5_upload_file.py`: Upload a file to Notion and attach it to a + page as an image block. + +## Running locally + +### 1. Clone project and install dependencies + +To use this example on your machine, clone the repo and move into your local +copy: + +```bash +git clone https://github.com/ramnes/notion-sdk-py.git +cd notion-sdk-py +``` + +Next, move into this example in the `/examples` directory, and install its +dependencies: + +```bash +cd examples/intro_to_notion_api +pip install -r requirements.txt +``` + +Alternatively, you can create a virtual environment: + +```bash +cd examples/intro_to_notion_api +python -m venv venv +source venv/bin/activate # On Windows use: venv\Scripts\activate +pip install -r requirements.txt +``` + +### 2. Set your environment variables in a `.env` file + +A `.env.example` file has been included and can be renamed `.env` (or you can +run `cp .env.example .env` to copy the file). + +Update the environment variables below: + +```bash +NOTION_API_KEY= +NOTION_PAGE_ID= +``` + +`NOTION_API_KEY`: Create a new integration in the +[integrations dashboard](https://www.notion.com/my-integrations) and retrieve +the API key from the integration's `Secrets` page. + +`NOTION_PAGE_ID`: Use the ID of any Notion page that you want to test adding +content to. + +The page ID is the 32 character string at the end of any page URL. +![A Notion page URL with the ID highlighted](./assets/page_id.png) + +### 3. Give the integration access to your page + +Your Notion integration will need permission to interact with the Notion page +being used for your `NOTION_PAGE_ID` variable. To provide access, do the +following: + +1. Go to the page in your workspace. +2. Click the `•••` (more menu) on the top-right corner of the page. +3. Scroll to the bottom of the menu and click `Add connections`. +4. Search for and select your integration in the `Search for connections...` + menu. + +Once selected, your integration will have permission to read content from the +page. + +**If you are receiving authorization errors, make sure the integration has +permission to access the page.** + +### 4. Run individual examples + +You have several options to run the examples: + +#### Option 1: Run directly with python + +```bash +python basic/1_add_block.py +python basic/2_add_linked_block.py +python basic/3_add_styled_block.py + +python intermediate/1_create_a_database.py +python intermediate/2_add_page_to_database.py +python intermediate/3_query_database.py +python intermediate/4_sort_database.py +python intermediate/5_upload_file.py +``` + +#### Option 2: Run as modules + +```bash +python -m basic.1_add_block +python -m intermediate.1_create_a_database +``` + +--- + +## Additional resources + +To learn more, read the +[Public API docs](https://developers.notion.com/) for additional information +on using Notion's API. The API docs include a series of +[guides](https://developers.notion.com/docs) and the +[API reference](https://developers.notion.com/reference/intro), which has a +full list of available endpoints. + +To see more examples of what you can build with Notion, see our other sample +integrations in the parent `/examples` directory. To learn how to build an +internal integration with an interactive frontend, read the +[Build your first integration](https://developers.notion.com/docs/create-a-notion-integration) +guide. + +To connect with other developers building with Notion, join the +[Notion Developers Slack group](https://join.slack.com/t/notiondevs/shared_invite/zt-20b5996xv-DzJdLiympy6jP0GGzu3AMg). diff --git a/examples/intro_to_notion_api/assets/page_id.png b/examples/intro_to_notion_api/assets/page_id.png new file mode 100644 index 00000000..d0e837b6 Binary files /dev/null and b/examples/intro_to_notion_api/assets/page_id.png differ diff --git a/examples/intro_to_notion_api/basic/1_add_block.py b/examples/intro_to_notion_api/basic/1_add_block.py new file mode 100644 index 00000000..3b14a93f --- /dev/null +++ b/examples/intro_to_notion_api/basic/1_add_block.py @@ -0,0 +1,52 @@ +import json +import os + +from notion_client import Client + +try: + from dotenv import load_dotenv + + load_dotenv() +except ModuleNotFoundError: + pass + +page_id = os.getenv("NOTION_PAGE_ID") +api_key = os.getenv("NOTION_API_KEY") + +notion = Client(auth=api_key) + +# --------------------------------------------------------------------------- + +""" +Resources: +- Appending block children endpoint (notion.blocks.children.append(): https://developers.notion.com/reference/patch-block-children) +- Working with page content guide: https://developers.notion.com/docs/working-with-page-content +""" + + +def main(): + block_id = page_id # Blocks can be appended to other blocks *or* pages. Therefore, a page ID can be used for the block_id parameter + new_heading_response = notion.blocks.children.append( + block_id=block_id, + # Pass an array of blocks to append to the page: https://developers.notion.com/reference/block#block-type-objects + children=[ + { + "heading_2": { + "rich_text": [ + { + "text": { + "content": "Types of kale", # This is the text that will be displayed in Notion + }, + }, + ], + }, + }, + ], + ) + + # Print the new block(s) response + print(json.dumps(new_heading_response, indent=2)) + + +if __name__ == "__main__": + main() diff --git a/examples/intro_to_notion_api/basic/2_add_linked_block.py b/examples/intro_to_notion_api/basic/2_add_linked_block.py new file mode 100644 index 00000000..651eb566 --- /dev/null +++ b/examples/intro_to_notion_api/basic/2_add_linked_block.py @@ -0,0 +1,68 @@ +import json +import os + +from notion_client import Client + +try: + from dotenv import load_dotenv + + load_dotenv() +except ModuleNotFoundError: + pass + +page_id = os.getenv("NOTION_PAGE_ID") +api_key = os.getenv("NOTION_API_KEY") + +notion = Client(auth=api_key) + +# --------------------------------------------------------------------------- + +""" +Resources: +- Appending block children endpoint (notion.blocks.children.append(): https://developers.notion.com/reference/patch-block-children) +- Rich text options: https://developers.notion.com/reference/rich-text +- Working with page content guide: https://developers.notion.com/docs/working-with-page-content +""" + + +def main(): + block_id = page_id # Blocks can be appended to other blocks *or* pages. Therefore, a page ID can be used for the block_id parameter + linked_text_response = notion.blocks.children.append( + block_id=block_id, + # Pass an array of blocks to append to the page: https://developers.notion.com/reference/block#block-type-objects + children=[ + { + "heading_3": { + "rich_text": [ + { + "text": { + "content": "Tuscan kale", # This is the text that will be displayed in Notion + }, + }, + ], + }, + }, + { + "paragraph": { + "rich_text": [ + { + "text": { + "content": "Tuscan kale is a variety of kale with a long tradition in Italian cuisine, especially that of Tuscany. It is also known as Tuscan kale, Italian kale, dinosaur kale, kale, flat back kale, palm tree kale, or black Tuscan palm.", + "link": { + # Include a url to make the paragraph a link in Notion + "url": "https://en.wikipedia.org/wiki/Kale", + }, + }, + }, + ], + }, + }, + ], + ) + + # Print the new block(s) response + print(json.dumps(linked_text_response, indent=2)) + + +if __name__ == "__main__": + main() diff --git a/examples/intro_to_notion_api/basic/3_add_styled_block.py b/examples/intro_to_notion_api/basic/3_add_styled_block.py new file mode 100644 index 00000000..fc74b17c --- /dev/null +++ b/examples/intro_to_notion_api/basic/3_add_styled_block.py @@ -0,0 +1,76 @@ +import json +import os + +from notion_client import Client + +try: + from dotenv import load_dotenv + + load_dotenv() +except ModuleNotFoundError: + pass + +page_id = os.getenv("NOTION_PAGE_ID") +api_key = os.getenv("NOTION_API_KEY") + +notion = Client(auth=api_key) + +# --------------------------------------------------------------------------- + +""" +Resources: +- Appending block children endpoint (notion.blocks.children.append(): https://developers.notion.com/reference/patch-block-children) +- Rich text options: https://developers.notion.com/reference/rich-text +- Working with page content guide: https://developers.notion.com/docs/working-with-page-content +""" + + +def main(): + block_id = page_id # Blocks can be appended to other blocks *or* pages. Therefore, a page ID can be used for the block_id parameter + styled_link_text_response = notion.blocks.children.append( + block_id=block_id, + children=[ + { + "heading_3": { + "rich_text": [ + { + "text": { + "content": "Tuscan kale", + }, + }, + ], + }, + }, + { + "paragraph": { + "rich_text": [ + { + "text": { + # Paragraph text + "content": "Tuscan kale is a variety of kale with a long tradition in Italian cuisine, especially that of Tuscany. It is also known as Tuscan kale, Italian kale, dinosaur kale, kale, flat back kale, palm tree kale, or black Tuscan palm.", + "link": { + # Paragraph link + "url": "https://en.wikipedia.org/wiki/Kale", + }, + }, + "annotations": { + # Paragraph styles + "bold": True, + "italic": True, + "strikethrough": True, + "underline": True, + "color": "green", + }, + }, + ], + }, + }, + ], + ) + + # Print the new block(s) response + print(json.dumps(styled_link_text_response, indent=2)) + + +if __name__ == "__main__": + main() diff --git a/examples/intro_to_notion_api/intermediate/1_create_a_database.py b/examples/intro_to_notion_api/intermediate/1_create_a_database.py new file mode 100644 index 00000000..fe1f36a0 --- /dev/null +++ b/examples/intro_to_notion_api/intermediate/1_create_a_database.py @@ -0,0 +1,68 @@ +import json +import os + +from notion_client import Client + +try: + from dotenv import load_dotenv + + load_dotenv() +except ModuleNotFoundError: + pass + +page_id = os.getenv("NOTION_PAGE_ID") +api_key = os.getenv("NOTION_API_KEY") + +notion = Client(auth=api_key) + +# --------------------------------------------------------------------------- + +""" +Resources: +- Create a database endpoint (notion.databases.create(): https://developers.notion.com/reference/create-a-database) +- Working with databases guide: https://developers.notion.com/docs/working-with-databases +""" + + +def main(): + # Create a new database + new_database = notion.databases.create( + parent={ + "type": "page_id", + "page_id": page_id, + }, + title=[ + { + "type": "text", + "text": { + "content": "New database name", + }, + }, + ], + initial_data_source={ + "properties": { + # These properties represent columns in the data source (i.e. its schema) + "Grocery item": { + "type": "title", + "title": {}, + }, + "Price": { + "type": "number", + "number": { + "format": "dollar", + }, + }, + "Last ordered": { + "type": "date", + "date": {}, + }, + }, + }, + ) + + # Print the new database response + print(json.dumps(new_database, indent=2)) + + +if __name__ == "__main__": + main() diff --git a/examples/intro_to_notion_api/intermediate/2_add_page_to_database.py b/examples/intro_to_notion_api/intermediate/2_add_page_to_database.py new file mode 100644 index 00000000..2edd88bc --- /dev/null +++ b/examples/intro_to_notion_api/intermediate/2_add_page_to_database.py @@ -0,0 +1,94 @@ +import json +import os + +from notion_client import Client + +from sample_data import properties_for_new_pages + +try: + from dotenv import load_dotenv + + load_dotenv() +except ModuleNotFoundError: + pass + +page_id = os.getenv("NOTION_PAGE_ID") +api_key = os.getenv("NOTION_API_KEY") + +notion = Client(auth=api_key) + +# --------------------------------------------------------------------------- + +""" +Resources: +- Create a database endpoint (notion.databases.create(): https://developers.notion.com/reference/create-a-database) +- Create a page endpoint (notion.pages.create(): https://developers.notion.com/reference/post-page) +- Working with databases guide: https://developers.notion.com/docs/working-with-databases +""" + + +def add_notion_page_to_data_source(data_source_id, page_properties): + new_page = notion.pages.create( + parent={ + "data_source_id": data_source_id, + }, + properties=page_properties, + ) + print(json.dumps(new_page, indent=2)) + + +def main(): + # Create a new database + new_database = notion.databases.create( + parent={ + "type": "page_id", + "page_id": page_id, + }, + title=[ + { + "type": "text", + "text": { + "content": "Grocery list", + }, + }, + ], + initial_data_source={ + "properties": { + # These properties represent columns in the data source (i.e. its schema) + "Grocery item": { + "type": "title", + "title": {}, + }, + "Price": { + "type": "number", + "number": { + "format": "dollar", + }, + }, + "Last ordered": { + "type": "date", + "date": {}, + }, + }, + }, + ) + + if new_database["object"] != "database": + print(f"No read permissions on database: {new_database['id']}") + return + + # Print the new database's URL. Visit the URL in your browser to see the pages that get created in the next step. + print(new_database["url"]) + + data_source_id = new_database["data_sources"][0]["id"] + if not data_source_id: # If there is no ID (if there's an error), return. + return + + print("Adding new pages...") + for i in range(len(properties_for_new_pages)): + # Add a few new pages to the database that was just created + add_notion_page_to_data_source(data_source_id, properties_for_new_pages[i]) + + +if __name__ == "__main__": + main() diff --git a/examples/intro_to_notion_api/intermediate/3_query_database.py b/examples/intro_to_notion_api/intermediate/3_query_database.py new file mode 100644 index 00000000..7398f46e --- /dev/null +++ b/examples/intro_to_notion_api/intermediate/3_query_database.py @@ -0,0 +1,118 @@ +import json +import os + +from notion_client import Client + +from sample_data import properties_for_new_pages + +try: + from dotenv import load_dotenv + + load_dotenv() +except ModuleNotFoundError: + pass + +page_id = os.getenv("NOTION_PAGE_ID") +api_key = os.getenv("NOTION_API_KEY") + +notion = Client(auth=api_key) + +# --------------------------------------------------------------------------- + +""" +Resources: +- Create a database endpoint (notion.databases.create(): https://developers.notion.com/reference/create-a-database) +- Create a page endpoint (notion.pages.create(): https://developers.notion.com/reference/post-page) +- Working with databases guide: https://developers.notion.com/docs/working-with-databases +Query a database: https://developers.notion.com/reference/post-database-query +Filter database entries: https://developers.notion.com/reference/post-database-query-filter +""" + + +def add_notion_page_to_data_source(data_source_id, page_properties): + notion.pages.create( + parent={ + "data_source_id": data_source_id, + }, + properties=page_properties, # Note: Page properties must match the schema of the database + ) + + +def query_data_source(data_source_id): + print("Querying database...") + # This query will filter database entries and return pages that have a "Last ordered" + # property that is more recent than 2022-12-31. Use multiple filters with the AND/OR + # options: https://developers.notion.com/reference/post-database-query-filter. + last_ordered_in_2023 = notion.data_sources.query( + data_source_id=data_source_id, + filter={ + "property": "Last ordered", + "date": { + "after": "2022-12-31", + }, + }, + ) + + # Print filtered results + print('Pages with the "Last ordered" date after 2022-12-31:') + print(json.dumps(last_ordered_in_2023, indent=2)) + + +def main(): + # Create a new database + new_database = notion.databases.create( + parent={ + "type": "page_id", + "page_id": page_id, + }, + title=[ + { + "type": "text", + "text": { + "content": "Grocery list", + }, + }, + ], + initial_data_source={ + "properties": { + # These properties represent columns in the data source (i.e. its schema) + "Grocery item": { + "type": "title", + "title": {}, + }, + "Price": { + "type": "number", + "number": { + "format": "dollar", + }, + }, + "Last ordered": { + "type": "date", + "date": {}, + }, + }, + }, + ) + + if new_database["object"] != "database": + print(f"No read permissions on database: {new_database['id']}") + return + + # Print the new database's URL. Visit the URL in your browser to see the pages that get created in the next step. + print(new_database["id"]) + + data_source_id = new_database["data_sources"][0]["id"] + if not data_source_id: # If there is no ID (if there's an error), return. + return + + print("Adding new pages...") + for i in range(len(properties_for_new_pages)): + # Add a few new pages to the database that was just created + add_notion_page_to_data_source(data_source_id, properties_for_new_pages[i]) + + # After adding pages, query the database entries (pages) + query_data_source(data_source_id) + + +if __name__ == "__main__": + main() diff --git a/examples/intro_to_notion_api/intermediate/4_sort_database.py b/examples/intro_to_notion_api/intermediate/4_sort_database.py new file mode 100644 index 00000000..c277b4eb --- /dev/null +++ b/examples/intro_to_notion_api/intermediate/4_sort_database.py @@ -0,0 +1,126 @@ +import json +import os + +from notion_client import Client + +from sample_data import properties_for_new_pages + +try: + from dotenv import load_dotenv + + load_dotenv() +except ModuleNotFoundError: + pass + +page_id = os.getenv("NOTION_PAGE_ID") +api_key = os.getenv("NOTION_API_KEY") + +notion = Client(auth=api_key) + +# --------------------------------------------------------------------------- + +""" +Resources: +- Create a database endpoint (notion.databases.create(): https://developers.notion.com/reference/create-a-database) +- Create a page endpoint (notion.pages.create(): https://developers.notion.com/reference/post-page) +- Working with databases guide: https://developers.notion.com/docs/working-with-databases +Query a database: https://developers.notion.com/reference/post-database-query +Filter database entries: https://developers.notion.com/reference/post-database-query-filter +Sort database entries: https://developers.notion.com/reference/post-database-query-sort +""" + + +def add_notion_page_to_data_source(data_source_id, page_properties): + notion.pages.create( + parent={ + "data_source_id": data_source_id, + }, + properties=page_properties, # Note: Page properties must match the schema of the database + ) + + +def query_and_sort_data_source(data_source_id): + print("Querying data source...") + # This query will filter and sort database entries. The returned pages will have a + # "Last ordered" property that is more recent than 2022-12-31. Any database property + # can be filtered or sorted. Pass multiple sort objects to the "sorts" array to + # apply more than one sorting rule. + last_ordered_in_2023_alphabetical = notion.data_sources.query( + data_source_id=data_source_id, + filter={ + "property": "Last ordered", + "date": { + "after": "2022-12-31", + }, + }, + sorts=[ + { + "property": "Grocery item", + "direction": "descending", + }, + ], + ) + + # Print filtered/sorted results + print('Pages with the "Last ordered" date after 2022-12-31 in descending order:') + print(json.dumps(last_ordered_in_2023_alphabetical, indent=2)) + + +def main(): + # Create a new database + new_database = notion.databases.create( + parent={ + "type": "page_id", + "page_id": page_id, + }, + title=[ + { + "type": "text", + "text": { + "content": "Grocery list", + }, + }, + ], + initial_data_source={ + "properties": { + # These properties represent columns in the data source (i.e. its schema) + "Grocery item": { + "type": "title", + "title": {}, + }, + "Price": { + "type": "number", + "number": { + "format": "dollar", + }, + }, + "Last ordered": { + "type": "date", + "date": {}, + }, + }, + }, + ) + + if new_database["object"] != "database": + print(f"No read permissions on database: {new_database['id']}") + return + + # Print the new database's URL. Visit the URL in your browser to see the pages that get created in the next step. + print(new_database["id"]) + + data_source_id = new_database["data_sources"][0]["id"] + if not data_source_id: + return + + print("Adding new pages...") + for i in range(len(properties_for_new_pages)): + # Add a few new pages to the database that was just created + add_notion_page_to_data_source(data_source_id, properties_for_new_pages[i]) + + # After adding pages, query the database entries (pages) and sort the results + query_and_sort_data_source(data_source_id) + + +if __name__ == "__main__": + main() diff --git a/examples/intro_to_notion_api/intermediate/5_upload_file.py b/examples/intro_to_notion_api/intermediate/5_upload_file.py new file mode 100644 index 00000000..63f50ab7 --- /dev/null +++ b/examples/intro_to_notion_api/intermediate/5_upload_file.py @@ -0,0 +1,128 @@ +import os +from pathlib import Path + +from notion_client import Client + +try: + from dotenv import load_dotenv + + load_dotenv() +except ModuleNotFoundError: + pass + +page_id = os.getenv("NOTION_PAGE_ID") +api_key = os.getenv("NOTION_API_KEY") + +notion = Client(auth=api_key) + +# --------------------------------------------------------------------------- + +""" +Resources: +- File upload guide: https://developers.notion.com/docs/uploading-small-files +- Create file upload API: https://developers.notion.com/reference/create-a-file-upload +""" + + +def create_file_upload(): + return notion.file_uploads.create( + mode="single_part", + ) + + +def send_file_upload(file_upload_id, file_path): + with open(file_path, "rb") as file: + return notion.file_uploads.send( + file_upload_id=file_upload_id, + file=file, + ) + + +def append_block_children(block_id, file_upload_id): + return notion.blocks.children.append( + block_id=block_id, + children=[ + { + "type": "image", + "image": { + "type": "file_upload", + "file_upload": { + "id": file_upload_id, + }, + }, + }, + { + "type": "paragraph", + "paragraph": { + "rich_text": [ + { + "type": "text", + "text": { + "content": "This is a test", + }, + }, + ], + }, + }, + ], + ) + + +def main(): + file_upload = create_file_upload() + print("Created file upload with ID:", file_upload["id"]) + + script_dir = Path(__file__).parent + image_path = script_dir.parent / "assets" / "page_id.png" + + file_upload = send_file_upload(file_upload["id"], str(image_path)) + print("Uploaded page_id.png to file upload; status is now:", file_upload["status"]) + + # Append an image block with the file upload from above, and a text block, + # to the configured page. + new_blocks = append_block_children(page_id, file_upload["id"]) + new_block_ids = [block["id"] for block in new_blocks["results"]] + print("Appended block children; new list of block children is:", new_block_ids) + + # Create a comment on the text block with the same image by providing + # the same file upload ID. Also use a custom display name. + comment = notion.comments.create( + parent={ + "type": "block_id", + "block_id": new_block_ids[1], + }, + rich_text=[ + { + "type": "text", + "text": {"content": "I'm commenting on this block with an image:"}, + }, + ], + attachments=[ + { + "type": "file_upload", + "file_upload_id": file_upload["id"], + }, + ], + display_name={ + "type": "custom", + "custom": { + "name": "Notion test auto commenter", + }, + }, + ) + + print("Comment ID:", comment["id"]) + + if comment["object"] == "comment": + print("Discussion ID:", comment["discussion_id"]) + print("Comment parent:", comment["parent"]) + print("Comment created by:", comment["created_by"]) + print("Comment display name:", comment["display_name"]) + else: + print("No read access to comment object") + + print("Done! Image & comment added to page:", page_id) + + +if __name__ == "__main__": + main() diff --git a/examples/intro_to_notion_api/intermediate/sample_data.py b/examples/intro_to_notion_api/intermediate/sample_data.py new file mode 100644 index 00000000..1ef5e764 --- /dev/null +++ b/examples/intro_to_notion_api/intermediate/sample_data.py @@ -0,0 +1,44 @@ +properties_for_new_pages = [ + { + "Grocery item": { + "type": "title", + "title": [{"type": "text", "text": {"content": "Tomatoes"}}], + }, + "Price": { + "type": "number", + "number": 1.49, + }, + "Last ordered": { + "type": "date", + "date": {"start": "2023-05-11"}, + }, + }, + { + "Grocery item": { + "type": "title", + "title": [{"type": "text", "text": {"content": "Lettuce"}}], + }, + "Price": { + "type": "number", + "number": 3.99, + }, + "Last ordered": { + "type": "date", + "date": {"start": "2023-05-04"}, + }, + }, + { + "Grocery item": { + "type": "title", + "title": [{"type": "text", "text": {"content": "Oranges"}}], + }, + "Price": { + "type": "number", + "number": 0.99, + }, + "Last ordered": { + "type": "date", + "date": {"start": "2022-04-29"}, + }, + }, +] diff --git a/examples/intro_to_notion_api/requirements.txt b/examples/intro_to_notion_api/requirements.txt new file mode 100644 index 00000000..6ac3ccf9 --- /dev/null +++ b/examples/intro_to_notion_api/requirements.txt @@ -0,0 +1,2 @@ +notion-client +python-dotenv