Introduction to pages¶
Pages are one of the most essential building blocks of Notion. A page has certain attributes such as a title, cover, icon, and wether it is deleted, i.e. in the trash, or not. Items within a database, or rows if you will, are just pages and the schema of the database, that is the set of columns and their types, imposes properties on each contained page.
Beside attributes and properties, a page also has a content, consisting of blocks for text and everything you can choose in the Notion UI by hitting /. As a page can be contained in another page, we can have a parent and children relation between pages. Check out the Page object to find out more about accessing these functionalities.
Searching for a page¶
To get started, assume we have a page called "Getting Started", which we want to access using Ultimate Notion.
import ultimate_notion as uno
notion = uno.Session.get_or_create() # if NOTION_TOKEN is set in environment
intro_page = notion.search_page('Getting Started').item()
We can also display that content of the page within JupyterLab or even at the console with
intro_page.show()
In a Jupyter notebook, you would see
Properties of a page¶
The properties of a page can be accessed with the props
attribute of each page object. Assume we have a page acting like a task in a database similar to the Task List example like this:
We search for Task DB
, retrieve all pages in a View and select the Run first Marathon
-page:
task_view = notion.search_db('Task DB').item().get_all_pages()
task = task_view.search_page('Run first Marathon').item()
Note
As Notion rarely has any uniqueness guarantees, many methods return SList, i.e. Single-item List, a special list type for lists that typically hold a single item. An SList
behaves exactly like a normal Python list except of the fact that it provides an additional item method to retrieve the single item or raise an exception otherwise.
To check again for the date of the marathon, and also if we completed this task, we can use props.col_name
, like
print(f'Task "{task.title}" was {task.props.status} on {task.props.due_date}')
to get the output:
Task "Run first Marathon" was Done on 2023-11-24 17:10:00+01:00
The actual property names like status
and due_date
can be easily find out by looking at the schema of the database holding our page, with:
task.parent_db.schema.show()
returning the actual column name, the property type and the Python attribute name within props
:
Name Property Attribute
-------- ---------- -----------
Urgency Formula urgency
Due Date Date due_date
Status Select status
Priority Select priority
Task Title task
It is also possible to access the property directly with the column name using the indexing operator [column name]
, e.g.:
f'Task "{task.title}" was {task.props["Status"]} on {task.props["Due Date"]}'
Working with properties¶
The properties of a page provide access to the actual low-level Python object like int
, float
, datetime
, the str
subtype RichText and so on. There are a few exceptions though, like Select, MultiSelect and Status, where an Option object gives you access to its name, color and description.
To change a page property, we can just assign a new value to the corresponding property, e.g.:
from datetime import datetime, timedelta
old_due_date = task.props.due_date
# assign a datetime Python object
new_due_date_dt = datetime(2024, 1, 1, 12, 0) + timedelta(days=7)
task.props.due_date = new_due_date_dt
assert task.props.due_date.date() == new_due_date_dt.date()
# reassign the old property value object
task.props.due_date = old_due_date
assert task.props.due_date == old_due_date
Those change will also be automatically reflected on the Notion server. So each assignment triggers an update web request.
Here is an example on how to change the task status, which is a select property. First we get the list of all options by accessing the the corresponding column type of the property with:
options = task.parent_db.schema.status.type.options
This generates a dictionary of Option objects:
{'backlog': <Option: 'Backlog' at 0x13513d570>,
'in_progress': <Option: 'In Progress' at 0x13513d630>,
'blocked': <Option: 'Blocked' at 0x13513d420>,
'done': <Option: 'Done' at 0x1350fa140>}
We now assign the In Progress
option to our task with:
task.props.status = options['In Progress']
Info
The functionality around updating select/multi-select properties will be changed in the future to make the experience more user-friendly.