Skip to content

Commit 413a344

Browse files
committed
feat: misc
1 parent fef467f commit 413a344

File tree

2 files changed

+52
-12
lines changed

2 files changed

+52
-12
lines changed

redash/query_runner/powerbi.py

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
# TODO: test
22
import logging
33
from typing import Optional, Tuple
4+
from enum import Enum
45

56
import yaml
67

8+
9+
class AuthType(Enum):
10+
CREDENTIALS = 1
11+
LOGIN_PASSWORD = 2
12+
13+
714
from redash.query_runner import (
815
TYPE_BOOLEAN,
916
TYPE_DATETIME,
@@ -68,9 +75,12 @@ class PowerBIDAX(BaseHTTPQueryRunner):
6875
requires_url = False
6976
url_title = "Power BI URL"
7077
username_title = "Username"
71-
password_title = "Password"
78+
password_title = "Password/Token"
7279
default_url = "https://api.powerbi.com/v1.0/myorg"
7380
default_scopes = '["https://analysis.windows.net/powerbi/api/.default"]'
81+
default_authority_url = (
82+
"https://login.microsoftonline.com/<tenant name/yourdomain.com>"
83+
)
7484

7585
@classmethod
7686
def configuration_schema(cls):
@@ -83,7 +93,7 @@ def configuration_schema(cls):
8393
"authority_url": {
8494
"type": "string",
8595
"title": cls.authority_url_title,
86-
"default": "https://login.microsoftonline.com/<tenant name/yourdomain.com>",
96+
"default": cls.default_authority_url,
8797
},
8898
"scopes": {
8999
"type": "string",
@@ -96,6 +106,7 @@ def configuration_schema(cls):
96106
"client_id",
97107
"authority_url",
98108
]
109+
schema["required"].remove("username")
99110
return schema
100111

101112
@classmethod
@@ -112,7 +123,6 @@ def __init__(self, *args, **kwargs):
112123
self.configuration["url"] = self.configuration.get("url", self.default_url)
113124
scopes = self.configuration.get("scopes", self.default_scopes)
114125
self.configuration["scopes"] = scopes
115-
self.configuration["scopes_array"] = json_loads(scopes)
116126

117127
def test_connection(self):
118128
_, error = self.get_response("/availableFeatures")
@@ -122,18 +132,49 @@ def test_connection(self):
122132
def get_auth(self):
123133
return None
124134

135+
def get_credentials(self):
136+
username = self.configuration.get("username")
137+
password = self.configuration.get("password")
138+
if password:
139+
return (username, password)
140+
if self.requires_authentication:
141+
raise ValueError("Username and Password or Token required")
142+
else:
143+
return None
144+
125145
def get_authorization(self):
126146
client_id = self.configuration["client_id"]
127147
authority_url = self.configuration["authority_url"]
148+
self.configuration["scopes_array"] = json_loads(self.configuration["scopes"])
128149
scopes = self.configuration["scopes_array"]
129-
username, password = super().get_auth()
130-
app = msal.PublicClientApplication(client_id=client_id, authority=authority_url)
131-
result = app.acquire_token_by_username_password(
132-
username=username,
133-
password=password,
134-
scopes=scopes,
135-
)
150+
username, password = self.get_credentials()
151+
if self.configuration.get("username") is None:
152+
self.auth_type = AuthType.CREDENTIALS
153+
else:
154+
self.auth_type = AuthType.LOGIN_PASSWORD
155+
if self.auth_type == AuthType.CREDENTIALS:
156+
app = msal.ConfidentialClientApplication(
157+
authority=authority_url,
158+
client_id=client_id,
159+
client_credential=password,
160+
)
161+
result = app.acquire_token_for_client(
162+
scopes=scopes,
163+
)
164+
elif self.auth_type == AuthType.LOGIN_PASSWORD:
165+
app = msal.PublicClientApplication(
166+
authority=authority_url,
167+
client_id=client_id,
168+
)
169+
result = app.acquire_token_by_username_password(
170+
username=username,
171+
password=password,
172+
scopes=scopes,
173+
)
174+
if "error" in result:
175+
raise ValueError(f"Couldn't acquire token: {result}")
136176
access_token = result["access_token"]
177+
logger.debug(result)
137178
return f"Bearer {access_token}"
138179

139180
def get_response(self, url: str, auth=None, http_method="get", **kwargs):

requirements_all_ds.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,9 @@ cmem-cmempy==21.2.3
4242
xlrd==2.0.1
4343
openpyxl==3.0.7
4444
firebolt-sdk
45-
databend-sqlalchemy==0.2.4
4645
pandas==1.3.4
4746
nzpy>=1.15
4847
nzalchemy
4948
python-arango==6.1.0
5049
pinotdb>=0.4.5
51-
pyarrow==10.0.0
50+
pyarrow==10.0.0

0 commit comments

Comments
 (0)