|
| 1 | +#!/usr/bin/env python3 |
| 2 | +""" |
| 3 | +Tutorial script demonstrating the Synapse Wiki models functionality. |
| 4 | +
|
| 5 | +This script shows how to: |
| 6 | +1. |
| 7 | +2. Work with wiki headers and hierarchy |
| 8 | +3. Access wiki history |
| 9 | +4. Manage wiki order hints |
| 10 | +5. Handle attachments and markdown content |
| 11 | +6. Download wiki content and attachments |
| 12 | +""" |
| 13 | +import gzip |
| 14 | +import os |
| 15 | +import uuid |
| 16 | + |
| 17 | +from synapseclient import Synapse |
| 18 | +from synapseclient.models import ( |
| 19 | + Project, |
| 20 | + WikiHeader, |
| 21 | + WikiHistorySnapshot, |
| 22 | + WikiOrderHint, |
| 23 | + WikiPage, |
| 24 | +) |
| 25 | + |
| 26 | +# Initialize Synapse client |
| 27 | +syn = Synapse() |
| 28 | +syn.login() |
| 29 | + |
| 30 | +# Create a Synapse Project to work with |
| 31 | +my_test_project = Project( |
| 32 | + name=f"My Test Project_{uuid.uuid4()}", |
| 33 | + description="This is a test project for the wiki tutorial.", |
| 34 | +).store() |
| 35 | +print(f"Created project: {my_test_project.name} with ID: {my_test_project.id}") |
| 36 | + |
| 37 | +# Section1: Create, read, and update wiki pages |
| 38 | +# Create a new wiki page for the project with plain text markdown |
| 39 | +wiki_page_1 = WikiPage( |
| 40 | + owner_id=my_test_project.id, |
| 41 | + title="My Root Wiki Page", |
| 42 | + markdown="# Welcome to My Root Wiki\n\nThis is a sample root wiki page created with the Synapse client.", |
| 43 | +).store() |
| 44 | + |
| 45 | +# OR you can create a wiki page with an existing markdown file |
| 46 | +markdown_file_path = "path/to/your_markdown_file.md" |
| 47 | +wiki_page_1 = WikiPage( |
| 48 | + owner_id=my_test_project.id, |
| 49 | + title="My First Root Wiki Page Version with existing markdown file", |
| 50 | + markdown=markdown_file_path, |
| 51 | +).store() |
| 52 | + |
| 53 | +# Create a new wiki page with updated content |
| 54 | +wiki_page_2 = WikiPage( |
| 55 | + owner_id=my_test_project.id, |
| 56 | + title="My First Root Wiki Page Version 1", |
| 57 | + markdown="# Welcome to My Root Wiki Version 1\n\nThis is a sample root wiki page created with the Synapse client.", |
| 58 | + id=wiki_page_1.id, |
| 59 | +).store() |
| 60 | + |
| 61 | +# Restore the wiki page to the original version |
| 62 | +wiki_page_restored = WikiPage( |
| 63 | + owner_id=my_test_project.id, id=wiki_page_1.id, wiki_version="0" |
| 64 | +).restore() |
| 65 | + |
| 66 | +# check if the content is restored |
| 67 | +comparisons = [ |
| 68 | + wiki_page_1.markdown_file_handle_id == wiki_page_restored.markdown_file_handle_id, |
| 69 | + wiki_page_1.id == wiki_page_restored.id, |
| 70 | + wiki_page_1.title == wiki_page_restored.title, |
| 71 | +] |
| 72 | +print(f"All fields match: {all(comparisons)}") |
| 73 | + |
| 74 | +# Create a sub-wiki page |
| 75 | +sub_wiki = WikiPage( |
| 76 | + owner_id=my_test_project.id, |
| 77 | + title="Sub Wiki Page 1", |
| 78 | + parent_id=wiki_page_1.id, # Use the ID of the parent wiki page we created '633033' |
| 79 | + markdown="# Sub Page 1\n\nThis is a sub-page of another wiki.", |
| 80 | +).store() |
| 81 | + |
| 82 | +# Get an existing wiki page for the project, now you can see one root wiki page and one sub-wiki page |
| 83 | +wiki_header_tree = WikiHeader.get(owner_id=my_test_project.id) |
| 84 | +print(wiki_header_tree) |
| 85 | + |
| 86 | +# Once you know the wiki page id, you can retrieve the wiki page with the id |
| 87 | +retrieved_wiki = WikiPage(owner_id=my_test_project.id, id=sub_wiki.id).get() |
| 88 | +print(f"Retrieved wiki page with title: {retrieved_wiki.title}") |
| 89 | + |
| 90 | +# Or you can retrieve the wiki page with the title |
| 91 | +retrieved_wiki = WikiPage(owner_id=my_test_project.id, title=wiki_page_1.title).get() |
| 92 | +print(f"Retrieved wiki page with title: {retrieved_wiki.title}") |
| 93 | + |
| 94 | +# Check if the retrieved wiki page is the same as the original wiki page |
| 95 | +comparisons = [ |
| 96 | + wiki_page_1.markdown_file_handle_id == retrieved_wiki.markdown_file_handle_id, |
| 97 | + wiki_page_1.id == retrieved_wiki.id, |
| 98 | + wiki_page_1.title == retrieved_wiki.title, |
| 99 | +] |
| 100 | +print(f"All fields match: {all(comparisons)}") |
| 101 | + |
| 102 | +# Section 2: WikiPage Markdown Operations |
| 103 | +# Create wiki page from markdown text |
| 104 | +markdown_content = """# Sample Markdown Content |
| 105 | +
|
| 106 | +## Section 1 |
| 107 | +This is a sample markdown file with multiple sections. |
| 108 | +
|
| 109 | +## Section 2 |
| 110 | +- List item 1 |
| 111 | +- List item 2 |
| 112 | +- List item 3 |
| 113 | +
|
| 114 | +## Code Example |
| 115 | +```python |
| 116 | +def hello_world(): |
| 117 | + print("Hello, World!") |
| 118 | +``` |
| 119 | +""" |
| 120 | + |
| 121 | +# Create wiki page from markdown text |
| 122 | +markdown_wiki = WikiPage( |
| 123 | + owner_id=my_test_project.id, |
| 124 | + parent_id=wiki_page_1.id, |
| 125 | + title="Sub Page 2 created from markdown text", |
| 126 | + markdown=markdown_content, |
| 127 | +).store() |
| 128 | + |
| 129 | +# Create a wiki page from a markdown file |
| 130 | +# Create a temporary markdown gzipped file from the markdown_content |
| 131 | +markdown_file_path = "temp_markdown_file.md.gz" |
| 132 | +with gzip.open(markdown_file_path, "wt", encoding="utf-8") as gz: |
| 133 | + gz.write("This is a markdown file") |
| 134 | + |
| 135 | +# Create wiki page from markdown file |
| 136 | +markdown_wiki = WikiPage( |
| 137 | + owner_id=my_test_project.id, |
| 138 | + parent_id=wiki_page_1.id, |
| 139 | + title="Sub Page 3 created from markdown file", |
| 140 | + markdown=markdown_file_path, |
| 141 | +).store() |
| 142 | + |
| 143 | +# Download the markdown file |
| 144 | +# delete the markdown file after downloading --> check if the file is downloaded |
| 145 | +os.remove(markdown_file_path) |
| 146 | +markdown_file = WikiPage(owner_id=my_test_project.id, id=markdown_wiki.id).get_markdown( |
| 147 | + download_file=True, download_location=".", download_file_name="markdown_file.md" |
| 148 | +) |
| 149 | + |
| 150 | +print(f"Markdown file downloaded to: {markdown_file}") |
| 151 | + |
| 152 | +# Section 3: WikiPage with Attachments |
| 153 | +# Create a temporary file for the attachment |
| 154 | +attachment_file_name = "temp_attachment.txt.gz" |
| 155 | +with gzip.open(attachment_file_name, "wt", encoding="utf-8") as gz: |
| 156 | + gz.write("This is a sample attachment.") |
| 157 | + |
| 158 | +# reformat the attachment file name to be a valid attachment path |
| 159 | +attachment_file_name_reformatted = attachment_file_name.replace(".", "%2E") |
| 160 | +attachment_file_name_reformatted = attachment_file_name_reformatted.replace("_", "%5F") |
| 161 | + |
| 162 | +wiki_with_attachments = WikiPage( |
| 163 | + owner_id=my_test_project.id, |
| 164 | + parent_id=wiki_page_1.id, |
| 165 | + title="Sub Page 4 with Attachments", |
| 166 | + markdown=f"# Sub Page 4 with Attachments\n\nThis is a attachment: ${{previewattachment?fileName={attachment_file_name_reformatted}}}", |
| 167 | + attachments=[attachment_file_name], |
| 168 | +).store() |
| 169 | + |
| 170 | +# Get attachment handles |
| 171 | +attachment_handles = WikiPage( |
| 172 | + owner_id=my_test_project.id, id=wiki_with_attachments.id |
| 173 | +).get_attachment_handles() |
| 174 | +print(f"Found {len(attachment_handles['list'])} attachments") |
| 175 | + |
| 176 | +# Delete the attachment file after uploading --> check if the file is deleted |
| 177 | +os.remove(attachment_file_name) |
| 178 | +# Download an attachment |
| 179 | +wiki_page = WikiPage( |
| 180 | + owner_id=my_test_project.id, id=wiki_with_attachments.id |
| 181 | +).get_attachment( |
| 182 | + file_name=attachment_file_name, |
| 183 | + download_file=True, |
| 184 | + download_location=".", |
| 185 | +) |
| 186 | +print(f"Attachment downloaded: {os.path.exists(attachment_file_name)}") |
| 187 | + |
| 188 | +# Get attachment URL without downloading |
| 189 | +wiki_page_url = WikiPage( |
| 190 | + owner_id=my_test_project.id, id=wiki_with_attachments.id |
| 191 | +).get_attachment( |
| 192 | + file_name="temp_attachment.txt.gz", |
| 193 | + download_file=False, |
| 194 | +) |
| 195 | +print(f"Attachment URL: {wiki_page_url}") |
| 196 | + |
| 197 | +# Download an attachment preview--? Failed to download the attachment preview, synapseclient.core.exceptions.SynapseHTTPError: 404 Client Error: Cannot find a wiki attachment for OwnerID: syn68493645, ObjectType: ENTITY, WikiPageId: 633100, fileName: preview.txt |
| 198 | +attachment_handles = WikiPage( |
| 199 | + owner_id=my_test_project.id, id=wiki_with_attachments.id |
| 200 | +).get_attachment_handles() |
| 201 | +print(f"Attachment handles: {attachment_handles}") |
| 202 | +wiki_page = WikiPage( |
| 203 | + owner_id=my_test_project.id, id=wiki_with_attachments.id |
| 204 | +).get_attachment_preview( |
| 205 | + file_name="preview.txt", |
| 206 | + download_file=True, |
| 207 | + download_location=".", |
| 208 | +) |
| 209 | + |
| 210 | +# Section 4: WikiHeader - Working with Wiki Hierarchy |
| 211 | + |
| 212 | +# Get wiki header tree (hierarchy) |
| 213 | +# Note: Uncomment to actually get the header tree |
| 214 | +headers = WikiHeader.get(owner_id=my_test_project.id) |
| 215 | +print(f"Found {len(headers)} wiki pages in hierarchy") |
| 216 | + |
| 217 | +# Section 5. WikiHistorySnapshot - Version History |
| 218 | +# Get wiki history |
| 219 | +history = WikiHistorySnapshot.get(owner_id=my_test_project.id, id=wiki_page_1.id) |
| 220 | + |
| 221 | +print(f"Found {len(history)} versions in history for {wiki_page_1.title}") |
| 222 | + |
| 223 | +# Section 6. WikiOrderHint - Ordering Wiki Pages |
| 224 | +# Get wiki order hint --> failed to get the order hint |
| 225 | +order_hint = WikiOrderHint(owner_id=my_test_project.id).get() |
| 226 | +print(f"Order hint for {my_test_project.id}: {order_hint}") |
| 227 | + |
| 228 | +# Update wiki order hint |
| 229 | +order_hint.id_list = [wiki_page_1.id] |
| 230 | + |
| 231 | +print(f"Created order hint for {len(order_hint.id_list)} wiki pages") |
| 232 | + |
| 233 | +# Update order hint |
| 234 | +order_hint.id_list = ["633084", "633085", "633086", "633087", "633088"] # Reorder |
| 235 | +order_hint.store() |
| 236 | + |
| 237 | +# Delete a wiki page |
| 238 | +wiki_page_to_delete = WikiPage( |
| 239 | + owner_id=my_test_project.id, id=wiki_with_attachments.id |
| 240 | +).delete() |
| 241 | + |
| 242 | +# clean up |
| 243 | +my_test_project.delete() |
0 commit comments