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,535 @@
1
+ import requests
2
+ import json
3
+ import os
4
+ from time import sleep
5
+
6
+ from msfabricpysdkcore.admin_item import AdminItem
7
+ from msfabricpysdkcore.client import FabricClient
8
+ from msfabricpysdkcore.domain import Domain
9
+ from msfabricpysdkcore.admin_workspace import AdminWorkspace
10
+
11
+ class FabricClientAdmin(FabricClient):
12
+ """FabricClientAdmin class to interact with Fabric Admin APIs"""
13
+
14
+ def __init__(self, tenant_id = None, client_id = None, client_secret = None) -> None:
15
+ """Initialize FabricClientAdmin object"""
16
+ super().__init__(tenant_id, client_id, client_secret)
17
+
18
+
19
+ def list_domains(self, nonEmptyOnly=False):
20
+ """List all domains in the tenant
21
+
22
+ Args:
23
+ nonEmptyOnly (bool): Whether to list only non-empty domains
24
+ Returns:
25
+ list: List of Domain objects"""
26
+ url = "https://api.fabric.microsoft.com/v1/admin/domains"
27
+ if nonEmptyOnly:
28
+ url = f"{url}?nonEmptyOnly=True"
29
+
30
+ for _ in range(10):
31
+ response = requests.get(url=url, headers=self.auth.get_headers())
32
+ if response.status_code == 429:
33
+ print("Too many requests, waiting 10 seconds")
34
+ sleep(10)
35
+ continue
36
+ if response.status_code not in (200, 429):
37
+ print(response.status_code)
38
+ print(response.text)
39
+ raise Exception(f"Error listing domains: {response.text}")
40
+ break
41
+
42
+ resp_dict = json.loads(response.text)
43
+ domains = resp_dict["domains"]
44
+
45
+ domains = [Domain.from_dict(i, self.auth) for i in domains]
46
+ return domains
47
+
48
+ def get_domain_by_id(self, domain_id):
49
+ """Method to get a domain by ID
50
+
51
+ Args:
52
+ domain_id (str): The ID of the domain
53
+ Returns:
54
+ Domain: The Domain object
55
+ """
56
+ url = f"https://api.fabric.microsoft.com/v1/admin/domains/{domain_id}"
57
+ for _ in range(10):
58
+ response = requests.get(url=url, headers=self.auth.get_headers())
59
+ if response.status_code == 429:
60
+ print("Too many requests, waiting 10 seconds")
61
+ sleep(10)
62
+ continue
63
+ if response.status_code not in (200, 429):
64
+ print(response.status_code)
65
+ print(response.text)
66
+ raise Exception(f"Error getting domain: {response.text}")
67
+ break
68
+
69
+ domain_dict = json.loads(response.text)
70
+ domain = Domain.from_dict(domain_dict, self.auth)
71
+ return domain
72
+
73
+ def get_domain_by_name(self, domain_name):
74
+ """Method to get a domain by name
75
+
76
+ Args:
77
+ domain_name (str): The name of the domain
78
+ Returns:
79
+ Domain: The Domain object
80
+ """
81
+ domains = self.list_domains()
82
+ for domain in domains:
83
+ if domain.display_name == domain_name:
84
+ return domain
85
+ raise ValueError("Domain not found")
86
+
87
+ def get_domain(self, domain_id = None, domain_name = None):
88
+ """Get a domain by ID or name
89
+
90
+ Args:
91
+ domain_id (str): The ID of the domain
92
+ domain_name (str): The name of the domain
93
+ Returns:
94
+ Domain: The Domain object
95
+ """
96
+ if domain_id:
97
+ return self.get_domain_by_id(domain_id)
98
+ if domain_name:
99
+ return self.get_domain_by_name(domain_name)
100
+ raise ValueError("Either domain_id or domain_name must be provided")
101
+
102
+ def create_domain(self, display_name, description = None, parent_domain_id = None):
103
+ """Method to create a domain
104
+
105
+ Args:
106
+ display_name (str): The display name of the domain
107
+ description (str): The description of the domain
108
+ parent_domain_id (str): The parent domain ID
109
+ Returns:
110
+ Domain: The Domain object
111
+ """
112
+ # POST https://api.fabric.microsoft.com/v1/admin/domains
113
+ url = "https://api.fabric.microsoft.com/v1/admin/domains"
114
+ body = {
115
+ "displayName": display_name
116
+ }
117
+ if description:
118
+ body["description"] = description
119
+ if parent_domain_id:
120
+ body["parentDomainId"] = parent_domain_id
121
+
122
+ for _ in range(10):
123
+ response = requests.post(url=url, headers=self.auth.get_headers(), json=body)
124
+ if response.status_code == 429:
125
+ print("Too many requests, waiting 10 seconds")
126
+ sleep(10)
127
+ continue
128
+ if response.status_code not in (200, 201, 429):
129
+ print(response.status_code)
130
+ print(response.text)
131
+ raise Exception(f"Error creating domain: {response.text}")
132
+ break
133
+
134
+ domain_dict = json.loads(response.text)
135
+ domain = Domain.from_dict(domain_dict, self.auth)
136
+ return domain
137
+
138
+ def delete_domain(self, domain_id):
139
+ """Method to delete a domain
140
+
141
+ Args:
142
+ domain_id (str): The ID of the domain
143
+ Returns:
144
+ status_code (int): The status code of the request
145
+ """
146
+ return self.get_domain_by_id(domain_id).delete()
147
+
148
+ def update_domain(self, domain_id, description = None, display_name = None, contributors_scope = None):
149
+ """Method to update a domain
150
+
151
+ Args:
152
+ domain_id (str): The ID of the domain
153
+ Returns:
154
+ Domain: The Domain object
155
+ """
156
+ domain = self.get_domain_by_id(domain_id)
157
+ return domain.update(description = description, display_name = display_name, contributors_scope = contributors_scope)
158
+
159
+ def list_domain_workspaces(self, domain_id, workspace_objects = False):
160
+ """List workspaces in a domain
161
+
162
+ Args:
163
+ domain_id (str): The ID of the domain
164
+ Returns:
165
+ list: List of Workspace objects
166
+ """
167
+ domain = self.get_domain_by_id(domain_id)
168
+ return domain.list_domain_workspaces(workspace_objects=workspace_objects)
169
+
170
+ def assign_domain_workspaces_by_capacities(self, domain_id, capacities_ids, wait_for_completion=True):
171
+ """Assign workspaces to a domain by capacities
172
+
173
+ Args:
174
+ domain_id (str): The ID of the domain
175
+ capacities (list): The list of capacity IDs
176
+ wait_for_completion (bool): Whether to wait for the operation to complete
177
+ Returns:
178
+ int: The status code of the response
179
+ """
180
+ domain = self.get_domain_by_id(domain_id)
181
+ return domain.assign_workspaces_by_capacities(capacities_ids, wait_for_completion)
182
+
183
+ def assign_domain_workspaces_by_ids(self, domain_id, workspace_ids):
184
+ """Assign workspaces to a domain by workspace IDs
185
+
186
+ Args:
187
+ domain_id (str): The ID of the domain
188
+ workspace_ids (list): The list of workspace IDs
189
+ wait_for_completion (bool): Whether to wait for the operation to complete
190
+ Returns:
191
+ int: The status code of the response
192
+ """
193
+ domain = self.get_domain_by_id(domain_id)
194
+ return domain.assign_workspaces_by_ids(workspace_ids)
195
+
196
+ def assign_domains_workspaces_by_principals(self, domain_id, principals, wait_for_completion=True):
197
+ """Assign workspaces to a domain by principals
198
+
199
+ Args:
200
+ domain_id (str): The ID of the domain
201
+ principals (list): The list of principal IDs
202
+ wait_for_completion (bool): Whether to wait for the operation to complete
203
+ Returns:
204
+ int: The status code of the response
205
+ """
206
+ domain = self.get_domain_by_id(domain_id)
207
+ return domain.assign_workspaces_by_principals(principals=principals, wait_for_completion=wait_for_completion)
208
+
209
+ def role_assignments_bulk_assign(self, domain_id, type, principals):
210
+ """Assign a role to principals in bulk
211
+
212
+ Args:
213
+ domain_id (str): The ID of the domain
214
+ type (str): The type of the role assignment
215
+ principals (list): The list of principals
216
+ Returns:
217
+ int: The status code of the response
218
+ """
219
+ domain = self.get_domain_by_id(domain_id)
220
+ return domain.role_assignments_bulk_assign(type, principals)
221
+
222
+ def role_assignments_bulk_unassign(self, domain_id, type, principals):
223
+ """Unassign a role from principals in bulk
224
+
225
+ Args:
226
+ domain_id (str): The ID of the domain
227
+ type (str): The type of the role assignment
228
+ principals (list): The list of principals
229
+ Returns:
230
+ int: The status code of the response
231
+ """
232
+ domain = self.get_domain_by_id(domain_id)
233
+ return domain.role_assignments_bulk_unassign(type, principals)
234
+
235
+ def unassign_all_domain_workspaces(self, domain_id):
236
+ """Unassign all workspaces from a domain
237
+
238
+ Args:
239
+ domain_id (str): The ID of the domain
240
+ Returns:
241
+ int: The status code of the response
242
+ """
243
+ domain = self.get_domain_by_id(domain_id)
244
+ return domain.unassign_all_workspaces()
245
+
246
+ def unassign_domain_workspaces_by_ids(self, domain_id, workspace_ids):
247
+ """Unassign workspaces from a domain by workspace IDs
248
+
249
+ Args:
250
+ domain_id (str): The ID of the domain
251
+ workspace_ids (list): The list of workspace IDs
252
+ Returns:
253
+ int: The status code of the response
254
+ """
255
+ domain = self.get_domain_by_id(domain_id)
256
+ return domain.unassign_workspaces_by_ids(workspace_ids=workspace_ids)
257
+
258
+ def get_workspace(self, workspace_id):
259
+ """Get a workspace by ID
260
+
261
+ Args:
262
+ workspace_id (str): The ID of the workspace
263
+ Returns:
264
+ Workspace: The Workspace object
265
+ """
266
+
267
+ url = f"https://api.fabric.microsoft.com/v1/admin/workspaces/{workspace_id}"
268
+ for _ in range(10):
269
+ response = requests.get(url=url, headers=self.auth.get_headers())
270
+ if response.status_code == 429:
271
+ print("Too many requests, waiting 10 seconds")
272
+ sleep(10)
273
+ continue
274
+ if response.status_code not in (200, 429):
275
+ print(response.status_code)
276
+ print(response.text)
277
+ raise Exception(f"Error getting workspace: {response.text}")
278
+ break
279
+
280
+ workspace_dict = json.loads(response.text)
281
+ workspace = AdminWorkspace.from_dict(workspace_dict, self.auth)
282
+ return workspace
283
+
284
+ def get_workspace_access_details(self, workspace_id):
285
+ """Get the access details of the workspace
286
+
287
+ Args:
288
+ workspace_id (str): The ID of the workspace
289
+ Returns:
290
+ dict: The access details of the workspace
291
+ """
292
+ ws = self.get_workspace(workspace_id)
293
+ return ws.get_workspace_access_details()
294
+
295
+ def list_workspaces(self, capacity_id = None, name=None, state=None, type=None, continuationToken = None):
296
+ """List all workspaces
297
+
298
+ Args:
299
+ capacity_id (str): The ID of the capacity
300
+ Returns:
301
+ list: List of Workspace objects
302
+ """
303
+ #GET https://api.fabric.microsoft.com/v1/admin/workspaces?type={type}&capacityId={capacityId}&name={name}&state={state}&continuationToken={continuationToken}
304
+ url = "https://api.fabric.microsoft.com/v1/admin/workspaces"
305
+ first_parameter = False
306
+ if type:
307
+ url = f"{url}?type={type}"
308
+ first_parameter = True
309
+ if capacity_id:
310
+ if first_parameter:
311
+ url = f"{url}&capacityId={capacity_id}"
312
+ else:
313
+ url = f"{url}?capacityId={capacity_id}"
314
+
315
+ if name:
316
+ if first_parameter:
317
+ url = f"{url}&name={name}"
318
+ else:
319
+ url = f"{url}?name={name}"
320
+
321
+ if state:
322
+ if first_parameter:
323
+ url = f"{url}&state={state}"
324
+ else:
325
+ url = f"{url}?state={state}"
326
+
327
+ if continuationToken:
328
+ if first_parameter:
329
+ url = f"{url}&continuationToken={continuationToken}"
330
+ else:
331
+ url = f"{url}?continuationToken={continuationToken}"
332
+
333
+ for _ in range(10):
334
+ response = requests.get(url=url, headers=self.auth.get_headers())
335
+ if response.status_code == 429:
336
+ print("Too many requests, waiting 10 seconds")
337
+ sleep(10)
338
+ continue
339
+ if response.status_code not in (200, 429):
340
+ print(response.status_code)
341
+ print(response.text)
342
+ raise Exception(f"Error listing workspaces: {response.text}")
343
+ break
344
+
345
+ resp_dict = json.loads(response.text)
346
+ workspaces = resp_dict["workspaces"]
347
+
348
+ workspaces = [AdminWorkspace.from_dict(i, self.auth) for i in workspaces]
349
+
350
+ if "continuationToken" in resp_dict and resp_dict["continuationToken"] is not None:
351
+ workspaces_next = self.list_workspaces(capacity_id=capacity_id, name=name, state=state, type=type,
352
+ continuationToken=resp_dict["continuationToken"])
353
+ workspaces.extend(workspaces_next)
354
+
355
+ return workspaces
356
+
357
+ def list_items(self, workspace_id = None, capacity_id = None, type=None,
358
+ state=None, continuationToken = None):
359
+ """List all items
360
+
361
+ Returns:
362
+ list: The list of items in the workspace
363
+ """
364
+
365
+ url = f"https://api.fabric.microsoft.com/v1/admin/items"
366
+ first_parameter = False
367
+ if workspace_id:
368
+ url = f"{url}?workspaceId={workspace_id}"
369
+ first_parameter = True
370
+ if capacity_id:
371
+ if first_parameter:
372
+ url = f"{url}&capacityId={capacity_id}"
373
+ else:
374
+ url = f"{url}?capacityId={capacity_id}"
375
+ if type:
376
+ if first_parameter:
377
+ url = f"{url}&type={type}"
378
+ else:
379
+ url = f"{url}?type={type}"
380
+ if state:
381
+ if first_parameter:
382
+ url = f"{url}&state={state}"
383
+ else:
384
+ url = f"{url}?state={state}"
385
+ if continuationToken:
386
+ if first_parameter:
387
+ url = f"{url}&continuationToken={continuationToken}"
388
+ else:
389
+ url = f"{url}?continuationToken={continuationToken}"
390
+
391
+ for _ in range(10):
392
+ response = requests.get(url=url, headers=self.auth.get_headers())
393
+ if response.status_code == 429:
394
+ print("Too many requests, waiting 10 seconds")
395
+ sleep(10)
396
+ continue
397
+ if response.status_code not in (200, 429):
398
+ print(response.status_code)
399
+ print(response.text)
400
+ raise Exception(f"Error listing items: {response.text}")
401
+ break
402
+ resp_dict = json.loads(response.text)
403
+ items = [AdminItem.from_dict(item, self.auth) for item in resp_dict["itemEntities"]]
404
+
405
+ if "continuationToken" in items and items["continuationToken"] is not None:
406
+ items_next = self.list_items(workspace_id=workspace_id, capacity_id=capacity_id, type=type,
407
+ state=state, continuationToken=items["continuationToken"])
408
+ items.extend(items_next)
409
+
410
+ return items
411
+
412
+ def get_item(self, item_id, workspace_id, type = None):
413
+ """Get an item from the workspace
414
+
415
+ Args:
416
+ item_id (str): The ID of the item
417
+ workspace_id (str): The ID of the workspace
418
+ type (str): The type of the item
419
+ Returns:
420
+ AdminItem: The item object
421
+ """
422
+ ws = self.get_workspace(workspace_id)
423
+ return ws.get_item(item_id, type)
424
+
425
+
426
+ def get_tenant_settings(self):
427
+ """Get the tenant settings
428
+
429
+ Returns:
430
+ dict: The tenant settings
431
+ """
432
+ url = "https://api.fabric.microsoft.com/v1/admin/tenantsettings"
433
+ for _ in range(10):
434
+ response = requests.get(url=url, headers=self.auth.get_headers())
435
+ if response.status_code == 429:
436
+ print("Too many requests, waiting 10 seconds")
437
+ sleep(10)
438
+ continue
439
+ if response.status_code not in (200, 429):
440
+ print(response.status_code)
441
+ print(response.text)
442
+ raise Exception(f"Error getting tenant settings: {response.text}")
443
+ break
444
+
445
+ return json.loads(response.text)
446
+
447
+
448
+ def get_capacities_tenant_settings_overrides(self, continuationToken = None):
449
+ """Returns list of tenant setting overrides that override at the capacities
450
+
451
+ Returns:
452
+ list: The capacities tenant settings overrides
453
+ """
454
+ url = "https://api.fabric.microsoft.com/v1/admin/capacities/delegatedTenantSettingOverrides"
455
+ if continuationToken:
456
+ url = f"{url}?continuationToken={continuationToken}"
457
+
458
+ for _ in range(10):
459
+ response = requests.get(url=url, headers=self.auth.get_headers())
460
+ if response.status_code == 429:
461
+ print("Too many requests, waiting 10 seconds")
462
+ sleep(10)
463
+ continue
464
+ if response.status_code not in (200, 429):
465
+ print(response.status_code)
466
+ print(response.text)
467
+ raise Exception(f"Error getting capacities tenant settings overrides: {response.text}")
468
+ break
469
+
470
+ resp_dict = json.loads(response.text)
471
+ overrides = resp_dict["Overrides"]
472
+
473
+ if "continuationToken" in resp_dict and resp_dict["continuationToken"] is not None:
474
+ overrides_next = self.get_capacities_tenant_settings_overrides(continuationToken=resp_dict["continuationToken"])
475
+ overrides.extend(overrides_next)
476
+
477
+ return overrides
478
+
479
+ def get_access_entities(self, user_id, type = None, continuationToken = None):
480
+ """Get the access entities for a user
481
+
482
+ Args:
483
+ user_id (str): The ID of the user
484
+ type (str): The type of the access entity
485
+ continuationToken (str): The continuation token
486
+ Returns:
487
+ list: The list of access entities
488
+ """
489
+
490
+ url = f"https://api.fabric.microsoft.com/v1/admin/users/{user_id}/access"
491
+
492
+ first_parameter = False
493
+ if type:
494
+ url = f"{url}?type={type}"
495
+ first_parameter = True
496
+ if continuationToken:
497
+ if first_parameter:
498
+ url = f"{url}&continuationToken={continuationToken}"
499
+ else:
500
+ url = f"{url}?continuationToken={continuationToken}"
501
+
502
+ for _ in range(10):
503
+ response = requests.get(url=url, headers=self.auth.get_headers())
504
+ if response.status_code == 429:
505
+ print("Too many requests, waiting 10 seconds")
506
+ sleep(10)
507
+ continue
508
+ if response.status_code not in (200, 429):
509
+ print(response.status_code)
510
+ print(response.text)
511
+ raise Exception(f"Error getting access entities: {response.text}")
512
+ break
513
+
514
+ resp_dict = json.loads(response.text)
515
+ access_entities = resp_dict["accessEntities"]
516
+
517
+ if "continuationToken" in resp_dict and resp_dict["continuationToken"] is not None:
518
+ access_entities_next = self.get_access_entities(user_id, type, continuationToken=resp_dict["continuationToken"])
519
+ resp_dict["accessEntities"].extend(access_entities_next)
520
+
521
+ return access_entities
522
+
523
+ def get_item_access_details(self, workspace_id, item_id, type=None):
524
+ """Get the access details of the item
525
+
526
+ Args:
527
+ workspace_id (str): The ID of the workspace
528
+ item_id (str): The ID of the item
529
+ type (str): The type of the item
530
+ Returns:
531
+ dict: The access details of the item
532
+ """
533
+ ws = self.get_workspace(workspace_id)
534
+ item = ws.get_item(item_id, type)
535
+ return item.get_item_access_details(type)
@@ -38,6 +38,9 @@ class Capacity:
38
38
  }
39
39
  return json.dumps(dic, indent=2)
40
40
 
41
+ def __repr__(self) -> str:
42
+ return self.__str__()
43
+
41
44
  def from_dict(dic):
42
45
  """Method to create a Capacity object from a dictionary
43
46