Skip to content

Commit 4777690

Browse files
authored
Merge pull request #85 from simvue-io/get_metrics
Adding metrics
2 parents 9084c93 + cefdfdb commit 4777690

File tree

3 files changed

+121
-1
lines changed

3 files changed

+121
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## v0.13.0
44

5+
* Added methods to the `Client` class for retrieving metrics.
56
* CPU architecture and processor obtained on Apple hardware.
67
* Client now reports to server when files have been successfully uploaded.
78
* `User-Agent` header now included in HTTP requests.

simvue/client.py

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from .serialization import Deserializer
77
from .utilities import get_auth
8-
from .converters import to_dataframe
8+
from .converters import to_dataframe, metrics_to_dataframe
99

1010
CONCURRENT_DOWNLOADS = 10
1111
DOWNLOAD_CHUNK_SIZE = 8192
@@ -293,3 +293,67 @@ def get_folders(self, filters, tags=False, metadata=False):
293293
return response.json()
294294

295295
raise Exception(response.text)
296+
297+
def get_metrics_summaries(self, run, name):
298+
"""
299+
Get summary metrics for the specified run and metrics name
300+
"""
301+
params = {'runs': run,
302+
'metrics': name,
303+
'summary': True}
304+
305+
response = requests.get(f"{self._url}/api/metrics", headers=self._headers, params=params)
306+
307+
if response.status_code == 200:
308+
return response.json()
309+
310+
raise Exception(response.text)
311+
312+
def get_metrics(self, run, name, xaxis, format='list'):
313+
"""
314+
Get time series metrics for the specified run and metrics name
315+
"""
316+
params = {'runs': run,
317+
'metrics': name,
318+
'summary': False,
319+
'xaxis': xaxis}
320+
321+
if xaxis not in ('step', 'time', 'timestamp'):
322+
raise Exception('Invalid xaxis specified, should be either "step", "time", or "timestamp"')
323+
324+
if format not in ('list', 'dataframe'):
325+
raise Exception('Invalid format specified, should be either "list" or "dataframe"')
326+
327+
response = requests.get(f"{self._url}/api/metrics", headers=self._headers, params=params)
328+
329+
if response.status_code == 200:
330+
if format == 'dataframe':
331+
return metrics_to_dataframe(response.json(), xaxis, name=name)
332+
return response.json()
333+
334+
raise Exception(response.text)
335+
336+
def get_metrics_multiple(self, runs, names, xaxis, sample_by, format='list'):
337+
"""
338+
Get time series metrics from multiple runs and/or metrics
339+
"""
340+
params = {'runs': ','.join(runs),
341+
'metrics': ','.join(names),
342+
'summary': False,
343+
'sample_by': sample_by,
344+
'xaxis': xaxis}
345+
346+
if xaxis not in ('step', 'time'):
347+
raise Exception('Invalid xaxis specified, should be either "step" or "time"')
348+
349+
if format not in ('list', 'dataframe'):
350+
raise Exception('Invalid format specified, should be either "list" or "dataframe"')
351+
352+
response = requests.get(f"{self._url}/api/metrics", headers=self._headers, params=params)
353+
354+
if response.status_code == 200:
355+
if format == 'dataframe':
356+
return metrics_to_dataframe(response.json(), xaxis)
357+
return response.json()
358+
359+
raise Exception(response.text)

simvue/converters.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,58 @@ def to_dataframe(data):
4444

4545
df = pd.DataFrame(data=columns)
4646
return df
47+
48+
def metrics_to_dataframe(data, xaxis, name=None):
49+
"""
50+
Convert metrics to dataframe
51+
"""
52+
import pandas as pd
53+
54+
if name:
55+
columns = {xaxis: [], name: []}
56+
for item in data:
57+
columns[xaxis].append(item[0])
58+
columns[name].append(item[1])
59+
60+
df = pd.DataFrame(data=columns)
61+
else:
62+
runs = []
63+
metrics = []
64+
for item in data:
65+
if item[2] not in runs:
66+
runs.append(item[2])
67+
if item[3] not in metrics:
68+
metrics.append(item[3])
69+
70+
headers = pd.MultiIndex.from_product([runs, metrics, [xaxis, 'value']], names=["run", "metric", "column"])
71+
72+
newdata = {}
73+
for row in data:
74+
if row[2] not in newdata:
75+
newdata[row[2]] = {}
76+
if row[3] not in newdata[row[2]]:
77+
newdata[row[2]][row[3]] = []
78+
79+
newdata[row[2]][row[3]].append([row[0], row[1]])
80+
81+
max_rows = 0
82+
for run in newdata:
83+
for metric in newdata[run]:
84+
if len(newdata[run][metric]) > max_rows:
85+
max_rows = len(newdata[run][metric])
86+
87+
results = []
88+
for count in range (0, max_rows):
89+
line = []
90+
for run in newdata:
91+
for metric in newdata[run]:
92+
if count < len(newdata[run][metric]):
93+
line.append(newdata[run][metric][count][0])
94+
line.append(newdata[run][metric][count][1])
95+
else:
96+
line.append(None)
97+
line.append(None)
98+
results.append(line)
99+
100+
df = pd.DataFrame(data=results, columns=headers)
101+
return df

0 commit comments

Comments
 (0)