Skip to content

Commit 4e89258

Browse files
committed
add tutorials
1 parent a620db5 commit 4e89258

File tree

2 files changed

+384
-1
lines changed

2 files changed

+384
-1
lines changed
Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
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()

docs/tutorials/python/wiki.md

Lines changed: 141 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,142 @@
11
# Wikis on Projects
2-
![Under Construction](../../assets/under_construction.png)
2+
3+
# Synapse Wiki Models Tutorial
4+
5+
This tutorial demonstrates how to work with Wiki models in the Synapse Python client. Wikis in Synapse provide a way to create rich documentation and collaborative content for projects, folders, files, datasets, and other entities.
6+
7+
## Overview
8+
9+
The Synapse Wiki models include:
10+
- **WikiPage**: The main wiki page model for creating and managing wiki content
11+
- **WikiHeader**: Represents wiki page headers and hierarchy information
12+
- **WikiHistorySnapshot**: Provides access to wiki version history
13+
- **WikiOrderHint**: Manages the order of wiki pages within an entity
14+
15+
## Basic Setup
16+
```python
17+
{!docs/tutorials/python/tutorial_scripts/wiki.py!lines=13-28}
18+
```
19+
20+
## 1. Create, read, and update wiki pages
21+
### Create a new wiki page for the project with plain text markdown
22+
```python
23+
{!docs/tutorials/python/tutorial_scripts/wiki.py!lines=32-36}
24+
```
25+
26+
### OR you can create a wiki page with an existing markdown file
27+
```python
28+
{!docs/tutorials/python/tutorial_scripts/wiki.py!lines=39-44}
29+
```
30+
31+
### Create a new wiki page with updated content
32+
```python
33+
{!docs/tutorials/python/tutorial_scripts/wiki.py!lines=47-52}
34+
```
35+
36+
### Restore the wiki page to the original version
37+
```python
38+
{!docs/tutorials/python/tutorial_scripts/wiki.py!lines=55-63}
39+
```
40+
41+
### Create a sub-wiki page
42+
```python
43+
{!docs/tutorials/python/tutorial_scripts/wiki.py!lines=66-71}
44+
```
45+
46+
### Get an existing wiki page for the project, now you can see one root wiki page and one sub-wiki page
47+
```python
48+
{!docs/tutorials/python/tutorial_scripts/wiki.py!lines=74-75}
49+
```
50+
51+
### Retrieving a Wiki Page
52+
Note: You need to know the wiki page ID or wiki page title to retrieve it
53+
#### Retrieve a Wiki Page with wiki page ID
54+
```python
55+
{!docs/tutorials/python/tutorial_scripts/wiki.py!lines=78-79}
56+
```
57+
58+
#### Retrieve a Wiki Page with wiki page title
59+
```python
60+
{!docs/tutorials/python/tutorial_scripts/wiki.py!lines=82-83}
61+
```
62+
63+
#### Check if the retrieved wiki page is the same as the original wiki page
64+
```python
65+
{!docs/tutorials/python/tutorial_scripts/wiki.py!lines=86-91}
66+
```
67+
68+
## 2. WikiPage Markdown Operations
69+
### Create wiki page from markdown text
70+
```python
71+
{!docs/tutorials/python/tutorial_scripts/wiki.py!lines=95-118}
72+
```
73+
74+
### Create wiki page from a markdown file
75+
```python
76+
{!docs/tutorials/python/tutorial_scripts/wiki.py!lines=122-132}
77+
```
78+
79+
### Download the markdown file
80+
```python
81+
{!docs/tutorials/python/tutorial_scripts/wiki.py!lines=136-143}
82+
```
83+
84+
## 3. WikiPage Attachments Operations
85+
### Create a wiki page with attachments
86+
```python
87+
{!docs/tutorials/python/tutorial_scripts/wiki.py!lines=147-161}
88+
```
89+
### Get the file handles of all attachments on this wiki page.
90+
```python
91+
{!docs/tutorials/python/tutorial_scripts/wiki.py!lines=164-165}
92+
```
93+
### Download an attachment
94+
```python
95+
{!docs/tutorials/python/tutorial_scripts/wiki.py!lines=168-175}
96+
```
97+
98+
### Get attachment URL without downloading
99+
```python
100+
{!docs/tutorials/python/tutorial_scripts/wiki.py!lines=178-182}
101+
```
102+
103+
### Download an attachment preview (WIP)
104+
```python
105+
{!docs/tutorials/python/tutorial_scripts/wiki.py!lines=185-191}
106+
```
107+
#### Get attachment preview URL without downloading (WIP)
108+
109+
110+
## 4. WikiHeader - Working with Wiki Hierarchy
111+
### Getting Wiki Header Tree
112+
```python
113+
{!docs/tutorials/python/tutorial_scripts/wiki.py!lines=197-200}
114+
```
115+
116+
## 5. WikiHistorySnapshot - Version History
117+
118+
### Accessing Wiki History
119+
```python
120+
{!docs/tutorials/python/tutorial_scripts/wiki.py!lines=203-207}
121+
```
122+
123+
## 6. WikiOrderHint - Managing Wiki Order
124+
### Get wiki order hint (No id_list returned, same result getting from direct endpoint calls)
125+
```python
126+
{!docs/tutorials/python/tutorial_scripts/wiki.py!lines=212-213}
127+
```
128+
### Update wiki order hint
129+
```python
130+
{!docs/tutorials/python/tutorial_scripts/wiki.py!lines=216-222}
131+
```
132+
133+
### Deleting a Wiki Page
134+
Note: You need to know the owner ID and wiki page ID to delete a wiki page
135+
```python
136+
{!docs/tutorials/python/tutorial_scripts/wiki.py!lines=225}
137+
```
138+
139+
## clean up
140+
```python
141+
{!docs/tutorials/python/tutorial_scripts/wiki.py!lines=228}
142+
```

0 commit comments

Comments
 (0)