MSTR-Robotics-magerdaniel 0.2.11__tar.gz → 0.3.1__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.
- {MSTR_Robotics_magerdaniel-0.2.11 → mstr_robotics_magerdaniel-0.3.1/MSTR_Robotics_magerdaniel.egg-info}/PKG-INFO +8 -2
- {MSTR_Robotics_magerdaniel-0.2.11 → mstr_robotics_magerdaniel-0.3.1}/MSTR_Robotics_magerdaniel.egg-info/SOURCES.txt +5 -3
- {MSTR_Robotics_magerdaniel-0.2.11/MSTR_Robotics_magerdaniel.egg-info → mstr_robotics_magerdaniel-0.3.1}/PKG-INFO +9 -3
- {MSTR_Robotics_magerdaniel-0.2.11 → mstr_robotics_magerdaniel-0.3.1}/mstr_robotics/_connectors.py +45 -3
- {MSTR_Robotics_magerdaniel-0.2.11 → mstr_robotics_magerdaniel-0.3.1}/mstr_robotics/_helper.py +40 -27
- mstr_robotics_magerdaniel-0.3.1/mstr_robotics/_lu_data.py +53 -0
- mstr_robotics_magerdaniel-0.3.1/mstr_robotics/_mod_prj_obj.py +67 -0
- mstr_robotics_magerdaniel-0.3.1/mstr_robotics/ai_openAi_faisst.py +250 -0
- mstr_robotics_magerdaniel-0.3.1/mstr_robotics/dossier.py +203 -0
- {MSTR_Robotics_magerdaniel-0.2.11 → mstr_robotics_magerdaniel-0.3.1}/mstr_robotics/mstr_classes.py +34 -7
- {MSTR_Robotics_magerdaniel-0.2.11 → mstr_robotics_magerdaniel-0.3.1}/mstr_robotics/mstr_pandas.py +10 -1
- mstr_robotics_magerdaniel-0.3.1/mstr_robotics/prepare_AI_data.py +229 -0
- mstr_robotics_magerdaniel-0.3.1/mstr_robotics/read_out_prj_obj.py +856 -0
- {MSTR_Robotics_magerdaniel-0.2.11 → mstr_robotics_magerdaniel-0.3.1}/mstr_robotics/report.py +196 -92
- {MSTR_Robotics_magerdaniel-0.2.11 → mstr_robotics_magerdaniel-0.3.1}/setup.py +1 -1
- MSTR_Robotics_magerdaniel-0.2.11/mstr_robotics/_lu_data.py +0 -49
- MSTR_Robotics_magerdaniel-0.2.11/mstr_robotics/jup_schema_monitor.ipynb +0 -421
- MSTR_Robotics_magerdaniel-0.2.11/mstr_robotics/read_out_prj_obj.py +0 -318
- MSTR_Robotics_magerdaniel-0.2.11/notebooks/jup_schema_monitor.ipynb +0 -567
- {MSTR_Robotics_magerdaniel-0.2.11 → mstr_robotics_magerdaniel-0.3.1}/LICENSE +0 -0
- {MSTR_Robotics_magerdaniel-0.2.11 → mstr_robotics_magerdaniel-0.3.1}/MANIFEST.in +0 -0
- {MSTR_Robotics_magerdaniel-0.2.11 → mstr_robotics_magerdaniel-0.3.1}/MSTR_Robotics_magerdaniel.egg-info/dependency_links.txt +0 -0
- {MSTR_Robotics_magerdaniel-0.2.11 → mstr_robotics_magerdaniel-0.3.1}/MSTR_Robotics_magerdaniel.egg-info/top_level.txt +0 -0
- {MSTR_Robotics_magerdaniel-0.2.11 → mstr_robotics_magerdaniel-0.3.1}/README.md +0 -0
- {MSTR_Robotics_magerdaniel-0.2.11 → mstr_robotics_magerdaniel-0.3.1}/mstr_robotics/__init__.py +0 -0
- {MSTR_Robotics_magerdaniel-0.2.11 → mstr_robotics_magerdaniel-0.3.1}/setup.cfg +0 -0
|
@@ -1,12 +1,18 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: MSTR_Robotics_magerdaniel
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: MicroStrateg(P)ython
|
|
5
5
|
Home-page: https://github.com/magerdaniel
|
|
6
6
|
Author: Daniel Mager
|
|
7
7
|
Author-email: "danielmager@gmx.de"
|
|
8
8
|
Description-Content-Type: text/markdown
|
|
9
9
|
License-File: LICENSE
|
|
10
|
+
Dynamic: author
|
|
11
|
+
Dynamic: author-email
|
|
12
|
+
Dynamic: description
|
|
13
|
+
Dynamic: description-content-type
|
|
14
|
+
Dynamic: home-page
|
|
15
|
+
Dynamic: summary
|
|
10
16
|
|
|
11
17
|
Hi,
|
|
12
18
|
|
|
@@ -10,9 +10,11 @@ mstr_robotics/__init__.py
|
|
|
10
10
|
mstr_robotics/_connectors.py
|
|
11
11
|
mstr_robotics/_helper.py
|
|
12
12
|
mstr_robotics/_lu_data.py
|
|
13
|
-
mstr_robotics/
|
|
13
|
+
mstr_robotics/_mod_prj_obj.py
|
|
14
|
+
mstr_robotics/ai_openAi_faisst.py
|
|
15
|
+
mstr_robotics/dossier.py
|
|
14
16
|
mstr_robotics/mstr_classes.py
|
|
15
17
|
mstr_robotics/mstr_pandas.py
|
|
18
|
+
mstr_robotics/prepare_AI_data.py
|
|
16
19
|
mstr_robotics/read_out_prj_obj.py
|
|
17
|
-
mstr_robotics/report.py
|
|
18
|
-
notebooks/jup_schema_monitor.ipynb
|
|
20
|
+
mstr_robotics/report.py
|
|
@@ -1,12 +1,18 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
2
|
-
Name:
|
|
3
|
-
Version: 0.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: MSTR_Robotics_magerdaniel
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: MicroStrateg(P)ython
|
|
5
5
|
Home-page: https://github.com/magerdaniel
|
|
6
6
|
Author: Daniel Mager
|
|
7
7
|
Author-email: "danielmager@gmx.de"
|
|
8
8
|
Description-Content-Type: text/markdown
|
|
9
9
|
License-File: LICENSE
|
|
10
|
+
Dynamic: author
|
|
11
|
+
Dynamic: author-email
|
|
12
|
+
Dynamic: description
|
|
13
|
+
Dynamic: description-content-type
|
|
14
|
+
Dynamic: home-page
|
|
15
|
+
Dynamic: summary
|
|
10
16
|
|
|
11
17
|
Hi,
|
|
12
18
|
|
{MSTR_Robotics_magerdaniel-0.2.11 → mstr_robotics_magerdaniel-0.3.1}/mstr_robotics/_connectors.py
RENAMED
|
@@ -5,6 +5,16 @@ i_msic=msic()
|
|
|
5
5
|
|
|
6
6
|
class mstr_api():
|
|
7
7
|
|
|
8
|
+
def get_prj_tbl(self,conn):
|
|
9
|
+
inst_u = f"{conn.base_url}/api/model/tables"
|
|
10
|
+
r = conn.get(inst_u)
|
|
11
|
+
return r
|
|
12
|
+
|
|
13
|
+
def get_dossier_prp_l(self,conn,dossier_id):
|
|
14
|
+
endpoint = f'/api/documents/{dossier_id}/prompts'
|
|
15
|
+
prp_l = conn.get(endpoint=endpoint).json()
|
|
16
|
+
return prp_l
|
|
17
|
+
|
|
8
18
|
def get_ele_prp_ans(self,conn,report_id,instance_id,prompt_id,att_form_str=None,offset=0, limit=200):
|
|
9
19
|
#get availeble objects from an element prompt
|
|
10
20
|
#be carefull, this can be an performance issue
|
|
@@ -23,6 +33,10 @@ class mstr_api():
|
|
|
23
33
|
offset += limit
|
|
24
34
|
return all_values
|
|
25
35
|
|
|
36
|
+
def create_dossier_instance(self, conn, dossier_id, body=None, error_msg=None):
|
|
37
|
+
endpoint = f'{conn.base_url}/api/dossiers/{dossier_id}/instances'
|
|
38
|
+
return conn.post(url=endpoint, json=body).json()["mid"]
|
|
39
|
+
|
|
26
40
|
def get_prp_ans(self,conn,report_id,instance_id,prompt_id,offset=0, limit=200):
|
|
27
41
|
#get availeble objects from an object prompt
|
|
28
42
|
rest_limit=limit
|
|
@@ -30,7 +44,7 @@ class mstr_api():
|
|
|
30
44
|
while rest_limit>=0:
|
|
31
45
|
inst_u = f'{conn.base_url}/api/reports/{report_id}/instances/{instance_id}/prompts/{prompt_id}/objects?offset={offset}&limit={limit}'
|
|
32
46
|
r = conn.get(inst_u, headers=conn.headers)
|
|
33
|
-
prp_ans_base_l.
|
|
47
|
+
prp_ans_base_l.extend(r.json()["objects"])
|
|
34
48
|
rest_limit=int(r.headers["x-mstr-total-count"])-offset
|
|
35
49
|
offset +=limit
|
|
36
50
|
|
|
@@ -62,12 +76,12 @@ class mstr_api():
|
|
|
62
76
|
|
|
63
77
|
return resp
|
|
64
78
|
|
|
65
|
-
def get_project_name(self, conn):
|
|
79
|
+
def get_project_name(self, conn,project_id):
|
|
66
80
|
#provides a readable project name for humans
|
|
67
81
|
project_resp = conn.get(f'{conn.base_url}/api/projects')
|
|
68
82
|
project_name=""
|
|
69
83
|
for p in project_resp.json():
|
|
70
|
-
if p["id"] ==
|
|
84
|
+
if p["id"] == project_id:
|
|
71
85
|
project_name= p["name"]
|
|
72
86
|
|
|
73
87
|
if project_name!="":
|
|
@@ -80,6 +94,16 @@ class mstr_api():
|
|
|
80
94
|
r = conn.get(inst_u, headers=conn.headers)
|
|
81
95
|
return r.json()
|
|
82
96
|
|
|
97
|
+
def get_custom_group(self,conn, custom_group_id, show_expression_as="tokens"):
|
|
98
|
+
url = f'{conn.base_url}/api/model/customGroups/{custom_group_id}?showExpressionAs={show_expression_as}'
|
|
99
|
+
custom_group_def = conn.get(url)
|
|
100
|
+
return custom_group_def.json()
|
|
101
|
+
|
|
102
|
+
def get_consolidation(self,conn, consolidation_id):
|
|
103
|
+
url = f'{conn.base_url}/api/model/consolidations/{consolidation_id}'
|
|
104
|
+
consolidation_def = conn.get(url)
|
|
105
|
+
return consolidation_def.json()
|
|
106
|
+
|
|
83
107
|
def get_hier_att(self,conn,hier_id,displayForms="All",offset=0, limit=200):
|
|
84
108
|
#Available displayForms: all, browseForms, reportDisplayForms, customForms, unknown
|
|
85
109
|
#I develope initially to get the form_ids for attribute qualification prompts
|
|
@@ -104,6 +128,12 @@ class mstr_api():
|
|
|
104
128
|
rep_sql=conn.get(url)
|
|
105
129
|
return rep_sql
|
|
106
130
|
|
|
131
|
+
def get_report_all_def(self,conn,report_id, show_expression_as="tokens",show_filter_tokens="true",show_advanced_properties="true"):
|
|
132
|
+
url=f'{conn.base_url}/api/model/reports/{report_id}?showExpressionAs={show_expression_as}&showFilterTokens={show_filter_tokens}&showAdvancedProperties={show_advanced_properties}'
|
|
133
|
+
#print(url)
|
|
134
|
+
report_def=conn.get(url)
|
|
135
|
+
return report_def.json()
|
|
136
|
+
|
|
107
137
|
def get_report_raw(self,conn,report_id,instance_id):
|
|
108
138
|
#normaly I use the report libraries from mstrio
|
|
109
139
|
# to fetch the data. Sometimes they bring back an error. so this one is for trouble
|
|
@@ -149,6 +179,18 @@ class mstr_api():
|
|
|
149
179
|
|
|
150
180
|
return {"metric_val_l":raw_val_l,"metric_guid_l":regam_job_metric_guid_l}
|
|
151
181
|
|
|
182
|
+
def get_dossier_def(self,conn,dossier_id):
|
|
183
|
+
url = f'{conn.base_url}/api/v2/dossiers/{dossier_id}/definition'
|
|
184
|
+
doss_hier = conn.get(url)
|
|
185
|
+
return doss_hier.json()
|
|
186
|
+
|
|
187
|
+
def get_dossier_detail(self, conn, dossier_id, instance_id, chapter_key, vis_id):
|
|
188
|
+
url = f"{conn.base_url}/api/v2/dossiers/{dossier_id}/instances/"
|
|
189
|
+
url += f"{instance_id}/chapters/{chapter_key}/visualizations/{vis_id}?offset=0&limit=1000"
|
|
190
|
+
return conn.get(url).json()
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
|
|
152
194
|
def ZZZ_get_cube_data(self,conn,cube_id,instance_id,offset,limit) :
|
|
153
195
|
inst_u = f'{conn.base_url}/api/v2/cubes/{cube_id}/instances/{instance_id}?offset={offset}&limit={limit}'
|
|
154
196
|
cube_ds = conn.get(inst_u, headers=conn.headers)
|
{MSTR_Robotics_magerdaniel-0.2.11 → mstr_robotics_magerdaniel-0.3.1}/mstr_robotics/_helper.py
RENAMED
|
@@ -91,7 +91,22 @@ class msic():
|
|
|
91
91
|
return key_l
|
|
92
92
|
|
|
93
93
|
def get_comon_val_l(self,list_1,list_2):
|
|
94
|
-
return list(set(list_1).intersection(list_2))
|
|
94
|
+
#return list(set(list_1).intersection(list_2))
|
|
95
|
+
matches = []
|
|
96
|
+
for item in list_1:
|
|
97
|
+
if item in list_2:
|
|
98
|
+
matches.append(item)
|
|
99
|
+
return matches
|
|
100
|
+
|
|
101
|
+
def keep_cols_from_dict_l(self,list_l,keep_cols):
|
|
102
|
+
clean_l = []
|
|
103
|
+
for e in list_l:
|
|
104
|
+
new_d = {}
|
|
105
|
+
for m in self.get_comon_val_l(keep_cols, list_2=e.keys()):
|
|
106
|
+
new_d[m] = e[m]
|
|
107
|
+
|
|
108
|
+
clean_l.append(new_d.copy())
|
|
109
|
+
return clean_l
|
|
95
110
|
|
|
96
111
|
def list_to_dict(self,list_in_l, col_l):
|
|
97
112
|
#merge do lists into one dict
|
|
@@ -108,43 +123,41 @@ class msic():
|
|
|
108
123
|
dict_l.append(dict_d.copy())
|
|
109
124
|
return dict_l
|
|
110
125
|
|
|
111
|
-
def add_prefix_to_dict_keys(self,dict, dpn_prefix):
|
|
126
|
+
def add_prefix_to_dict_keys(self,dict, dpn_prefix, dict_cols= []):
|
|
112
127
|
#adds a prefix to the keys of a dict
|
|
113
128
|
# use case here is to distinct i.e. between the object_id and the depn_object_id
|
|
114
129
|
new_dict = {}
|
|
130
|
+
include=0
|
|
115
131
|
if dpn_prefix==None:
|
|
116
132
|
return dict
|
|
117
133
|
for key, value in dict.items():
|
|
118
|
-
|
|
119
|
-
|
|
134
|
+
if dict_cols==[]:
|
|
135
|
+
include=1
|
|
136
|
+
|
|
137
|
+
if key in dict_cols:
|
|
138
|
+
include = 1
|
|
139
|
+
|
|
140
|
+
if include==1:
|
|
141
|
+
new_key = dpn_prefix + key
|
|
142
|
+
new_dict[new_key] = value
|
|
143
|
+
|
|
120
144
|
return new_dict
|
|
121
145
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
146
|
+
def rem_dbl_dict_in_l (self,dict_l):
|
|
147
|
+
|
|
148
|
+
tuple_l = set(tuple(sorted(d.items())) for d in dict_l)
|
|
125
149
|
|
|
150
|
+
#tuple_l =list(set(tuple(keys) for keys in dict_l))
|
|
151
|
+
# Convert tuples back to dictionaries
|
|
152
|
+
unique_dict_l = [dict(t) for t in tuple_l]
|
|
126
153
|
|
|
127
|
-
|
|
154
|
+
return unique_dict_l
|
|
128
155
|
|
|
129
|
-
def
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
doubles_y = [col for col in df.columns if col.endswith(postfix_right)]
|
|
133
|
-
df.drop(columns=doubles_y, inplace=True)
|
|
134
|
-
df.columns = [col.replace(postfix_left, '') for col in df.columns]
|
|
135
|
-
return df
|
|
156
|
+
def rem_dbl_in_l(self,list_l):
|
|
157
|
+
list_l = list(set(list_l))
|
|
158
|
+
return list_l
|
|
136
159
|
|
|
137
|
-
def
|
|
138
|
-
|
|
139
|
-
return df
|
|
160
|
+
def sort_dict_by_key_in_l(self,dict_l,sort_key, reverse=False):
|
|
161
|
+
return sorted(dict_l, key=lambda x: x.get(sort_key, None), reverse=reverse)
|
|
140
162
|
|
|
141
163
|
|
|
142
|
-
def flag_folder_df(self,flag_path_d_l, obj_df, obj_path="path", flag_path="flag_path"):
|
|
143
|
-
flag_path_df = pd.DataFrame.from_dict(flag_path_d_l)
|
|
144
|
-
unique_str = flag_path_df[flag_path].unique()
|
|
145
|
-
matching_rows_df = obj_df[obj_df['path'].str.contains('|'.join(unique_str))]
|
|
146
|
-
flaged_obj_df = pd.merge(matching_rows_df, flag_path_df, left_on=matching_rows_df['path']
|
|
147
|
-
.str.extract(f'({"|".join(unique_str)})')[0],
|
|
148
|
-
right_on='flag_path')
|
|
149
|
-
return flaged_obj_df
|
|
150
|
-
"""
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
|
|
2
|
+
class lu_mstr_md:
|
|
3
|
+
|
|
4
|
+
def lu_object_type(self):
|
|
5
|
+
return [
|
|
6
|
+
{'PA_OBJ_TYPE_ID': '6', 'PA_OBJ_TYPE_DESC': 'Custom Group', 'MD_OBJ_TYPE_ID': '1',
|
|
7
|
+
'MD_OBJ_TYPE_BEZ': 'Filter'},
|
|
8
|
+
{'PA_OBJ_TYPE_ID': '8', 'PA_OBJ_TYPE_DESC': 'Data Import Cube', 'MD_OBJ_TYPE_ID': '3',
|
|
9
|
+
'MD_OBJ_TYPE_BEZ': 'Report'},
|
|
10
|
+
{'PA_OBJ_TYPE_ID': '16', 'PA_OBJ_TYPE_DESC': 'Filter', 'MD_OBJ_TYPE_ID': '1', 'MD_OBJ_TYPE_BEZ': 'Filter'},
|
|
11
|
+
{'PA_OBJ_TYPE_ID': '40', 'PA_OBJ_TYPE_DESC': 'Template', 'MD_OBJ_TYPE_ID': '2',
|
|
12
|
+
'MD_OBJ_TYPE_BEZ': 'Template'},
|
|
13
|
+
{'PA_OBJ_TYPE_ID': '31', 'PA_OBJ_TYPE_DESC': 'SQL Report', 'MD_OBJ_TYPE_ID': '3',
|
|
14
|
+
'MD_OBJ_TYPE_BEZ': 'Report'},
|
|
15
|
+
{'PA_OBJ_TYPE_ID': '19', 'PA_OBJ_TYPE_DESC': 'SQL Report', 'MD_OBJ_TYPE_ID': '3',
|
|
16
|
+
'MD_OBJ_TYPE_BEZ': 'Report'},
|
|
17
|
+
{'PA_OBJ_TYPE_ID': '23', 'PA_OBJ_TYPE_DESC': 'Metric', 'MD_OBJ_TYPE_ID': '4', 'MD_OBJ_TYPE_BEZ': 'Metric'},
|
|
18
|
+
{'PA_OBJ_TYPE_ID': '107', 'PA_OBJ_TYPE_DESC': 'User Folder', 'MD_OBJ_TYPE_ID': '8',
|
|
19
|
+
'MD_OBJ_TYPE_BEZ': 'Folder'},
|
|
20
|
+
{'PA_OBJ_TYPE_ID': '2', 'PA_OBJ_TYPE_DESC': 'Attribute Element Prompt', 'MD_OBJ_TYPE_ID': '10',
|
|
21
|
+
'MD_OBJ_TYPE_BEZ': 'Prompt'},
|
|
22
|
+
{'PA_OBJ_TYPE_ID': '37', 'PA_OBJ_TYPE_DESC': 'Embedded Prompt', 'MD_OBJ_TYPE_ID': '10',
|
|
23
|
+
'MD_OBJ_TYPE_BEZ': 'Prompt'},
|
|
24
|
+
{'PA_OBJ_TYPE_ID': '58', 'PA_OBJ_TYPE_DESC': 'Level prompt', 'MD_OBJ_TYPE_ID': '10',
|
|
25
|
+
'MD_OBJ_TYPE_BEZ': 'Prompt'},
|
|
26
|
+
{'PA_OBJ_TYPE_ID': '24', 'PA_OBJ_TYPE_DESC': 'Object Prompt', 'MD_OBJ_TYPE_ID': '10',
|
|
27
|
+
'MD_OBJ_TYPE_BEZ': 'Prompt'},
|
|
28
|
+
{'PA_OBJ_TYPE_ID': '28', 'PA_OBJ_TYPE_DESC': 'Prompt', 'MD_OBJ_TYPE_ID': '10', 'MD_OBJ_TYPE_BEZ': 'Prompt'},
|
|
29
|
+
{'PA_OBJ_TYPE_ID': '57', 'PA_OBJ_TYPE_DESC': 'Prompt Expression Draft', 'MD_OBJ_TYPE_ID': '10',
|
|
30
|
+
'MD_OBJ_TYPE_BEZ': 'Prompt'},
|
|
31
|
+
{'PA_OBJ_TYPE_ID': '36', 'PA_OBJ_TYPE_DESC': 'Value Prompt', 'MD_OBJ_TYPE_ID': '10',
|
|
32
|
+
'MD_OBJ_TYPE_BEZ': 'Prompt'},
|
|
33
|
+
{'PA_OBJ_TYPE_ID': '1', 'PA_OBJ_TYPE_DESC': 'Attribute', 'MD_OBJ_TYPE_ID': '12',
|
|
34
|
+
'MD_OBJ_TYPE_BEZ': 'Attribute'},
|
|
35
|
+
{'PA_OBJ_TYPE_ID': '15', 'PA_OBJ_TYPE_DESC': 'Fact', 'MD_OBJ_TYPE_ID': '13', 'MD_OBJ_TYPE_BEZ': 'Fact'},
|
|
36
|
+
{'PA_OBJ_TYPE_ID': '102', 'PA_OBJ_TYPE_DESC': 'System Hierarchy', 'MD_OBJ_TYPE_ID': '14',
|
|
37
|
+
'MD_OBJ_TYPE_BEZ': 'Dimension'},
|
|
38
|
+
{'PA_OBJ_TYPE_ID': '103', 'PA_OBJ_TYPE_DESC': 'User Hierarchy', 'MD_OBJ_TYPE_ID': '14',
|
|
39
|
+
'MD_OBJ_TYPE_BEZ': 'Dimension'},
|
|
40
|
+
{'PA_OBJ_TYPE_ID': '35', 'PA_OBJ_TYPE_DESC': 'Transformation', 'MD_OBJ_TYPE_ID': '43',
|
|
41
|
+
'MD_OBJ_TYPE_BEZ': 'Role'},
|
|
42
|
+
{'PA_OBJ_TYPE_ID': '5', 'PA_OBJ_TYPE_DESC': 'Consolidation', 'MD_OBJ_TYPE_ID': '47',
|
|
43
|
+
'MD_OBJ_TYPE_BEZ': 'Consolidation'},
|
|
44
|
+
{'PA_OBJ_TYPE_ID': '7', 'PA_OBJ_TYPE_DESC': 'Document', 'MD_OBJ_TYPE_ID': '55',
|
|
45
|
+
'MD_OBJ_TYPE_BEZ': 'DocumentDefinition'},
|
|
46
|
+
{'PA_OBJ_TYPE_ID': '14', 'PA_OBJ_TYPE_DESC': 'Dossier', 'MD_OBJ_TYPE_ID': '55',
|
|
47
|
+
'MD_OBJ_TYPE_BEZ': 'DocumentDefinition'},
|
|
48
|
+
{'PA_OBJ_TYPE_ID': '110', 'PA_OBJ_TYPE_DESC': 'Security Filter', 'MD_OBJ_TYPE_ID': '58',
|
|
49
|
+
'MD_OBJ_TYPE_BEZ': 'Security Filter'},
|
|
50
|
+
{'PA_OBJ_TYPE_ID': '-1', 'PA_OBJ_TYPE_DESC': 'Search', 'MD_OBJ_TYPE_ID': '39', 'MD_OBJ_TYPE_BEZ': 'Search'},
|
|
51
|
+
{'PA_OBJ_TYPE_ID': '-2', 'PA_OBJ_TYPE_DESC': 'Shortcut', 'MD_OBJ_TYPE_ID': '18',
|
|
52
|
+
'MD_OBJ_TYPE_BEZ': 'Shortcut'},
|
|
53
|
+
]
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
from mstr_robotics.mstr_classes import mstr_global
|
|
2
|
+
from mstr_robotics._connectors import mstr_api
|
|
3
|
+
from mstr_robotics._helper import str_func
|
|
4
|
+
|
|
5
|
+
class bld_short_cuts:
|
|
6
|
+
|
|
7
|
+
def __init__(self):
|
|
8
|
+
self.str= str_func()
|
|
9
|
+
#self.rep = rep
|
|
10
|
+
self.glob = mstr_global()
|
|
11
|
+
self.mstr_api = mstr_api()
|
|
12
|
+
|
|
13
|
+
def bld_short_cut(self,conn,folder_id,object_id,
|
|
14
|
+
object_type,new_name,object_desc):
|
|
15
|
+
#In Version 11 update 7, it's not possible to define a free name and description
|
|
16
|
+
# when creating a short cut. Thus I create the shurt cut first and rename it later
|
|
17
|
+
short_cut_obj_rep = self.mstr_api.cr_short_cut(conn=conn,object_id=object_id,object_type=object_type,folder_id=folder_id)
|
|
18
|
+
self.mstr_api.rename_object(conn=conn, object_id=short_cut_obj_rep.json()["id"], object_type=18, new_name=new_name, desc_str=object_desc)
|
|
19
|
+
|
|
20
|
+
def run_short_cut_build(self, conn,project_id,short_cut_df,folder_id,df_key_cols_d=None):
|
|
21
|
+
#requiers as imput a pandas data frame with 4 colmuns
|
|
22
|
+
# object_id, object_type, object_name, object_desc
|
|
23
|
+
conn.select_project(project_id)
|
|
24
|
+
if not df_key_cols_d:
|
|
25
|
+
df_key_cols_d={"object_id":"Object@GUID",
|
|
26
|
+
"object_type":"OBJECT_TYPE_ID",
|
|
27
|
+
"object_name":"Object@Name",
|
|
28
|
+
"object_desc":"OBJECT_DESC"}
|
|
29
|
+
|
|
30
|
+
#before adding new short cuts to the shortcut folder, all shortcuts gonna be deleted
|
|
31
|
+
self.clean_shortcut_folder(conn=conn,folder_id=folder_id)
|
|
32
|
+
short_cut_folder_j = f'{{"folderId": "{folder_id}"}}'
|
|
33
|
+
#iterrating throuh all the objects in the list
|
|
34
|
+
short_cut_df.reset_index()
|
|
35
|
+
for index, obj in short_cut_df.iterrows():
|
|
36
|
+
#short_cut_url = f'{conn.base_url}/objects/{obj[2]}/type/{str(obj[4])}/shortcuts'
|
|
37
|
+
try:
|
|
38
|
+
if obj[df_key_cols_d["object_type"]]!=str(18):
|
|
39
|
+
print(obj[df_key_cols_d["object_id"]] +"____"+ str(obj[df_key_cols_d["object_type"]]))
|
|
40
|
+
print("Create short: "+obj[df_key_cols_d["object_name"]]+" of type: "+str(obj[df_key_cols_d["object_type"]]) )
|
|
41
|
+
self.bld_short_cut(conn=conn
|
|
42
|
+
,folder_id=folder_id
|
|
43
|
+
,object_id=obj[df_key_cols_d["object_id"]]
|
|
44
|
+
,object_type=obj[df_key_cols_d["object_type"]]
|
|
45
|
+
,new_name=obj[df_key_cols_d["object_name"]]
|
|
46
|
+
#max lentgh of descriptions in MSTR
|
|
47
|
+
,object_desc=self.str._get_first_x_chars(str_=str(obj[df_key_cols_d["object_desc"]]),i=249)
|
|
48
|
+
)
|
|
49
|
+
else:
|
|
50
|
+
print(f'Obect: {obj[2]} is a shortcut. MSTR does not allow short cuts o short cuts,'
|
|
51
|
+
f' thus they are not supported' )
|
|
52
|
+
except Exception as err:
|
|
53
|
+
print(f'Obect: {obj[2]} hasn not been created. The error is {err}')
|
|
54
|
+
|
|
55
|
+
return
|
|
56
|
+
#@logger
|
|
57
|
+
def clean_shortcut_folder(self,conn,folder_id):
|
|
58
|
+
existing_obj_l = self.glob.get_folder_obj_l(conn=conn, folder_id=folder_id)
|
|
59
|
+
obj_l = self._get_col_from_obj_l(dict_l=existing_obj_l, key_col="id")
|
|
60
|
+
self.glob._delete_object(conn=conn,existing_obj_l=existing_obj_l)
|
|
61
|
+
|
|
62
|
+
#@logger
|
|
63
|
+
def _get_col_from_obj_l(self, dict_l=None, key_col=None):
|
|
64
|
+
key_val_l = []
|
|
65
|
+
for o in dict_l:
|
|
66
|
+
key_val_l.append(o[key_col])
|
|
67
|
+
return key_val_l
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import pandas as pd
|
|
3
|
+
from langchain.vectorstores import FAISS
|
|
4
|
+
from langchain.embeddings import OpenAIEmbeddings
|
|
5
|
+
from openai import OpenAI
|
|
6
|
+
from flashtext import KeywordProcessor
|
|
7
|
+
from itertools import chain
|
|
8
|
+
from mstr_robotics.report import prompts,cube,rep
|
|
9
|
+
from mstr_robotics.mstr_pandas import df_helper
|
|
10
|
+
from mstr_robotics._helper import msic
|
|
11
|
+
from mstr_robotics.prepare_AI_data import map_objects
|
|
12
|
+
import json
|
|
13
|
+
|
|
14
|
+
i_KeywordProcessor = KeywordProcessor()
|
|
15
|
+
i_chain=chain()
|
|
16
|
+
i_rep=rep()
|
|
17
|
+
i_prompts=prompts()
|
|
18
|
+
i_df_helper=df_helper()
|
|
19
|
+
i_cube=cube()
|
|
20
|
+
i_map_objects=map_objects()
|
|
21
|
+
i_msic=msic()
|
|
22
|
+
|
|
23
|
+
class vectorDB_faisst():
|
|
24
|
+
|
|
25
|
+
def __init__(self,sKey):
|
|
26
|
+
#self.sKey=sKey
|
|
27
|
+
os.environ["OPENAI_API_KEY"] = sKey
|
|
28
|
+
self.i_embeddings = OpenAIEmbeddings()
|
|
29
|
+
|
|
30
|
+
def load_vector_store(self,key_l):
|
|
31
|
+
# Flatten and ensure all items are strings
|
|
32
|
+
# Create FAISS vector store
|
|
33
|
+
vector_store = FAISS.from_texts(key_l, self.i_embeddings)
|
|
34
|
+
|
|
35
|
+
return vector_store
|
|
36
|
+
|
|
37
|
+
def load_keyword_processor(self,key_l):
|
|
38
|
+
for val in key_l:
|
|
39
|
+
i_KeywordProcessor.add_keyword(val)
|
|
40
|
+
return i_KeywordProcessor
|
|
41
|
+
|
|
42
|
+
def extract_keywords(self,msg_t):
|
|
43
|
+
keywords_l = i_KeywordProcessor.extract_keywords(msg_t)
|
|
44
|
+
return keywords_l
|
|
45
|
+
|
|
46
|
+
class run_chat_request():
|
|
47
|
+
|
|
48
|
+
def __init__(self,cube_obj_prp_rel_id
|
|
49
|
+
,cube_RAG_form_val_ans_id
|
|
50
|
+
,cube_att_form_def_id
|
|
51
|
+
,rep_dos_id
|
|
52
|
+
,mstr_rag_col_d):
|
|
53
|
+
|
|
54
|
+
self.cube_obj_prp_rel_id=cube_obj_prp_rel_id
|
|
55
|
+
self.cube_RAG_form_val_ans_id=cube_RAG_form_val_ans_id
|
|
56
|
+
self.rep_dos_id=rep_dos_id
|
|
57
|
+
self.mstr_rag_col_d=mstr_rag_col_d
|
|
58
|
+
self.cube_att_form_def_id=cube_att_form_def_id
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def bld_AI_filt_prp_ans(self,conn,vector_store,filter_d):
|
|
62
|
+
# print(json_f)
|
|
63
|
+
# v_andOr_s="And"
|
|
64
|
+
# att_filt_prp_id="1F21042E4FC08886A9D7E4920CA4EC59"
|
|
65
|
+
# met_filt_prp_id="14B57F1F46127BC6E6F746888BC3C7CB"
|
|
66
|
+
prp_ans_d_l = []
|
|
67
|
+
|
|
68
|
+
# ={}
|
|
69
|
+
last_p_ans_d_j = {}
|
|
70
|
+
|
|
71
|
+
for f in list(filter_d.keys()):
|
|
72
|
+
print(f)
|
|
73
|
+
results = vector_store.similarity_search_with_score(query=f, top_k=1)
|
|
74
|
+
|
|
75
|
+
filter_obj_name = results[0][0].page_content
|
|
76
|
+
#print(filter_obj_name)
|
|
77
|
+
#print(self.mstr_rag_col_d)
|
|
78
|
+
filt_obj_rag_df = i_map_objects.get_rag_rep_prp_df(conn, cube_id=self.cube_obj_prp_rel_id, rep_dos_id=self.rep_dos_id,
|
|
79
|
+
key_word_l=[filter_obj_name],mstr_rag_col_d=self.mstr_rag_col_d)
|
|
80
|
+
|
|
81
|
+
filt_obj_rag_df = filt_obj_rag_df[filt_obj_rag_df['prp_subType'].isin(['prompt_expression'])]
|
|
82
|
+
|
|
83
|
+
operator = next(iter(filter_d[f]))
|
|
84
|
+
filter_val_l = filter_d[f][operator]
|
|
85
|
+
#print("DDDDDDDDDDDDDDDDD")
|
|
86
|
+
#print(filt_obj_rag_df)
|
|
87
|
+
d_prp_ans_d = {}
|
|
88
|
+
for index, obj in filt_obj_rag_df.iterrows():
|
|
89
|
+
d_prp_ans_d["prompt_id"] = obj["prompt_id"]
|
|
90
|
+
d_prp_ans_d["prp_subType"] = obj["prp_subType"]
|
|
91
|
+
d_prp_ans_d["object_id"] = obj["object_id"]
|
|
92
|
+
d_prp_ans_d["obj_type"] = obj["obj_type"]
|
|
93
|
+
d_prp_ans_d["operator"] = operator
|
|
94
|
+
if obj["obj_type"] == "attribute":
|
|
95
|
+
if operator in ("In", "notIn"):
|
|
96
|
+
|
|
97
|
+
filter_val_df = i_map_objects.get_rag_rep_prp_df(conn, cube_id=self.cube_RAG_form_val_ans_id,
|
|
98
|
+
rep_dos_id=self.rep_dos_id, key_word_l=filter_val_l,mstr_rag_col_d=self.mstr_rag_col_d)
|
|
99
|
+
filt_df = pd.merge(filt_obj_rag_df[["prompt_id", "prp_subType", "object_id", "obj_type"]],
|
|
100
|
+
filter_val_df[
|
|
101
|
+
["prompt_id", "prp_subType", "attribute_id", "attribute_name", "form_id",
|
|
102
|
+
"form_name", "form_dataType", "key"]],
|
|
103
|
+
left_on=['object_id'], right_on=['attribute_id'], how='inner')
|
|
104
|
+
filt_df = i_df_helper.clean_double_col(df=filt_df)
|
|
105
|
+
#print(filt_df)
|
|
106
|
+
filter_val_l = []
|
|
107
|
+
for index, f_form_ele in filt_df.iterrows():
|
|
108
|
+
form_id = f_form_ele["form_id"]
|
|
109
|
+
form_dataType = f_form_ele["form_dataType"]
|
|
110
|
+
filter_val_l.append(f_form_ele["key"])
|
|
111
|
+
|
|
112
|
+
att_exp_ans_d = {"att_id": d_prp_ans_d["object_id"], "att_form_id": form_id,
|
|
113
|
+
"form_data_type": form_dataType, "operator": operator,
|
|
114
|
+
"filter_val_l": filter_val_l}
|
|
115
|
+
|
|
116
|
+
att_exp_ans_d = i_prompts.bld_att_exp_prp_l(prp_job_ans_d=att_exp_ans_d)
|
|
117
|
+
d_prp_ans_d["prp_ans_d"] = att_exp_ans_d
|
|
118
|
+
prp_ans_d_l.append(d_prp_ans_d.copy())
|
|
119
|
+
#print(d_prp_ans_d)
|
|
120
|
+
|
|
121
|
+
else:
|
|
122
|
+
col_id = i_cube.get_RAG_cube_col_mstr_id(cube_id=self.cube_att_form_def_id, col_name="attribute_id",mstr_rag_col_d=self.mstr_rag_col_d)
|
|
123
|
+
attr_elements = col_id + ":" + obj["object_id"]
|
|
124
|
+
df = i_cube.quick_query_cube(conn, cube_id=self.cube_att_form_def_id, attribute_l=None, metric_l=None,
|
|
125
|
+
attr_elements=attr_elements)
|
|
126
|
+
|
|
127
|
+
for index, form in df.iterrows():
|
|
128
|
+
if int(form["display_form_nr"]) > 0:
|
|
129
|
+
att_exp_ans_d = {"att_id": form["attribute_id"], "att_form_id": form["form_id"],
|
|
130
|
+
"form_data_type": form["REST_form_type"], "operator": operator,
|
|
131
|
+
"filter_val_l": filter_val_l}
|
|
132
|
+
|
|
133
|
+
att_exp_ans_d = i_prompts.bld_att_exp_prp(prp_job_ans_d=att_exp_ans_d)
|
|
134
|
+
d_prp_ans_d["prp_ans_d"] = att_exp_ans_d
|
|
135
|
+
prp_ans_d_l.append(d_prp_ans_d.copy())
|
|
136
|
+
#print(d_prp_ans_d)
|
|
137
|
+
|
|
138
|
+
if obj["obj_type"] == "metric":
|
|
139
|
+
metric_exp_prp = {}
|
|
140
|
+
metric_exp_prp["met_id"] = obj["object_id"]
|
|
141
|
+
metric_exp_prp["data_type"] = "Real"
|
|
142
|
+
metric_exp_prp["operator"] = operator
|
|
143
|
+
metric_exp_prp["filter_val_l"] = filter_val_l
|
|
144
|
+
metric_exp_prp["level"] = "default"
|
|
145
|
+
d_prp_ans_d["prp_ans_d"] = i_prompts.bld_metric_exp_prp(metric_exp_prp=metric_exp_prp.copy())
|
|
146
|
+
prp_ans_d_l.append(d_prp_ans_d.copy())
|
|
147
|
+
#print(print(d_prp_ans_d))
|
|
148
|
+
|
|
149
|
+
# prp_ans_d_l.append(last_p_ans_d_j.copy())
|
|
150
|
+
return prp_ans_d_l
|
|
151
|
+
|
|
152
|
+
def bld_ai_obj_ans_prp(self,conn,json_t_d):
|
|
153
|
+
key_l = []
|
|
154
|
+
col_id = i_cube.get_RAG_cube_col_mstr_id(cube_id=self.cube_obj_prp_rel_id, col_name="object_id",mstr_rag_col_d=self.mstr_rag_col_d)
|
|
155
|
+
obj_l = []
|
|
156
|
+
template_obj_d = {}
|
|
157
|
+
|
|
158
|
+
for obj_type in json_t_d["template"].keys():
|
|
159
|
+
for obj in json_t_d["template"][obj_type]:
|
|
160
|
+
template_obj_d = {"obj_type": obj_type, "obj": obj}
|
|
161
|
+
obj_l.append(template_obj_d.copy())
|
|
162
|
+
|
|
163
|
+
for obj in obj_l:
|
|
164
|
+
key_l.append(obj["obj"])
|
|
165
|
+
|
|
166
|
+
template_obj_rag_df = i_map_objects.get_rag_rep_prp_df(conn, cube_id=self.cube_obj_prp_rel_id, rep_dos_id=self.rep_dos_id,
|
|
167
|
+
key_word_l=key_l,mstr_rag_col_d=self.mstr_rag_col_d)
|
|
168
|
+
template_obj_rag_df = template_obj_rag_df[template_obj_rag_df['prp_subType'].isin(['prompt_objects'])]
|
|
169
|
+
template_obj_rag_df = template_obj_rag_df[['prompt_id', 'prp_subType', "object_id", "obj_type"]]
|
|
170
|
+
|
|
171
|
+
template_obj_rag_df.rename(columns={'object_id': 'id', 'obj_type': 'type'}, inplace=True)
|
|
172
|
+
prp_ans_d_l = template_obj_rag_df.groupby(['prompt_id']).apply(
|
|
173
|
+
lambda x: x[['id', 'type']].to_dict(orient='records')).to_dict()
|
|
174
|
+
obj_prp_ans_l = []
|
|
175
|
+
for prp in prp_ans_d_l:
|
|
176
|
+
obj_prp_ans_d = {}
|
|
177
|
+
obj_prp_ans_d["id"] = prp
|
|
178
|
+
obj_prp_ans_d["type"] = "OBJECTS"
|
|
179
|
+
obj_prp_ans_d["answers"] = prp_ans_d_l[prp]
|
|
180
|
+
obj_prp_ans_l.append(obj_prp_ans_d)
|
|
181
|
+
|
|
182
|
+
return obj_prp_ans_l
|
|
183
|
+
|
|
184
|
+
def merge_exp_prp_ans_l(self,ai_prp_filt_ans_d):
|
|
185
|
+
prp_ans_l = []
|
|
186
|
+
prp_id_l = i_msic.get_key_form_dict_l(dict_l=ai_prp_filt_ans_d, key="prompt_id")
|
|
187
|
+
prp_ans_d_all = {}
|
|
188
|
+
operand_X = "AND"
|
|
189
|
+
for prp_id in prp_id_l:
|
|
190
|
+
prp_ans_d_all[prp_id] = []
|
|
191
|
+
|
|
192
|
+
for prp_ans in ai_prp_filt_ans_d:
|
|
193
|
+
for prp_id in prp_ans_d_all.keys():
|
|
194
|
+
if prp_ans["prompt_id"] == prp_id:
|
|
195
|
+
prp_ans_d_all[prp_id].append(prp_ans["prp_ans_d"])
|
|
196
|
+
|
|
197
|
+
for prp_id in prp_ans_d_all:
|
|
198
|
+
# print(prp_ans_d_all[prp_id])
|
|
199
|
+
prp_ans_d_all[prp_id] = i_prompts.bld_exp_operands_d(p_ans_d_d_l=prp_ans_d_all[prp_id], operator="AND")
|
|
200
|
+
|
|
201
|
+
for prp_ans_id in prp_ans_d_all:
|
|
202
|
+
for prp in ai_prp_filt_ans_d:
|
|
203
|
+
if prp_ans_id == prp["prompt_id"]:
|
|
204
|
+
if prp["prp_subType"] == "prompt_expression" and prp["obj_type"] == "attribute":
|
|
205
|
+
prp_ans_l.append(i_prompts.bld_prp_exp_d(prompt_id=prp_ans_id,
|
|
206
|
+
p_ans_d_j=prp_ans_d_all[prp_ans_id], operator="And"))
|
|
207
|
+
|
|
208
|
+
if prp["prp_subType"] == "prompt_expression" and prp["obj_type"] == "metric":
|
|
209
|
+
prp_ans_l.append(i_prompts.frame_metric_exp_prp(prompt_id=prp_ans_id, p_ans_d_j=prp_ans_d_all[prp_ans_id]))
|
|
210
|
+
break
|
|
211
|
+
return prp_ans_l
|
|
212
|
+
|
|
213
|
+
def save_AI_rep(self, conn, rep_wizzard_id, prompt_answ, ai_rep_name, ai_rep_folder_id):
|
|
214
|
+
instance_id = i_rep.open_Instance(conn=conn, report_id=rep_wizzard_id)
|
|
215
|
+
first_draft = i_rep.set_inst_prompt_ans(conn=conn, report_id=rep_wizzard_id, instance_id=instance_id,
|
|
216
|
+
prompt_answ=prompt_answ)
|
|
217
|
+
rep_id = i_rep.save_rep_inst(conn=conn, instance_id=instance_id, rep_name=ai_rep_name
|
|
218
|
+
, save_mode="OVERWRITE"
|
|
219
|
+
, promptOption="static"
|
|
220
|
+
, setCurrentAsDefaultAnswer=True)
|
|
221
|
+
|
|
222
|
+
return rep_id
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
class openAI():
|
|
226
|
+
|
|
227
|
+
def __init__(self,sKey):
|
|
228
|
+
#self.sKey=sKey
|
|
229
|
+
os.environ["OPENAI_API_KEY"] = sKey
|
|
230
|
+
self.i_embeddings = OpenAIEmbeddings()
|
|
231
|
+
|
|
232
|
+
def check_trans_chatGPT(self,sKey,messages,*args,**kwargs):
|
|
233
|
+
chat_completion = self.call_open_AI(sKey=sKey,messages=messages,*args,**kwargs)
|
|
234
|
+
js = json.loads(chat_completion.json())
|
|
235
|
+
return js
|
|
236
|
+
|
|
237
|
+
def call_open_AI(self, sKey, messages, max_tokens=1000, temperature=0.3, model="gpt-4o-mini"):
|
|
238
|
+
# This is the default and can be omitted
|
|
239
|
+
client = OpenAI(api_key=sKey)
|
|
240
|
+
|
|
241
|
+
chat_completion = client.chat.completions.create(
|
|
242
|
+
messages=messages,
|
|
243
|
+
# model="gpt-3.5-turbo",
|
|
244
|
+
model=model,
|
|
245
|
+
max_tokens=max_tokens,
|
|
246
|
+
temperature=temperature
|
|
247
|
+
)
|
|
248
|
+
js = json.loads(chat_completion.json())
|
|
249
|
+
return js
|
|
250
|
+
|