fameio 3.2.0__py3-none-any.whl → 3.3.0__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 (53) hide show
  1. fameio/cli/convert_results.py +4 -6
  2. fameio/cli/make_config.py +3 -5
  3. fameio/cli/options.py +6 -4
  4. fameio/cli/parser.py +53 -29
  5. fameio/cli/reformat.py +58 -0
  6. fameio/input/__init__.py +4 -4
  7. fameio/input/loader/__init__.py +4 -6
  8. fameio/input/loader/controller.py +11 -16
  9. fameio/input/loader/loader.py +11 -9
  10. fameio/input/metadata.py +26 -29
  11. fameio/input/resolver.py +4 -6
  12. fameio/input/scenario/agent.py +18 -16
  13. fameio/input/scenario/attribute.py +85 -31
  14. fameio/input/scenario/contract.py +23 -28
  15. fameio/input/scenario/exception.py +3 -6
  16. fameio/input/scenario/fameiofactory.py +7 -12
  17. fameio/input/scenario/generalproperties.py +7 -8
  18. fameio/input/scenario/scenario.py +14 -18
  19. fameio/input/scenario/stringset.py +5 -6
  20. fameio/input/schema/agenttype.py +8 -10
  21. fameio/input/schema/attribute.py +30 -36
  22. fameio/input/schema/java_packages.py +6 -7
  23. fameio/input/schema/schema.py +9 -11
  24. fameio/input/validator.py +178 -41
  25. fameio/input/writer.py +20 -29
  26. fameio/logs.py +28 -19
  27. fameio/output/agent_type.py +14 -16
  28. fameio/output/conversion.py +9 -12
  29. fameio/output/csv_writer.py +33 -23
  30. fameio/output/data_transformer.py +11 -11
  31. fameio/output/execution_dao.py +170 -0
  32. fameio/output/input_dao.py +16 -19
  33. fameio/output/output_dao.py +7 -7
  34. fameio/output/reader.py +8 -10
  35. fameio/output/yaml_writer.py +2 -3
  36. fameio/scripts/__init__.py +15 -4
  37. fameio/scripts/convert_results.py +18 -17
  38. fameio/scripts/exception.py +1 -1
  39. fameio/scripts/make_config.py +3 -4
  40. fameio/scripts/reformat.py +71 -0
  41. fameio/scripts/reformat.py.license +3 -0
  42. fameio/series.py +78 -47
  43. fameio/time.py +15 -18
  44. fameio/tools.py +42 -4
  45. {fameio-3.2.0.dist-info → fameio-3.3.0.dist-info}/METADATA +33 -23
  46. fameio-3.3.0.dist-info/RECORD +60 -0
  47. {fameio-3.2.0.dist-info → fameio-3.3.0.dist-info}/entry_points.txt +1 -0
  48. fameio-3.2.0.dist-info/RECORD +0 -56
  49. {fameio-3.2.0.dist-info → fameio-3.3.0.dist-info}/LICENSE.txt +0 -0
  50. {fameio-3.2.0.dist-info → fameio-3.3.0.dist-info}/LICENSES/Apache-2.0.txt +0 -0
  51. {fameio-3.2.0.dist-info → fameio-3.3.0.dist-info}/LICENSES/CC-BY-4.0.txt +0 -0
  52. {fameio-3.2.0.dist-info → fameio-3.3.0.dist-info}/LICENSES/CC0-1.0.txt +0 -0
  53. {fameio-3.2.0.dist-info → fameio-3.3.0.dist-info}/WHEEL +0 -0
@@ -14,10 +14,10 @@ from fameio.tools import ensure_is_list, keys_to_lower
14
14
 
15
15
 
16
16
  class Contract(Metadata):
17
- """Contract between two Agents of a scenario"""
17
+ """Contract between two Agents of a scenario."""
18
18
 
19
19
  class ContractError(InputError):
20
- """An error that occurred while parsing Contract definitions"""
20
+ """An error that occurred while parsing Contract definitions."""
21
21
 
22
22
  KEY_SENDER: Final[str] = "SenderId".lower()
23
23
  KEY_RECEIVER: Final[str] = "ReceiverId".lower()
@@ -50,8 +50,7 @@ class Contract(Metadata):
50
50
  expiration_time: int | None = None,
51
51
  metadata: dict | None = None,
52
52
  ) -> None:
53
- """
54
- Constructs a new Contract
53
+ """Constructs a new Contract.
55
54
 
56
55
  Args:
57
56
  sender_id: unique id of sender
@@ -84,56 +83,55 @@ class Contract(Metadata):
84
83
  self._attributes: dict = {}
85
84
 
86
85
  def _notify_data_changed(self):
87
- """Placeholder method used to signal data changes to derived types"""
86
+ """Placeholder method used to signal data changes to derived types."""
88
87
 
89
88
  @property
90
89
  def product_name(self) -> str:
91
- """Returns the product name of the contract"""
90
+ """Returns the product name of the contract."""
92
91
  return self._product_name
93
92
 
94
93
  @property
95
94
  def sender_id(self) -> int:
96
- """Returns the sender ID of the contract"""
95
+ """Returns the sender ID of the contract."""
97
96
  return self._sender_id
98
97
 
99
98
  @property
100
99
  def display_sender_id(self) -> str:
101
- """Returns the sender ID of the contract as a string for display purposes"""
100
+ """Returns the sender ID of the contract as a string for display purposes."""
102
101
  return f"#{self._sender_id}"
103
102
 
104
103
  @property
105
104
  def receiver_id(self) -> int:
106
- """Returns the receiver ID of the contract"""
105
+ """Returns the receiver ID of the contract."""
107
106
  return self._receiver_id
108
107
 
109
108
  @property
110
109
  def display_receiver_id(self) -> str:
111
- """Returns the receiver ID of the contract as a string for display purposes"""
110
+ """Returns the receiver ID of the contract as a string for display purposes."""
112
111
  return f"#{self._receiver_id}"
113
112
 
114
113
  @property
115
114
  def delivery_interval(self) -> int:
116
- """Returns the delivery interval of the contract (in steps)"""
115
+ """Returns the delivery interval of the contract (in steps)."""
117
116
  return self._delivery_interval
118
117
 
119
118
  @property
120
119
  def first_delivery_time(self) -> int:
121
- """Returns the first delivery time of the contract"""
120
+ """Returns the first delivery time of the contract."""
122
121
  return self._first_delivery_time
123
122
 
124
123
  @property
125
124
  def expiration_time(self) -> int | None:
126
- """Returns the expiration time of the contract if available, None otherwise"""
125
+ """Returns the expiration time of the contract if available, None otherwise."""
127
126
  return self._expiration_time
128
127
 
129
128
  @property
130
129
  def attributes(self) -> dict[str, Attribute]:
131
- """Returns dictionary of all Attributes of the contract"""
130
+ """Returns dictionary of all Attributes of the contract."""
132
131
  return self._attributes
133
132
 
134
133
  def add_attribute(self, name: str, value: Attribute) -> None:
135
- """
136
- Adds a new attribute to the Contract
134
+ """Adds a new attribute to the Contract.
137
135
 
138
136
  Args:
139
137
  name: of the attribute
@@ -149,8 +147,7 @@ class Contract(Metadata):
149
147
 
150
148
  @classmethod
151
149
  def from_dict(cls, definitions: dict) -> Contract:
152
- """
153
- Parses contract from given `definitions`
150
+ """Parses contract from given `definitions`.
154
151
 
155
152
  Args:
156
153
  definitions: dictionary representation of a contract
@@ -177,8 +174,7 @@ class Contract(Metadata):
177
174
 
178
175
  @staticmethod
179
176
  def _get_or_raise(dictionary: dict, key: str, error_message: str) -> Any:
180
- """
181
- Returns value associated with `key` in given `dictionary`, or raises exception if key or value is missing
177
+ """Returns value associated with `key` in given `dictionary`, or raises exception if key or value is missing.
182
178
 
183
179
  Args:
184
180
  dictionary: to search the key in
@@ -205,8 +201,7 @@ class Contract(Metadata):
205
201
 
206
202
  @staticmethod
207
203
  def _get_time(definitions: dict, key: str, mandatory: bool = True) -> int | None:
208
- """
209
- Extract time representation value at given key, and, if present, convert to integer, else return None
204
+ """Extract time representation value at given key, and, if present, convert to integer, else return None.
210
205
 
211
206
  Args:
212
207
  definitions: to search given key in
@@ -230,8 +225,7 @@ class Contract(Metadata):
230
225
  return None
231
226
 
232
227
  def _init_attributes_from_dict(self, attributes: dict[str, Any]) -> None:
233
- """
234
- Resets Contract `attributes` from dict
228
+ """Resets Contract `attributes` from dict.
235
229
 
236
230
  Args:
237
231
  attributes: key-value pairs of attributes to be set
@@ -244,7 +238,7 @@ class Contract(Metadata):
244
238
  self.add_attribute(name, Attribute(full_name, value))
245
239
 
246
240
  def _to_dict(self) -> dict:
247
- """Serializes the Contract content to a dict"""
241
+ """Serializes the Contract content to a dict."""
248
242
  result = {
249
243
  self.KEY_SENDER: self.sender_id,
250
244
  self.KEY_RECEIVER: self.receiver_id,
@@ -262,9 +256,10 @@ class Contract(Metadata):
262
256
 
263
257
  @staticmethod
264
258
  def split_contract_definitions(multi_definition: dict) -> list[dict]:
265
- """
259
+ """Split given M:N `multi_definition` of contracts to multiple 1:1 contracts.
260
+
266
261
  Splits given dictionary of contracts with potentially more than ore sender and/or receiver into a list
267
- of individual contract definitions with one sender and one receiver
262
+ of individual contract definitions with one sender and one receiver.
268
263
 
269
264
  Args:
270
265
  multi_definition: contract definitions with potentially more than ore sender and/or receiver
@@ -309,7 +304,7 @@ class Contract(Metadata):
309
304
 
310
305
  @staticmethod
311
306
  def _copy_contract(sender: int, receiver: int, base_data: dict) -> dict:
312
- """Returns a new contract definition dictionary, with given `sender` and `receiver` and copied `base_data`"""
307
+ """Returns a new contract definition dictionary, with given `sender` and `receiver` and copied `base_data`."""
313
308
  contract = {
314
309
  Contract.KEY_SENDER: sender,
315
310
  Contract.KEY_RECEIVER: receiver,
@@ -12,8 +12,7 @@ _DEFAULT_USED = "Using default value '{}' for missing key '{}'"
12
12
 
13
13
 
14
14
  def log_scenario_error(message: str) -> ScenarioError:
15
- """
16
- Creates exception with given `message`, logs it on level "Error" and returns it
15
+ """Creates exception with given `message`, logs it on level "Error" and returns it.
17
16
 
18
17
  Args:
19
18
  message: to be logged and included in the exception if key is missing
@@ -27,8 +26,7 @@ def log_scenario_error(message: str) -> ScenarioError:
27
26
 
28
27
 
29
28
  def get_or_raise(dictionary: dict, key: str, error_message: str) -> Any:
30
- """
31
- Returns value associated with `key` in given `dictionary`, or raises exception if key or value is missing
29
+ """Returns value associated with `key` in given `dictionary`, or raises exception if key or value is missing.
32
30
 
33
31
  Args:
34
32
  dictionary: to search the key in
@@ -47,8 +45,7 @@ def get_or_raise(dictionary: dict, key: str, error_message: str) -> Any:
47
45
 
48
46
 
49
47
  def assert_or_raise(assertion: bool, error_message: str) -> None:
50
- """
51
- Raises exception with given `msg` if `assertion` is False
48
+ """Raises exception with given `error_message` if `assertion` is False.
52
49
 
53
50
  Args:
54
51
  assertion: expression that must be True, else an exception is raised
@@ -9,15 +9,14 @@ from .stringset import StringSet
9
9
 
10
10
 
11
11
  class FameIOFactory:
12
- """
13
- Factory used to instantiate the types defined in a scenario file.
12
+ """Factory used to instantiate the types defined in a scenario file.
13
+
14
14
  This allows a client to subclass some types in order to extend what a scenario can contain.
15
15
  """
16
16
 
17
17
  @staticmethod
18
18
  def new_schema_from_dict(definitions: dict) -> Schema:
19
- """
20
- Load given dictionary `definitions` into a new schema
19
+ """Loads given dictionary `definitions` into a new schema.
21
20
 
22
21
  Args:
23
22
  definitions: dictionary representation of schema
@@ -32,8 +31,7 @@ class FameIOFactory:
32
31
 
33
32
  @staticmethod
34
33
  def new_general_properties_from_dict(definitions: dict) -> GeneralProperties:
35
- """
36
- Parse general properties from provided `definitions`
34
+ """Parses general properties from provided `definitions`.
37
35
 
38
36
  Args:
39
37
  definitions: dictionary representation of general properties
@@ -48,8 +46,7 @@ class FameIOFactory:
48
46
 
49
47
  @staticmethod
50
48
  def new_agent_from_dict(definitions: dict) -> Agent:
51
- """
52
- Parses an agent from provided `definitions`
49
+ """Parses an agent from provided `definitions`.
53
50
 
54
51
  Args:
55
52
  definitions: dictionary representation of an agent
@@ -64,8 +61,7 @@ class FameIOFactory:
64
61
 
65
62
  @staticmethod
66
63
  def new_contract_from_dict(definitions: dict) -> Contract:
67
- """
68
- Parses contract from given `definitions`
64
+ """Parses contract from given `definitions`.
69
65
 
70
66
  Args:
71
67
  definitions: dictionary representation of a contract
@@ -80,8 +76,7 @@ class FameIOFactory:
80
76
 
81
77
  @staticmethod
82
78
  def new_string_set_from_dict(definition: StringSet.StringSetType) -> StringSet:
83
- """
84
- Returns string set initialised from `definition`
79
+ """Returns string set initialised from `definition`.
85
80
 
86
81
  Args:
87
82
  definition: dictionary representation of string set
@@ -12,7 +12,7 @@ from .exception import get_or_raise
12
12
 
13
13
 
14
14
  class GeneralProperties:
15
- """Hosts general properties of a scenario"""
15
+ """Hosts general properties of a scenario."""
16
16
 
17
17
  KEY_RUN: Final[str] = "RunId".lower()
18
18
  KEY_SIMULATION = "Simulation".lower()
@@ -39,8 +39,7 @@ class GeneralProperties:
39
39
 
40
40
  @classmethod
41
41
  def from_dict(cls, definitions: dict) -> GeneralProperties:
42
- """
43
- Parse general properties from provided `definitions`
42
+ """Parses general properties from provided `definitions`.
44
43
 
45
44
  Args:
46
45
  definitions: dictionary representation of general properties
@@ -79,7 +78,7 @@ class GeneralProperties:
79
78
  return cls(run_id, start_time, stop_time, random_seed)
80
79
 
81
80
  def to_dict(self) -> dict:
82
- """Serializes the general properties to a dict"""
81
+ """Serializes the general properties to a dict."""
83
82
  result: dict = {self.KEY_RUN: self._run_id}
84
83
  simulation_dict = {
85
84
  self.KEY_START: self.simulation_start_time,
@@ -91,20 +90,20 @@ class GeneralProperties:
91
90
 
92
91
  @property
93
92
  def run_id(self) -> int:
94
- """Returns the run ID"""
93
+ """Returns the run ID."""
95
94
  return self._run_id
96
95
 
97
96
  @property
98
97
  def simulation_start_time(self) -> int:
99
- """Returns the simulation start time"""
98
+ """Returns the simulation start time."""
100
99
  return self._simulation_start_time
101
100
 
102
101
  @property
103
102
  def simulation_stop_time(self) -> int:
104
- """Returns the simulation stop time"""
103
+ """Returns the simulation stop time."""
105
104
  return self._simulation_stop_time
106
105
 
107
106
  @property
108
107
  def simulation_random_seed(self) -> int:
109
- """Returns the simulation random seed"""
108
+ """Returns the simulation random seed."""
110
109
  return self._simulation_random_seed
@@ -18,7 +18,7 @@ from fameio.tools import keys_to_lower
18
18
 
19
19
 
20
20
  class Scenario(Metadata):
21
- """Definition of a scenario"""
21
+ """Definition of a scenario."""
22
22
 
23
23
  KEY_SCHEMA: Final[str] = "Schema".lower()
24
24
  KEY_GENERAL: Final[str] = "GeneralProperties".lower()
@@ -42,8 +42,7 @@ class Scenario(Metadata):
42
42
 
43
43
  @classmethod
44
44
  def from_dict(cls, definitions: dict, factory: FameIOFactory = FameIOFactory()) -> Scenario:
45
- """
46
- Parse scenario from provided `definitions` using given `factory`
45
+ """Parses scenario from provided `definitions` using given `factory`.
47
46
 
48
47
  Args:
49
48
  definitions: dictionary representation of scenario
@@ -73,8 +72,7 @@ class Scenario(Metadata):
73
72
 
74
73
  @staticmethod
75
74
  def _extract_schema(definitions: dict, factory: FameIOFactory) -> Schema:
76
- """
77
- Extract schema from given definitions and create Schema from it
75
+ """Extracts schema from given definitions and creates Schema from it.
78
76
 
79
77
  Args:
80
78
  definitions: dictionary representation of scenario
@@ -94,8 +92,7 @@ class Scenario(Metadata):
94
92
 
95
93
  @staticmethod
96
94
  def _extract_string_sets(definitions: dict, factory: FameIOFactory) -> dict[str, StringSet]:
97
- """
98
- Extract string sets from given definitions and create dictionary from it
95
+ """Extracts string sets from given definitions and creates dictionary from it.
99
96
 
100
97
  Args:
101
98
  definitions: dictionary representation of scenario
@@ -117,8 +114,7 @@ class Scenario(Metadata):
117
114
 
118
115
  @staticmethod
119
116
  def _extract_contracts(definitions: dict, factory: FameIOFactory) -> list[Contract]:
120
- """
121
- Extract contracts from given definitions
117
+ """Extracts contracts from given definitions.
122
118
 
123
119
  Args:
124
120
  definitions: dictionary representation of scenario
@@ -143,7 +139,7 @@ class Scenario(Metadata):
143
139
  return contracts
144
140
 
145
141
  def _to_dict(self) -> dict:
146
- """Serializes the scenario content to a dict"""
142
+ """Serializes the scenario content to a dict."""
147
143
  result: dict[str, Any] = {
148
144
  Scenario.KEY_GENERAL: self.general_properties.to_dict(),
149
145
  Scenario.KEY_SCHEMA: self.schema.to_dict(),
@@ -164,37 +160,37 @@ class Scenario(Metadata):
164
160
 
165
161
  @property
166
162
  def agents(self) -> list[Agent]:
167
- """Returns all the agents of this scenario as a list"""
163
+ """Returns all the agents of this scenario as a list."""
168
164
  return self._agents
169
165
 
170
166
  def add_agent(self, agent: Agent) -> None:
171
- """Adds a new agent to this scenario"""
167
+ """Adds a new agent to this scenario."""
172
168
  self._agents.append(agent)
173
169
 
174
170
  @property
175
171
  def contracts(self) -> list[Contract]:
176
- """Returns all the contracts of this scenario as a list"""
172
+ """Returns all the contracts of this scenario as a list."""
177
173
  return self._contracts
178
174
 
179
175
  def add_contract(self, contract: Contract) -> None:
180
- """Adds a new contract to this scenario"""
176
+ """Adds a new contract to this scenario."""
181
177
  self._contracts.append(contract)
182
178
 
183
179
  @property
184
180
  def schema(self) -> Schema:
185
- """Returns Schema associated with this scenario"""
181
+ """Returns Schema associated with this scenario."""
186
182
  return self._schema
187
183
 
188
184
  @property
189
185
  def general_properties(self) -> GeneralProperties:
190
- """Returns General properties of this scenario"""
186
+ """Returns General properties of this scenario."""
191
187
  return self._general_props
192
188
 
193
189
  @property
194
190
  def string_sets(self) -> dict[str, StringSet]:
195
- """Returns StringSets of this scenario"""
191
+ """Returns StringSets of this scenario."""
196
192
  return self._string_sets
197
193
 
198
194
  def add_string_set(self, name: str, string_set: StringSet) -> None:
199
- """Adds `string_set` with `name`"""
195
+ """Adds `string_set` with `name`."""
200
196
  self._string_sets[name] = string_set
@@ -12,10 +12,10 @@ from fameio.tools import keys_to_lower
12
12
 
13
13
 
14
14
  class StringSet(Metadata):
15
- """Hosts a StringSet in the given format"""
15
+ """Hosts a StringSet in the given format."""
16
16
 
17
17
  class StringSetError(InputError):
18
- """An error that occurred while parsing a StringSet definition"""
18
+ """An error that occurred while parsing a StringSet definition."""
19
19
 
20
20
  KEY_VALUES: Final[str] = "Values".lower()
21
21
 
@@ -31,8 +31,7 @@ class StringSet(Metadata):
31
31
 
32
32
  @classmethod
33
33
  def from_dict(cls, definition: StringSetType) -> StringSet:
34
- """
35
- Returns StringSet initialised from `definition`
34
+ """Returns StringSet initialised from `definition`.
36
35
 
37
36
  Args:
38
37
  definition: dictionary representation of string set
@@ -59,9 +58,9 @@ class StringSet(Metadata):
59
58
 
60
59
  @property
61
60
  def values(self) -> dict[str, MetadataComponent]:
62
- """Returns values and their associated MetadataComponent"""
61
+ """Returns values and their associated MetadataComponent."""
63
62
  return self._value_container.values
64
63
 
65
64
  def is_in_set(self, key: Any) -> bool:
66
- """Returns True if `key` is a valid name in this StringSet"""
65
+ """Returns True if `key` is a valid name in this StringSet."""
67
66
  return self._value_container.has_value(key)
@@ -13,7 +13,7 @@ from .attribute import AttributeSpecs
13
13
 
14
14
 
15
15
  class AgentType(Metadata):
16
- """Schema definitions for an Agent type"""
16
+ """Schema definitions for an Agent type."""
17
17
 
18
18
  KEY_ATTRIBUTES: Final[str] = "Attributes".lower()
19
19
  KEY_PRODUCTS: Final[str] = "Products".lower()
@@ -47,8 +47,7 @@ class AgentType(Metadata):
47
47
 
48
48
  @classmethod
49
49
  def from_dict(cls, name: str, definitions: dict) -> AgentType:
50
- """
51
- Creates AgentType with given `name` from specified dictionary
50
+ """Creates AgentType with given `name` from specified dictionary.
52
51
 
53
52
  Args:
54
53
  name: of the agent type
@@ -89,8 +88,7 @@ class AgentType(Metadata):
89
88
 
90
89
  @staticmethod
91
90
  def _read_values(section: str, agent_type: str, values: Any) -> ValueContainer:
92
- """
93
- Returns ValueContainer for `section` of in specifications of `agent_type` extracted from given `values`
91
+ """Returns ValueContainer for `section` in specifications of `agent_type` extracted from given `values`.
94
92
 
95
93
  Args:
96
94
  section: key of the section that contains the values
@@ -113,26 +111,26 @@ class AgentType(Metadata):
113
111
 
114
112
  @property
115
113
  def name(self) -> str:
116
- """Returns the agent type name"""
114
+ """Returns the agent type name."""
117
115
  return self._name
118
116
 
119
117
  @property
120
118
  def products(self) -> dict[str, MetadataComponent]:
121
- """Returns dict of products or an empty dict if no products are defined"""
119
+ """Returns dict of products or an empty dict if no products are defined."""
122
120
  return self._products.values
123
121
 
124
122
  def get_product_names(self) -> list[str]:
125
- """Returns list of product names or an empty list if no products are defined"""
123
+ """Returns list of product names or an empty list if no products are defined."""
126
124
  return self._products.as_list()
127
125
 
128
126
  @property
129
127
  def attributes(self) -> dict[str, AttributeSpecs]:
130
- """Returns list of Attributes of this agent or an empty list if no attributes are defined"""
128
+ """Returns list of Attributes of this agent or an empty list if no attributes are defined."""
131
129
  return self._attributes
132
130
 
133
131
  @property
134
132
  def outputs(self) -> dict[str, MetadataComponent]:
135
- """Returns list of outputs or an empty list if no outputs are defined"""
133
+ """Returns list of outputs or an empty list if no outputs are defined."""
136
134
  return self._outputs.values
137
135
 
138
136
  def _to_dict(self) -> dict: