vavacars-data-utils 1.3.6__tar.gz → 1.4.0__tar.gz
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.
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/PKG-INFO +8 -4
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/setup.cfg +6 -2
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/azure/az_helper.py +17 -1
- vavacars_data_utils-1.4.0/vava_utils/loganalytics/__init__.py +1 -0
- vavacars_data_utils-1.4.0/vava_utils/loganalytics/loganalytics_helper.py +51 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/sql/sql_helper.py +69 -5
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vavacars_data_utils.egg-info/PKG-INFO +8 -4
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vavacars_data_utils.egg-info/SOURCES.txt +33 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vavacars_data_utils.egg-info/requires.txt +6 -1
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/README.md +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/pyproject.toml +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/test/utils/__init__.py +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/test/utils/test_strings.py +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/__init__.py +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/azure/__init__.py +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/bigquery/__init__.py +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/bigquery/bigquery_helper.py +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/camunda/__init__.py +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/camunda/camunda_helper.py +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/email/__init__.py +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/email/email_helper.py +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/salesforce/__init__.py +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/salesforce/salesforce_helper.py +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/smartiq/__init__.py +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/smartiq/smartiq_helper.py +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/smartiq/smartiq_helper_v2.py +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/sql/__init__.py +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/turkey/__init__.py +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/turkey/dates.py +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/utils/__init__.py +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/utils/callables.py +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/utils/comparisons.py +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/utils/naming.py +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/utils/singleton.py +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/utils/strings.py +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/utils/utils.py +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/vavaprice/__init__.py +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/vavaprice/vavaprice_helper.py +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vavacars_data_utils.egg-info/dependency_links.txt +0 -0
- {vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vavacars_data_utils.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: vavacars_data_utils
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: Package with utils
|
|
5
5
|
Home-page: https://dev.azure.com/vavacars/DataScience/_git/Data.Utils
|
|
6
6
|
Author: Vavacars Data Science Team
|
|
@@ -22,10 +22,14 @@ Requires-Dist: sqlalchemy<2.0; extra == "sql"
|
|
|
22
22
|
Requires-Dist: psycopg2-binary; extra == "sql"
|
|
23
23
|
Requires-Dist: pyodbc; extra == "sql"
|
|
24
24
|
Requires-Dist: msal; extra == "sql"
|
|
25
|
-
Provides-Extra:
|
|
26
|
-
Requires-Dist:
|
|
25
|
+
Provides-Extra: email
|
|
26
|
+
Requires-Dist: azureml-core; extra == "email"
|
|
27
|
+
Requires-Dist: azure-communication-email; extra == "email"
|
|
27
28
|
Provides-Extra: azure
|
|
28
29
|
Requires-Dist: azureml-core; extra == "azure"
|
|
30
|
+
Provides-Extra: loganalytics
|
|
31
|
+
Requires-Dist: azureml-core; extra == "loganalytics"
|
|
32
|
+
Requires-Dist: azure-monitor-query; extra == "loganalytics"
|
|
29
33
|
|
|
30
34
|
# Vavacars
|
|
31
35
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[metadata]
|
|
2
2
|
name = vavacars_data_utils
|
|
3
|
-
version = 1.
|
|
3
|
+
version = 1.4.0
|
|
4
4
|
author = Vavacars Data Science Team
|
|
5
5
|
author_email = acg@vava.cars
|
|
6
6
|
description = Package with utils
|
|
@@ -40,10 +40,14 @@ sql =
|
|
|
40
40
|
psycopg2-binary
|
|
41
41
|
pyodbc
|
|
42
42
|
msal
|
|
43
|
-
|
|
43
|
+
email =
|
|
44
|
+
azureml-core
|
|
44
45
|
azure-communication-email
|
|
45
46
|
azure =
|
|
46
47
|
azureml-core
|
|
48
|
+
loganalytics =
|
|
49
|
+
azureml-core
|
|
50
|
+
azure-monitor-query
|
|
47
51
|
|
|
48
52
|
[egg_info]
|
|
49
53
|
tag_build =
|
|
@@ -9,6 +9,7 @@ from azureml.core.authentication import ServicePrincipalAuthentication
|
|
|
9
9
|
from azureml.core.model import Model
|
|
10
10
|
from azureml.data.datapath import DataPath
|
|
11
11
|
|
|
12
|
+
from azure.storage.blob import BlobServiceClient
|
|
12
13
|
|
|
13
14
|
from vava_utils.utils.singleton import singleton
|
|
14
15
|
|
|
@@ -26,7 +27,7 @@ class Az_Helper:
|
|
|
26
27
|
- service_principal_password
|
|
27
28
|
- subscription_id
|
|
28
29
|
- resource_group
|
|
29
|
-
-
|
|
30
|
+
- workspace
|
|
30
31
|
"""
|
|
31
32
|
self.auth = ServicePrincipalAuthentication(
|
|
32
33
|
tenant_id=config["tenant_id"],
|
|
@@ -39,6 +40,9 @@ class Az_Helper:
|
|
|
39
40
|
workspace_name=config["workspace"],
|
|
40
41
|
auth=self.auth,
|
|
41
42
|
)
|
|
43
|
+
self.blob = BlobServiceClient.from_connection_string(
|
|
44
|
+
f"DefaultEndpointsProtocol=https;AccountName={self.account_name};AccountKey={account_key};EndpointSuffix=core.windows.net"
|
|
45
|
+
)
|
|
42
46
|
|
|
43
47
|
def register_model(self, path, name, include_version=True, **kwargs):
|
|
44
48
|
"""
|
|
@@ -258,3 +262,15 @@ class Az_Helper:
|
|
|
258
262
|
tags=tags,
|
|
259
263
|
**kwargs,
|
|
260
264
|
)
|
|
265
|
+
|
|
266
|
+
def write_blob_file(self, container, local_file):
|
|
267
|
+
"""
|
|
268
|
+
Write local file to Azure Blob Storage
|
|
269
|
+
|
|
270
|
+
Parameters:
|
|
271
|
+
container (string): Azure Blob Storage container name
|
|
272
|
+
local_file (string): local file path
|
|
273
|
+
"""
|
|
274
|
+
blob = Datastore.get(self.ws, container)
|
|
275
|
+
blob.upload_files(files=[local_file], target_path=".", overwrite=True)
|
|
276
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .loganalytics_helper import LogAnalyticsHelper
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import pandas as pd
|
|
3
|
+
from azure.identity import ClientSecretCredential
|
|
4
|
+
from azure.monitor.query import LogsQueryClient, LogsQueryStatus
|
|
5
|
+
from azure.core.exceptions import HttpResponseError
|
|
6
|
+
import datetime
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class UnknownQueryStatusError(Exception):
|
|
10
|
+
"""Custom exception for unknown query status"""
|
|
11
|
+
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class LogAnalyticsHelper:
|
|
16
|
+
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
service_principal_id: str,
|
|
20
|
+
service_principal_password: str,
|
|
21
|
+
tentant_id: str,
|
|
22
|
+
workspace_id: str = "58ca4766-72b7-4610-8d1c-4b6a88a49a01",
|
|
23
|
+
):
|
|
24
|
+
self.client = LogsQueryClient(
|
|
25
|
+
ClientSecretCredential(tentant_id, service_principal_id, service_principal_password)
|
|
26
|
+
)
|
|
27
|
+
self.workspace_id = workspace_id
|
|
28
|
+
|
|
29
|
+
def query(self, query: str, start: datetime.datetime = None, end: datetime.datetime = None, **kwargs):
|
|
30
|
+
|
|
31
|
+
timespan = None if start is None or end is None else (start, end)
|
|
32
|
+
response = self.client.query_workspace(workspace_id=self.workspace_id, query=query, timespan=timespan, **kwargs)
|
|
33
|
+
|
|
34
|
+
if response.status == LogsQueryStatus.SUCCESS:
|
|
35
|
+
data = response.tables
|
|
36
|
+
elif response.status == LogsQueryStatus.PARTIAL:
|
|
37
|
+
logging.warning(f"Partial query success. Error: {response.partial_error.message}")
|
|
38
|
+
data = response.partial_data
|
|
39
|
+
else:
|
|
40
|
+
logging.error(f"Unknown query status: {response.status}")
|
|
41
|
+
raise UnknownQueryStatusError(f"Received an unknown query status: {response.status}")
|
|
42
|
+
|
|
43
|
+
dataframes = [pd.DataFrame(t.rows, columns=t.columns) for t in data]
|
|
44
|
+
|
|
45
|
+
if len(dataframes) == 1:
|
|
46
|
+
return dataframes[0]
|
|
47
|
+
elif len(dataframes) > 1:
|
|
48
|
+
return dataframes
|
|
49
|
+
else:
|
|
50
|
+
logging.warning("No data found in the query result")
|
|
51
|
+
return None
|
|
@@ -49,18 +49,39 @@ def get_mysql_helper(host, user, port, database=None, password=None, **kwargs):
|
|
|
49
49
|
return SQL_Helper(engine, engine_type=MYSQL)
|
|
50
50
|
|
|
51
51
|
|
|
52
|
-
def
|
|
52
|
+
def _get_sqlserver_helper_from_user_password(
|
|
53
|
+
host,
|
|
54
|
+
database,
|
|
55
|
+
user,
|
|
56
|
+
password,
|
|
57
|
+
port,
|
|
58
|
+
db_driver,
|
|
59
|
+
fast_execute_many,
|
|
60
|
+
**kwargs,
|
|
61
|
+
):
|
|
62
|
+
conn_str = urllib.parse.quote_plus(
|
|
63
|
+
f"DRIVER={{{db_driver}}};SERVER={host},{port};DATABASE={database};UID={user};PWD={password}"
|
|
64
|
+
)
|
|
65
|
+
engine = create_engine(
|
|
66
|
+
url=URL.create("mssql+pyodbc", query={"odbc_connect": conn_str}),
|
|
67
|
+
fast_executemany=fast_execute_many,
|
|
68
|
+
pool_pre_ping=True,
|
|
69
|
+
**kwargs,
|
|
70
|
+
)
|
|
71
|
+
return SQL_Helper(engine, engine_type=SQL_SERVER)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _get_sqlserver_helper_from_service_principal(
|
|
53
75
|
host,
|
|
54
76
|
database,
|
|
55
77
|
service_principal_id,
|
|
56
78
|
service_principal_secret,
|
|
57
79
|
tenant_id,
|
|
58
|
-
port
|
|
59
|
-
db_driver
|
|
60
|
-
fast_execute_many
|
|
80
|
+
port,
|
|
81
|
+
db_driver,
|
|
82
|
+
fast_execute_many,
|
|
61
83
|
**kwargs,
|
|
62
84
|
):
|
|
63
|
-
|
|
64
85
|
creds = ConfidentialClientApplication(
|
|
65
86
|
client_id=service_principal_id,
|
|
66
87
|
client_credential=service_principal_secret,
|
|
@@ -89,6 +110,49 @@ def get_sqlserver_helper(
|
|
|
89
110
|
return SQL_Helper(engine, engine_type=SQL_SERVER)
|
|
90
111
|
|
|
91
112
|
|
|
113
|
+
def get_sqlserver_helper(
|
|
114
|
+
host,
|
|
115
|
+
database,
|
|
116
|
+
service_principal_id=None,
|
|
117
|
+
service_principal_secret=None,
|
|
118
|
+
tenant_id=None,
|
|
119
|
+
user=None,
|
|
120
|
+
password=None,
|
|
121
|
+
port=1433,
|
|
122
|
+
db_driver="ODBC Driver 17 for SQL Server",
|
|
123
|
+
fast_execute_many=True,
|
|
124
|
+
**kwargs,
|
|
125
|
+
):
|
|
126
|
+
|
|
127
|
+
if user and password:
|
|
128
|
+
return _get_sqlserver_helper_from_user_password(
|
|
129
|
+
host,
|
|
130
|
+
database,
|
|
131
|
+
user,
|
|
132
|
+
password,
|
|
133
|
+
port,
|
|
134
|
+
db_driver,
|
|
135
|
+
fast_execute_many,
|
|
136
|
+
**kwargs,
|
|
137
|
+
)
|
|
138
|
+
elif service_principal_id and service_principal_secret and tenant_id:
|
|
139
|
+
return _get_sqlserver_helper_from_service_principal(
|
|
140
|
+
host,
|
|
141
|
+
database,
|
|
142
|
+
service_principal_id,
|
|
143
|
+
service_principal_secret,
|
|
144
|
+
tenant_id,
|
|
145
|
+
port,
|
|
146
|
+
db_driver,
|
|
147
|
+
fast_execute_many,
|
|
148
|
+
**kwargs,
|
|
149
|
+
)
|
|
150
|
+
else:
|
|
151
|
+
raise ValueError(
|
|
152
|
+
"Either user and password or service_principal_id, service_principal_secret and tenant_id must be provided"
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
|
|
92
156
|
def _value_to_str(v):
|
|
93
157
|
if isinstance(v, bool):
|
|
94
158
|
return str(int(v))
|
{vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vavacars_data_utils.egg-info/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: vavacars_data_utils
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: Package with utils
|
|
5
5
|
Home-page: https://dev.azure.com/vavacars/DataScience/_git/Data.Utils
|
|
6
6
|
Author: Vavacars Data Science Team
|
|
@@ -22,10 +22,14 @@ Requires-Dist: sqlalchemy<2.0; extra == "sql"
|
|
|
22
22
|
Requires-Dist: psycopg2-binary; extra == "sql"
|
|
23
23
|
Requires-Dist: pyodbc; extra == "sql"
|
|
24
24
|
Requires-Dist: msal; extra == "sql"
|
|
25
|
-
Provides-Extra:
|
|
26
|
-
Requires-Dist:
|
|
25
|
+
Provides-Extra: email
|
|
26
|
+
Requires-Dist: azureml-core; extra == "email"
|
|
27
|
+
Requires-Dist: azure-communication-email; extra == "email"
|
|
27
28
|
Provides-Extra: azure
|
|
28
29
|
Requires-Dist: azureml-core; extra == "azure"
|
|
30
|
+
Provides-Extra: loganalytics
|
|
31
|
+
Requires-Dist: azureml-core; extra == "loganalytics"
|
|
32
|
+
Requires-Dist: azure-monitor-query; extra == "loganalytics"
|
|
29
33
|
|
|
30
34
|
# Vavacars
|
|
31
35
|
|
{vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vavacars_data_utils.egg-info/SOURCES.txt
RENAMED
|
@@ -12,6 +12,8 @@ setup.cfg
|
|
|
12
12
|
./vava_utils/camunda/camunda_helper.py
|
|
13
13
|
./vava_utils/email/__init__.py
|
|
14
14
|
./vava_utils/email/email_helper.py
|
|
15
|
+
./vava_utils/loganalytics/__init__.py
|
|
16
|
+
./vava_utils/loganalytics/loganalytics_helper.py
|
|
15
17
|
./vava_utils/salesforce/__init__.py
|
|
16
18
|
./vava_utils/salesforce/salesforce_helper.py
|
|
17
19
|
./vava_utils/smartiq/__init__.py
|
|
@@ -30,6 +32,37 @@ setup.cfg
|
|
|
30
32
|
./vava_utils/utils/utils.py
|
|
31
33
|
./vava_utils/vavaprice/__init__.py
|
|
32
34
|
./vava_utils/vavaprice/vavaprice_helper.py
|
|
35
|
+
test/utils/__init__.py
|
|
36
|
+
test/utils/test_strings.py
|
|
37
|
+
vava_utils/__init__.py
|
|
38
|
+
vava_utils/azure/__init__.py
|
|
39
|
+
vava_utils/azure/az_helper.py
|
|
40
|
+
vava_utils/bigquery/__init__.py
|
|
41
|
+
vava_utils/bigquery/bigquery_helper.py
|
|
42
|
+
vava_utils/camunda/__init__.py
|
|
43
|
+
vava_utils/camunda/camunda_helper.py
|
|
44
|
+
vava_utils/email/__init__.py
|
|
45
|
+
vava_utils/email/email_helper.py
|
|
46
|
+
vava_utils/loganalytics/__init__.py
|
|
47
|
+
vava_utils/loganalytics/loganalytics_helper.py
|
|
48
|
+
vava_utils/salesforce/__init__.py
|
|
49
|
+
vava_utils/salesforce/salesforce_helper.py
|
|
50
|
+
vava_utils/smartiq/__init__.py
|
|
51
|
+
vava_utils/smartiq/smartiq_helper.py
|
|
52
|
+
vava_utils/smartiq/smartiq_helper_v2.py
|
|
53
|
+
vava_utils/sql/__init__.py
|
|
54
|
+
vava_utils/sql/sql_helper.py
|
|
55
|
+
vava_utils/turkey/__init__.py
|
|
56
|
+
vava_utils/turkey/dates.py
|
|
57
|
+
vava_utils/utils/__init__.py
|
|
58
|
+
vava_utils/utils/callables.py
|
|
59
|
+
vava_utils/utils/comparisons.py
|
|
60
|
+
vava_utils/utils/naming.py
|
|
61
|
+
vava_utils/utils/singleton.py
|
|
62
|
+
vava_utils/utils/strings.py
|
|
63
|
+
vava_utils/utils/utils.py
|
|
64
|
+
vava_utils/vavaprice/__init__.py
|
|
65
|
+
vava_utils/vavaprice/vavaprice_helper.py
|
|
33
66
|
vavacars_data_utils.egg-info/PKG-INFO
|
|
34
67
|
vavacars_data_utils.egg-info/SOURCES.txt
|
|
35
68
|
vavacars_data_utils.egg-info/dependency_links.txt
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/bigquery/bigquery_helper.py
RENAMED
|
File without changes
|
|
File without changes
|
{vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/camunda/camunda_helper.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/salesforce/salesforce_helper.py
RENAMED
|
File without changes
|
|
File without changes
|
{vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/smartiq/smartiq_helper.py
RENAMED
|
File without changes
|
{vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/smartiq/smartiq_helper_v2.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vava_utils/vavaprice/vavaprice_helper.py
RENAMED
|
File without changes
|
|
File without changes
|
{vavacars_data_utils-1.3.6 → vavacars_data_utils-1.4.0}/vavacars_data_utils.egg-info/top_level.txt
RENAMED
|
File without changes
|