msfabricpysdkcore 0.0.3__py3-none-any.whl → 0.0.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,378 @@
1
+ import json
2
+ from time import sleep
3
+
4
+ import requests
5
+ from msfabricpysdkcore.long_running_operation import check_long_running_operation
6
+
7
+ class Domain:
8
+ """Class to represent a domain in Microsoft Fabric"""
9
+
10
+ def __init__(self, id, display_name, description, parent_domain_id, contributors_scope, auth):
11
+ """Constructor for the Domain class
12
+
13
+ Args:
14
+ id (str): The ID of the domain
15
+ display_name (str): The display name of the domain
16
+ description (str): The description of the domain
17
+ parent_domain_id (str): The parent domain ID of the domain
18
+ contributors_scope (str): The contributors scope of the domain
19
+ Returns:
20
+ Domain: The Domain object created"""
21
+
22
+ self.id = id
23
+ self.display_name = display_name
24
+ self.description = description
25
+ self.parent_domain_id = parent_domain_id
26
+ self.contributors_scope = contributors_scope
27
+
28
+ self.auth = auth
29
+
30
+ def __str__(self):
31
+ """Method to return a string representation of the Domain object
32
+
33
+ Returns:
34
+ str: The string representation of the Domain object
35
+ """
36
+ dic = {
37
+ 'id': self.id,
38
+ 'display_name': self.display_name,
39
+ 'description': self.description,
40
+ 'parent_domain_id': self.parent_domain_id,
41
+ 'contributors_scope': self.contributors_scope
42
+ }
43
+ return json.dumps(dic, indent=2)
44
+
45
+ def __repr__(self) -> str:
46
+ return self.__str__()
47
+
48
+ def from_dict(dic, auth):
49
+ """Method to create a Domain object from a dictionary
50
+
51
+ Args:
52
+ dic (dict): The dictionary containing the domain information
53
+ Returns:
54
+ Domain: The Domain object created from the dictionary
55
+
56
+ """
57
+ if "display_name" not in dic:
58
+ dic["display_name"] = dic["displayName"]
59
+ if "parent_domain_id" not in dic:
60
+ dic["parent_domain_id"] = dic["parentDomainId"]
61
+ if "contributors_scope" not in dic:
62
+ dic["contributors_scope"] = dic["contributorsScope"]
63
+ return Domain(id=dic['id'], display_name=dic['display_name'],
64
+ description=dic['description'], parent_domain_id=dic['parent_domain_id'],
65
+ contributors_scope=dic['contributors_scope'], auth=auth)
66
+
67
+ def list_domain_workspaces(self, workspace_objects = False, continuationToken = None):
68
+ """Method to list the workspaces in the domain
69
+
70
+ Args:
71
+ continuationToken (str): The continuation token to use for pagination
72
+ Returns:
73
+ list: The list of workspaces in the domain
74
+ """
75
+ if workspace_objects:
76
+ from msfabricpysdkcore import FabricClientCore
77
+ fc = FabricClientCore()
78
+
79
+ url = f"https://api.fabric.microsoft.com/v1/admin/domains/{self.id}/workspaces"
80
+ if continuationToken:
81
+ url = f"{url}?continuationToken={continuationToken}"
82
+
83
+ for _ in range(10):
84
+ response = requests.get(url=url, headers=self.auth.get_headers())
85
+ if response.status_code == 429:
86
+ print("Too many requests, waiting 10 seconds")
87
+ sleep(10)
88
+ continue
89
+ if response.status_code not in (200, 429):
90
+ print(response.status_code)
91
+ print(response.text)
92
+ raise Exception(f"Error listing workspaces: {response.text}")
93
+ break
94
+
95
+ resp_dict = json.loads(response.text)
96
+ workspaces = resp_dict["value"]
97
+
98
+ if workspace_objects:
99
+ workspaces = [fc.get_workspace_by_id(workspace["id"]) for workspace in workspaces]
100
+
101
+ if "continuationToken" in resp_dict:
102
+ workspaces_next = self.list_domain_workspaces(continuationToken=resp_dict["continuationToken"])
103
+ workspaces.extend(workspaces_next)
104
+
105
+ return workspaces
106
+
107
+ def delete(self):
108
+ """Method to delete the domain
109
+
110
+ Returns:
111
+ int: The status code of the response
112
+ """
113
+ # DELETE https://api.fabric.microsoft.com/v1/admin/domains/{domainId}
114
+ url = f"https://api.fabric.microsoft.com/v1/admin/domains/{self.id}"
115
+ for _ in range(10):
116
+ response = requests.delete(url=url, headers=self.auth.get_headers())
117
+ if response.status_code == 429:
118
+ print("Too many requests, waiting 10 seconds")
119
+ sleep(10)
120
+ continue
121
+ if response.status_code not in (200, 429):
122
+ print(response.status_code)
123
+ print(response.text)
124
+ raise Exception(f"Error deleting domain: {response.text}")
125
+ break
126
+
127
+ return response.status_code
128
+
129
+
130
+ # PATCH https://api.fabric.microsoft.com/v1/admin/domains/{domainId}
131
+
132
+ def update(self, description = None, display_name = None, contributors_scope = None):
133
+ """Method to update the domain
134
+
135
+ Args:
136
+ description (str): The description of the domain
137
+ display_name (str): The display name of the domain
138
+ contributors_scope (str): The contributors scope of the domain
139
+ Returns:
140
+ Domain: The Domain object created from the dictionary
141
+ """
142
+ url = f"https://api.fabric.microsoft.com/v1/admin/domains/{self.id}"
143
+ body = {}
144
+ if description:
145
+ body["description"] = description
146
+ else:
147
+ body["description"] = self.description
148
+
149
+ if display_name:
150
+ body["displayName"] = display_name
151
+ else:
152
+ body["displayName"] = self.display_name
153
+
154
+ if contributors_scope:
155
+ body["contributorsScope"] = contributors_scope
156
+ else:
157
+ body["contributorsScope"] = self.contributors_scope
158
+
159
+ for _ in range(10):
160
+ response = requests.patch(url=url, headers=self.auth.get_headers(), json=body)
161
+ if response.status_code == 429:
162
+ print("Too many requests, waiting 10 seconds")
163
+ sleep(10)
164
+ continue
165
+ if response.status_code not in (200, 429):
166
+ print(response.status_code)
167
+ print(response.text)
168
+ raise Exception(f"Error updating domain: {response.text}")
169
+ break
170
+
171
+ self.description = body["description"]
172
+ self.display_name = body["displayName"]
173
+ self.contributors_scope = body["contributorsScope"]
174
+
175
+ return self
176
+
177
+ def assign_workspaces_by_capacities(self, capacities_ids, wait_for_completion=True):
178
+ """Method to assign workspaces to the domain based on capacities_ids
179
+
180
+ Args:
181
+ capacities_ids (list): The list of capacitiy ids to assign workspaces
182
+ Returns:
183
+ int: The status code of the response
184
+ """
185
+ # POST https://api.fabric.microsoft.com/v1/admin/domains/{domainId}/assignWorkspacesByCapacities
186
+ url = f"https://api.fabric.microsoft.com/v1/admin/domains/{self.id}/assignWorkspacesByCapacities"
187
+
188
+ body = {
189
+ "capacitiesIds": capacities_ids
190
+ }
191
+
192
+ for _ in range(10):
193
+ response = requests.post(url=url, headers=self.auth.get_headers(), json=body)
194
+ if response.status_code == 429:
195
+ print("Too many requests, waiting 10 seconds")
196
+ sleep(10)
197
+ continue
198
+ if response.status_code == 202 and wait_for_completion:
199
+ check_long_running_operation(response.headers, self.auth)
200
+ if response.status_code not in (202, 429):
201
+ print(response.status_code)
202
+ print(response.text)
203
+ raise Exception(f"Error assigning workspaces by capacities: {response.text}")
204
+ break
205
+
206
+ return response.status_code
207
+
208
+
209
+ def assign_workspaces_by_ids(self, workspaces_ids):
210
+
211
+ """Method to assign workspaces to the domain based on workspaces_ids
212
+
213
+ Args:
214
+ workspaces_ids (list): The list of workspace ids to assign workspaces
215
+ Returns:
216
+ int: The status code of the response
217
+ """
218
+ url = f"https://api.fabric.microsoft.com/v1/admin/domains/{self.id}/assignWorkspaces"
219
+ body = {
220
+ "workspacesIds": workspaces_ids
221
+ }
222
+
223
+ for _ in range(10):
224
+ response = requests.post(url=url, headers=self.auth.get_headers(), json=body)
225
+ if response.status_code == 429:
226
+ print("Too many requests, waiting 10 seconds")
227
+ sleep(10)
228
+ continue
229
+ if response.status_code not in (200, 429):
230
+ print(response.status_code)
231
+ print(response.text)
232
+ raise Exception(f"Error assigning workspaces by ids: {response.text}")
233
+ break
234
+
235
+ return response.status_code
236
+
237
+
238
+ def assign_workspaces_by_principals(self, principals, wait_for_completion=True):
239
+ """Method to assign workspaces to the domain based on principals
240
+
241
+ Args:
242
+ principals (list): The list of principals to assign workspaces
243
+ Returns:
244
+ int: The status code of the response
245
+ """
246
+ url = f"https://api.fabric.microsoft.com/v1/admin/domains/{self.id}/assignWorkspacesByPrincipals"
247
+ body = {
248
+ "principals": principals
249
+ }
250
+
251
+ for _ in range(10):
252
+ response = requests.post(url=url, headers=self.auth.get_headers(), json=body)
253
+ if response.status_code == 429:
254
+ print("Too many requests, waiting 10 seconds")
255
+ sleep(10)
256
+ continue
257
+ if response.status_code == 202 and wait_for_completion:
258
+ check_long_running_operation(response.headers, self.auth)
259
+ if response.status_code not in (202, 429):
260
+ print(response.status_code)
261
+ print(response.text)
262
+ raise Exception(f"Error assigning workspaces by principals: {response.text}")
263
+ break
264
+
265
+ return response.status_code
266
+
267
+ # POST https://api.fabric.microsoft.com/v1/admin/domains/{domainId}/roleAssignments/bulkAssign
268
+
269
+ def role_assignments_bulk_assign(self, type, principals):
270
+ """Method to bulk assign role assignments
271
+
272
+ Args:
273
+ type (str): The type of the role assignment
274
+ principals (list): The list of principals to assign the role
275
+ Returns:
276
+ int: The status code of the response
277
+ """
278
+
279
+ url = f"https://api.fabric.microsoft.com/v1/admin/domains/{self.id}/roleAssignments/bulkAssign"
280
+ body = {
281
+ "type": type,
282
+ "principals": principals
283
+ }
284
+
285
+ for _ in range(10):
286
+ response = requests.post(url=url, headers=self.auth.get_headers(), json=body)
287
+ if response.status_code == 429:
288
+ print("Too many requests, waiting 10 seconds")
289
+ sleep(10)
290
+ continue
291
+ if response.status_code not in (200, 429):
292
+ print(response.status_code)
293
+ print(response.text)
294
+ raise Exception(f"Error bulk assigning role assignments: {response.text}")
295
+ break
296
+
297
+ return response.status_code
298
+
299
+
300
+ def role_assignments_bulk_unassign(self, type, principals):
301
+ """Method to bulk unassign role assignments
302
+
303
+ Args:
304
+ type (str): The type of the role assignment
305
+ principals (list): The list of principals to unassign the role
306
+ Returns:
307
+ int: The status code of the response
308
+ """
309
+
310
+ url = f"https://api.fabric.microsoft.com/v1/admin/domains/{self.id}/roleAssignments/bulkUnassign"
311
+ body = {
312
+ "type": type,
313
+ "principals": principals
314
+ }
315
+
316
+ for _ in range(10):
317
+ response = requests.post(url=url, headers=self.auth.get_headers(), json=body)
318
+ if response.status_code == 429:
319
+ print("Too many requests, waiting 10 seconds")
320
+ sleep(10)
321
+ continue
322
+ if response.status_code not in (200, 429):
323
+ print(response.status_code)
324
+ print(response.text)
325
+ raise Exception(f"Error bulk unassigning role assignments: {response.text}")
326
+ break
327
+
328
+ return response.status_code
329
+
330
+
331
+ def unassign_all_workspaces(self):
332
+ """Method to unassign all workspaces from the domain
333
+
334
+ Returns:
335
+ int: The status code of the response
336
+ """
337
+ url = f"https://api.fabric.microsoft.com/v1/admin/domains/{self.id}/unassignAllWorkspaces"
338
+
339
+ for _ in range(10):
340
+ response = requests.post(url=url, headers=self.auth.get_headers())
341
+ if response.status_code == 429:
342
+ print("Too many requests, waiting 10 seconds")
343
+ sleep(10)
344
+ continue
345
+ if response.status_code not in (200, 429):
346
+ print(response.status_code)
347
+ print(response.text)
348
+ raise Exception(f"Error unassigning all workspaces: {response.text}")
349
+ break
350
+
351
+ return response.status_code
352
+
353
+ def unassign_workspaces_by_ids(self, workspace_ids):
354
+ """Method to unassign workspaces from the domain
355
+
356
+ Args:
357
+ workspace_ids (list): The list of workspace ids to unassign
358
+ Returns:
359
+ int: The status code of the response
360
+ """
361
+ url = f"https://api.fabric.microsoft.com/v1/admin/domains/{self.id}/unassignWorkspaces"
362
+ body = {
363
+ "workspacesIds": workspace_ids
364
+ }
365
+
366
+ for _ in range(10):
367
+ response = requests.post(url=url, headers=self.auth.get_headers(), json=body)
368
+ if response.status_code == 429:
369
+ print("Too many requests, waiting 10 seconds")
370
+ sleep(10)
371
+ continue
372
+ if response.status_code not in (200, 429):
373
+ print(response.status_code)
374
+ print(response.text)
375
+ raise Exception(f"Error unassigning workspaces by ids: {response.text}")
376
+ break
377
+
378
+ return response.status_code
msfabricpysdkcore/item.py CHANGED
@@ -35,6 +35,9 @@ class Item:
35
35
  }
36
36
  return json.dumps(dict_, indent=2)
37
37
 
38
+ def __repr__(self) -> str:
39
+ return self.__str__()
40
+
38
41
  def from_dict(item_dict, auth):
39
42
  """Create Item object from dictionary"""
40
43
 
@@ -39,6 +39,9 @@ class JobInstance:
39
39
  }
40
40
  return json.dumps(dict_, indent=2)
41
41
 
42
+ def __repr__(self) -> str:
43
+ return self.__str__()
44
+
42
45
  def from_dict(job_dict, auth):
43
46
  """Create JobInstance object from dictionary"""
44
47
  return JobInstance(id=job_dict['id'], item_id=job_dict['itemId'], workspace_id=job_dict['workspaceId'],
@@ -27,6 +27,9 @@ class OneLakeShortcut:
27
27
  }
28
28
  return json.dumps(dict_, indent=2)
29
29
 
30
+ def __repr__(self) -> str:
31
+ return self.__str__()
32
+
30
33
  def from_dict(short_dict, auth):
31
34
  """Create OneLakeShortCut object from dictionary"""
32
35
  return OneLakeShortcut(name=short_dict['name'],
@@ -0,0 +1,69 @@
1
+ import unittest
2
+ from dotenv import load_dotenv
3
+ from msfabricpysdkcore import FabricClientAdmin
4
+
5
+ load_dotenv()
6
+
7
+ class TestFabricClientCore(unittest.TestCase):
8
+
9
+ def __init__(self, *args, **kwargs):
10
+ super(TestFabricClientCore, self).__init__(*args, **kwargs)
11
+
12
+
13
+ def test_domains(self):
14
+ fca = FabricClientAdmin()
15
+
16
+ user_id = 'b4f4e299-e6e1-4667-886c-57e4a8dde1c2'
17
+
18
+ # List workspaces
19
+ ws = fca.list_workspaces(name="testworkspace")[0]
20
+
21
+ self.assertEqual(ws.name, "testworkspace")
22
+
23
+ # Get workspace
24
+ ws_clone = fca.get_workspace(workspace_id=ws.id)
25
+
26
+ self.assertEqual(ws.id, ws_clone.id)
27
+
28
+ # Get workspace access details
29
+
30
+ ws_access = fca.get_workspace_access_details(ws.id)
31
+ principials = ws_access["accessDetails"]
32
+ principials_ids = [p["principal"]["id"] for p in principials]
33
+ self.assertIn(user_id, principials_ids)
34
+
35
+ # Get access entities
36
+
37
+ access_entities = fca.get_access_entities(user_id, type="Notebook")
38
+ self.assertGreater(len(access_entities), 0)
39
+
40
+ # Get tenant settings
41
+
42
+ tenant_settings = fca.get_tenant_settings()
43
+ self.assertGreater(len(tenant_settings["tenantSettings"]), 0)
44
+
45
+ # Get capacity tenant settings overrides
46
+
47
+ overrides = fca.get_capacities_tenant_settings_overrides()
48
+ self.assertGreater(len(overrides), -1)
49
+
50
+ # List items
51
+
52
+ item_list = fca.list_items(workspace_id=ws.id)
53
+ self.assertGreater(len(item_list), 0)
54
+
55
+ # Get item
56
+
57
+ item = fca.get_item(workspace_id=ws.id, item_id=item_list[0].id)
58
+ self.assertEqual(item.id, item_list[0].id)
59
+
60
+ # Get item access details
61
+
62
+ item_access = fca.get_item_access_details(workspace_id=ws.id, item_id=item_list[0].id)
63
+ principials = item_access["accessDetails"]
64
+
65
+ principials_ids = [p["principal"]["id"] for p in principials]
66
+
67
+ self.assertIn(user_id, principials_ids)
68
+
69
+
@@ -0,0 +1,125 @@
1
+ import unittest
2
+ from dotenv import load_dotenv
3
+ from datetime import datetime
4
+ from msfabricpysdkcore import FabricClientCore, FabricClientAdmin
5
+
6
+ load_dotenv()
7
+
8
+ class TestFabricClientCore(unittest.TestCase):
9
+
10
+ def __init__(self, *args, **kwargs):
11
+ super(TestFabricClientCore, self).__init__(*args, **kwargs)
12
+
13
+
14
+ def test_domains(self):
15
+ fcc = FabricClientCore()
16
+ fca = FabricClientAdmin()
17
+
18
+ ws = fcc.get_workspace_by_name("sdktestdomains")
19
+ cap = fcc.get_capacity(capacity_id=ws.capacity_id)
20
+ principal = {'id': 'b4f4e299-e6e1-4667-886c-57e4a8dde1c2', 'type': 'User'}
21
+
22
+ # Delete if exists
23
+ try:
24
+ domain = fca.get_domain_by_name("sdktestdomains")
25
+ domain.delete()
26
+ except:
27
+ pass
28
+ try:
29
+ domain = fca.get_domain_by_name("sdktestdomains2")
30
+ domain.delete()
31
+ except:
32
+ pass
33
+
34
+ # Create domain
35
+ domain_name = "sdktestdomains"
36
+ domain = fca.create_domain(display_name=domain_name)
37
+ self.assertIsNotNone(domain.id)
38
+ self.assertEqual(domain.display_name, domain_name)
39
+
40
+ # Get domain by name
41
+ domain_clone = fca.get_domain_by_name(domain_name)
42
+ self.assertIsNotNone(domain_clone.id)
43
+ self.assertEqual(domain_clone.display_name, domain_name)
44
+
45
+ # Get domain by id
46
+ domain_clone = fca.get_domain_by_id(domain.id)
47
+ self.assertIsNotNone(domain_clone.id)
48
+ self.assertEqual(domain_clone.display_name, domain_name)
49
+
50
+ # List domains
51
+ domains = fca.list_domains()
52
+ self.assertGreater(len(domains), 0)
53
+ domains_ids = [d.id for d in domains]
54
+ self.assertIn(domain.id, domains_ids)
55
+
56
+ # Update domain
57
+ domain_new_name = "sdktestdomains2"
58
+ domain_clone = fca.update_domain(domain.id, display_name=domain_new_name)
59
+ self.assertEqual(domain_clone.display_name, domain_new_name)
60
+
61
+ # Assign domain workspaces by Ids
62
+ status_code = fca.assign_domain_workspaces_by_ids(domain.id, [ws.id])
63
+ self.assertEqual(status_code, 200)
64
+
65
+ # List domain workspaces
66
+ workspaces = fca.list_domain_workspaces(domain.id, workspace_objects=True)
67
+ self.assertGreater(len(workspaces), 0)
68
+ workspaces_ids = [w.id for w in workspaces]
69
+ self.assertIn(ws.id, workspaces_ids)
70
+
71
+ # Unassign domain workspaces by ids
72
+ status_code = fca.unassign_domain_workspaces_by_ids(domain.id, [ws.id])
73
+ self.assertEqual(status_code, 200)
74
+
75
+ workspaces = fca.list_domain_workspaces(domain.id)
76
+ self.assertEqual(len(workspaces), 0)
77
+
78
+ # Assign domain workspaces by capacities
79
+ status_code = fca.assign_domain_workspaces_by_capacities(domain.id, [cap.id])
80
+ self.assertEqual(status_code, 202)
81
+
82
+ workspaces = fca.list_domain_workspaces(domain.id, workspace_objects=True)
83
+ self.assertGreater(len(workspaces), 0)
84
+ workspaces_ids = [w.id for w in workspaces]
85
+ self.assertIn(ws.id, workspaces_ids)
86
+
87
+ # Unassign all domain workspaces
88
+ status_code = fca.unassign_all_domain_workspaces(domain.id)
89
+ self.assertEqual(status_code, 200)
90
+
91
+ workspaces = fca.list_domain_workspaces(domain.id)
92
+ self.assertEqual(len(workspaces), 0)
93
+
94
+ # Assign domain workspaces by principals
95
+ status_code = fca.assign_domains_workspaces_by_principals(domain.id, [principal], wait_for_completion=True)
96
+
97
+ self.assertEqual(status_code, 202)
98
+
99
+ workspaces = fca.list_domain_workspaces(domain.id, workspace_objects=True)
100
+ self.assertGreater(len(workspaces), 0)
101
+ workspaces_ids = [w.id for w in workspaces]
102
+ self.assertIn(ws.id, workspaces_ids)
103
+
104
+ # Role assignments bulk assign
105
+
106
+ principal_2 = {'id': '6edbc444-16cd-43f4-ae48-cbe734b89657', 'type': 'User'}
107
+ principals = [principal, principal_2]
108
+
109
+ status_code = fca.role_assignments_bulk_assign(domain.id, "Contributors", principals)
110
+
111
+ self.assertEqual(status_code, 200)
112
+
113
+ # Role assignments bulk unassign
114
+ status_code = fca.role_assignments_bulk_unassign(domain.id, "Contributors", [principal_2])
115
+
116
+ self.assertEqual(status_code, 200)
117
+
118
+ # Delete domain
119
+ status_code = fca.delete_domain(domain.id)
120
+
121
+ self.assertEqual(status_code, 200)
122
+
123
+ domains = fca.list_domains()
124
+ domains_ids = [d.id for d in domains]
125
+ self.assertNotIn(domain.id, domains_ids)
@@ -1,5 +1,5 @@
1
1
  import unittest
2
- from msfabricpysdkcore.client import FabricClientCore
2
+ from msfabricpysdkcore.coreapi import FabricClientCore
3
3
  from datetime import datetime
4
4
  from dotenv import load_dotenv
5
5
 
@@ -2,7 +2,7 @@ import unittest
2
2
  from datetime import datetime
3
3
  from dotenv import load_dotenv
4
4
  from time import sleep
5
- from msfabricpysdkcore.client import FabricClientCore
5
+ from msfabricpysdkcore.coreapi import FabricClientCore
6
6
 
7
7
  class TestFabricClientCore(unittest.TestCase):
8
8
 
@@ -1,7 +1,5 @@
1
1
  import unittest
2
- from msfabricpysdkcore.client import FabricClientCore
3
- from datetime import datetime
4
- from dotenv import load_dotenv
2
+ from msfabricpysdkcore.coreapi import FabricClientCore
5
3
 
6
4
  class TestFabricClientCore(unittest.TestCase):
7
5
 
@@ -1,5 +1,5 @@
1
1
  import unittest
2
- from msfabricpysdkcore.client import FabricClientCore
2
+ from msfabricpysdkcore.coreapi import FabricClientCore
3
3
  from datetime import datetime
4
4
  from dotenv import load_dotenv
5
5
 
@@ -1,7 +1,7 @@
1
1
  import unittest
2
2
  from dotenv import load_dotenv
3
3
  from datetime import datetime
4
- from msfabricpysdkcore.client import FabricClientCore
4
+ from msfabricpysdkcore.coreapi import FabricClientCore
5
5
 
6
6
  load_dotenv()
7
7
 
@@ -33,6 +33,9 @@ class Workspace:
33
33
  }
34
34
  return json.dumps(dict_, indent=2)
35
35
 
36
+ def __repr__(self) -> str:
37
+ return self.__str__()
38
+
36
39
  def get_role_assignments(self):
37
40
  """Get role assignments for the workspace"""
38
41
  url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.id}/roleAssignments"