Pingshian Yu
3 min readSep 22, 2023

Notion API with FastAPI (Releasing Daily Leetcode Problem Page’s Public Link)

Recently, I joined a Discord server that encourages its members to solve a LeetCode problem every day, though participation isn’t mandatory. While I don’t manage to solve one every single day, I make it a point to do so on weekdays. However, I encountered some difficulty when it came to copying and pasting the public URLs of Notion pages from a database into the Discord server. I thought it was a trivial task. To simplify this process, I decided to create a Notion API connection with a Linebot that can automatically provide me with the Notion page public link.

  • Here’s my Leetcode Problems Notion Template
Notion Template Link
  • First, let’s talk about some definition & settings:

0. AUTHENTICATION ( Follow the steps and complete the API settings. )

Notion Developers
Create a new Integration
Create a new Integration
Get the Integration Secret
Add Integration into Pages/Databases you want to Process
  1. DATABASE_ID

2. PAGE_ID

  • Then, we can commence our project. Since the setup process for Linebot is quite complex and not directly relevant to the main topic of this article, I’ve opted to use FastAPI instead.
  1. Main function only these lines:
@app.post("/notion/")
async def get_notion_page(
database_id: Annotated[
str, Query(..., title="DATABASE_ID 測試", description="DATABASE_ID 測試")
] = DATABASE_ID
):
# query Notion database
# only filter unchecked rows
# order_by Createed Time
res = NotionConnections.query_db(database_id)

# get the first create row
target_data = res.get("results")[0]

# get page_id from target_data
page_id = target_data.get("id")

# update page's Checked to True by page_id
res = NotionConnections.update_page(page_id)
if res.get("id") == page_id:

# get the title of the page
title = res["properties"]["Name"]["title"][0]["text"]["content"]

# get the public link of the page
public_url = res["public_url"]
logger.warning(f"{title}, page_id: {page_id} has been shared.")

return {"code": 0, "msg": f"{title} share url: {public_url}"}
return {"code": -1, "msg": "update resp no id"}

2. And Below is the content of ‘Connections.py’:

class NotionConnections:
@staticmethod
def query_db(database_id: str) -> dict or None:
url = f"{NOTION_API}/databases/{database_id}/query"

# filter and sorts in post_data
payload = {
"filter": {"property": "Checked", "checkbox": {"equals": False}},
"sorts": [{"property": "Created time", "direction": "ascending"}],
}
r = requests.post(url, headers=NOTION_HEADERS, json=payload)
r.raise_for_status()
if r.status_code == 200:
res = r.json()
return res

@staticmethod
def update_page(page_id: str) -> dict or None:
page_id = page_id.replace("-", "")
url = f"https://api.notion.com/v1/pages/{page_id}"
r = requests.patch(
url,
headers=NOTION_HEADERS,
json={"properties": {"Checked": {"checkbox": True}}},
)
r.raise_for_status()
if r.status_code == 200:
res = r.json()
return res

Additionally, if you wish to obtain the public URL of a page, you need to manually publish the page yourself initially.

  • Finally, below is a demonstration picture of the result achieved by connecting FastAPI with the Notion API:
FastAPI Demo
  • As we can see, the Notion database’s target page has been successfully updated.
Notion Template Result
  • That concludes the article. You can find the code for this article on GitHub by following this link: Github Link

Reference

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

No responses yet

Write a response