Skip to content

Commit 1631205

Browse files
committed
Add remaining Confluence v2 implementation files for Phases 1-4
1 parent c066bf0 commit 1631205

6 files changed

+1662
-0
lines changed

atlassian/confluence_base.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,21 @@ class ConfluenceEndpoints:
4646
'comment_by_id': 'api/v2/comments/{id}',
4747
'comment_children': 'api/v2/comments/{id}/children',
4848

49+
# Whiteboard endpoints
50+
'whiteboard': 'api/v2/whiteboards',
51+
'whiteboard_by_id': 'api/v2/whiteboards/{id}',
52+
'whiteboard_children': 'api/v2/whiteboards/{id}/children',
53+
'whiteboard_ancestors': 'api/v2/whiteboards/{id}/ancestors',
54+
55+
# Custom content endpoints
56+
'custom_content': 'api/v2/custom-content',
57+
'custom_content_by_id': 'api/v2/custom-content/{id}',
58+
'custom_content_children': 'api/v2/custom-content/{id}/children',
59+
'custom_content_ancestors': 'api/v2/custom-content/{id}/ancestors',
60+
'custom_content_labels': 'api/v2/custom-content/{id}/labels',
61+
'custom_content_properties': 'api/v2/custom-content/{id}/properties',
62+
'custom_content_property_by_key': 'api/v2/custom-content/{id}/properties/{key}',
63+
4964
# More v2 endpoints will be added in Phase 2 and 3
5065
}
5166

Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Example demonstrating the usage of Whiteboard and Custom Content methods
4+
with the Confluence API v2.
5+
"""
6+
7+
import os
8+
import logging
9+
from pprint import pprint
10+
11+
from atlassian import Confluence
12+
from atlassian.confluence_base import ConfluenceBase
13+
14+
# Set up logging
15+
logging.basicConfig(level=logging.INFO)
16+
17+
# Initialize the Confluence client with API v2
18+
# Use your Confluence Cloud URL, username, and API token
19+
url = os.environ.get('CONFLUENCE_URL')
20+
username = os.environ.get('CONFLUENCE_USERNAME')
21+
api_token = os.environ.get('CONFLUENCE_API_TOKEN')
22+
23+
# Initialize the client with API version 2
24+
confluence = ConfluenceBase.factory(
25+
url=url,
26+
username=username,
27+
password=api_token,
28+
api_version=2
29+
)
30+
31+
def whiteboard_examples(space_id):
32+
"""
33+
Examples of using whiteboard methods with Confluence API v2.
34+
35+
Args:
36+
space_id: ID of the space where whiteboards will be created
37+
"""
38+
print("\n=== WHITEBOARD EXAMPLES ===\n")
39+
40+
# Create a whiteboard
41+
print("Creating whiteboard...")
42+
whiteboard = confluence.create_whiteboard(
43+
space_id=space_id,
44+
title="API Created Whiteboard",
45+
template_key="timeline" # Optional: use a template
46+
)
47+
48+
whiteboard_id = whiteboard['id']
49+
print(f"Created whiteboard with ID: {whiteboard_id}")
50+
print("Whiteboard details:")
51+
pprint(whiteboard)
52+
53+
# Get whiteboard by ID
54+
print("\nRetrieving whiteboard...")
55+
retrieved_whiteboard = confluence.get_whiteboard_by_id(whiteboard_id)
56+
print(f"Retrieved whiteboard title: {retrieved_whiteboard['title']}")
57+
58+
# Create a nested whiteboard
59+
print("\nCreating nested whiteboard...")
60+
nested_whiteboard = confluence.create_whiteboard(
61+
space_id=space_id,
62+
title="Nested Whiteboard",
63+
parent_id=whiteboard_id
64+
)
65+
66+
nested_whiteboard_id = nested_whiteboard['id']
67+
print(f"Created nested whiteboard with ID: {nested_whiteboard_id}")
68+
69+
# Get whiteboard children
70+
print("\nRetrieving whiteboard children...")
71+
children = confluence.get_whiteboard_children(whiteboard_id)
72+
print(f"Whiteboard has {len(children)} children:")
73+
for child in children:
74+
print(f"- {child['title']} (ID: {child['id']})")
75+
76+
# Get whiteboard ancestors
77+
print("\nRetrieving whiteboard ancestors...")
78+
ancestors = confluence.get_whiteboard_ancestors(nested_whiteboard_id)
79+
print(f"Nested whiteboard has {len(ancestors)} ancestors:")
80+
for ancestor in ancestors:
81+
print(f"- {ancestor.get('id')}")
82+
83+
# Delete whiteboards
84+
print("\nDeleting nested whiteboard...")
85+
confluence.delete_whiteboard(nested_whiteboard_id)
86+
print("Nested whiteboard deleted")
87+
88+
print("\nDeleting parent whiteboard...")
89+
confluence.delete_whiteboard(whiteboard_id)
90+
print("Parent whiteboard deleted")
91+
92+
return whiteboard_id
93+
94+
def custom_content_examples(space_id, page_id=None):
95+
"""
96+
Examples of using custom content methods with Confluence API v2.
97+
98+
Args:
99+
space_id: ID of the space where custom content will be created
100+
page_id: (optional) ID of a page to associate custom content with
101+
"""
102+
print("\n=== CUSTOM CONTENT EXAMPLES ===\n")
103+
104+
# Create custom content
105+
print("Creating custom content...")
106+
custom_content = confluence.create_custom_content(
107+
type="my.custom.type", # Define your custom content type
108+
title="API Created Custom Content",
109+
body="<p>This is a test custom content created via API</p>",
110+
space_id=space_id,
111+
page_id=page_id, # Optional: associate with a page
112+
body_format="storage" # Can be storage, atlas_doc_format, or raw
113+
)
114+
115+
custom_content_id = custom_content['id']
116+
print(f"Created custom content with ID: {custom_content_id}")
117+
print("Custom content details:")
118+
pprint(custom_content)
119+
120+
# Get custom content by ID
121+
print("\nRetrieving custom content...")
122+
retrieved_content = confluence.get_custom_content_by_id(
123+
custom_content_id,
124+
body_format="storage"
125+
)
126+
print(f"Retrieved custom content title: {retrieved_content['title']}")
127+
128+
# Update custom content
129+
print("\nUpdating custom content...")
130+
current_version = retrieved_content['version']['number']
131+
updated_content = confluence.update_custom_content(
132+
custom_content_id=custom_content_id,
133+
type="my.custom.type",
134+
title="Updated Custom Content",
135+
body="<p>This content has been updated via API</p>",
136+
status="current",
137+
version_number=current_version + 1,
138+
space_id=space_id,
139+
page_id=page_id,
140+
body_format="storage",
141+
version_message="Updated via API example"
142+
)
143+
144+
print(f"Updated custom content to version: {updated_content['version']['number']}")
145+
146+
# Work with custom content properties
147+
print("\nAdding a property to custom content...")
148+
property_data = {
149+
"color": "blue",
150+
"priority": "high",
151+
"tags": ["example", "api", "v2"]
152+
}
153+
154+
property_key = "my-example-property"
155+
156+
# Create property
157+
created_property = confluence.create_custom_content_property(
158+
custom_content_id=custom_content_id,
159+
key=property_key,
160+
value=property_data
161+
)
162+
163+
print(f"Created property with key: {created_property['key']}")
164+
165+
# Get properties
166+
print("\nRetrieving custom content properties...")
167+
properties = confluence.get_custom_content_properties(custom_content_id)
168+
print(f"Custom content has {len(properties)} properties:")
169+
for prop in properties:
170+
print(f"- {prop['key']}")
171+
172+
# Get specific property
173+
print(f"\nRetrieving specific property '{property_key}'...")
174+
property_details = confluence.get_custom_content_property_by_key(
175+
custom_content_id=custom_content_id,
176+
property_key=property_key
177+
)
178+
print("Property value:")
179+
pprint(property_details['value'])
180+
181+
# Update property
182+
print("\nUpdating property...")
183+
property_data["color"] = "red"
184+
property_data["status"] = "active"
185+
186+
updated_property = confluence.update_custom_content_property(
187+
custom_content_id=custom_content_id,
188+
key=property_key,
189+
value=property_data,
190+
version_number=property_details['version']['number'] + 1
191+
)
192+
193+
print(f"Updated property to version: {updated_property['version']['number']}")
194+
195+
# Add labels to custom content
196+
print("\nAdding labels to custom content...")
197+
label1 = confluence.add_custom_content_label(
198+
custom_content_id=custom_content_id,
199+
label="api-example"
200+
)
201+
202+
label2 = confluence.add_custom_content_label(
203+
custom_content_id=custom_content_id,
204+
label="documentation",
205+
prefix="global"
206+
)
207+
208+
print(f"Added labels: {label1['name']}, {label2['prefix']}:{label2['name']}")
209+
210+
# Get labels
211+
print("\nRetrieving custom content labels...")
212+
labels = confluence.get_custom_content_labels(custom_content_id)
213+
print(f"Custom content has {len(labels)} labels:")
214+
for label in labels:
215+
prefix = f"{label['prefix']}:" if label.get('prefix') else ""
216+
print(f"- {prefix}{label['name']}")
217+
218+
# Create nested custom content
219+
print("\nCreating nested custom content...")
220+
nested_content = confluence.create_custom_content(
221+
type="my.custom.child.type",
222+
title="Nested Custom Content",
223+
body="<p>This is a nested custom content</p>",
224+
custom_content_id=custom_content_id, # Set parent ID
225+
body_format="storage"
226+
)
227+
228+
nested_content_id = nested_content['id']
229+
print(f"Created nested custom content with ID: {nested_content_id}")
230+
231+
# Get children
232+
print("\nRetrieving custom content children...")
233+
children = confluence.get_custom_content_children(custom_content_id)
234+
print(f"Custom content has {len(children)} children:")
235+
for child in children:
236+
print(f"- {child['title']} (ID: {child['id']})")
237+
238+
# Get ancestors
239+
print("\nRetrieving custom content ancestors...")
240+
ancestors = confluence.get_custom_content_ancestors(nested_content_id)
241+
print(f"Nested custom content has {len(ancestors)} ancestors:")
242+
for ancestor in ancestors:
243+
print(f"- {ancestor.get('id')}")
244+
245+
# Clean up - delete custom content
246+
# Delete property first
247+
print("\nDeleting property...")
248+
confluence.delete_custom_content_property(
249+
custom_content_id=custom_content_id,
250+
key=property_key
251+
)
252+
print(f"Deleted property {property_key}")
253+
254+
# Delete label
255+
print("\nDeleting label...")
256+
confluence.delete_custom_content_label(
257+
custom_content_id=custom_content_id,
258+
label="api-example"
259+
)
260+
print("Deleted label 'api-example'")
261+
262+
# Delete nested custom content
263+
print("\nDeleting nested custom content...")
264+
confluence.delete_custom_content(nested_content_id)
265+
print(f"Deleted nested custom content {nested_content_id}")
266+
267+
# Delete parent custom content
268+
print("\nDeleting parent custom content...")
269+
confluence.delete_custom_content(custom_content_id)
270+
print(f"Deleted parent custom content {custom_content_id}")
271+
272+
return custom_content_id
273+
274+
def main():
275+
"""
276+
Main function to run the examples.
277+
"""
278+
# Replace these with actual IDs from your Confluence instance
279+
space_id = "123456" # Replace with a real space ID
280+
page_id = "789012" # Replace with a real page ID (optional)
281+
282+
try:
283+
# Run whiteboard examples
284+
whiteboard_examples(space_id)
285+
286+
# Run custom content examples (page_id is optional)
287+
custom_content_examples(space_id, page_id)
288+
except Exception as e:
289+
logging.error(f"Error occurred: {e}")
290+
291+
if __name__ == "__main__":
292+
logging.info("Running Confluence V2 Content Types Examples")
293+
294+
if not url or not username or not api_token:
295+
logging.error(
296+
"Please set the environment variables: "
297+
"CONFLUENCE_URL, CONFLUENCE_USERNAME, CONFLUENCE_API_TOKEN"
298+
)
299+
else:
300+
main()

0 commit comments

Comments
 (0)