Last active
August 29, 2015 14:24
-
-
Save andsor/07b409388bbeacd78d94 to your computer and use it in GitHub Desktop.
Helper functions to dump and load system information -- Enhances reproducibility of a scientific computing environment
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Helper functions to dump and load system information | |
Enhances reproducibility of a scientific computing environment | |
License: http://creativecommons.org/publicdomain/zero/1.0/ | |
To the extent possible under law, the author has waived all copyright and | |
related or neighboring rights to this work. | |
This work is published from: Germany. | |
""" | |
from __future__ import unicode_literals | |
from builtins import str | |
import json | |
import os | |
import socket | |
import sys | |
import time | |
import uuid | |
import pip | |
def get_float_info(): | |
float_info = str(sys.float_info) | |
items = float_info[float_info.find('(') + 1:].rstrip(')').split() | |
return { | |
key: value | |
for key, value in [ | |
item.rstrip(',').split('=') | |
for item in items | |
] | |
} | |
def get_sys_info(): | |
return { | |
'os': os.name, | |
'environ': dict(os.environ), | |
'argv': sys.argv, | |
'timestamp': int(time.time()), | |
'hostname': socket.gethostname(), | |
'platform': sys.platform, | |
'float_info': get_float_info(), | |
'python': { | |
'version': sys.version, | |
'executable': sys.executable, | |
'version_info': sys.version_info, | |
'prefix': sys.prefix, | |
}, | |
'packages': { | |
package.key: package.version | |
for package in pip.get_installed_distributions() | |
}, | |
'uuid': str(uuid.uuid4()), | |
'_json_dumps': ( | |
'environ', | |
'argv', | |
'float_info', | |
'python', | |
'packages', | |
), | |
} | |
def dump_sys_info(target, sys_info=None): | |
""" | |
Write the system information to a target with dict-like access structure | |
E.g. via the ``attrs`` proxy object of a HDF5 file or group object | |
""" | |
if sys_info is None: | |
sys_info = get_sys_info() | |
for key, value in sys_info.items(): | |
target[key] = ( | |
json.dumps(value) | |
if key == '_json_dumps' or key in sys_info['_json_dumps'] | |
else value | |
) | |
return target | |
def load_sys_info(source): | |
""" | |
Load the system information from a source with dict-like access structure | |
E.g. via the ``attrs`` proxy object of a HDF5 file or group object | |
""" | |
ret = dict(source) | |
ret['_json_dumps'] = json.loads(ret['_json_dumps']) | |
for key in ret['_json_dumps']: | |
ret[key] = json.loads(ret[key]) | |
return ret | |
class Timer: | |
""" | |
Helper class to time script execution | |
See https://www.python.org/dev/peps/pep-0418/ | |
""" | |
times = ('process_time', 'perf_counter', 'time') | |
def __init__(self): | |
self.timer = dict() | |
for my_time in self.times: | |
self.timer[my_time] = dict() | |
def start(self): | |
for my_time in self.times: | |
self.timer[my_time]['start'] = getattr(time, my_time)() | |
def stop(self): | |
for my_time in self.times: | |
self.timer[my_time]['stop'] = getattr(time, my_time)() | |
def get_times(self): | |
ret = { | |
my_time: self.timer[my_time]['stop'] - self.timer[my_time]['start'] | |
for my_time in self.times | |
} | |
ret['start_timestamp'] = int(self.timer['time']['start']) | |
ret['stop_timestamp'] = int(self.timer['time']['stop']) | |
return ret | |
def dump_times(self, target, my_times=None): | |
""" | |
Write the times to a target with dict-like access structure | |
E.g. via the ``attrs`` proxy object of a HDF5 file or group object | |
""" | |
if my_times is None: | |
my_times = self.get_times() | |
for key, value in my_times.items(): | |
target[key] = value | |
return target |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment