Skip to content

Commit f801afb

Browse files
committed
Merge branch 'm-kovalsky/authentication_azure'
2 parents bd6a72d + 11d4d76 commit f801afb

File tree

13 files changed

+1542
-283
lines changed

13 files changed

+1542
-283
lines changed

docs/requirements.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,4 @@ anytree
1111
IPython
1212
polib
1313
powerbiclient
14-
azure.mgmt.resource
1514
jsonpath_ng

notebooks/Capacity Migration.ipynb

Lines changed: 379 additions & 1 deletion
Large diffs are not rendered by default.

notebooks/Service Principal.ipynb

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"id": "5c27dfd1-4fe0-4a97-92e6-ddf78889aa93",
6+
"metadata": {
7+
"nteract": {
8+
"transient": {
9+
"deleting": false
10+
}
11+
}
12+
},
13+
"source": [
14+
"### Install the latest .whl package\n",
15+
"\n",
16+
"Check [here](https://pypi.org/project/semantic-link-labs/) to see the latest version."
17+
]
18+
},
19+
{
20+
"cell_type": "code",
21+
"execution_count": null,
22+
"id": "d5cae9db-cef9-48a8-a351-9c5fcc99645c",
23+
"metadata": {
24+
"jupyter": {
25+
"outputs_hidden": true,
26+
"source_hidden": false
27+
},
28+
"nteract": {
29+
"transient": {
30+
"deleting": false
31+
}
32+
}
33+
},
34+
"outputs": [],
35+
"source": [
36+
"%pip install semantic-link-labs"
37+
]
38+
},
39+
{
40+
"cell_type": "markdown",
41+
"id": "b195eae8",
42+
"metadata": {},
43+
"source": [
44+
"### Import the library and obtain a TokenProvider using Azure Key Vault"
45+
]
46+
},
47+
{
48+
"cell_type": "code",
49+
"execution_count": null,
50+
"id": "1344e286",
51+
"metadata": {},
52+
"outputs": [],
53+
"source": [
54+
"import sempy_labs as labs\n",
55+
"from sempy_labs import admin\n",
56+
"from sempy_labs.tom import connect_semantic_model\n",
57+
"\n",
58+
"token_provider = labs.ServicePrincipalTokenProvider.from_azure_key_vault(\n",
59+
" key_vault_uri = '', # Enter your key vault URI\n",
60+
" key_vault_tenant_id = '', # Enter the key vault secret storing your Tenant ID\n",
61+
" key_vault_client_id = '', # Enter the key vault secret storing your Client ID (Applciation ID)\n",
62+
" key_vault_client_secret = '' # Enter the key vault secret storing your Client Secret\n",
63+
")"
64+
]
65+
},
66+
{
67+
"cell_type": "markdown",
68+
"id": "55e5ca67",
69+
"metadata": {},
70+
"source": [
71+
"### Use the generated TokenProvider to authenticate in other functions"
72+
]
73+
},
74+
{
75+
"cell_type": "code",
76+
"execution_count": null,
77+
"id": "a9f984e9",
78+
"metadata": {},
79+
"outputs": [],
80+
"source": [
81+
"admin.list_capacities(token_provider=token_provider)"
82+
]
83+
},
84+
{
85+
"cell_type": "code",
86+
"execution_count": null,
87+
"id": "a0d58c85",
88+
"metadata": {},
89+
"outputs": [],
90+
"source": [
91+
"dataset = '' # Enter the name of the semantic model\n",
92+
"workspace = None # Enter the name of the workspace\n",
93+
"with connect_semantic_model(dataset=dataset, workspace=workspace, readonly=True, token_provider=token_provider) as tom:\n",
94+
" for t in tom.model.Tables:\n",
95+
" print(t.Name)"
96+
]
97+
},
98+
{
99+
"cell_type": "markdown",
100+
"id": "27826ff4",
101+
"metadata": {},
102+
"source": [
103+
"### Use the TokenProvider to connect to Azure Analysis Services"
104+
]
105+
},
106+
{
107+
"cell_type": "code",
108+
"execution_count": null,
109+
"id": "0c21bd7e",
110+
"metadata": {},
111+
"outputs": [],
112+
"source": [
113+
"dataset = '' # Enter the name of the semantic model\n",
114+
"workspace = '' # Enter the name of the Azure Analysis Serivces instance (i.e. \"asazure://region.asazure...\")\n",
115+
"with connect_semantic_model(dataset=dataset, workspace=workspace, readonly=True, token_provider=token_provider) as tom:\n",
116+
" for t in tom.model.Tables:\n",
117+
" print(t.Name)"
118+
]
119+
}
120+
],
121+
"metadata": {
122+
"kernel_info": {
123+
"name": "synapse_pyspark"
124+
},
125+
"kernelspec": {
126+
"display_name": "Synapse PySpark",
127+
"language": "Python",
128+
"name": "synapse_pyspark"
129+
},
130+
"language_info": {
131+
"name": "python"
132+
},
133+
"microsoft": {
134+
"language": "python"
135+
},
136+
"nteract": {
137+
"version": "[email protected]"
138+
},
139+
"spark_compute": {
140+
"compute_id": "/trident/default"
141+
},
142+
"synapse_widget": {
143+
"state": {},
144+
"version": "0.1"
145+
},
146+
"widgets": {}
147+
},
148+
"nbformat": 4,
149+
"nbformat_minor": 5
150+
}

pyproject.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ dependencies = [
2727
"anytree",
2828
"powerbiclient",
2929
"polib",
30-
"azure.mgmt.resource",
3130
"jsonpath_ng",
3231
]
3332

@@ -46,7 +45,7 @@ test = [
4645
Repository = "https://github.com/microsoft/semantic-link-labs.git"
4746

4847
[[tool.mypy.overrides]]
49-
module = "sempy.*,Microsoft.*,System.*,anytree.*,powerbiclient.*,synapse.ml.services.*,polib.*,azure.mgmt.resource.*,jsonpath_ng.*"
48+
module = "sempy.*,Microsoft.*,System.*,anytree.*,powerbiclient.*,synapse.ml.services.*,polib.*,jsonpath_ng.*"
5049
ignore_missing_imports = true
5150

5251
[tool.flake8]

src/sempy_labs/__init__.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
update_on_premises_gateway,
1515
bind_semantic_model_to_gateway,
1616
)
17-
1817
from sempy_labs._authentication import (
1918
ServicePrincipalTokenProvider,
2019
)
@@ -121,6 +120,17 @@
121120
delete_embedded_capacity,
122121
delete_premium_capacity,
123122
create_resource_group,
123+
list_skus,
124+
list_skus_for_capacity,
125+
list_subscriptions,
126+
list_tenants,
127+
get_subscription,
128+
check_resource_group_existence,
129+
list_storage_accounts,
130+
create_storage_account,
131+
create_or_update_resource_group,
132+
list_resource_groups,
133+
get_resource_group,
124134
)
125135
from sempy_labs._spark import (
126136
get_spark_settings,
@@ -474,4 +484,15 @@
474484
"list_semantic_model_errors",
475485
"list_item_job_instances",
476486
"list_item_schedules",
487+
"list_skus",
488+
"list_skus_for_capacity",
489+
"list_subscriptions",
490+
"list_tenants",
491+
"get_subscription",
492+
"check_resource_group_existence",
493+
"list_storage_accounts",
494+
"create_storage_account",
495+
"create_or_update_resource_group",
496+
"list_resource_groups",
497+
"get_resource_group",
477498
]

src/sempy_labs/_authentication.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Literal
1+
from typing import Literal, Optional
22
from sempy.fabric._token_provider import TokenProvider
33
from azure.identity import ClientSecretCredential
44

@@ -41,6 +41,10 @@ def from_aad_application_key_authentication(
4141
tenant_id=tenant_id, client_id=client_id, client_secret=client_secret
4242
)
4343

44+
cls.tenant_id = tenant_id
45+
cls.client_id = client_id
46+
cls.client_secret = client_secret
47+
4448
return cls(credential)
4549

4650
@classmethod
@@ -89,16 +93,26 @@ def from_azure_key_vault(
8993
tenant_id=tenant_id, client_id=client_id, client_secret=client_secret
9094
)
9195

96+
cls.tenant_id = tenant_id
97+
cls.client_id = client_id
98+
cls.client_secret = client_secret
99+
92100
return cls(credential)
93101

94102
def __call__(
95-
self, audience: Literal["pbi", "storage", "azure", "graph"] = "pbi"
103+
self,
104+
audience: Literal[
105+
"pbi", "storage", "azure", "graph", "asazure", "keyvault"
106+
] = "pbi",
107+
region: Optional[str] = None,
96108
) -> str:
97109
"""
98110
Parameters
99111
----------
100-
audience : Literal["pbi", "storage", "azure", "graph"] = "pbi") -> str
112+
audience : Literal["pbi", "storage", "azure", "graph", "asazure", "keyvault"] = "pbi") -> str
101113
Literal if it's for PBI/Fabric API call or OneLake/Storage Account call.
114+
region : str, default=None
115+
The region of the Azure Analysis Services. For example: 'westus2'.
102116
"""
103117
if audience == "pbi":
104118
return self.credential.get_token(
@@ -114,12 +128,19 @@ def __call__(
114128
return self.credential.get_token(
115129
"https://graph.microsoft.com/.default"
116130
).token
131+
elif audience == "asazure":
132+
return self.credential.get_token(
133+
f"https://{region}.asazure.windows.net/.default"
134+
).token
135+
elif audience == "keyvault":
136+
return self.credential.get_token("https://vault.azure.net/.default").token
117137
else:
118138
raise NotImplementedError
119139

120140

121141
def _get_headers(
122-
token_provider: str, audience: Literal["pbi", "storage", "azure", "graph"] = "azure"
142+
token_provider: str,
143+
audience: Literal["pbi", "storage", "azure", "graph", "asazure", "keyvault"] = "azure",
123144
):
124145
"""
125146
Generates headers for an API request.

0 commit comments

Comments
 (0)