llumo 0.2.14b6__py3-none-any.whl → 0.2.14b7__py3-none-any.whl
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.
- llumo/client.py +51 -32
- llumo/helpingFuntions.py +54 -12
- llumo/sockets.py +3 -3
- {llumo-0.2.14b6.dist-info → llumo-0.2.14b7.dist-info}/METADATA +1 -1
- llumo-0.2.14b7.dist-info/RECORD +13 -0
- llumo-0.2.14b6.dist-info/RECORD +0 -13
- {llumo-0.2.14b6.dist-info → llumo-0.2.14b7.dist-info}/WHEEL +0 -0
- {llumo-0.2.14b6.dist-info → llumo-0.2.14b7.dist-info}/licenses/LICENSE +0 -0
- {llumo-0.2.14b6.dist-info → llumo-0.2.14b7.dist-info}/top_level.txt +0 -0
llumo/client.py
CHANGED
@@ -25,6 +25,11 @@ postUrl = (
|
|
25
25
|
fetchUrl = (
|
26
26
|
"https://red-skull-service-392377961931.us-central1.run.app/api/get-cells-data"
|
27
27
|
)
|
28
|
+
socketDataUrl = "https://app.llumo.ai/api/eval/get-awaited"
|
29
|
+
# {
|
30
|
+
# "workspaceID":"c9191fdf33bdd7838328c1a0",
|
31
|
+
# "playgroundID":"17496117244856b7815ac94004347b1c2e2f7e01600ec"
|
32
|
+
# }
|
28
33
|
validateUrl = "https://app.llumo.ai/api/workspace-details"
|
29
34
|
socketUrl = "https://red-skull-service-392377961931.us-central1.run.app/"
|
30
35
|
|
@@ -89,9 +94,8 @@ class LlumoClient:
|
|
89
94
|
)
|
90
95
|
self.email = data["data"]["data"].get("email", None)
|
91
96
|
|
92
|
-
self.definationMapping[evalName] = data
|
93
|
-
|
94
|
-
]
|
97
|
+
self.definationMapping[evalName] = data.get("data", {}).get("data", {}).get("analyticsMapping", {}).get(evalName, None)
|
98
|
+
|
95
99
|
except Exception as e:
|
96
100
|
# print(f"Error extracting data from response: {str(e)}")
|
97
101
|
raise LlumoAIError.UnexpectedError(detail=str(e))
|
@@ -602,13 +606,16 @@ class LlumoClient:
|
|
602
606
|
kwargs={
|
603
607
|
"min_wait": 40,
|
604
608
|
"max_wait": timeout,
|
605
|
-
"inactivity_timeout":
|
609
|
+
"inactivity_timeout": 10,
|
606
610
|
"expected_results": expectedResults,
|
607
611
|
},
|
608
612
|
daemon=True,
|
609
613
|
)
|
610
614
|
listener_thread.start()
|
611
|
-
|
615
|
+
|
616
|
+
activePlayground = f"{int(time.time() * 1000)}{uuid.uuid4()}".replace(
|
617
|
+
"-", ""
|
618
|
+
)
|
612
619
|
for evalName in evals:
|
613
620
|
# print(f"\n======= Running evaluation for: {evalName} =======")
|
614
621
|
|
@@ -656,9 +663,7 @@ class LlumoClient:
|
|
656
663
|
inputDict = {key: row[key] for key in keys if key in row}
|
657
664
|
output = row.get(outputColName, "")
|
658
665
|
|
659
|
-
|
660
|
-
"-", ""
|
661
|
-
)
|
666
|
+
|
662
667
|
rowID = f"{int(time.time() * 1000)}{uuid.uuid4()}".replace("-", "")
|
663
668
|
columnID = f"{int(time.time() * 1000)}{uuid.uuid4()}".replace("-", "")
|
664
669
|
|
@@ -751,15 +756,27 @@ class LlumoClient:
|
|
751
756
|
time.sleep(3)
|
752
757
|
listener_thread.join()
|
753
758
|
|
754
|
-
|
755
|
-
|
759
|
+
|
760
|
+
rawResults = self.socket.getReceivedData()
|
761
|
+
|
762
|
+
# print("data from db #####################",dataFromDb)
|
756
763
|
# Fix here: keep full keys, do not split keys
|
757
|
-
|
758
|
-
|
759
|
-
|
764
|
+
receivedRowIDs = {key for item in rawResults for key in item.keys()}
|
765
|
+
expectedRowIDs = set(rowIdMapping.keys())
|
766
|
+
missingRowIDs = expectedRowIDs - receivedRowIDs
|
760
767
|
# print("All expected keys:", expected_rowIDs)
|
761
768
|
# print("All received keys:", received_rowIDs)
|
762
|
-
print("Missing keys:", len(
|
769
|
+
# print("Missing keys:", len(missingRowIDs))
|
770
|
+
missingRowIDs=list(missingRowIDs)
|
771
|
+
|
772
|
+
if len(missingRowIDs) > 0:
|
773
|
+
dataFromDb=fetchData(workspaceID,activePlayground,missingRowIDs)
|
774
|
+
rawResults.extend(dataFromDb)
|
775
|
+
|
776
|
+
|
777
|
+
|
778
|
+
|
779
|
+
|
763
780
|
|
764
781
|
# Initialize dataframe columns for each eval
|
765
782
|
for eval in evals:
|
@@ -767,7 +784,7 @@ class LlumoClient:
|
|
767
784
|
dataframe[f"{eval} Reason"] = None
|
768
785
|
|
769
786
|
# Map results to dataframe rows
|
770
|
-
for item in
|
787
|
+
for item in rawResults:
|
771
788
|
for compound_key, value in item.items():
|
772
789
|
if compound_key in rowIdMapping:
|
773
790
|
index = rowIdMapping[compound_key]["index"]
|
@@ -776,6 +793,7 @@ class LlumoClient:
|
|
776
793
|
dataframe.at[index, f"{evalName} Reason"] = value.get("reasoning")
|
777
794
|
|
778
795
|
self.socket.disconnect()
|
796
|
+
|
779
797
|
|
780
798
|
if createExperiment:
|
781
799
|
pd.set_option("future.no_silent_downcasting", True)
|
@@ -805,7 +823,7 @@ class LlumoClient:
|
|
805
823
|
createExperiment: bool = False,
|
806
824
|
) -> pd.DataFrame:
|
807
825
|
|
808
|
-
self.validateApiKey(evalName="")
|
826
|
+
self.validateApiKey(evalName=" ")
|
809
827
|
workspaceID = self.workspaceID
|
810
828
|
email = self.email
|
811
829
|
executor = ModelExecutor(apiKey)
|
@@ -940,7 +958,7 @@ class LlumoClient:
|
|
940
958
|
if createExperiment:
|
941
959
|
pd.set_option("future.no_silent_downcasting", True)
|
942
960
|
df = toolResponseDf.fillna("Some error occured")
|
943
|
-
if createPlayground(self.email, self.workspaceID, df):
|
961
|
+
if createPlayground(self.email, self.workspaceID, df,promptText=prompt_template,definationMapping=self.definationMapping):
|
944
962
|
print(
|
945
963
|
"Your data has been saved in the Llumo Experiment. Visit https://app.llumo.ai/evallm to see the results."
|
946
964
|
)
|
@@ -971,11 +989,15 @@ class LlumoClient:
|
|
971
989
|
# )
|
972
990
|
toolResponseDf = self.evaluateMultiple(
|
973
991
|
toolResponseDf.to_dict(orient="records"),
|
974
|
-
|
992
|
+
evals=evals,
|
975
993
|
prompt_template="Give answer for the given query: {{query}}",
|
976
994
|
outputColName=outputColName,
|
995
|
+
createExperiment=createExperiment
|
977
996
|
)
|
978
|
-
|
997
|
+
if createExperiment:
|
998
|
+
pass
|
999
|
+
else:
|
1000
|
+
return toolResponseDf
|
979
1001
|
|
980
1002
|
except Exception as e:
|
981
1003
|
raise e
|
@@ -1165,18 +1187,8 @@ class LlumoClient:
|
|
1165
1187
|
|
1166
1188
|
workspaceID = None
|
1167
1189
|
email = None
|
1168
|
-
socketID = self.socket.connect(timeout=150)
|
1169
|
-
self.allBatches = []
|
1170
|
-
|
1171
|
-
# Wait for socket connection
|
1172
|
-
max_wait_secs = 20
|
1173
|
-
waited_secs = 0
|
1174
|
-
while not self.socket._connection_established.is_set():
|
1175
|
-
time.sleep(0.1)
|
1176
|
-
waited_secs += 0.1
|
1177
|
-
if waited_secs >= max_wait_secs:
|
1178
|
-
raise RuntimeError("Timeout waiting for server connection")
|
1179
1190
|
|
1191
|
+
|
1180
1192
|
try:
|
1181
1193
|
self.validateApiKey()
|
1182
1194
|
except Exception as e:
|
@@ -1195,14 +1207,21 @@ class LlumoClient:
|
|
1195
1207
|
elif ext in [".xlsx", ".xls"]:
|
1196
1208
|
df = pd.read_excel(file_path)
|
1197
1209
|
elif ext == ".json":
|
1198
|
-
df = pd.read_json(file_path)
|
1210
|
+
df = pd.read_json(file_path, orient="records")
|
1199
1211
|
elif ext == ".parquet":
|
1200
1212
|
df = pd.read_parquet(file_path)
|
1201
1213
|
else:
|
1202
1214
|
raise ValueError(f"Unsupported file format: {ext}")
|
1203
1215
|
|
1204
1216
|
# If successfully loaded, call createPlayground
|
1205
|
-
|
1217
|
+
df = df.astype(str)
|
1218
|
+
if createPlayground(self.email, self.workspaceID, df):
|
1219
|
+
|
1220
|
+
print(
|
1221
|
+
"Your data has been saved in the Llumo Experiment. Visit https://app.llumo.ai/evallm to see the results."
|
1222
|
+
)
|
1223
|
+
|
1224
|
+
return True
|
1206
1225
|
|
1207
1226
|
except Exception as e:
|
1208
1227
|
print(f"Error: {e}")
|
llumo/helpingFuntions.py
CHANGED
@@ -212,8 +212,7 @@ def deleteColumnListInPlayground(workspaceID: str, playgroundID: str):
|
|
212
212
|
print("❌ Error:", response.status_code, response.text)
|
213
213
|
return None
|
214
214
|
|
215
|
-
|
216
|
-
def createColumn(workspaceID, dataframe, playgroundID, promptText=None,queryColName=None,outputColName= "output",dataStreamName=None,definationMapping=None,uploadViaSDK = False):
|
215
|
+
def createColumn(workspaceID, dataframe, playgroundID, promptText=None,queryColName=None,outputColName= "output",dataStreamName=None,definationMapping=None):
|
217
216
|
if len(dataframe) > 100:
|
218
217
|
dataframe = dataframe.head(100)
|
219
218
|
print("⚠️ Dataframe truncated to 100 rows for upload.")
|
@@ -238,7 +237,7 @@ def createColumn(workspaceID, dataframe, playgroundID, promptText=None,queryColN
|
|
238
237
|
columnIDMapping[col] = columnID
|
239
238
|
|
240
239
|
|
241
|
-
if col.startswith('output') and
|
240
|
+
if col.startswith('output') and promptText!=None:
|
242
241
|
# For output columns, create the prompt template with promptText
|
243
242
|
if promptText:
|
244
243
|
# Extract variables from promptText and set them as dependencies
|
@@ -291,7 +290,7 @@ def createColumn(workspaceID, dataframe, playgroundID, promptText=None,queryColN
|
|
291
290
|
"type": "DATA_STREAM",
|
292
291
|
"order": indx}
|
293
292
|
|
294
|
-
elif col in allEvals and
|
293
|
+
elif col in allEvals and promptText!=None:
|
295
294
|
|
296
295
|
dependencies = []
|
297
296
|
variables = re.findall(r'{{(.*?)}}', promptText)
|
@@ -341,7 +340,7 @@ def createColumn(workspaceID, dataframe, playgroundID, promptText=None,queryColN
|
|
341
340
|
"order": indx
|
342
341
|
}
|
343
342
|
|
344
|
-
elif col.endswith(' Reason'):
|
343
|
+
elif col.endswith(' Reason') and promptText!=None:
|
345
344
|
continue
|
346
345
|
|
347
346
|
|
@@ -374,7 +373,7 @@ def createColumn(workspaceID, dataframe, playgroundID, promptText=None,queryColN
|
|
374
373
|
for col in dataframe.columns:
|
375
374
|
columnID = columnIDMapping[col]
|
376
375
|
|
377
|
-
if col in allEvals:
|
376
|
+
if col in allEvals and promptText!=None:
|
378
377
|
row_dict[columnID] = {
|
379
378
|
|
380
379
|
"value": row[col],
|
@@ -385,7 +384,7 @@ def createColumn(workspaceID, dataframe, playgroundID, promptText=None,queryColN
|
|
385
384
|
"kpi": col
|
386
385
|
|
387
386
|
}
|
388
|
-
elif col.endswith(' Reason'):
|
387
|
+
elif col.endswith(' Reason') and promptText!=None:
|
389
388
|
continue
|
390
389
|
else:# Get the columnID from the mapping
|
391
390
|
row_dict[columnID] = row[col]
|
@@ -397,6 +396,7 @@ def createColumn(workspaceID, dataframe, playgroundID, promptText=None,queryColN
|
|
397
396
|
|
398
397
|
# Return the column template, row template, and the column ID mapping
|
399
398
|
return coltemplate, rowTemplate
|
399
|
+
|
400
400
|
def uploadColumnListInPlayground(payload):
|
401
401
|
url = uploadColList
|
402
402
|
headers = {
|
@@ -440,15 +440,14 @@ def uploadRowsInDBPlayground(payload):
|
|
440
440
|
return None
|
441
441
|
|
442
442
|
|
443
|
-
def createPlayground(email, workspaceID, df, promptText=None,queryColName=None,dataStreamName=None,definationMapping=None,outputColName="output"
|
443
|
+
def createPlayground(email, workspaceID, df, promptText=None,queryColName=None,dataStreamName=None,definationMapping=None,outputColName="output"):
|
444
444
|
|
445
445
|
playgroundId = str(createEvalPlayground(email=email, workspaceID=workspaceID))
|
446
446
|
payload1, payload2 = createColumn(
|
447
|
-
workspaceID=workspaceID, dataframe=df, playgroundID=playgroundId, promptText=promptText,queryColName=queryColName,dataStreamName=dataStreamName,definationMapping=definationMapping,outputColName=outputColName
|
447
|
+
workspaceID=workspaceID, dataframe=df, playgroundID=playgroundId, promptText=promptText,queryColName=queryColName,dataStreamName=dataStreamName,definationMapping=definationMapping,outputColName=outputColName
|
448
448
|
)
|
449
449
|
|
450
|
-
|
451
|
-
|
450
|
+
# Debugging line to check the payload2 structure
|
452
451
|
deleteExistingRows = deleteColumnListInPlayground(
|
453
452
|
workspaceID=workspaceID, playgroundID=playgroundId
|
454
453
|
)
|
@@ -460,6 +459,7 @@ def createPlayground(email, workspaceID, df, promptText=None,queryColName=None,d
|
|
460
459
|
|
461
460
|
|
462
461
|
|
462
|
+
|
463
463
|
def getPlaygroundInsights(workspaceID: str, activePlayground: str):
|
464
464
|
headers = {
|
465
465
|
|
@@ -563,4 +563,46 @@ def checkDependency(selectedEval, columns,tocheck=True):
|
|
563
563
|
}
|
564
564
|
return {"status":True,"message":"success"}
|
565
565
|
else:
|
566
|
-
return {"status":True,"message":"success"}
|
566
|
+
return {"status":True,"message":"success"}
|
567
|
+
|
568
|
+
|
569
|
+
def fetchData(workspaceID, playgroundID, missingList: list):
|
570
|
+
# Define the URL and prepare the payload
|
571
|
+
socket_data_url = "https://app.llumo.ai/api/eval/get-awaited"
|
572
|
+
payload = {
|
573
|
+
"workspaceID": workspaceID,
|
574
|
+
"playgroundID": playgroundID,
|
575
|
+
"missingList": missingList
|
576
|
+
}
|
577
|
+
|
578
|
+
try:
|
579
|
+
# Send a POST request to the API
|
580
|
+
response = requests.post(socket_data_url, json=payload)
|
581
|
+
|
582
|
+
# Check if the response is successful
|
583
|
+
if response.status_code == 200:
|
584
|
+
# Parse the JSON data from the response
|
585
|
+
data = response.json().get("data", {})
|
586
|
+
|
587
|
+
|
588
|
+
# Prepare the list of all data values in the desired format
|
589
|
+
result_list = []
|
590
|
+
for key, value in data.items():
|
591
|
+
# Create a dictionary for each item in the response data
|
592
|
+
result_list.append({
|
593
|
+
key: {
|
594
|
+
"value": value.get("value"),
|
595
|
+
"reasoning": value.get("reasoning"),
|
596
|
+
"edgeCase": value.get("edgeCase"),
|
597
|
+
"kpi": value.get("kpi")
|
598
|
+
}
|
599
|
+
})
|
600
|
+
|
601
|
+
return result_list
|
602
|
+
else:
|
603
|
+
print(f"Failed to fetch data. Status Code: {response.status_code}")
|
604
|
+
return []
|
605
|
+
|
606
|
+
except Exception as e:
|
607
|
+
print(f"An error occurred: {e}")
|
608
|
+
return []
|
llumo/sockets.py
CHANGED
@@ -17,10 +17,10 @@ class LlumoSocketClient:
|
|
17
17
|
|
18
18
|
# Initialize client
|
19
19
|
self.sio = socketio.Client(
|
20
|
-
logger=
|
21
|
-
engineio_logger=
|
20
|
+
logger=False,
|
21
|
+
engineio_logger=False,
|
22
22
|
reconnection=True,
|
23
|
-
reconnection_attempts=
|
23
|
+
reconnection_attempts=1,
|
24
24
|
reconnection_delay=1,
|
25
25
|
)
|
26
26
|
|
@@ -0,0 +1,13 @@
|
|
1
|
+
llumo/__init__.py,sha256=O04b4yW1BnOvcHzxWFddAKhtdBEhBNhLdb6xgnpHH_Q,205
|
2
|
+
llumo/client.py,sha256=HpvUyucrGPbcPQMz_cTRDcEsBFpmNt8jfW1zJU4Nyss,46781
|
3
|
+
llumo/exceptions.py,sha256=i3Qv4_g7XjRuho7-b7ybjw2bwSh_NhvICR6ZAgiLQX8,1944
|
4
|
+
llumo/execution.py,sha256=x88wQV8eL99wNN5YtjFaAMCIfN1PdfQVlAZQb4vzgQ0,1413
|
5
|
+
llumo/functionCalling.py,sha256=D5jYapu1rIvdIJNUYPYMTyhQ1H-6nkwoOLMi6eekfUE,7241
|
6
|
+
llumo/helpingFuntions.py,sha256=RgWok8DoE1R-Tc0kJ9B5En6LEUEk5EvQU8iJiGPbUsw,21911
|
7
|
+
llumo/models.py,sha256=YH-qAMnShmUpmKE2LQAzQdpRsaXkFSlOqMxHwU4zBUI,1560
|
8
|
+
llumo/sockets.py,sha256=I2JO_eNEctRo_ikgvFVp5zDd-m0VDu04IEUhhsa1Tic,5950
|
9
|
+
llumo-0.2.14b7.dist-info/licenses/LICENSE,sha256=tF9yAcfPV9xGT3ViWmC8hPvOo8BEk4ZICbUfcEo8Dlk,182
|
10
|
+
llumo-0.2.14b7.dist-info/METADATA,sha256=kdeDmcNgV8uRyH7gXhhAqeb3se5U_Gqo3bA3Cf4SLlM,1521
|
11
|
+
llumo-0.2.14b7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
12
|
+
llumo-0.2.14b7.dist-info/top_level.txt,sha256=d5zUTMI99llPtLRB8rtSrqELm_bOqX-bNC5IcwlDk88,6
|
13
|
+
llumo-0.2.14b7.dist-info/RECORD,,
|
llumo-0.2.14b6.dist-info/RECORD
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
llumo/__init__.py,sha256=O04b4yW1BnOvcHzxWFddAKhtdBEhBNhLdb6xgnpHH_Q,205
|
2
|
-
llumo/client.py,sha256=YmvbfyWR9YCDOFrKM0nwDMWYLGpu4RSZwbkiUJ3e78M,46162
|
3
|
-
llumo/exceptions.py,sha256=i3Qv4_g7XjRuho7-b7ybjw2bwSh_NhvICR6ZAgiLQX8,1944
|
4
|
-
llumo/execution.py,sha256=x88wQV8eL99wNN5YtjFaAMCIfN1PdfQVlAZQb4vzgQ0,1413
|
5
|
-
llumo/functionCalling.py,sha256=D5jYapu1rIvdIJNUYPYMTyhQ1H-6nkwoOLMi6eekfUE,7241
|
6
|
-
llumo/helpingFuntions.py,sha256=f2Y-x-DbGk3E29qaJWDOsTkuqqDFl9-VQTRM490amE4,20443
|
7
|
-
llumo/models.py,sha256=YH-qAMnShmUpmKE2LQAzQdpRsaXkFSlOqMxHwU4zBUI,1560
|
8
|
-
llumo/sockets.py,sha256=-zJYRCDRwElIPr5iOFqzQxjecuLJ7mztiyYJz14pGLY,5949
|
9
|
-
llumo-0.2.14b6.dist-info/licenses/LICENSE,sha256=tF9yAcfPV9xGT3ViWmC8hPvOo8BEk4ZICbUfcEo8Dlk,182
|
10
|
-
llumo-0.2.14b6.dist-info/METADATA,sha256=2Yl4gnAXsfpJWLB6mhlza0HUE76uJY3sC1TWK7GlUu4,1521
|
11
|
-
llumo-0.2.14b6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
12
|
-
llumo-0.2.14b6.dist-info/top_level.txt,sha256=d5zUTMI99llPtLRB8rtSrqELm_bOqX-bNC5IcwlDk88,6
|
13
|
-
llumo-0.2.14b6.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|