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 ("\n Retrieving 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 ("\n Creating 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 ("\n Retrieving 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 ("\n Retrieving 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 ("\n Deleting nested whiteboard..." )
85+ confluence .delete_whiteboard (nested_whiteboard_id )
86+ print ("Nested whiteboard deleted" )
87+
88+ print ("\n Deleting 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 ("\n Retrieving 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 ("\n Updating 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 ("\n Adding 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 ("\n Retrieving 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"\n Retrieving 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 ("\n Updating 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 ("\n Adding 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 ("\n Retrieving 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 ("\n Creating 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 ("\n Retrieving 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 ("\n Retrieving 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 ("\n Deleting 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 ("\n Deleting 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 ("\n Deleting 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 ("\n Deleting 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