semantic-link-labs 0.8.11__py3-none-any.whl → 0.9.0__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.

Potentially problematic release.


This version of semantic-link-labs might be problematic. Click here for more details.

Files changed (40) hide show
  1. {semantic_link_labs-0.8.11.dist-info → semantic_link_labs-0.9.0.dist-info}/METADATA +5 -5
  2. {semantic_link_labs-0.8.11.dist-info → semantic_link_labs-0.9.0.dist-info}/RECORD +40 -40
  3. {semantic_link_labs-0.8.11.dist-info → semantic_link_labs-0.9.0.dist-info}/WHEEL +1 -1
  4. sempy_labs/__init__.py +29 -2
  5. sempy_labs/_authentication.py +80 -4
  6. sempy_labs/_capacities.py +770 -200
  7. sempy_labs/_capacity_migration.py +7 -37
  8. sempy_labs/_clear_cache.py +8 -8
  9. sempy_labs/_deployment_pipelines.py +1 -1
  10. sempy_labs/_gateways.py +2 -0
  11. sempy_labs/_generate_semantic_model.py +8 -0
  12. sempy_labs/_helper_functions.py +119 -79
  13. sempy_labs/_job_scheduler.py +138 -3
  14. sempy_labs/_list_functions.py +40 -31
  15. sempy_labs/_model_bpa.py +207 -204
  16. sempy_labs/_model_bpa_bulk.py +2 -2
  17. sempy_labs/_model_bpa_rules.py +3 -3
  18. sempy_labs/_notebooks.py +2 -0
  19. sempy_labs/_query_scale_out.py +8 -0
  20. sempy_labs/_sql.py +11 -7
  21. sempy_labs/_vertipaq.py +4 -2
  22. sempy_labs/_warehouses.py +6 -6
  23. sempy_labs/admin/_basic_functions.py +156 -103
  24. sempy_labs/admin/_domains.py +7 -2
  25. sempy_labs/admin/_git.py +4 -1
  26. sempy_labs/admin/_items.py +7 -2
  27. sempy_labs/admin/_scanner.py +7 -4
  28. sempy_labs/directlake/_directlake_schema_compare.py +7 -2
  29. sempy_labs/directlake/_directlake_schema_sync.py +6 -0
  30. sempy_labs/directlake/_dl_helper.py +51 -31
  31. sempy_labs/directlake/_get_directlake_lakehouse.py +20 -27
  32. sempy_labs/directlake/_update_directlake_partition_entity.py +5 -0
  33. sempy_labs/lakehouse/_get_lakehouse_columns.py +17 -22
  34. sempy_labs/lakehouse/_get_lakehouse_tables.py +20 -32
  35. sempy_labs/lakehouse/_lakehouse.py +2 -19
  36. sempy_labs/report/_generate_report.py +45 -0
  37. sempy_labs/report/_report_bpa.py +2 -2
  38. sempy_labs/tom/_model.py +97 -16
  39. {semantic_link_labs-0.8.11.dist-info → semantic_link_labs-0.9.0.dist-info}/LICENSE +0 -0
  40. {semantic_link_labs-0.8.11.dist-info → semantic_link_labs-0.9.0.dist-info}/top_level.txt +0 -0
sempy_labs/_capacities.py CHANGED
@@ -1,11 +1,14 @@
1
1
  import sempy.fabric as fabric
2
- from typing import Optional, List
2
+ from typing import Optional, List, Tuple
3
3
  from sempy._utils._log import log
4
4
  import sempy_labs._icons as icons
5
5
  from sempy.fabric.exceptions import FabricHTTPException
6
6
  import requests
7
- from sempy_labs._helper_functions import _get_azure_token_credentials
8
7
  import pandas as pd
8
+ from sempy_labs._authentication import _get_headers, ServicePrincipalTokenProvider
9
+ from uuid import UUID
10
+ from sempy_labs._helper_functions import _is_valid_uuid
11
+ import sempy_labs._authentication as auth
9
12
 
10
13
 
11
14
  def _add_sll_tag(payload, tags):
@@ -24,20 +27,19 @@ def _add_sll_tag(payload, tags):
24
27
  def create_fabric_capacity(
25
28
  capacity_name: str,
26
29
  azure_subscription_id: str,
27
- key_vault_uri: str,
28
- key_vault_tenant_id: str,
29
- key_vault_client_id: str,
30
- key_vault_client_secret: str,
31
30
  resource_group: str,
32
31
  region: str,
33
32
  sku: str,
34
33
  admin_members: str | List[str],
35
34
  tags: Optional[dict] = None,
35
+ **kwargs,
36
36
  ):
37
37
  """
38
38
  This function creates a new Fabric capacity within an Azure subscription.
39
39
 
40
- This is a wrapper function for the following API: `Fabric Capacities - Create Or Update <https://learn.microsoft.com/rest/api/microsoftfabric/fabric-capacities/create-or-update?view=rest-microsoftfabric-2023-11-01>`_.
40
+ This is a wrapper function for the following API: `Fabric Capacities - Create Or Update <https://learn.microsoft.com/rest/api/microsoftfabric/fabric-capacities/create-or-update>`_.
41
+
42
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
41
43
 
42
44
  Parameters
43
45
  ----------
@@ -45,14 +47,6 @@ def create_fabric_capacity(
45
47
  Name of the Fabric capacity.
46
48
  azure_subscription_id : str
47
49
  The Azure subscription ID.
48
- key_vault_uri : str
49
- The name of the `Azure key vault <https://azure.microsoft.com/products/key-vault>`_ URI. Example: "https://<Key Vault Name>.vault.azure.net/"
50
- key_vault_tenant_id : str
51
- The name of the Azure key vault secret storing the Tenant ID.
52
- key_vault_client_id : str
53
- The name of the Azure key vault secret storing the Client ID.
54
- key_vault_client_secret : str
55
- The name of the Azure key vault secret storing the Client Secret.
56
50
  resource_group : str
57
51
  The name of the Azure resource group.
58
52
  region : str
@@ -65,8 +59,6 @@ def create_fabric_capacity(
65
59
  Tag(s) to add to the capacity. Example: {'tagName': 'tagValue'}.
66
60
  """
67
61
 
68
- from azure.mgmt.resource import ResourceManagementClient
69
-
70
62
  if isinstance(admin_members, str):
71
63
  admin_members = [admin_members]
72
64
 
@@ -143,29 +135,41 @@ def create_fabric_capacity(
143
135
  f"{icons.red_dot} Invalid region. Valid options: {valid_regions}."
144
136
  )
145
137
 
146
- azure_token, credential, headers = _get_azure_token_credentials(
147
- key_vault_uri=key_vault_uri,
148
- key_vault_tenant_id=key_vault_tenant_id,
149
- key_vault_client_id=key_vault_client_id,
150
- key_vault_client_secret=key_vault_client_secret,
151
- )
152
-
153
- resource_client = ResourceManagementClient(credential, azure_subscription_id)
138
+ token_provider = auth.token_provider.get()
139
+ if token_provider is None:
140
+ token_provider = ServicePrincipalTokenProvider.from_azure_key_vault(
141
+ key_vault_uri=kwargs["key_vault_uri"],
142
+ key_vault_tenant_id=kwargs["key_vault_tenant_id"],
143
+ key_vault_client_id=kwargs["key_vault_client_id"],
144
+ key_vault_client_secret=kwargs["key_vault_client_secret"],
145
+ )
146
+ print(
147
+ f"{icons.info} Please use the 'token_provider' parameter instead of the key vault parameters within this function as the key vault parameters have been deprecated."
148
+ )
149
+ headers = _get_headers(token_provider, audience="azure")
154
150
 
155
151
  if resource_group is None:
156
- for i in resource_client.resources.list(
157
- "resourceType eq 'Microsoft.PowerBIDedicated/capacities'"
158
- ):
159
- if i.name == capacity_name.removesuffix(icons.migrate_capacity_suffix):
160
- resource_group = i.id.split("/")[4]
161
- print(
162
- f"{icons.yellow_dot} Override resource group flag detected for A SKUs - using the existing resource group '{resource_group}' for the '{capacity_name}' capacity."
163
- )
152
+ dfRG = list_resource_groups(
153
+ azure_subscription_id=azure_subscription_id,
154
+ filter="resourceType eq 'Microsoft.PowerBIDedicated/capacities'",
155
+ )
156
+ dfRG_filt = dfRG[
157
+ dfRG["Resource Group Name"]
158
+ == capacity_name.removesuffix(icons.migrate_capacity_suffix)
159
+ ]
160
+ if not dfRG_filt.empty:
161
+ resource_group = dfRG_filt["Resource Group Name"].iloc[0]
162
+ print(
163
+ f"{icons.yellow_dot} Override resource group flag detected for A SKUs - using the existing resource group '{resource_group}' for the '{capacity_name}' capacity."
164
+ )
164
165
  else:
165
166
  # Attempt to get the resource group
166
167
  try:
167
- rg = resource_client.resource_groups.get(resource_group)
168
- if rg.location != region:
168
+ dfRG = get_resource_group(
169
+ azure_subscription_id=azure_subscription_id,
170
+ resource_group=resource_group,
171
+ )
172
+ if dfRG["Location"].iloc[0] != region:
169
173
  print(
170
174
  f"{icons.yellow_dot} The '{resource_group}' resource group exists, but in a different region."
171
175
  )
@@ -177,11 +181,10 @@ def create_fabric_capacity(
177
181
  print(
178
182
  f"{icons.in_progress} Creating the '{resource_group}' resource group in the '{region}' region"
179
183
  )
180
- rg_result = resource_client.resource_groups.create_or_update(
181
- resource_group, {"location": region}
182
- )
183
- print(
184
- f"{icons.green_dot} Provisioned resource group with ID: {rg_result.id}"
184
+ create_or_update_resource_group(
185
+ azure_subscription_id=azure_subscription_id,
186
+ resource_group=resource_group,
187
+ region=region,
185
188
  )
186
189
 
187
190
  payload = {
@@ -243,20 +246,20 @@ def get_capacity_resource_governance(capacity_name: str):
243
246
  return response.json()["workloadSettings"]
244
247
 
245
248
 
249
+ @log
246
250
  def suspend_fabric_capacity(
247
251
  capacity_name: str,
248
252
  azure_subscription_id: str,
249
253
  resource_group: str,
250
- key_vault_uri: str,
251
- key_vault_tenant_id: str,
252
- key_vault_client_id: str,
253
- key_vault_client_secret: str,
254
+ **kwargs,
254
255
  ):
255
256
  """
256
257
  This function suspends a Fabric capacity.
257
258
 
258
259
  This is a wrapper function for the following API: `Fabric Capacities - Suspend <https://learn.microsoft.com/rest/api/microsoftfabric/fabric-capacities/suspend?view=rest-microsoftfabric-2023-11-01>`_.
259
260
 
261
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
262
+
260
263
  Parameters
261
264
  ----------
262
265
  capacity_name : str
@@ -265,23 +268,21 @@ def suspend_fabric_capacity(
265
268
  The Azure subscription ID.
266
269
  resource_group : str
267
270
  The name of the Azure resource group.
268
- key_vault_uri : str
269
- The name of the `Azure key vault <https://azure.microsoft.com/products/key-vault>`_ URI. Example: "https://<Key Vault Name>.vault.azure.net/"
270
- key_vault_tenant_id : str
271
- The name of the Azure key vault secret storing the Tenant ID.
272
- key_vault_client_id : str
273
- The name of the Azure key vault secret storing the Client ID.
274
- key_vault_client_secret : str
275
- The name of the Azure key vault secret storing the Client Secret.
276
- """
277
- # https://learn.microsoft.com/en-us/rest/api/microsoftfabric/fabric-capacities/suspend?view=rest-microsoftfabric-2023-11-01&tabs=HTTP
278
-
279
- azure_token, credential, headers = _get_azure_token_credentials(
280
- key_vault_uri=key_vault_uri,
281
- key_vault_tenant_id=key_vault_tenant_id,
282
- key_vault_client_id=key_vault_client_id,
283
- key_vault_client_secret=key_vault_client_secret,
284
- )
271
+ """
272
+
273
+ token_provider = auth.token_provider.get()
274
+ if token_provider is None:
275
+ token_provider = ServicePrincipalTokenProvider.from_azure_key_vault(
276
+ key_vault_uri=kwargs["key_vault_uri"],
277
+ key_vault_tenant_id=kwargs["key_vault_tenant_id"],
278
+ key_vault_client_id=kwargs["key_vault_client_id"],
279
+ key_vault_client_secret=kwargs["key_vault_client_secret"],
280
+ )
281
+ print(
282
+ f"{icons.info} Please use the 'token_provider' parameter instead of the key vault parameters within this function as the key vault parameters have been deprecated."
283
+ )
284
+
285
+ headers = _get_headers(token_provider, audience="azure")
285
286
 
286
287
  url = f"https://management.azure.com/subscriptions/{azure_subscription_id}/resourceGroups/{resource_group}/providers/Microsoft.Fabric/capacities/{capacity_name}/suspend?api-version={icons.azure_api_version}"
287
288
 
@@ -293,20 +294,20 @@ def suspend_fabric_capacity(
293
294
  print(f"{icons.green_dot} The '{capacity_name}' capacity has been suspended.")
294
295
 
295
296
 
297
+ @log
296
298
  def resume_fabric_capacity(
297
299
  capacity_name: str,
298
300
  azure_subscription_id: str,
299
301
  resource_group: str,
300
- key_vault_uri: str,
301
- key_vault_tenant_id: str,
302
- key_vault_client_id: str,
303
- key_vault_client_secret: str,
302
+ **kwargs,
304
303
  ):
305
304
  """
306
305
  This function resumes a Fabric capacity.
307
306
 
308
307
  This is a wrapper function for the following API: `Fabric Capacities - Resume <https://learn.microsoft.com/rest/api/microsoftfabric/fabric-capacities/resume?view=rest-microsoftfabric-2023-11-01>`_.
309
308
 
309
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
310
+
310
311
  Parameters
311
312
  ----------
312
313
  capacity_name : str
@@ -315,24 +316,21 @@ def resume_fabric_capacity(
315
316
  The Azure subscription ID.
316
317
  resource_group : str
317
318
  The name of the Azure resource group.
318
- key_vault_uri : str
319
- The name of the `Azure key vault <https://azure.microsoft.com/products/key-vault>`_ URI. Example: "https://<Key Vault Name>.vault.azure.net/"
320
- key_vault_tenant_id : str
321
- The name of the Azure key vault secret storing the Tenant ID.
322
- key_vault_client_id : str
323
- The name of the Azure key vault secret storing the Client ID.
324
- key_vault_client_secret : str
325
- The name of the Azure key vault secret storing the Client Secret.
326
- """
327
-
328
- # https://learn.microsoft.com/en-us/rest/api/microsoftfabric/fabric-capacities/resume?view=rest-microsoftfabric-2023-11-01&tabs=HTTP
329
-
330
- azure_token, credential, headers = _get_azure_token_credentials(
331
- key_vault_uri=key_vault_uri,
332
- key_vault_tenant_id=key_vault_tenant_id,
333
- key_vault_client_id=key_vault_client_id,
334
- key_vault_client_secret=key_vault_client_secret,
335
- )
319
+ """
320
+
321
+ token_provider = auth.token_provider.get()
322
+ if token_provider is None:
323
+ token_provider = ServicePrincipalTokenProvider.from_azure_key_vault(
324
+ key_vault_uri=kwargs["key_vault_uri"],
325
+ key_vault_tenant_id=kwargs["key_vault_tenant_id"],
326
+ key_vault_client_id=kwargs["key_vault_client_id"],
327
+ key_vault_client_secret=kwargs["key_vault_client_secret"],
328
+ )
329
+ print(
330
+ f"{icons.info} Please use the 'token_provider' parameter instead of the key vault parameters within this function as the key vault parameters have been deprecated."
331
+ )
332
+
333
+ headers = _get_headers(token_provider, audience="azure")
336
334
 
337
335
  url = f"https://management.azure.com/subscriptions/{azure_subscription_id}/resourceGroups/{resource_group}/providers/Microsoft.Fabric/capacities/{capacity_name}/resume?api-version={icons.azure_api_version}"
338
336
 
@@ -344,18 +342,18 @@ def resume_fabric_capacity(
344
342
  print(f"{icons.green_dot} The '{capacity_name}' capacity has been resumed.")
345
343
 
346
344
 
345
+ @log
347
346
  def delete_embedded_capacity(
348
347
  capacity_name: str,
349
348
  azure_subscription_id: str,
350
349
  resource_group: str,
351
- key_vault_uri: str,
352
- key_vault_tenant_id: str,
353
- key_vault_client_id: str,
354
- key_vault_client_secret: str,
350
+ **kwargs,
355
351
  ):
356
352
  """
357
353
  This function deletes a Power BI Embedded capacity.
358
354
 
355
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
356
+
359
357
  Parameters
360
358
  ----------
361
359
  capacity_name : str
@@ -364,24 +362,21 @@ def delete_embedded_capacity(
364
362
  The Azure subscription ID.
365
363
  resource_group : str
366
364
  The name of the Azure resource group.
367
- key_vault_uri : str
368
- The name of the `Azure key vault <https://azure.microsoft.com/products/key-vault>`_ URI. Example: "https://<Key Vault Name>.vault.azure.net/"
369
- key_vault_tenant_id : str
370
- The name of the Azure key vault secret storing the Tenant ID.
371
- key_vault_client_id : str
372
- The name of the Azure key vault secret storing the Client ID.
373
- key_vault_client_secret : str
374
- The name of the Azure key vault secret storing the Client Secret.
375
- """
376
-
377
- # https://learn.microsoft.com/en-us/rest/api/power-bi-embedded/capacities/delete?view=rest-power-bi-embedded-2021-01-01&tabs=HTTP
378
-
379
- azure_token, credential, headers = _get_azure_token_credentials(
380
- key_vault_uri=key_vault_uri,
381
- key_vault_tenant_id=key_vault_tenant_id,
382
- key_vault_client_id=key_vault_client_id,
383
- key_vault_client_secret=key_vault_client_secret,
384
- )
365
+ """
366
+
367
+ token_provider = auth.token_provider.get()
368
+ if token_provider is None:
369
+ token_provider = ServicePrincipalTokenProvider.from_azure_key_vault(
370
+ key_vault_uri=kwargs["key_vault_uri"],
371
+ key_vault_tenant_id=kwargs["key_vault_tenant_id"],
372
+ key_vault_client_id=kwargs["key_vault_client_id"],
373
+ key_vault_client_secret=kwargs["key_vault_client_secret"],
374
+ )
375
+ print(
376
+ f"{icons.info} Please use the 'token_provider' parameter instead of the key vault parameters within this function as the key vault parameters have been deprecated."
377
+ )
378
+
379
+ headers = _get_headers(token_provider, audience="azure")
385
380
 
386
381
  url = f"https://management.azure.com/subscriptions/{azure_subscription_id}/resourceGroups/{resource_group}/providers/Microsoft.PowerBIDedicated/capacities/{capacity_name}?api-version={icons.azure_api_version}"
387
382
 
@@ -393,6 +388,7 @@ def delete_embedded_capacity(
393
388
  print(f"{icons.green_dot} The '{capacity_name}' capacity has been deleted.")
394
389
 
395
390
 
391
+ @log
396
392
  def delete_premium_capacity(capacity_name: str):
397
393
  """
398
394
  This function deletes a Power BI Premium capacity.
@@ -421,20 +417,20 @@ def delete_premium_capacity(capacity_name: str):
421
417
  print(f"{icons.green_dot} The '{capacity_name}' capacity has been deleted.")
422
418
 
423
419
 
420
+ @log
424
421
  def delete_fabric_capacity(
425
422
  capacity_name: str,
426
423
  azure_subscription_id: str,
427
424
  resource_group: str,
428
- key_vault_uri: str,
429
- key_vault_tenant_id: str,
430
- key_vault_client_id: str,
431
- key_vault_client_secret: str,
425
+ **kwargs,
432
426
  ):
433
427
  """
434
428
  This function deletes a Fabric capacity.
435
429
 
436
430
  This is a wrapper function for the following API: `Fabric Capacities - Delete <https://learn.microsoft.com/rest/api/microsoftfabric/fabric-capacities/delete?view=rest-microsoftfabric-2023-11-01>`_.
437
431
 
432
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
433
+
438
434
  Parameters
439
435
  ----------
440
436
  capacity_name : str
@@ -443,24 +439,21 @@ def delete_fabric_capacity(
443
439
  The Azure subscription ID.
444
440
  resource_group : str
445
441
  The name of the Azure resource group.
446
- key_vault_uri : str
447
- The name of the `Azure key vault <https://azure.microsoft.com/products/key-vault>`_ URI. Example: "https://<Key Vault Name>.vault.azure.net/"
448
- key_vault_tenant_id : str
449
- The name of the Azure key vault secret storing the Tenant ID.
450
- key_vault_client_id : str
451
- The name of the Azure key vault secret storing the Client ID.
452
- key_vault_client_secret : str
453
- The name of the Azure key vault secret storing the Client Secret.
454
- """
455
-
456
- # https://learn.microsoft.com/en-us/rest/api/microsoftfabric/fabric-capacities/delete?view=rest-microsoftfabric-2023-11-01&tabs=HTTP
457
-
458
- azure_token, credential, headers = _get_azure_token_credentials(
459
- key_vault_uri=key_vault_uri,
460
- key_vault_tenant_id=key_vault_tenant_id,
461
- key_vault_client_id=key_vault_client_id,
462
- key_vault_client_secret=key_vault_client_secret,
463
- )
442
+ """
443
+
444
+ token_provider = auth.token_provider.get()
445
+ if token_provider is None:
446
+ token_provider = ServicePrincipalTokenProvider.from_azure_key_vault(
447
+ key_vault_uri=kwargs["key_vault_uri"],
448
+ key_vault_tenant_id=kwargs["key_vault_tenant_id"],
449
+ key_vault_client_id=kwargs["key_vault_client_id"],
450
+ key_vault_client_secret=kwargs["key_vault_client_secret"],
451
+ )
452
+ print(
453
+ f"{icons.info} Please use the 'token_provider' parameter instead of the key vault parameters within this function as the key vault parameters have been deprecated."
454
+ )
455
+
456
+ headers = _get_headers(token_provider, audience="azure")
464
457
 
465
458
  url = f"https://management.azure.com/subscriptions/{azure_subscription_id}/resourceGroups/{resource_group}/providers/Microsoft.Fabric/capacities/{capacity_name}?api-version={icons.azure_api_version}"
466
459
 
@@ -472,23 +465,23 @@ def delete_fabric_capacity(
472
465
  print(f"{icons.green_dot} The '{capacity_name}' capacity has been deleted.")
473
466
 
474
467
 
468
+ @log
475
469
  def update_fabric_capacity(
476
470
  capacity_name: str,
477
471
  azure_subscription_id: str,
478
472
  resource_group: str,
479
- key_vault_uri: str,
480
- key_vault_tenant_id: str,
481
- key_vault_client_id: str,
482
- key_vault_client_secret: str,
483
473
  sku: Optional[str] = None,
484
474
  admin_members: Optional[str | List[str]] = None,
485
475
  tags: Optional[dict] = None,
476
+ **kwargs,
486
477
  ):
487
478
  """
488
479
  This function updates a Fabric capacity's properties.
489
480
 
490
481
  This is a wrapper function for the following API: `Fabric Capacities - Update <https://learn.microsoft.com/rest/api/microsoftfabric/fabric-capacities/update?view=rest-microsoftfabric-2023-11-01>`_.
491
482
 
483
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
484
+
492
485
  Parameters
493
486
  ----------
494
487
  capacity_name : str
@@ -497,14 +490,6 @@ def update_fabric_capacity(
497
490
  The Azure subscription ID.
498
491
  resource_group : str
499
492
  The name of the Azure resource group.
500
- key_vault_uri : str
501
- The name of the `Azure key vault <https://azure.microsoft.com/products/key-vault>`_ URI. Example: "https://<Key Vault Name>.vault.azure.net/"
502
- key_vault_tenant_id : str
503
- The name of the Azure key vault secret storing the Tenant ID.
504
- key_vault_client_id : str
505
- The name of the Azure key vault secret storing the Client ID.
506
- key_vault_client_secret : str
507
- The name of the Azure key vault secret storing the Client Secret.
508
493
  sku : str, default=None
509
494
  The `sku size <https://azure.microsoft.com/pricing/details/microsoft-fabric/>`_ of the Fabric capacity.
510
495
  admin_members : str | List[str], default=None
@@ -513,21 +498,19 @@ def update_fabric_capacity(
513
498
  Tag(s) to add to the capacity. Example: {'tagName': 'tagValue'}.
514
499
  """
515
500
 
516
- # https://learn.microsoft.com/en-us/rest/api/microsoftfabric/fabric-capacities/update?view=rest-microsoftfabric-2023-11-01&tabs=HTTP
517
-
518
- if isinstance(admin_members, str):
519
- admin_members = [admin_members]
520
- if tags is not None and not isinstance(tags, dict):
521
- raise ValueError(
522
- f"{icons.red_dot} If specified, the 'tags' parameter must be a dictionary."
501
+ token_provider = auth.token_provider.get()
502
+ if token_provider is None:
503
+ token_provider = ServicePrincipalTokenProvider.from_azure_key_vault(
504
+ key_vault_uri=kwargs["key_vault_uri"],
505
+ key_vault_tenant_id=kwargs["key_vault_tenant_id"],
506
+ key_vault_client_id=kwargs["key_vault_client_id"],
507
+ key_vault_client_secret=kwargs["key_vault_client_secret"],
508
+ )
509
+ print(
510
+ f"{icons.info} Please use the 'token_provider' parameter instead of the key vault parameters within this function as the key vault parameters have been deprecated."
523
511
  )
524
512
 
525
- azure_token, credential, headers = _get_azure_token_credentials(
526
- key_vault_uri=key_vault_uri,
527
- key_vault_tenant_id=key_vault_tenant_id,
528
- key_vault_client_id=key_vault_client_id,
529
- key_vault_client_secret=key_vault_client_secret,
530
- )
513
+ headers = _get_headers(token_provider, audience="azure")
531
514
 
532
515
  url = f"https://management.azure.com/subscriptions/{azure_subscription_id}/resourceGroups/{resource_group}/providers/Microsoft.Fabric/capacities/{capacity_name}?api-version={icons.azure_api_version}"
533
516
 
@@ -575,20 +558,20 @@ def update_fabric_capacity(
575
558
  )
576
559
 
577
560
 
561
+ @log
578
562
  def check_fabric_capacity_name_availablility(
579
563
  capacity_name: str,
580
564
  azure_subscription_id: str,
581
565
  region: str,
582
- key_vault_uri: str,
583
- key_vault_tenant_id: str,
584
- key_vault_client_id: str,
585
- key_vault_client_secret: str,
566
+ **kwargs,
586
567
  ) -> bool:
587
568
  """
588
569
  This function updates a Fabric capacity's properties.
589
570
 
590
571
  This is a wrapper function for the following API: `Fabric Capacities - Check Name Availability <https://learn.microsoft.com/rest/api/microsoftfabric/fabric-capacities/check-name-availability?view=rest-microsoftfabric-2023-11-01>`_.
591
572
 
573
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
574
+
592
575
  Parameters
593
576
  ----------
594
577
  capacity_name : str
@@ -597,34 +580,32 @@ def check_fabric_capacity_name_availablility(
597
580
  The Azure subscription ID.
598
581
  region : str
599
582
  The region name.
600
- key_vault_uri : str
601
- The name of the `Azure key vault <https://azure.microsoft.com/products/key-vault>`_ URI. Example: "https://<Key Vault Name>.vault.azure.net/"
602
- key_vault_tenant_id : str
603
- The name of the Azure key vault secret storing the Tenant ID.
604
- key_vault_client_id : str
605
- The name of the Azure key vault secret storing the Client ID.
606
- key_vault_client_secret : str
607
- The name of the Azure key vault secret storing the Client Secret.
608
583
 
609
584
  Returns
610
585
  -------
611
586
  bool
612
587
  An indication as to whether the Fabric capacity name is available or not.
613
588
  """
614
- # https://learn.microsoft.com/en-us/rest/api/microsoftfabric/fabric-capacities/check-name-availability?view=rest-microsoftfabric-2023-11-01&tabs=HTTP
615
589
 
616
- azure_token, credential, headers = _get_azure_token_credentials(
617
- key_vault_uri=key_vault_uri,
618
- key_vault_tenant_id=key_vault_tenant_id,
619
- key_vault_client_id=key_vault_client_id,
620
- key_vault_client_secret=key_vault_client_secret,
621
- )
590
+ token_provider = auth.token_provider.get()
591
+ if token_provider is None:
592
+ token_provider = ServicePrincipalTokenProvider.from_azure_key_vault(
593
+ key_vault_uri=kwargs["key_vault_uri"],
594
+ key_vault_tenant_id=kwargs["key_vault_tenant_id"],
595
+ key_vault_client_id=kwargs["key_vault_client_id"],
596
+ key_vault_client_secret=kwargs["key_vault_client_secret"],
597
+ )
598
+ print(
599
+ f"{icons.info} Please use the 'token_provider' parameter instead of the key vault parameters within this function as the key vault parameters have been deprecated."
600
+ )
601
+
602
+ headers = _get_headers(token_provider, audience="azure")
622
603
 
623
604
  payload = {"name": capacity_name, "type": "Microsoft.Fabric/capacities"}
624
605
 
625
606
  url = f"https://management.azure.com/subscriptions/{azure_subscription_id}/providers/Microsoft.Fabric/locations/{region}/checkNameAvailability?api-version={icons.azure_api_version}"
626
607
 
627
- response = requests.post(url, headers=headers, data=payload)
608
+ response = requests.post(url, headers=headers, json=payload)
628
609
 
629
610
  if response.status_code != 202:
630
611
  raise FabricHTTPException(response)
@@ -632,59 +613,648 @@ def check_fabric_capacity_name_availablility(
632
613
  return bool(response.json().get("nameAvailable"))
633
614
 
634
615
 
616
+ @log
635
617
  def create_resource_group(
636
618
  azure_subscription_id: str,
637
- key_vault_uri: str,
638
- key_vault_tenant_id: str,
639
- key_vault_client_id: str,
640
- key_vault_client_secret: str,
641
619
  resource_group: str,
642
620
  region: str,
621
+ **kwargs,
643
622
  ):
644
623
  """
645
624
  This function creates a resource group in a region within an Azure subscription.
646
625
 
647
- This is a wrapper function for the following API: `ResourceGroupsOperations Class - CreateOrUpdate <https://learn.microsoft.com/python/api/azure-mgmt-resource/azure.mgmt.resource.resources.v2022_09_01.operations.resourcegroupsoperations?view=azure-python#azure-mgmt-resource-resources-v2022-09-01-operations-resourcegroupsoperations-create-or-update>`_.
626
+ This is a wrapper function for the following API: `Resource Groups - Create Or Update <https://learn.microsoft.com/rest/api/resources/resource-groups/create-or-update>`_.
627
+
628
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
648
629
 
649
630
  Parameters
650
631
  ----------
651
632
  azure_subscription_id : str
652
633
  The Azure subscription ID.
653
- key_vault_uri : str
654
- The name of the `Azure key vault <https://azure.microsoft.com/products/key-vault>`_ URI. Example: "https://<Key Vault Name>.vault.azure.net/"
655
- key_vault_tenant_id : str
656
- The name of the Azure key vault secret storing the Tenant ID.
657
- key_vault_client_id : str
658
- The name of the Azure key vault secret storing the Client ID.
659
- key_vault_client_secret : str
660
- The name of the Azure key vault secret storing the Client Secret.
661
634
  resource_group : str
662
635
  The name of the Azure resource group to be created.
663
636
  region : str
664
637
  The name of the region in which the resource group will be created.
665
638
  """
666
639
 
667
- from azure.mgmt.resource import ResourceManagementClient
668
-
669
- azure_token, credential, headers = _get_azure_token_credentials(
670
- key_vault_uri=key_vault_uri,
671
- key_vault_tenant_id=key_vault_tenant_id,
672
- key_vault_client_id=key_vault_client_id,
673
- key_vault_client_secret=key_vault_client_secret,
674
- )
675
-
676
- resource_client = ResourceManagementClient(credential, azure_subscription_id)
677
-
678
- if resource_client.resource_groups.check_existence(resource_group):
640
+ if check_resource_group_existence(
641
+ azure_subscription_id=azure_subscription_id,
642
+ resource_group=resource_group,
643
+ ):
679
644
  print(
680
645
  f"{icons.info} The '{resource_group}' resource group already exists in the '{region}' region within the '{azure_subscription_id}' Azure subscription."
681
646
  )
682
647
  return
683
648
 
684
- resource_client.resource_groups.create_or_update(
685
- resource_group, {"location": region}
649
+ create_or_update_resource_group(
650
+ azure_subscription_id=azure_subscription_id,
651
+ resource_group=resource_group,
652
+ region=region,
653
+ )
654
+
655
+
656
+ @log
657
+ def list_skus_for_capacity(
658
+ capacity: str,
659
+ azure_subscription_id: str,
660
+ resource_group: str,
661
+ ) -> pd.DataFrame:
662
+ """
663
+ Lists eligible SKUs for a Microsoft Fabric resource.
664
+
665
+ This is a wrapper function for the following API: `Fabric Capacities - List Skus For Capacity <https://learn.microsoft.com/rest/api/microsoftfabric/fabric-capacities/list-skus-for-capacity?view=rest-microsoftfabric-2023-11-01>`_.
666
+
667
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
668
+
669
+ Parameters
670
+ ----------
671
+ capacity : str
672
+ The capacity name.
673
+ azure_subscription_id : str
674
+ The Azure subscription ID.
675
+ resource_group : str
676
+ The name of the resource group.
677
+
678
+ Returns
679
+ -------
680
+ pandas.DataFrame
681
+ A pandas dataframe showing a list of eligible SKUs for a Microsoft Fabric resource.
682
+ """
683
+
684
+ df = pd.DataFrame(columns=["Resource Type", "Sku", "Sku Tier"])
685
+ url = f"https://management.azure.com/subscriptions/{azure_subscription_id}/resourceGroups/{resource_group}/providers/Microsoft.Fabric/capacities/{capacity}/skus?api-version=2023-11-01"
686
+ headers = _get_headers(token_provider=auth.token_provider.get(), audience="azure")
687
+
688
+ response = requests.get(url, headers=headers)
689
+ if response.status_code != 200:
690
+ raise FabricHTTPException(response)
691
+
692
+ for v in response.json().get("value", []):
693
+ sku = v.get("sku", {})
694
+ new_data = {
695
+ "Resource Type": v.get("resourceType"),
696
+ "Sku": sku.get("name"),
697
+ "Sku Tier": sku.get("tier"),
698
+ }
699
+
700
+ df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
701
+
702
+ return df
703
+
704
+
705
+ @log
706
+ def list_skus(
707
+ azure_subscription_id: str,
708
+ ) -> pd.DataFrame:
709
+ """
710
+ Lists eligible SKUs for Microsoft Fabric resource provider.
711
+
712
+ This is a wrapper function for the following API: `Fabric Capacities - List Skus For Capacity <https://learn.microsoft.com/rest/api/microsoftfabric/fabric-capacities/list-skus?view=rest-microsoftfabric-2023-11-01>`_.
713
+
714
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
715
+
716
+ Parameters
717
+ ----------
718
+ azure_subscription_id : str
719
+ The Azure subscription ID.
720
+
721
+ Returns
722
+ -------
723
+ pandas.DataFrame
724
+ A pandas dataframe showing a list of eligible SKUs for Microsoft Fabric resource provider.
725
+ """
726
+
727
+ df = pd.DataFrame(columns=["Sku", "Locations"])
728
+ url = f"https://management.azure.com/subscriptions/{azure_subscription_id}/providers/Microsoft.Fabric/skus?api-version=2023-11-01"
729
+ headers = _get_headers(token_provider=auth.token_provider.get(), audience="azure")
730
+
731
+ response = requests.get(url, headers=headers)
732
+ if response.status_code != 200:
733
+ raise FabricHTTPException(response)
734
+
735
+ for v in response.json().get("value", []):
736
+ new_data = {
737
+ "Sku": v.get("name"),
738
+ "Locations": v.get("locations", []),
739
+ }
740
+
741
+ df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
742
+
743
+ return df
744
+
745
+
746
+ @log
747
+ def list_subscriptions() -> pd.DataFrame:
748
+ """
749
+ Gets all subscriptions for a tenant.
750
+
751
+ This is a wrapper function for the following API: `Subscriptions - List <https://learn.microsoft.com/rest/api/resources/subscriptions/list?view=rest-resources-2022-12-01>`_.
752
+
753
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
754
+
755
+ Returns
756
+ -------
757
+ pandas.DataFrame
758
+ A pandas dataframe showing a list of all subscriptions for a tenant.
759
+ """
760
+
761
+ df = pd.DataFrame(
762
+ columns=[
763
+ "Subscription Id",
764
+ "Subscription Name",
765
+ "Tenant Id",
766
+ "State",
767
+ "Location Placement Id",
768
+ "Quota Id",
769
+ "Spending Limit",
770
+ "Authorization Source",
771
+ "Managed By Tenants",
772
+ "Tags",
773
+ ]
686
774
  )
775
+ url = "https://management.azure.com/subscriptions?api-version=2022-12-01"
776
+ headers = _get_headers(token_provider=auth.token_provider.get(), audience="azure")
777
+
778
+ response = requests.get(url, headers=headers)
779
+ if response.status_code != 200:
780
+ raise FabricHTTPException(response)
781
+
782
+ for v in response.json().get("value", []):
783
+ policy = v.get("subscriptionPolicies", {})
784
+ tenants = v.get("managedByTenants")
785
+ new_data = {
786
+ "Subscription Id": v.get("subscriptionId"),
787
+ "Subscription Name": v.get("displayName"),
788
+ "Tenant Id": v.get("tenantId"),
789
+ "State": v.get("state"),
790
+ "Location Placement Id": policy.get("locationPlacementId"),
791
+ "Quota Id": policy.get("quotaId"),
792
+ "Spending Limit": policy.get("spendingLimit"),
793
+ "Authorization Source": v.get("authorizationSource"),
794
+ "Managed by Tenants": tenants if tenants is not None else [],
795
+ "Tags": v.get("tags", {}),
796
+ }
797
+
798
+ df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
799
+
800
+ return df
801
+
802
+
803
+ @log
804
+ def get_subscription(azure_subscription_id: str) -> pd.DataFrame:
805
+ """
806
+ Gets details about a specified subscription.
807
+
808
+ This is a wrapper function for the following API: `Subscriptions - Get <https://learn.microsoft.com/rest/api/resources/subscriptions/get?view=rest-resources-2022-12-01>`_.
809
+
810
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
811
+
812
+ Parameters
813
+ ----------
814
+ azure_subscription_id : str
815
+ The Azure subscription ID.
816
+
817
+ Returns
818
+ -------
819
+ pandas.DataFrame
820
+ A pandas dataframe showing details of a specific subscription.
821
+ """
822
+
823
+ df = pd.DataFrame(
824
+ columns=[
825
+ "Subscription Id",
826
+ "Subscription Name",
827
+ "Tenant Id",
828
+ "State",
829
+ "Location Placement Id",
830
+ "Quota Id",
831
+ "Spending Limit",
832
+ "Authorization Source",
833
+ "Managed By Tenants",
834
+ "Tags",
835
+ ]
836
+ )
837
+ url = f"https://management.azure.com/subscriptions/{azure_subscription_id}?api-version=2022-12-01"
838
+ headers = _get_headers(token_provider=auth.token_provider.get(), audience="azure")
839
+
840
+ response = requests.get(url, headers=headers)
841
+ if response.status_code != 200:
842
+ raise FabricHTTPException(response)
843
+
844
+ v = response.json()
845
+ policy = v.get("subscriptionPolicies", {})
846
+ tenants = v.get("managedByTenants")
847
+ new_data = {
848
+ "Subscription Id": v.get("subscriptionId"),
849
+ "Subscription Name": v.get("displayName"),
850
+ "Tenant Id": v.get("tenantId"),
851
+ "State": v.get("state"),
852
+ "Location Placement Id": policy.get("locationPlacementId"),
853
+ "Quota Id": policy.get("quotaId"),
854
+ "Spending Limit": policy.get("spendingLimit"),
855
+ "Authorization Source": v.get("authorizationSource"),
856
+ "Managed by Tenants": tenants if tenants is not None else [],
857
+ "Tags": v.get("tags", {}),
858
+ }
859
+
860
+ df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
861
+
862
+ return df
863
+
864
+
865
+ def _resolve_subscription_name_and_id(
866
+ azure_subscription: str | UUID,
867
+ ) -> Tuple[str, UUID]:
868
+
869
+ if _is_valid_uuid(azure_subscription):
870
+ subscription_id = azure_subscription
871
+ df = get_subscription(azure_subscription_id=subscription_id)
872
+ if df.empty:
873
+ raise ValueError(f"{icons.red_dot} The subscription ID does not exist.")
874
+ subscription_name = df["Subscription Name"].iloc[0]
875
+ else:
876
+ subscription_name = azure_subscription
877
+ df = list_subscriptions()
878
+ df_filt = df[df["Subscription Name"] == subscription_name]
879
+ if df_filt.empty:
880
+ raise ValueError(f"{icons.red_dot} The subscription name does not exist.")
881
+ subscription_id = df_filt["Subscription Id"].iloc[0]
882
+
883
+ return subscription_name, subscription_id
884
+
885
+
886
+ @log
887
+ def list_tenants() -> pd.DataFrame:
888
+ """
889
+ Gets the tenants for your account.
890
+
891
+ This is a wrapper function for the following API: `Tenants - List <https://learn.microsoft.com/rest/api/resources/tenants/list?view=rest-resources-2022-12-01>`_.
892
+
893
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
894
+
895
+ Returns
896
+ -------
897
+ pandas.DataFrame
898
+ A pandas dataframe showing a list of all tenants for your account.
899
+ """
900
+
901
+ df = pd.DataFrame(
902
+ columns=[
903
+ "Tenant Id",
904
+ "Tenant Name",
905
+ "Country Code",
906
+ "Domains",
907
+ "Tenant Category",
908
+ "Default Domain",
909
+ "Tenant Type",
910
+ "Tenant Branding Logo Url",
911
+ ]
912
+ )
913
+ url = "https://management.azure.com/tenants?api-version=2022-12-01"
914
+ headers = _get_headers(token_provider=auth.token_provider.get(), audience="azure")
915
+
916
+ response = requests.get(url, headers=headers)
917
+ if response.status_code != 200:
918
+ raise FabricHTTPException(response)
919
+
920
+ for v in response.json().get("value", []):
921
+ d = v.get("domains")
922
+ new_data = {
923
+ "Tenant Id": v.get("tenantId"),
924
+ "Tenant Name": v.get("displayName"),
925
+ "Country Code": v.get("countryCode"),
926
+ "Domains": d if d is not None else "",
927
+ "Tenant Category": v.get("tenantCategory"),
928
+ "Default Domain": v.get("defaultDomain"),
929
+ "Tenant Type": v.get("tenantType"),
930
+ "Tenant Branding Logo Url": v.get("tenantBrandingLogoUrl"),
931
+ }
932
+
933
+ df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
934
+
935
+ return df
936
+
937
+
938
+ @log
939
+ def create_or_update_resource_group(
940
+ azure_subscription_id: str,
941
+ resource_group: str,
942
+ region: str,
943
+ ):
944
+ """
945
+ Creates or updates a resource group.
946
+
947
+ This is a wrapper function for the following API: `Resource Groups - Create Or Update <https://learn.microsoft.com/rest/api/resources/resource-groups/create-or-update>`_.
948
+
949
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
950
+
951
+ Parameters
952
+ ----------
953
+ azure_subscription_id : str
954
+ The Azure subscription Id.
955
+ resource_group : str
956
+ The name of the resource group.
957
+ region : str
958
+ The name of the region.
959
+ """
960
+
961
+ headers = _get_headers(auth.token_provider.get(), audience="azure")
962
+ url = f"https://management.azure.com/subscriptions/{azure_subscription_id}/resourcegroups/{resource_group}?api-version=2021-04-01"
963
+
964
+ payload = {
965
+ "location": region,
966
+ }
967
+
968
+ response = requests.put(url, headers=headers, json=payload)
969
+ if response.status_code not in [200, 201]:
970
+ raise FabricHTTPException(response)
687
971
 
688
972
  print(
689
- f"{icons.green_dot} The '{resource_group}' resource group has been created within the '{region}' region within the '{azure_subscription_id}' Azure subscription."
973
+ f"{icons.green_dot} The '{resource_group}' resource group has been created/updated."
690
974
  )
975
+
976
+
977
+ @log
978
+ def create_storage_account(
979
+ azure_subscription_id: str,
980
+ resource_group: str,
981
+ storage_account: str,
982
+ region: str,
983
+ ):
984
+ """
985
+ Asynchronously creates a new storage account with the specified parameters. If an account is already created and a subsequent create request is issued with different properties, the account properties will be updated. If an account is already created and a subsequent create or update request is issued with the exact same set of properties, the request will succeed.
986
+
987
+ This is a wrapper function for the following API: `Storage Accounts - Create <https://learn.microsoft.com/rest/api/storagerp/storage-accounts/create`_.
988
+
989
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
990
+
991
+ Parameters
992
+ ----------
993
+ azure_subscription_id : str
994
+ The Azure subscription Id.
995
+ resource_group : str
996
+ The name of the resource group.
997
+ storage_account : str
998
+ The name of the storage account to be created.
999
+ region : str
1000
+ The name of the region.
1001
+ """
1002
+
1003
+ headers = _get_headers(auth.token_provider.get(), audience="azure")
1004
+ url = f"https://management.azure.com/subscriptions/{azure_subscription_id}/resourceGroups/{resource_group}/providers/Microsoft.Storage/storageAccounts/{storage_account}?api-version=2018-02-01"
1005
+
1006
+ payload = {
1007
+ "sku": {"name": "Standard_GRS"},
1008
+ "kind": "StorageV2",
1009
+ "location": region,
1010
+ }
1011
+
1012
+ response = requests.put(url, headers=headers, json=payload)
1013
+
1014
+ if response.status_code != 200:
1015
+ raise FabricHTTPException(response)
1016
+
1017
+ print(
1018
+ f"{icons.green_dot} The '{storage_account}' storage account has been created."
1019
+ )
1020
+
1021
+
1022
+ @log
1023
+ def list_storage_accounts(
1024
+ azure_subscription_id: str,
1025
+ resource_group: Optional[str] = None,
1026
+ ) -> pd.DataFrame:
1027
+ """
1028
+ Lists all the storage accounts available under the subscription (or resource group). Note that storage keys are not returned; use the ListKeys operation for this.
1029
+
1030
+ This is a wrapper function for the following APIs: `Storage Accounts - List <https://learn.microsoft.com/rest/api/storagerp/storage-accounts/list>`_, `Storage Accounts - List By Resource Group <https://learn.microsoft.com/rest/api/storagerp/storage-accounts/list-by-resource-group>`_.
1031
+
1032
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
1033
+
1034
+ Parameters
1035
+ ----------
1036
+ azure_subscription_id : str
1037
+ The Azure subscription Id.
1038
+ resource_group : str, default=None
1039
+ If set to None, retrieves all storage accounts for the subscription. If not None, shows the storage accounts within that resource group.
1040
+
1041
+ Returns
1042
+ -------
1043
+ pandas.DataFrame
1044
+ A pandas dataframe showing a list of all storage accounts within the subscription (or resource group).
1045
+ """
1046
+
1047
+ headers = _get_headers(auth.token_provider.get(), audience="azure")
1048
+
1049
+ url = f"https://management.azure.com/subscriptions/{azure_subscription_id}"
1050
+
1051
+ if resource_group is not None:
1052
+ url += f"/resourceGroups/{resource_group}"
1053
+
1054
+ url += "/providers/Microsoft.Storage/storageAccounts?api-version=2023-05-01"
1055
+
1056
+ df = pd.DataFrame(
1057
+ columns=[
1058
+ "Storage Account Id",
1059
+ "Storage Account Name",
1060
+ "Kind",
1061
+ "Location",
1062
+ "Sku Name",
1063
+ "Sku Tier",
1064
+ "Is HNS Enabled",
1065
+ "Creation Time",
1066
+ "Web Endpoint",
1067
+ "DFS Endpoint",
1068
+ "Blob Endpoint",
1069
+ "File Endpoint",
1070
+ "Queue Endpoint",
1071
+ "Table Endpoint",
1072
+ "Primary Location",
1073
+ "Provisioning State",
1074
+ "Secondary Location",
1075
+ "Status of Primary",
1076
+ "Status of Secondary",
1077
+ "Supports HTTPS Traffic Only",
1078
+ "Tags",
1079
+ ]
1080
+ )
1081
+ response = requests.get(url, headers=headers)
1082
+
1083
+ if response.status_code != 200:
1084
+ raise FabricHTTPException(response)
1085
+
1086
+ for v in response.json().get("value", []):
1087
+ p = v.get("properties", {})
1088
+ new_data = {
1089
+ "Storage Account Id": v.get("id"),
1090
+ "Storage Account Name": v.get("name"),
1091
+ "Kind": v.get("kind"),
1092
+ "Location": v.get("location"),
1093
+ "Sku Name": v.get("sku", {}).get("name"),
1094
+ "Sku Tier": v.get("sku", {}).get("tier"),
1095
+ "Is HNS Enabled": p.get("isHnsEnabled"),
1096
+ "Creation Time": p.get("creationTime"),
1097
+ "Web Endpoint": p.get("primaryEndpoints", {}).get("web"),
1098
+ "DFS Endpoint": p.get("primaryEndpoints", {}).get("dfs"),
1099
+ "Blob Endpoint": p.get("primaryEndpoints", {}).get("blob"),
1100
+ "File Endpoint": p.get("primaryEndpoints", {}).get("file"),
1101
+ "Queue Endpoint": p.get("primaryEndpoints", {}).get("queue"),
1102
+ "Table Endpoint": p.get("primaryEndpoints", {}).get("table"),
1103
+ "Primary Location": p.get("primaryLocation"),
1104
+ "Provisioning State": p.get("provisioningState"),
1105
+ "Secondary Location": p.get("secondaryLocation"),
1106
+ "Status of Primary": p.get("statusOfPrimary"),
1107
+ "Status of Secondary": p.get("statusOfSecondary"),
1108
+ "Supports HTTPS Traffic Only": p.get("supportsHttpsTrafficOnly"),
1109
+ "Tags": v.get("tags"),
1110
+ }
1111
+
1112
+ df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
1113
+
1114
+ bool_cols = ["Is HNS Enabled", "Supports HTTPS Traffic Only"]
1115
+ df[bool_cols] = df[bool_cols].astype(bool)
1116
+ df["Creation Time"] = pd.to_datetime(df["Creation Time"])
1117
+
1118
+ return df
1119
+
1120
+
1121
+ @log
1122
+ def check_resource_group_existence(
1123
+ azure_subscription_id: str, resource_group: str
1124
+ ) -> bool:
1125
+ """
1126
+ Checks whether a resource group exists.
1127
+
1128
+ This is a wrapper function for the following API: `Resource Groups - Check Existence <https://learn.microsoft.com/rest/api/resources/resource-groups/check-existence>`_.
1129
+
1130
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
1131
+
1132
+ Parameters
1133
+ ----------
1134
+ azure_subscription_id : str
1135
+ The Azure subscription Id.
1136
+ resource_group : str
1137
+ The name of the resource group.
1138
+
1139
+ Returns
1140
+ -------
1141
+ bool
1142
+ True/False indicating if the resource group exists or not.
1143
+ """
1144
+
1145
+ headers = _get_headers(auth.token_provider.get(), audience="azure")
1146
+ url = f"https://management.azure.com/subscriptions/{azure_subscription_id}/resourceGroups/{resource_group}?api-version=2021-04-01"
1147
+
1148
+ response = requests.get(url, headers=headers)
1149
+
1150
+ if response.status_code not in [200, 204, 404]:
1151
+ raise FabricHTTPException(response)
1152
+
1153
+ if response.status_code == 200:
1154
+ return True
1155
+ elif response.status_code in [204, 404]:
1156
+ return False
1157
+
1158
+
1159
+ @log
1160
+ def list_resource_groups(
1161
+ azure_subscription_id: str,
1162
+ filter: Optional[str] = None,
1163
+ top: Optional[int] = None,
1164
+ ) -> pd.DataFrame:
1165
+ """
1166
+ Lists all resource groups within a subscription.
1167
+
1168
+ This is a wrapper function for the following API: `Resource Groups - List <https://learn.microsoft.com/rest/api/resources/resource-groups/list>`_.
1169
+
1170
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
1171
+
1172
+ Parameters
1173
+ ----------
1174
+ azure_subscription_id : str
1175
+ The Azure subscription Id.
1176
+ filter : str, default=None
1177
+ The filter to apply to the operation. Example: filter="tagname eq 'tagvalue'".
1178
+ top : int, default=None
1179
+ The number of results to return. If not specified, returns all results.
1180
+
1181
+ Returns
1182
+ -------
1183
+ pandas.DataFrame
1184
+ A pandas dataframe showing a list of all resource groups within the subscription.
1185
+ """
1186
+
1187
+ headers = _get_headers(auth.token_provider.get(), audience="azure")
1188
+ url = f"https://management.azure.com/subscriptions/{azure_subscription_id}/resourceGroups?"
1189
+
1190
+ if filter is not None:
1191
+ url += f"$filter={filter}&"
1192
+ if top is not None:
1193
+ url += f"$top={top}&"
1194
+
1195
+ url += "api-version=2021-04-01"
1196
+
1197
+ df = pd.DataFrame(columns=["Resource Group Name", "Location", "Tags"])
1198
+ response = requests.get(url, headers=headers)
1199
+
1200
+ if response.status_code != 200:
1201
+ raise FabricHTTPException(response)
1202
+
1203
+ for v in response.json().get("value", []):
1204
+ new_data = {
1205
+ "Resource Group Id": v.get("id"),
1206
+ "Resource Group Name": v.get("name"),
1207
+ "Location": v.get("location"),
1208
+ "Managed By": v.get("managedBy"),
1209
+ "Tags": v.get("tags"),
1210
+ "Type": v.get("type"),
1211
+ "Provisioning State": v.get("properties", {}).get("provisioningState"),
1212
+ }
1213
+
1214
+ df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
1215
+
1216
+ return df
1217
+
1218
+
1219
+ @log
1220
+ def get_resource_group(azure_subscription_id: str, resource_group: str) -> pd.DataFrame:
1221
+ """
1222
+ Gets details about a specified resource group.
1223
+
1224
+ This is a wrapper function for the following API: `Resource Groups - Get <https://learn.microsoft.com/rest/api/resources/resource-groups/get>`_.
1225
+
1226
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
1227
+
1228
+ Parameters
1229
+ ----------
1230
+ azure_subscription_id : str
1231
+ The Azure subscription Id.
1232
+ resource_group : str
1233
+ The name of the resource group.
1234
+
1235
+ Returns
1236
+ -------
1237
+ pandas.DataFrame
1238
+ A pandas dataframe showing details of a specific resource group.
1239
+ """
1240
+
1241
+ headers = _get_headers(auth.token_provider.get(), audience="azure")
1242
+ url = f"https://management.azure.com/subscriptions/{azure_subscription_id}/resourceGroups/{resource_group}?api-version=2021-04-01"
1243
+
1244
+ response = requests.get(url, headers=headers)
1245
+
1246
+ if response.status_code != 200:
1247
+ raise FabricHTTPException(response)
1248
+
1249
+ v = response.json()
1250
+ new_data = {
1251
+ "Resource Group Id": v.get("id"),
1252
+ "Resource Group Name": v.get("name"),
1253
+ "Location": v.get("location"),
1254
+ "Managed By": v.get("managedBy"),
1255
+ "Tags": v.get("tags"),
1256
+ "Type": v.get("type"),
1257
+ "Provisioning State": v.get("properties", {}).get("provisioningState"),
1258
+ }
1259
+
1260
+ return pd.DataFrame(new_data, index=[0])