def get_page_text_as_html_with_decorations_and_links(page_id: str):
Fetches the main text content of a Notion page and converts it to HTML.
Handles paragraphs, bullet lists, text decorations, and links.
blocks_response = requests.get(
f"https://api.notion.com/v1/blocks/{page_id}/children", headers=headers
blocks = blocks_response.json().get("results", [])
def apply_decorations(text: str, annotations: dict, href: str = None) -> str:
Applies text decorations (bold, italic, underline) and wraps links based on annotations.
if annotations.get("bold"):
if annotations.get("italic"):
if annotations.get("underline"):
if annotations.get("strikethrough"):
if annotations.get("code"):
text = f"<code>{text}</code>"
text = f"<a href='{href}' target='_blank'>{text}</a>"
block_type = block["type"]
if block_type == "paragraph":
# Extract and decorate text from a paragraph
rich_text = block["paragraph"]["rich_text"]
decorated_text = "".join(
[apply_decorations(rt["text"]["content"], rt["annotations"], rt["href"]) for rt in rich_text]
html_content += f"<p>{decorated_text}</p>\n"
elif block_type == "bulleted_list_item":
# Extract and decorate text from a bullet list item
rich_text = block["bulleted_list_item"]["rich_text"]
decorated_text = "".join(
[apply_decorations(rt["text"]["content"], rt["annotations"], rt["href"]) for rt in rich_text]
html_content += f"<li>{decorated_text}</li>\n"
# Wrap bullet list items in a <ul> if they exist
if "<li>" in html_content:
html_content = html_content.replace("<li>", "<ul>\n<li>", 1)
html_content = html_content.replace("</li>", "</li>\n</ul>", 1)