diff --git a/src/sempy_labs/__init__.py b/src/sempy_labs/__init__.py index 11772b31..90cead12 100644 --- a/src/sempy_labs/__init__.py +++ b/src/sempy_labs/__init__.py @@ -1,3 +1,15 @@ +from sempy_labs._gateways import ( + list_gateway_members, + list_gateway_role_assigments, + list_gateways, + delete_gateway, + delete_gateway_member, + delete_gateway_role_assignment, + create_vnet_gateway, + update_vnet_gateway, + update_on_premises_gateway, +) + from sempy_labs._authentication import ( ServicePrincipalTokenProvider, ) @@ -435,4 +447,13 @@ "create_vnet_connection", "create_on_prem_connection", "create_cloud_connection", + "list_gateway_members", + "list_gateway_role_assigments", + "list_gateways", + "delete_gateway", + "delete_gateway_member", + "delete_gateway_role_assignment", + "create_vnet_gateway", + "update_vnet_gateway", + "update_on_premises_gateway", ] diff --git a/src/sempy_labs/_authentication.py b/src/sempy_labs/_authentication.py index 5c33dc17..088729e4 100644 --- a/src/sempy_labs/_authentication.py +++ b/src/sempy_labs/_authentication.py @@ -1,6 +1,5 @@ from typing import Literal from sempy.fabric._token_provider import TokenProvider -import notebookutils from azure.identity import ClientSecretCredential @@ -12,6 +11,7 @@ class ServicePrincipalTokenProvider(TokenProvider): """ def __init__(self, credential: ClientSecretCredential): + self.credential = credential @classmethod @@ -54,7 +54,7 @@ def with_azure_key_vault( """ Create the ServicePrincipalTokenProvider providing the information with the Service Principal information. - For more information on Azure Key Vault check `About Azure Key Vault `_ + For more information on Azure Key Vault check `About Azure Key Vault `_. Parameters ---------- @@ -72,6 +72,9 @@ def with_azure_key_vault( sempy.fabric.TokenProvider Token provider to be used with FabricRestClient or PowerBIRestClient. """ + + import notebookutils + tenant_id = notebookutils.credentials.getSecret( key_vault_uri, key_vault_tenant_id ) diff --git a/src/sempy_labs/_connections.py b/src/sempy_labs/_connections.py index d0436a9e..8462f77c 100644 --- a/src/sempy_labs/_connections.py +++ b/src/sempy_labs/_connections.py @@ -8,7 +8,7 @@ ) from uuid import UUID import sempy_labs._icons as icons -from sempy_labs._gateways import resolve_gateway_id +from sempy_labs._gateways import _resolve_gateway_id def delete_connection(connection: str | UUID): @@ -23,7 +23,7 @@ def delete_connection(connection: str | UUID): The connection name or ID. """ - connection_id = resolve_connection_id(connection) + connection_id = _resolve_connection_id(connection) client = fabric.FabricRestClient() response = client.delete(f"/v1/connections/{connection_id}") @@ -48,7 +48,7 @@ def delete_connection_role_assignment(connection: str | UUID, role_assignment_id The role assignment ID. """ - connection_id = resolve_connection_id(connection) + connection_id = _resolve_connection_id(connection) client = fabric.FabricRestClient() response = client.delete( @@ -63,7 +63,7 @@ def delete_connection_role_assignment(connection: str | UUID, role_assignment_id ) -def resolve_connection_id(connection: str | UUID) -> UUID: +def _resolve_connection_id(connection: str | UUID) -> UUID: dfC = list_connections() if _is_valid_uuid(connection): @@ -96,7 +96,7 @@ def list_connection_role_assignments(connection: str | UUID) -> pd.DataFrame: A pandas dataframe showing a list of connection role assignments. """ - connection_id = resolve_connection_id(connection) + connection_id = _resolve_connection_id(connection) client = fabric.FabricRestClient() response = client.get(f"/v1/connections/{connection_id}/roleAssignments") @@ -277,7 +277,7 @@ def _list_supported_connection_types( url = f"/v1/connections/supportedConnectionTypes?showAllCreationMethods={show_all_creation_methods}&" if gateway is not None: - gateway_id = resolve_gateway_id(gateway) + gateway_id = _resolve_gateway_id(gateway) url += f"gatewayId={gateway_id}" df = pd.DataFrame( @@ -434,7 +434,7 @@ def create_on_prem_connection( If True, skips the test connection. """ - gateway_id = resolve_gateway_id(gateway) + gateway_id = _resolve_gateway_id(gateway) request_body = { "connectivityType": "OnPremisesGateway", @@ -515,7 +515,7 @@ def create_vnet_connection( If True, skips the test connection. """ - gateway_id = resolve_gateway_id(gateway) + gateway_id = _resolve_gateway_id(gateway) request_body = { "connectivityType": "VirtualNetworkGateway", diff --git a/src/sempy_labs/_gateways.py b/src/sempy_labs/_gateways.py index 44865b7e..c8b95830 100644 --- a/src/sempy_labs/_gateways.py +++ b/src/sempy_labs/_gateways.py @@ -12,6 +12,16 @@ def list_gateways() -> pd.DataFrame: + """ + Returns a list of all gateways the user has permission for, including on-premises, on-premises (personal mode), and virtual network gateways. + + This is a wrapper function for the following API: `Gateways - List Gateways `_. + + Returns + ------- + pandas.DataFrame + A pandas dataframe showing a list of all gateways the user has permission for, including on-premises, on-premises (personal mode), and virtual network gateways. + """ client = fabric.FabricRestClient() response = client.get("/v1/gateways") @@ -61,7 +71,7 @@ def list_gateways() -> pd.DataFrame: return df -def resolve_gateway_id(gateway: str | UUID) -> UUID: +def _resolve_gateway_id(gateway: str | UUID) -> UUID: dfG = list_gateways() if _is_valid_uuid(gateway): @@ -76,8 +86,18 @@ def resolve_gateway_id(gateway: str | UUID) -> UUID: def delete_gateway(gateway: str | UUID): + """ + Deletes a gateway. + + This is a wrapper function for the following API: `Gateways - Delete Gateway `_. + + Parameters + ---------- + gateway : str | UUID + The gateway name or ID. + """ - gateway_id = resolve_gateway_id(gateway) + gateway_id = _resolve_gateway_id(gateway) client = fabric.FabricRestClient() response = client.delete(f"/v1/gateways/{gateway_id}") @@ -88,10 +108,25 @@ def delete_gateway(gateway: str | UUID): def list_gateway_role_assigments(gateway: str | UUID) -> pd.DataFrame: + """ + Returns a list of gateway role assignments. + + This is a wrapper function for the following API: `Gateways - List Gateway Role Assignments `_. + + Parameters + ---------- + gateway : str | UUID + The gateway name or ID. + + Returns + ------- + pandas.DataFrame + A pandas dataframe showing a list of gateway role assignments. + """ - gateway_id = resolve_gateway_id(gateway) + gateway_id = _resolve_gateway_id(gateway) client = fabric.FabricRestClient() - response = client.delete(f"/v1/gateways/{gateway_id}/roleAssignments") + response = client.get(f"/v1/gateways/{gateway_id}/roleAssignments") if response.status_code != 200: raise FabricHTTPException(response) @@ -115,8 +150,20 @@ def list_gateway_role_assigments(gateway: str | UUID) -> pd.DataFrame: def delete_gateway_role_assignment(gateway: str | UUID, role_assignement_id: UUID): + """ + Delete the specified role assignment for the gateway. - gateway_id = resolve_gateway_id(gateway) + This is a wrapper function for the following API: `Gateways - Delete Gateway Role Assignment `_. + + Parameters + ---------- + gateway : str | UUID + The gateway name or ID. + role_assignement_id : UUID + The role assignment ID. + """ + + gateway_id = _resolve_gateway_id(gateway) client = fabric.FabricRestClient() response = client.delete( f"/v1/gateways/{gateway_id}/roleAssignments/{role_assignement_id}" @@ -130,9 +177,9 @@ def delete_gateway_role_assignment(gateway: str | UUID, role_assignement_id: UUI ) -def delete_gateway_member(gateway: str | UUID, gateway_member: UUID): +def _resolve_gateway_member_id(gateway: str | UUID, gateway_member: str | UUID) -> UUID: - gateway_id = resolve_gateway_id(gateway) + gateway_id = _resolve_gateway_id(gateway) dfM = list_gateway_members(gateway=gateway_id) if _is_valid_uuid(gateway_member): @@ -143,7 +190,28 @@ def delete_gateway_member(gateway: str | UUID, gateway_member: UUID): raise ValueError( f"{icons.red_dot} The '{gateway_member}' gateway member does not exist within the '{gateway}' gateway." ) - member_id = dfM_filt["Member Id"].iloc[0] + + return dfM_filt["Member Id"].iloc[0] + + +def delete_gateway_member(gateway: str | UUID, gateway_member: str | UUID): + """ + Delete gateway member of an on-premises gateway. + + This is a wrapper function for the following API: `Gateways - Delete Gateway Member `_. + + Parameters + ---------- + gateway : str | UUID + The gateway name or ID. + gateway_member : str | UUID + The gateway member name or ID. + """ + + gateway_id = _resolve_gateway_id(gateway) + member_id = _resolve_gateway_member_id( + gateway=gateway_id, gateway_member=gateway_member + ) client = fabric.FabricRestClient() response = client.delete(f"/v1/gateways/{gateway_id}/members/{member_id}") @@ -157,8 +225,23 @@ def delete_gateway_member(gateway: str | UUID, gateway_member: UUID): def list_gateway_members(gateway: str | UUID) -> pd.DataFrame: + """ + Lists gateway members of an on-premises gateway. + + This is a wrapper function for the following API: `Gateways - List Gateway Members `_. - gateway_id = resolve_gateway_id(gateway) + Parameters + ---------- + gateway : str | UUID + The gateway name or ID. + + Returns + ------- + pandas.DataFrame + A pandas dataframe showing a list of gateway members of an on-premises gateway. + """ + + gateway_id = _resolve_gateway_id(gateway) client = fabric.FabricRestClient() response = client.get(f"/v1/gateways/{gateway_id}/members") @@ -191,17 +274,43 @@ def list_gateway_members(gateway: str | UUID) -> pd.DataFrame: bool_cols = ["Enabled"] df[bool_cols] = df[bool_cols].astype(bool) + return df + def create_vnet_gateway( name: str, capacity: str | UUID, inactivity_minutes_before_sleep: int, number_of_member_gateways: int, - subscription_id: UUID, + subscription_id: str, resource_group: str, virtual_network: str, subnet: str, ): + """ + Creates a virtual network gateway. + + This is a wrapper function for the following API: `Gateways - Create Gateway `_. + + Parameters + ---------- + name : str + The gateway name. + capacity : str | UUID + The capacity name or Id. + inactivity_minutes_before_sleep : int + The minutes of inactivity before the virtual network gateway goes into auto-sleep. Must be one of the following values: 30, 60, 90, 120, 150, 240, 360, 480, 720, 1440. + number_of_member_gateways: int + The number of member gateways. A number between 1 and 7. + subscription_id : str + The subscription ID. + resource_group : str + The name of the resource group. + virtual_network : str + The name of the virtual network. + subnet : str + The name of the subnet. + """ client = fabric.FabricRestClient() @@ -229,17 +338,30 @@ def create_vnet_gateway( ) -# def add_gateway_role_assignment(gateway : str | UUID)\: - - def update_on_premises_gateway( gateway: str, allow_cloud_connection_refresh: Optional[bool] = None, allow_custom_connectors: Optional[bool] = None, load_balancing_setting: Optional[str] = None, ): + """ + Updates an on-premises gateway. - gateway_id = resolve_gateway_id(gateway) + This is a wrapper function for the following API: `Gateways - Update Gateway `_. + + Parameters + ---------- + gateway : str | UUID + The gateway name or ID. + allow_cloud_connection_refresh : bool, default=None + Whether to allow cloud connections to refresh through this on-premises gateway. True - Allow, False - Do not allow. + allow_custom_connectors : bool, default=None + Whether to allow custom connectors to be used with this on-premises gateway. True - Allow, False - Do not allow. + load_balancing_setting : str, default=None + The `load balancing setting `_ of the on-premises gateway. + """ + + gateway_id = _resolve_gateway_id(gateway) payload = {} @@ -272,8 +394,24 @@ def update_vnet_gateway( inactivity_minutes_before_sleep: Optional[int] = None, number_of_member_gateways: Optional[int] = None, ): - - gateway_id = resolve_gateway_id(gateway) + """ + Updates a virtual network gateway. + + This is a wrapper function for the following API: `Gateways - Update Gateway `_. + + Parameters + ---------- + gateway : str | UUID + The gateway name or ID. + capacity: str | UUID + The capacity name or ID. + inactivity_minutes_before_sleep : int, default=None + The minutes of inactivity before the virtual network gateway goes into auto-sleep. Must be one of the following values: 30, 60, 90, 120, 150, 240, 360, 480, 720, 1440. + number_of_member_gateways : int, default=None + The number of member gateways. A number between 1 and 7. + """ + + gateway_id = _resolve_gateway_id(gateway) payload = {} diff --git a/src/sempy_labs/_generate_semantic_model.py b/src/sempy_labs/_generate_semantic_model.py index 3b530862..37ea8e44 100644 --- a/src/sempy_labs/_generate_semantic_model.py +++ b/src/sempy_labs/_generate_semantic_model.py @@ -308,7 +308,6 @@ def deploy_semantic_model( dataset=target_dataset, bim_file=bim, workspace=target_workspace, - overwrite=overwrite, ) # Update the semantic model if the model exists else: