idmtools 0.0.0.dev0__py3-none-any.whl → 0.0.3__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.
Files changed (118) hide show
  1. idmtools/__init__.py +27 -8
  2. idmtools/analysis/__init__.py +5 -0
  3. idmtools/analysis/add_analyzer.py +89 -0
  4. idmtools/analysis/analyze_manager.py +490 -0
  5. idmtools/analysis/csv_analyzer.py +103 -0
  6. idmtools/analysis/download_analyzer.py +96 -0
  7. idmtools/analysis/map_worker_entry.py +100 -0
  8. idmtools/analysis/platform_analysis_bootstrap.py +94 -0
  9. idmtools/analysis/platform_anaylsis.py +291 -0
  10. idmtools/analysis/tags_analyzer.py +93 -0
  11. idmtools/assets/__init__.py +9 -0
  12. idmtools/assets/asset.py +453 -0
  13. idmtools/assets/asset_collection.py +514 -0
  14. idmtools/assets/content_handlers.py +19 -0
  15. idmtools/assets/errors.py +23 -0
  16. idmtools/assets/file_list.py +191 -0
  17. idmtools/builders/__init__.py +11 -0
  18. idmtools/builders/arm_simulation_builder.py +152 -0
  19. idmtools/builders/csv_simulation_builder.py +76 -0
  20. idmtools/builders/simulation_builder.py +348 -0
  21. idmtools/builders/sweep_arm.py +109 -0
  22. idmtools/builders/yaml_simulation_builder.py +82 -0
  23. idmtools/config/__init__.py +7 -0
  24. idmtools/config/idm_config_parser.py +486 -0
  25. idmtools/core/__init__.py +10 -0
  26. idmtools/core/cache_enabled.py +114 -0
  27. idmtools/core/context.py +68 -0
  28. idmtools/core/docker_task.py +207 -0
  29. idmtools/core/enums.py +51 -0
  30. idmtools/core/exceptions.py +91 -0
  31. idmtools/core/experiment_factory.py +71 -0
  32. idmtools/core/id_file.py +70 -0
  33. idmtools/core/interfaces/__init__.py +5 -0
  34. idmtools/core/interfaces/entity_container.py +64 -0
  35. idmtools/core/interfaces/iassets_enabled.py +58 -0
  36. idmtools/core/interfaces/ientity.py +331 -0
  37. idmtools/core/interfaces/iitem.py +206 -0
  38. idmtools/core/interfaces/imetadata_operations.py +89 -0
  39. idmtools/core/interfaces/inamed_entity.py +17 -0
  40. idmtools/core/interfaces/irunnable_entity.py +159 -0
  41. idmtools/core/logging.py +387 -0
  42. idmtools/core/platform_factory.py +316 -0
  43. idmtools/core/system_information.py +104 -0
  44. idmtools/core/task_factory.py +145 -0
  45. idmtools/entities/__init__.py +10 -0
  46. idmtools/entities/command_line.py +229 -0
  47. idmtools/entities/command_task.py +155 -0
  48. idmtools/entities/experiment.py +787 -0
  49. idmtools/entities/generic_workitem.py +43 -0
  50. idmtools/entities/ianalyzer.py +163 -0
  51. idmtools/entities/iplatform.py +1106 -0
  52. idmtools/entities/iplatform_default.py +39 -0
  53. idmtools/entities/iplatform_ops/__init__.py +5 -0
  54. idmtools/entities/iplatform_ops/iplatform_asset_collection_operations.py +148 -0
  55. idmtools/entities/iplatform_ops/iplatform_experiment_operations.py +415 -0
  56. idmtools/entities/iplatform_ops/iplatform_simulation_operations.py +315 -0
  57. idmtools/entities/iplatform_ops/iplatform_suite_operations.py +322 -0
  58. idmtools/entities/iplatform_ops/iplatform_workflowitem_operations.py +301 -0
  59. idmtools/entities/iplatform_ops/utils.py +185 -0
  60. idmtools/entities/itask.py +316 -0
  61. idmtools/entities/iworkflow_item.py +167 -0
  62. idmtools/entities/platform_requirements.py +20 -0
  63. idmtools/entities/relation_type.py +14 -0
  64. idmtools/entities/simulation.py +255 -0
  65. idmtools/entities/suite.py +188 -0
  66. idmtools/entities/task_proxy.py +37 -0
  67. idmtools/entities/templated_simulation.py +325 -0
  68. idmtools/frozen/frozen_dict.py +71 -0
  69. idmtools/frozen/frozen_list.py +66 -0
  70. idmtools/frozen/frozen_set.py +86 -0
  71. idmtools/frozen/frozen_tuple.py +18 -0
  72. idmtools/frozen/frozen_utils.py +179 -0
  73. idmtools/frozen/ifrozen.py +66 -0
  74. idmtools/plugins/__init__.py +5 -0
  75. idmtools/plugins/git_commit.py +117 -0
  76. idmtools/registry/__init__.py +4 -0
  77. idmtools/registry/experiment_specification.py +105 -0
  78. idmtools/registry/functions.py +28 -0
  79. idmtools/registry/hook_specs.py +132 -0
  80. idmtools/registry/master_plugin_registry.py +51 -0
  81. idmtools/registry/platform_specification.py +138 -0
  82. idmtools/registry/plugin_specification.py +129 -0
  83. idmtools/registry/task_specification.py +104 -0
  84. idmtools/registry/utils.py +119 -0
  85. idmtools/services/__init__.py +5 -0
  86. idmtools/services/ipersistance_service.py +135 -0
  87. idmtools/services/platforms.py +13 -0
  88. idmtools/utils/__init__.py +5 -0
  89. idmtools/utils/caller.py +24 -0
  90. idmtools/utils/collections.py +246 -0
  91. idmtools/utils/command_line.py +45 -0
  92. idmtools/utils/decorators.py +300 -0
  93. idmtools/utils/display/__init__.py +22 -0
  94. idmtools/utils/display/displays.py +181 -0
  95. idmtools/utils/display/settings.py +25 -0
  96. idmtools/utils/dropbox_location.py +30 -0
  97. idmtools/utils/entities.py +127 -0
  98. idmtools/utils/file.py +72 -0
  99. idmtools/utils/file_parser.py +151 -0
  100. idmtools/utils/filter_simulations.py +182 -0
  101. idmtools/utils/filters/__init__.py +5 -0
  102. idmtools/utils/filters/asset_filters.py +88 -0
  103. idmtools/utils/general.py +286 -0
  104. idmtools/utils/gitrepo.py +336 -0
  105. idmtools/utils/hashing.py +239 -0
  106. idmtools/utils/info.py +124 -0
  107. idmtools/utils/json.py +82 -0
  108. idmtools/utils/language.py +107 -0
  109. idmtools/utils/local_os.py +40 -0
  110. idmtools/utils/time.py +22 -0
  111. idmtools-0.0.3.dist-info/METADATA +120 -0
  112. idmtools-0.0.3.dist-info/RECORD +116 -0
  113. idmtools-0.0.3.dist-info/entry_points.txt +9 -0
  114. idmtools-0.0.3.dist-info/licenses/LICENSE.TXT +3 -0
  115. idmtools-0.0.0.dev0.dist-info/METADATA +0 -41
  116. idmtools-0.0.0.dev0.dist-info/RECORD +0 -5
  117. {idmtools-0.0.0.dev0.dist-info → idmtools-0.0.3.dist-info}/WHEEL +0 -0
  118. {idmtools-0.0.0.dev0.dist-info → idmtools-0.0.3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,181 @@
1
+ """
2
+ Tools around displays and formatting.
3
+
4
+ Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
5
+ """
6
+ from abc import ABCMeta, abstractmethod
7
+ from typing import Any
8
+ from tabulate import tabulate
9
+
10
+ from idmtools.utils.collections import cut_iterable_to
11
+
12
+
13
+ class IDisplaySetting(metaclass=ABCMeta):
14
+ """
15
+ Base class for a display setting.
16
+
17
+ The child class needs to implement the :meth:`display` method.
18
+
19
+ Includes:
20
+
21
+ - header: Optional header for the display.
22
+ - field: If specified, the :meth:`get_object` will call :attr:`getattr` for this field on the object.
23
+ """
24
+
25
+ def __init__(self, header: str = None, field: str = None):
26
+ """
27
+ Initialize our IDisplaySetting.
28
+
29
+ Args:
30
+ header: Header for display
31
+ field: Optional field to display instead of object
32
+ """
33
+ self.header = header
34
+ self.field = field
35
+
36
+ def get_object(self, obj: Any) -> Any:
37
+ """
38
+ Get object or field depending if field is set.
39
+
40
+ Args:
41
+ obj: Object to get
42
+
43
+ Returns:
44
+ Either obj.field or obj depending if self.field is set
45
+ """
46
+ return getattr(obj, self.field) if self.field else obj
47
+
48
+ @abstractmethod
49
+ def display(self, obj: Any) -> str:
50
+ """
51
+ Display the object.
52
+
53
+ Note that the attribute (identified by self.field) should be handled with :meth:`get_object`.
54
+
55
+ Args:
56
+ obj: The object to consider for display.
57
+
58
+ Returns:
59
+ A string representing what to show.
60
+ """
61
+ pass
62
+
63
+
64
+ class StringDisplaySetting(IDisplaySetting):
65
+ """
66
+ Class that displays the object as string.
67
+ """
68
+
69
+ def display(self, obj):
70
+ """
71
+ Display object.
72
+
73
+ Args:
74
+ obj: Object to display
75
+
76
+ Returns:
77
+ String of object
78
+ """
79
+ obj = self.get_object(obj)
80
+ return str(obj)
81
+
82
+
83
+ class DictDisplaySetting(IDisplaySetting):
84
+ """
85
+ Class that displays a dictionary.
86
+ """
87
+
88
+ def __init__(self, header: str = None, field: str = None, max_items: int = 10, flat: bool = False):
89
+ """
90
+ DictDisplay.
91
+
92
+ Args:
93
+ header: Optional field header.
94
+ field: The field in the object to consider.
95
+ max_items: The maximum number of items to display.
96
+ flat: If False, display as a list; if True, display as a comma-separated list.
97
+ """
98
+ super().__init__(header=header, field=field)
99
+ self.max_items = max_items
100
+ self.flat = flat
101
+
102
+ def display(self, obj: Any) -> str:
103
+ """
104
+ Display a dictionary.
105
+
106
+ Args:
107
+ obj: Object to display
108
+
109
+ Returns:
110
+ String display of object
111
+ """
112
+ # Retrieve our object
113
+ obj = self.get_object(obj)
114
+
115
+ # Slice the dictionary depending on the `max_items`
116
+ slice, remaining = cut_iterable_to(obj, self.max_items)
117
+ printout = ""
118
+
119
+ # Different display depending on `flat`
120
+ if self.flat:
121
+ printout = ", ".join(f"{k}:{v}" for k, v in slice.items())
122
+ else:
123
+ for k, v in slice.items():
124
+ printout += f"- {k}:{v}\n"
125
+ printout = printout.strip()
126
+
127
+ # If there are items remaining, display
128
+ if remaining > 0:
129
+ printout = str(printout)
130
+ printout += f"\n... and {remaining} more"
131
+
132
+ return printout
133
+
134
+
135
+ class TableDisplay(IDisplaySetting):
136
+ """
137
+ Class that displays the object as a table.
138
+ """
139
+
140
+ def __init__(self, columns, max_rows=5, field=None):
141
+ """
142
+ Initialize our TableDisplay.
143
+
144
+ Args:
145
+ columns: A list of display settings.
146
+ max_rows: The maximum number of rows to display.
147
+ field: The field of the object to consider.
148
+ """
149
+ super().__init__(field=field)
150
+ self.columns = columns
151
+ self.max_rows = max_rows
152
+
153
+ def display(self, obj) -> str:
154
+ """
155
+ Display our object as a table.
156
+
157
+ Args:
158
+ obj: Object to display
159
+
160
+ Returns:
161
+ Table represented as a string of the object
162
+ """
163
+ # Retrieve our object
164
+ obj = super().get_object(obj)
165
+
166
+ # Cut the rows
167
+ slice, remaining = cut_iterable_to(obj, self.max_rows)
168
+
169
+ # Create the table
170
+ rows = []
171
+ for child in slice:
172
+ rows.append([s.display(child) for s in self.columns])
173
+
174
+ printout = tabulate(rows, headers=[s.header for s in self.columns], tablefmt='psql', showindex=False)
175
+
176
+ # If there are items remaining, display
177
+ if remaining > 0:
178
+ printout = str(printout)
179
+ printout += f"\n... and {remaining} more"
180
+
181
+ return printout
@@ -0,0 +1,25 @@
1
+ """
2
+ defines views for different types if items.
3
+
4
+ Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
5
+ """
6
+ from idmtools.utils.display.displays import DictDisplaySetting, StringDisplaySetting, TableDisplay
7
+
8
+ simulation_display_settings = [
9
+ StringDisplaySetting(header="ID", field="uid"),
10
+ DictDisplaySetting(header="Tags", field="tags", flat=False)]
11
+
12
+ experiment_display_settings = [
13
+ StringDisplaySetting(header="ID", field="uid"),
14
+ StringDisplaySetting(header="Simulation count", field="simulation_count")
15
+ ]
16
+
17
+ experiment_table_display = [
18
+ StringDisplaySetting(),
19
+ TableDisplay(field="simulations", columns=simulation_display_settings)
20
+ ]
21
+
22
+ suite_table_display = [
23
+ StringDisplaySetting(),
24
+ TableDisplay(field="experiments", columns=experiment_display_settings)
25
+ ]
@@ -0,0 +1,30 @@
1
+ """
2
+ utilities for pathing of dropbox folders.
3
+
4
+ Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
5
+ """
6
+ import os
7
+
8
+
9
+ def get_current_user():
10
+ """
11
+ Get current user name.
12
+
13
+ Returns:
14
+ Current username
15
+ """
16
+ # Returns current logged in user for Windows filesystem
17
+ import getpass
18
+ return getpass.getuser()
19
+
20
+
21
+ def get_dropbox_location():
22
+ """
23
+ Get user dropbox location.
24
+
25
+ Returns:
26
+ User dropbox location
27
+ """
28
+ user = get_current_user()
29
+ dropbox_filepath = os.path.join("C:/Users/", user, "Dropbox (IDM)")
30
+ return dropbox_filepath
@@ -0,0 +1,127 @@
1
+ """
2
+ utilities for dataclasses.
3
+
4
+ Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
5
+ """
6
+ import ast
7
+ import os
8
+ import dataclasses
9
+ import typing
10
+ from logging import getLogger
11
+ from pathlib import Path
12
+
13
+ if typing.TYPE_CHECKING:
14
+ from idmtools.entities.experiment import Experiment
15
+ from idmtools.entities.iworkflow_item import IWorkflowItem
16
+ from idmtools.entities.iplatform import IPlatform
17
+
18
+ user_logger = getLogger('user')
19
+
20
+
21
+ def get_dataclass_common_fields(src, dest, exclude_none: bool = True) -> typing.Dict:
22
+ """
23
+ Extracts fields from a dataclass source object who are also defined on destination object.
24
+
25
+ Useful for situations like nested configurations of data class options.
26
+
27
+ Args:
28
+ src: Source dataclass object
29
+ dest: Dest dataclass object
30
+ exclude_none: When true, values of None will be excluded
31
+
32
+ Returns:
33
+ Dictionary of common fields between source and destination object
34
+ """
35
+ dest_fields = [f.name for f in dataclasses.fields(dest)]
36
+ src_fields = dataclasses.fields(src)
37
+ result = dict()
38
+ for field in src_fields:
39
+ if field.name in dest_fields and (not exclude_none or (exclude_none and getattr(src, field.name, None) is not None)):
40
+ result[field.name] = getattr(src, field.name)
41
+ return result
42
+
43
+
44
+ def as_dict(src, exclude: typing.List[str] = None, exclude_private_fields: bool = True):
45
+ """
46
+ Converts a dataclass to a dict while also obeys rules for exclusion.
47
+
48
+ Args:
49
+ src:
50
+ exclude: List of fields to exclude
51
+ exclude_private_fields: Should fields that star
52
+
53
+ Returns:
54
+ Data class as dict
55
+ """
56
+ if exclude is None:
57
+ exclude = []
58
+
59
+ result = dict()
60
+ # get metadata
61
+ metadata = dataclasses.fields(src.__class__)
62
+ for field in metadata:
63
+ field_metadata = field.metadata
64
+ if (not exclude_private_fields or field.name[0] != '_') and \
65
+ ('exclude_from_metadata' not in field_metadata or not field_metadata['exclude_from_metadata']) and \
66
+ field.name not in exclude:
67
+ result[field.name] = getattr(src, field.name)
68
+ return result
69
+
70
+
71
+ def validate_user_inputs_against_dataclass(field_type, field_value):
72
+ """
73
+ Validates user entered data against dataclass fields and types.
74
+
75
+ Args:
76
+ field_type: Field type
77
+ field_value: Fields value
78
+
79
+ Returns:
80
+ Validates user values
81
+ """
82
+ fs_kwargs = set(field_type.keys()).intersection(set(field_value.keys()))
83
+ for fn in fs_kwargs:
84
+ ft = field_type[fn]
85
+ try:
86
+ if ft in (int, float, str):
87
+ field_value[fn] = ft(field_value[fn]) if field_value[fn] is not None else field_value[fn]
88
+ elif ft is bool:
89
+ field_value[fn] = ast.literal_eval(field_value[fn]) if isinstance(field_value[fn], str) else \
90
+ field_value[fn]
91
+ except ValueError as e:
92
+ user_logger.error(f"The field {fn} requires a value of type {ft.__name__}. You provided <{field_value[fn]}>")
93
+ raise e
94
+ return fs_kwargs
95
+
96
+
97
+ def get_default_tags() -> typing.Dict[str, str]:
98
+ """
99
+ Get common default tags. Currently this is the version of idmtools.
100
+
101
+ Returns:
102
+ Default tags which is idmtools version
103
+ """
104
+ from idmtools import __version__
105
+ return dict(idmtools=__version__)
106
+
107
+
108
+ def save_id_as_file_as_hook(item: typing.Union['Experiment', 'IWorkflowItem'], platform: 'IPlatform'):
109
+ """
110
+ Predefined hook that will save ids to files for Experiment or WorkItems.
111
+
112
+ Args:
113
+ item:
114
+ platform:
115
+
116
+ Returns:
117
+ None
118
+ """
119
+ # Import locally because of circular deps
120
+ from idmtools.entities.experiment import Experiment
121
+ from idmtools.entities.iworkflow_item import IWorkflowItem
122
+ if not isinstance(item, (Experiment, IWorkflowItem)):
123
+ raise NotImplementedError("Saving id is currently only support for Experiments and Workitems")
124
+ id_file = Path(f'{item.item_type}.{item.name}.id')
125
+ if os.path.exists(id_file):
126
+ os.remove(id_file)
127
+ item.to_id_file(id_file)
idmtools/utils/file.py ADDED
@@ -0,0 +1,72 @@
1
+ """
2
+ utilities for files.
3
+
4
+ Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
5
+ """
6
+ import os
7
+ from io import BytesIO
8
+ from os import DirEntry
9
+ from typing import Iterable, Generator, List, Union
10
+
11
+
12
+ def scan_directory(basedir: str, recursive: bool = True, ignore_directories: List[str] = None) -> Iterable[DirEntry]:
13
+ """
14
+ Scan a directory recursively or not.
15
+
16
+ Args:
17
+ basedir: The root directory to start from.
18
+ recursive: True to search the sub-folders recursively; False to stay in the root directory.
19
+ ignore_directories: Ignore directories
20
+
21
+ Returns:
22
+ An iterator yielding all the files found.
23
+ """
24
+ for entry in os.scandir(basedir):
25
+ if entry.is_file():
26
+ yield entry
27
+ elif recursive:
28
+ if ignore_directories is None or entry.name not in ignore_directories:
29
+ yield from scan_directory(entry.path)
30
+
31
+
32
+ def file_content_to_generator(absolute_path, chunk_size=128) -> Generator[bytearray, None, None]:
33
+ """
34
+ Create a generator from file contents in chunks(useful for streaming binary data and piping).
35
+
36
+ Args:
37
+ absolute_path: absolute path to file
38
+ chunk_size: chunk size
39
+
40
+ Returns:
41
+ Generator that return bytes in chunks of size chunk_size
42
+ """
43
+ with open(absolute_path, 'rb') as i:
44
+ while True:
45
+ res = i.read(chunk_size)
46
+ if res == b'':
47
+ break
48
+ else:
49
+ yield res
50
+
51
+
52
+ def content_generator(content: Union[str, bytes], chunk_size=128) -> Generator[bytearray, None, None]:
53
+ """
54
+ Create a generator from file contents in chunks(useful for streaming binary data and piping).
55
+
56
+ Args:
57
+ content : file content
58
+ chunk_size : chunk size
59
+
60
+ Returns:
61
+ Generator that return bytes in chunks of size chunk_size
62
+ """
63
+ if isinstance(content, str):
64
+ content_io = BytesIO(content.encode())
65
+ else:
66
+ content_io = BytesIO(content)
67
+ while True:
68
+ chunk = content_io.read(chunk_size)
69
+ if chunk == b'':
70
+ break
71
+ else:
72
+ yield chunk
@@ -0,0 +1,151 @@
1
+ """
2
+ File parser utility. Used to automatically load data.
3
+
4
+ Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
5
+ """
6
+ import json
7
+ import os
8
+ from logging import getLogger
9
+ from typing import Dict
10
+
11
+ import pandas as pd
12
+
13
+ from io import StringIO, BytesIO
14
+
15
+ logger = getLogger(__name__)
16
+
17
+
18
+ class FileParser:
19
+ """
20
+ FileParser to load contents in analysis.
21
+ """
22
+
23
+ @classmethod
24
+ def parse(cls, filename, content=None):
25
+ """
26
+ Parse filename and load the content.
27
+
28
+ Args:
29
+ filename: Filename to load
30
+ content: Content to load
31
+
32
+ Returns:
33
+ Content loaded
34
+ """
35
+ file_extension = os.path.splitext(filename)[1][1:].lower()
36
+ content = BytesIO(content)
37
+
38
+ if file_extension == 'json':
39
+ return cls.load_json_file(filename, content)
40
+
41
+ if file_extension == 'csv':
42
+ return cls.load_csv_file(filename, content)
43
+
44
+ if file_extension == 'xlsx':
45
+ return cls.load_xlsx_file(filename, content)
46
+
47
+ if file_extension == 'txt':
48
+ return cls.load_txt_file(filename, content)
49
+
50
+ if file_extension == 'bin' and 'SpatialReport' in filename:
51
+ return cls.load_bin_file(filename, content)
52
+
53
+ return cls.load_raw_file(filename, content)
54
+
55
+ @classmethod
56
+ def load_json_file(cls, filename, content) -> Dict:
57
+ """
58
+ Load JSON File.
59
+
60
+ Args:
61
+ filename: Filename to load
62
+ content: Content
63
+
64
+ Returns:
65
+ JSOn as dict
66
+ """
67
+ return json.load(content)
68
+
69
+ @classmethod
70
+ def load_raw_file(self, filename, content):
71
+ """
72
+ Load content raw.
73
+
74
+ Args:
75
+ filename: Filename is none
76
+ content: Content to load
77
+
78
+ Returns:
79
+ Content as it was
80
+ """
81
+ return content
82
+
83
+ @classmethod
84
+ def load_csv_file(cls, filename, content) -> pd.DataFrame:
85
+ """
86
+ Load csv file.
87
+
88
+ Args:
89
+ filename: Filename to load
90
+ content: Content is loading
91
+
92
+ Returns:
93
+ Loaded csv file
94
+ """
95
+ if not isinstance(content, StringIO) and not isinstance(content, BytesIO):
96
+ content = StringIO(content)
97
+
98
+ csv_read = pd.read_csv(content, skipinitialspace=True)
99
+ return csv_read
100
+
101
+ @classmethod
102
+ def load_xlsx_file(cls, filename, content) -> Dict[str, pd.ExcelFile]:
103
+ """
104
+ Load excel_file.
105
+
106
+ Args:
107
+ filename: Filename to load
108
+ content: Content to load
109
+
110
+ Returns:
111
+ Loaded excel file
112
+ """
113
+ excel_file = pd.ExcelFile(content)
114
+ return {sheet_name: excel_file.parse(sheet_name) for sheet_name in excel_file.sheet_names}
115
+
116
+ @classmethod
117
+ def load_txt_file(cls, filename, content):
118
+ """
119
+ Load text file.
120
+
121
+ Args:
122
+ filename: Filename to load
123
+ content: Content to load
124
+
125
+ Returns:
126
+ Content
127
+ """
128
+ return str(content.getvalue().decode())
129
+
130
+ @classmethod
131
+ def load_bin_file(cls, filename, content):
132
+ """
133
+ Load a bin file.
134
+
135
+ Args:
136
+ filename: Filename to load
137
+ content: Content to load
138
+
139
+ Returns:
140
+ Loaded bin file
141
+
142
+ Notes:
143
+ We should move this to a plugin in emodpy. We need to figure out how to structure that.
144
+ """
145
+ try:
146
+ from idmtools_platform_comps.utils.spatial_output import SpatialOutput
147
+ so = SpatialOutput.from_bytes(content.read(), 'Filtered' in filename)
148
+ return so.to_dict()
149
+ except ImportError as ex:
150
+ logger.exception(ex)
151
+ logger.error("Could not import item. Most likely dtk.tools is not installed")