humalab 0.0.5__py3-none-any.whl → 0.0.6__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.
Potentially problematic release.
This version of humalab might be problematic. Click here for more details.
- humalab/__init__.py +11 -0
- humalab/assets/__init__.py +2 -2
- humalab/assets/files/resource_file.py +29 -3
- humalab/assets/files/urdf_file.py +14 -10
- humalab/assets/resource_operator.py +91 -0
- humalab/constants.py +39 -5
- humalab/dists/bernoulli.py +2 -1
- humalab/dists/discrete.py +2 -2
- humalab/dists/gaussian.py +2 -2
- humalab/dists/log_uniform.py +2 -2
- humalab/dists/truncated_gaussian.py +4 -4
- humalab/episode.py +181 -11
- humalab/humalab.py +44 -28
- humalab/humalab_api_client.py +301 -94
- humalab/humalab_test.py +46 -17
- humalab/metrics/__init__.py +5 -5
- humalab/metrics/code.py +28 -0
- humalab/metrics/metric.py +41 -108
- humalab/metrics/scenario_stats.py +95 -0
- humalab/metrics/summary.py +24 -18
- humalab/run.py +180 -103
- humalab/scenarios/__init__.py +4 -0
- humalab/{scenario.py → scenarios/scenario.py} +120 -129
- humalab/scenarios/scenario_operator.py +82 -0
- humalab/{scenario_test.py → scenarios/scenario_test.py} +150 -269
- humalab/utils.py +37 -0
- {humalab-0.0.5.dist-info → humalab-0.0.6.dist-info}/METADATA +1 -1
- humalab-0.0.6.dist-info/RECORD +39 -0
- humalab/assets/resource_manager.py +0 -58
- humalab/evaluators/__init__.py +0 -16
- humalab/humalab_main.py +0 -119
- humalab/metrics/dist_metric.py +0 -22
- humalab-0.0.5.dist-info/RECORD +0 -37
- {humalab-0.0.5.dist-info → humalab-0.0.6.dist-info}/WHEEL +0 -0
- {humalab-0.0.5.dist-info → humalab-0.0.6.dist-info}/entry_points.txt +0 -0
- {humalab-0.0.5.dist-info → humalab-0.0.6.dist-info}/licenses/LICENSE +0 -0
- {humalab-0.0.5.dist-info → humalab-0.0.6.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
from typing import Any
|
|
2
|
+
from threading import RLock
|
|
3
|
+
|
|
2
4
|
import numpy as np
|
|
3
|
-
from omegaconf import OmegaConf,
|
|
5
|
+
from omegaconf import OmegaConf, DictConfig, ListConfig
|
|
4
6
|
import yaml
|
|
5
7
|
from humalab.dists.bernoulli import Bernoulli
|
|
6
8
|
from humalab.dists.categorical import Categorical
|
|
@@ -10,9 +12,7 @@ from humalab.dists.log_uniform import LogUniform
|
|
|
10
12
|
from humalab.dists.gaussian import Gaussian
|
|
11
13
|
from humalab.dists.truncated_gaussian import TruncatedGaussian
|
|
12
14
|
from functools import partial
|
|
13
|
-
from humalab.constants import
|
|
14
|
-
from humalab.metrics.dist_metric import DistributionMetric
|
|
15
|
-
from humalab.metrics.metric import MetricGranularity
|
|
15
|
+
from humalab.constants import GraphType, MetricDimType
|
|
16
16
|
import copy
|
|
17
17
|
import uuid
|
|
18
18
|
|
|
@@ -37,39 +37,40 @@ DISTRIBUTION_MAP = {
|
|
|
37
37
|
|
|
38
38
|
# 2D distributions
|
|
39
39
|
"uniform_2d": Uniform,
|
|
40
|
-
"bernoulli_2d": Bernoulli,
|
|
41
|
-
"categorical_2d": Categorical,
|
|
42
|
-
"discrete_2d": Discrete,
|
|
43
|
-
"log_uniform_2d": LogUniform,
|
|
40
|
+
# "bernoulli_2d": Bernoulli,
|
|
41
|
+
# "categorical_2d": Categorical,
|
|
42
|
+
# "discrete_2d": Discrete,
|
|
43
|
+
# "log_uniform_2d": LogUniform,
|
|
44
44
|
"gaussian_2d": Gaussian,
|
|
45
45
|
"truncated_gaussian_2d": TruncatedGaussian,
|
|
46
46
|
|
|
47
47
|
# 3D distributions
|
|
48
48
|
"uniform_3d": Uniform,
|
|
49
|
-
"bernoulli_3d": Bernoulli,
|
|
50
|
-
"categorical_3d": Categorical,
|
|
51
|
-
"discrete_3d": Discrete,
|
|
52
|
-
"log_uniform_3d": LogUniform,
|
|
49
|
+
# "bernoulli_3d": Bernoulli,
|
|
50
|
+
# "categorical_3d": Categorical,
|
|
51
|
+
# "discrete_3d": Discrete,
|
|
52
|
+
# "log_uniform_3d": LogUniform,
|
|
53
53
|
"gaussian_3d": Gaussian,
|
|
54
54
|
"truncated_gaussian_3d": TruncatedGaussian,
|
|
55
55
|
|
|
56
56
|
# 4D distributions
|
|
57
|
-
"uniform_4d": Uniform,
|
|
58
|
-
"bernoulli_4d": Bernoulli,
|
|
59
|
-
"categorical_4d": Categorical,
|
|
60
|
-
"discrete_4d": Discrete,
|
|
61
|
-
"log_uniform_4d": LogUniform,
|
|
62
|
-
"gaussian_4d": Gaussian,
|
|
63
|
-
"truncated_gaussian_4d": TruncatedGaussian,
|
|
64
|
-
|
|
57
|
+
# "uniform_4d": Uniform,
|
|
58
|
+
# "bernoulli_4d": Bernoulli,
|
|
59
|
+
# "categorical_4d": Categorical,
|
|
60
|
+
# "discrete_4d": Discrete,
|
|
61
|
+
# "log_uniform_4d": LogUniform,
|
|
62
|
+
# "gaussian_4d": Gaussian,
|
|
63
|
+
# "truncated_gaussian_4d": TruncatedGaussian,
|
|
64
|
+
|
|
65
65
|
# nD distributions
|
|
66
|
-
"uniform_nd": Uniform,
|
|
67
|
-
"bernoulli_nd": Bernoulli,
|
|
68
|
-
"categorical_nd": Categorical,
|
|
69
|
-
"discrete_nd": Discrete,
|
|
70
|
-
"log_uniform_nd": LogUniform,
|
|
71
|
-
"gaussian_nd": Gaussian,
|
|
72
|
-
"truncated_gaussian_nd": TruncatedGaussian,
|
|
66
|
+
# "uniform_nd": Uniform,
|
|
67
|
+
# "bernoulli_nd": Bernoulli,
|
|
68
|
+
# "categorical_nd": Categorical,
|
|
69
|
+
# "discrete_nd": Discrete,
|
|
70
|
+
# "log_uniform_nd": LogUniform,
|
|
71
|
+
# "gaussian_nd": Gaussian,
|
|
72
|
+
# "truncated_gaussian_nd": TruncatedGaussian,
|
|
73
|
+
|
|
73
74
|
}
|
|
74
75
|
|
|
75
76
|
DISTRIBUTION_DIMENSION_MAP = {
|
|
@@ -93,39 +94,13 @@ DISTRIBUTION_DIMENSION_MAP = {
|
|
|
93
94
|
|
|
94
95
|
# 2D distributions
|
|
95
96
|
"uniform_2d": 2,
|
|
96
|
-
"bernoulli_2d": 2,
|
|
97
|
-
"categorical_2d": 2,
|
|
98
|
-
"discrete_2d": 2,
|
|
99
|
-
"log_uniform_2d": 2,
|
|
100
97
|
"gaussian_2d": 2,
|
|
101
98
|
"truncated_gaussian_2d": 2,
|
|
102
99
|
|
|
103
100
|
# 3D distributions
|
|
104
101
|
"uniform_3d": 3,
|
|
105
|
-
"bernoulli_3d": 3,
|
|
106
|
-
"categorical_3d": 3,
|
|
107
|
-
"discrete_3d": 3,
|
|
108
|
-
"log_uniform_3d": 3,
|
|
109
102
|
"gaussian_3d": 3,
|
|
110
103
|
"truncated_gaussian_3d": 3,
|
|
111
|
-
|
|
112
|
-
# 4D distributions
|
|
113
|
-
"uniform_4d": 4,
|
|
114
|
-
"bernoulli_4d": 4,
|
|
115
|
-
"categorical_4d": 4,
|
|
116
|
-
"discrete_4d": 4,
|
|
117
|
-
"log_uniform_4d": 4,
|
|
118
|
-
"gaussian_4d": 4,
|
|
119
|
-
"truncated_gaussian_4d": 4,
|
|
120
|
-
|
|
121
|
-
# nD distributions
|
|
122
|
-
"uniform_nd": -1,
|
|
123
|
-
"bernoulli_nd": -1,
|
|
124
|
-
"categorical_nd": -1,
|
|
125
|
-
"discrete_nd": -1,
|
|
126
|
-
"log_uniform_nd": -1,
|
|
127
|
-
"gaussian_nd": -1,
|
|
128
|
-
"truncated_gaussian_nd": -1,
|
|
129
104
|
}
|
|
130
105
|
|
|
131
106
|
DISTRIBUTION_PARAM_NUM_MAP = {
|
|
@@ -149,39 +124,73 @@ DISTRIBUTION_PARAM_NUM_MAP = {
|
|
|
149
124
|
|
|
150
125
|
# 2D distributions
|
|
151
126
|
"uniform_2d": 2,
|
|
152
|
-
"bernoulli_2d": 1,
|
|
153
|
-
"categorical_2d": 2,
|
|
154
|
-
"discrete_2d": 3,
|
|
155
|
-
"log_uniform_2d": 2,
|
|
156
127
|
"gaussian_2d": 2,
|
|
157
128
|
"truncated_gaussian_2d": 4,
|
|
158
129
|
|
|
159
130
|
# 3D distributions
|
|
160
131
|
"uniform_3d": 2,
|
|
161
|
-
"bernoulli_3d": 1,
|
|
162
|
-
"categorical_3d": 2,
|
|
163
|
-
"discrete_3d": 3,
|
|
164
|
-
"log_uniform_3d": 2,
|
|
165
132
|
"gaussian_3d": 2,
|
|
166
133
|
"truncated_gaussian_3d": 4,
|
|
134
|
+
}
|
|
167
135
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
"
|
|
171
|
-
"
|
|
172
|
-
"
|
|
173
|
-
"
|
|
174
|
-
"
|
|
175
|
-
"
|
|
136
|
+
SCENARIO_STATS_DIM_TYPE_MAP = {
|
|
137
|
+
# 0D distributions
|
|
138
|
+
"uniform": MetricDimType.ONE_D,
|
|
139
|
+
"bernoulli": MetricDimType.ONE_D,
|
|
140
|
+
"categorical": MetricDimType.ONE_D,
|
|
141
|
+
"discrete": MetricDimType.ONE_D,
|
|
142
|
+
"log_uniform": MetricDimType.ONE_D,
|
|
143
|
+
"gaussian": MetricDimType.ONE_D,
|
|
144
|
+
"truncated_gaussian": MetricDimType.ONE_D,
|
|
176
145
|
|
|
177
|
-
#
|
|
178
|
-
"
|
|
179
|
-
"
|
|
180
|
-
"
|
|
181
|
-
"
|
|
182
|
-
"
|
|
183
|
-
"
|
|
184
|
-
"
|
|
146
|
+
# 1D distributions
|
|
147
|
+
"uniform_1d": MetricDimType.ONE_D,
|
|
148
|
+
"bernoulli_1d": MetricDimType.ONE_D,
|
|
149
|
+
"categorical_1d": MetricDimType.ONE_D,
|
|
150
|
+
"discrete_1d": MetricDimType.ONE_D,
|
|
151
|
+
"log_uniform_1d": MetricDimType.ONE_D,
|
|
152
|
+
"gaussian_1d": MetricDimType.ONE_D,
|
|
153
|
+
"truncated_gaussian_1d": MetricDimType.ONE_D,
|
|
154
|
+
|
|
155
|
+
# 2D distributions
|
|
156
|
+
"uniform_2d": MetricDimType.TWO_D,
|
|
157
|
+
"gaussian_2d": MetricDimType.TWO_D,
|
|
158
|
+
"truncated_gaussian_2d": MetricDimType.TWO_D,
|
|
159
|
+
|
|
160
|
+
# 3D distributions
|
|
161
|
+
"uniform_3d": MetricDimType.THREE_D,
|
|
162
|
+
"gaussian_3d": MetricDimType.THREE_D,
|
|
163
|
+
"truncated_gaussian_3d": MetricDimType.THREE_D,
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
DISTRIBUTION_GRAPH_TYPE = {
|
|
167
|
+
# 0D distributions
|
|
168
|
+
"uniform": GraphType.HISTOGRAM,
|
|
169
|
+
"bernoulli": GraphType.BAR,
|
|
170
|
+
"categorical": GraphType.BAR,
|
|
171
|
+
"discrete": GraphType.BAR,
|
|
172
|
+
"log_uniform": GraphType.HISTOGRAM,
|
|
173
|
+
"gaussian": GraphType.GAUSSIAN,
|
|
174
|
+
"truncated_gaussian": GraphType.GAUSSIAN,
|
|
175
|
+
|
|
176
|
+
# 1D distributions
|
|
177
|
+
"uniform_1d": GraphType.HISTOGRAM,
|
|
178
|
+
"bernoulli_1d": GraphType.BAR,
|
|
179
|
+
"categorical_1d": GraphType.BAR,
|
|
180
|
+
"discrete_1d": GraphType.BAR,
|
|
181
|
+
"log_uniform_1d": GraphType.HISTOGRAM,
|
|
182
|
+
"gaussian_1d": GraphType.GAUSSIAN,
|
|
183
|
+
"truncated_gaussian_1d": GraphType.GAUSSIAN,
|
|
184
|
+
|
|
185
|
+
# 2D distributions
|
|
186
|
+
"uniform_2d": GraphType.SCATTER,
|
|
187
|
+
"gaussian_2d": GraphType.HEATMAP,
|
|
188
|
+
"truncated_gaussian_2d": GraphType.HEATMAP,
|
|
189
|
+
|
|
190
|
+
# 3D distributions
|
|
191
|
+
"uniform_3d": GraphType.THREE_D_MAP,
|
|
192
|
+
"gaussian_3d": GraphType.THREE_D_MAP,
|
|
193
|
+
"truncated_gaussian_3d": GraphType.THREE_D_MAP,
|
|
185
194
|
}
|
|
186
195
|
|
|
187
196
|
class Scenario:
|
|
@@ -192,9 +201,10 @@ class Scenario:
|
|
|
192
201
|
self._cur_scenario = OmegaConf.create()
|
|
193
202
|
self._scenario_id = None
|
|
194
203
|
|
|
204
|
+
self._episode_vals = {}
|
|
205
|
+
self._lock = RLock()
|
|
206
|
+
|
|
195
207
|
def init(self,
|
|
196
|
-
run_id: str,
|
|
197
|
-
episode_id: str,
|
|
198
208
|
scenario: str | list | dict | None = None,
|
|
199
209
|
seed: int | None=None,
|
|
200
210
|
scenario_id: str | None=None,
|
|
@@ -204,24 +214,30 @@ class Scenario:
|
|
|
204
214
|
Initialize the scenario with the given parameters.
|
|
205
215
|
|
|
206
216
|
Args:
|
|
207
|
-
run_id: The ID of the current run.
|
|
208
217
|
episode_id: The ID of the current episode.
|
|
209
218
|
scenario: The scenario configuration (YAML string, list, or dict).
|
|
210
219
|
seed: Optional seed for random number generation.
|
|
211
220
|
scenario_id: Optional scenario ID. If None, a new UUID is generated.
|
|
212
221
|
# num_env: Optional number of parallel environments.
|
|
213
222
|
"""
|
|
214
|
-
self._run_id = run_id
|
|
215
|
-
self._episode_id = episode_id
|
|
216
|
-
self._metrics = {}
|
|
217
|
-
|
|
218
223
|
self._num_env = None # num_env
|
|
224
|
+
|
|
225
|
+
# Parse scenario id
|
|
226
|
+
scenario_version = 1
|
|
227
|
+
if scenario_id is not None:
|
|
228
|
+
scenario_arr = scenario_id.split(":")
|
|
229
|
+
if len(scenario_arr) < 1:
|
|
230
|
+
raise ValueError("Invalid scenario_id format. Expected 'scenario_id' or 'scenario_name:version'.")
|
|
231
|
+
scenario_id = scenario_arr[0]
|
|
232
|
+
scenario_version = int(scenario_arr[1]) if len(scenario_arr) > 1 else None
|
|
219
233
|
self._scenario_id = scenario_id or str(uuid.uuid4())
|
|
234
|
+
self._scenario_version = scenario_version
|
|
235
|
+
|
|
220
236
|
self._generator = np.random.default_rng(seed)
|
|
221
237
|
self._configure()
|
|
222
238
|
scenario = scenario or {}
|
|
239
|
+
|
|
223
240
|
self._scenario_template = OmegaConf.create(scenario)
|
|
224
|
-
self.reset(episode_id=episode_id)
|
|
225
241
|
|
|
226
242
|
def _validate_distribution_params(self, dist_name: str, *args: tuple) -> None:
|
|
227
243
|
dimensions = DISTRIBUTION_DIMENSION_MAP[dist_name]
|
|
@@ -291,13 +307,6 @@ class Scenario:
|
|
|
291
307
|
root_yaml = yaml.safe_load(OmegaConf.to_yaml(_root_))
|
|
292
308
|
key_path = self._get_node_path(root_yaml, str(_node_))
|
|
293
309
|
|
|
294
|
-
if key_path not in self._metrics:
|
|
295
|
-
self._metrics[key_path] = DistributionMetric(name=key_path,
|
|
296
|
-
distribution_type=dist_name,
|
|
297
|
-
run_id=self._run_id,
|
|
298
|
-
episode_id=self._episode_id,
|
|
299
|
-
granularity=MetricGranularity.EPISODE)
|
|
300
|
-
|
|
301
310
|
shape = None
|
|
302
311
|
|
|
303
312
|
if DISTRIBUTION_DIMENSION_MAP[dist_name] == -1:
|
|
@@ -315,7 +324,13 @@ class Scenario:
|
|
|
315
324
|
|
|
316
325
|
if isinstance(ret_val, list):
|
|
317
326
|
ret_val = ListConfig(ret_val)
|
|
318
|
-
|
|
327
|
+
|
|
328
|
+
self._episode_vals[key_path] = {
|
|
329
|
+
"value": ret_val,
|
|
330
|
+
"distribution": dist_name,
|
|
331
|
+
"graph_type": DISTRIBUTION_GRAPH_TYPE[dist_name],
|
|
332
|
+
"metric_dim_type": SCENARIO_STATS_DIM_TYPE_MAP[dist_name],
|
|
333
|
+
}
|
|
319
334
|
return ret_val
|
|
320
335
|
|
|
321
336
|
for dist_name in DISTRIBUTION_MAP.keys():
|
|
@@ -325,33 +340,18 @@ class Scenario:
|
|
|
325
340
|
self.dist_cache.clear()
|
|
326
341
|
OmegaConf.clear_resolvers()
|
|
327
342
|
|
|
328
|
-
def
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
def __getitem__(self, key: Any) -> Any:
|
|
334
|
-
if key in self._cur_scenario:
|
|
335
|
-
return self._cur_scenario[key]
|
|
336
|
-
raise KeyError(f"'Scenario' object has no key '{key}'")
|
|
337
|
-
|
|
338
|
-
def reset(self,
|
|
339
|
-
episode_id: str | None = None) -> None:
|
|
340
|
-
"""Reset the scenario for a new episode.
|
|
341
|
-
|
|
342
|
-
Args:
|
|
343
|
-
episode_id: Optional new episode ID. If None, keeps the current episode ID.
|
|
344
|
-
"""
|
|
345
|
-
for metric in self._metrics.values():
|
|
346
|
-
metric.reset(episode_id=episode_id)
|
|
347
|
-
self._cur_scenario = copy.deepcopy(self._scenario_template)
|
|
348
|
-
OmegaConf.resolve(self._cur_scenario)
|
|
349
|
-
|
|
350
|
-
def finish(self) -> None:
|
|
351
|
-
"""Finish the scenario and submit final metrics.
|
|
343
|
+
def resolve(self) -> tuple[DictConfig | ListConfig, dict]:
|
|
344
|
+
"""Resolve the scenario configuration, sampling all distributions.
|
|
345
|
+
|
|
346
|
+
Returns:
|
|
347
|
+
tuple[DictConfig | ListConfig, dict]: The resolved scenario and episode values.
|
|
352
348
|
"""
|
|
353
|
-
|
|
354
|
-
|
|
349
|
+
with self._lock:
|
|
350
|
+
cur_scenario = copy.deepcopy(self._scenario_template)
|
|
351
|
+
self._episode_vals = {}
|
|
352
|
+
OmegaConf.resolve(cur_scenario)
|
|
353
|
+
episode_vals = copy.deepcopy(self._episode_vals)
|
|
354
|
+
return cur_scenario, episode_vals
|
|
355
355
|
|
|
356
356
|
@property
|
|
357
357
|
def template(self) -> Any:
|
|
@@ -362,15 +362,6 @@ class Scenario:
|
|
|
362
362
|
"""
|
|
363
363
|
return self._scenario_template
|
|
364
364
|
|
|
365
|
-
@property
|
|
366
|
-
def cur_scenario(self) -> Any:
|
|
367
|
-
"""The current scenario configuration.
|
|
368
|
-
|
|
369
|
-
Returns:
|
|
370
|
-
Any: The current scenario as an OmegaConf object.
|
|
371
|
-
"""
|
|
372
|
-
return self._cur_scenario
|
|
373
|
-
|
|
374
365
|
@property
|
|
375
366
|
def yaml(self) -> str:
|
|
376
367
|
"""The current scenario configuration as a YAML string.
|
|
@@ -378,4 +369,4 @@ class Scenario:
|
|
|
378
369
|
Returns:
|
|
379
370
|
str: The current scenario as a YAML string.
|
|
380
371
|
"""
|
|
381
|
-
return OmegaConf.to_yaml(self.
|
|
372
|
+
return OmegaConf.to_yaml(self._scenario_template)
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
|
|
4
|
+
from humalab.humalab_api_client import HumaLabApiClient
|
|
5
|
+
from humalab.scenarios.scenario import Scenario
|
|
6
|
+
from humalab.constants import DEFAULT_PROJECT
|
|
7
|
+
|
|
8
|
+
@dataclass
|
|
9
|
+
class ScenarioMetadata:
|
|
10
|
+
id: str
|
|
11
|
+
version: int
|
|
12
|
+
project: str
|
|
13
|
+
name: str
|
|
14
|
+
description: str | None
|
|
15
|
+
created_at: str
|
|
16
|
+
updated_at: str
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def list_scenarios(project: str = DEFAULT_PROJECT,
|
|
20
|
+
limit: int = 20,
|
|
21
|
+
offset: int = 0,
|
|
22
|
+
include_inactive: bool = False,
|
|
23
|
+
search: Optional[str] = None,
|
|
24
|
+
status_filter: Optional[str] = None,
|
|
25
|
+
|
|
26
|
+
base_url: str | None = None,
|
|
27
|
+
api_key: str | None = None,
|
|
28
|
+
timeout: float | None = None,
|
|
29
|
+
) -> list[dict]:
|
|
30
|
+
"""
|
|
31
|
+
List all scenarios for a given project.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
project: The project name to list scenarios from.
|
|
35
|
+
base_url: The base URL of the HumaLab API.
|
|
36
|
+
api_key: The API key for authentication.
|
|
37
|
+
timeout: The timeout for API requests.
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
A list of scenario metadata dictionaries.
|
|
41
|
+
"""
|
|
42
|
+
api_client = HumaLabApiClient(base_url=base_url,
|
|
43
|
+
api_key=api_key,
|
|
44
|
+
timeout=timeout)
|
|
45
|
+
resp = api_client.get_scenarios(project_name=project,
|
|
46
|
+
limit=limit,
|
|
47
|
+
offset=offset,
|
|
48
|
+
include_inactive=include_inactive,
|
|
49
|
+
search=search,
|
|
50
|
+
status_filter=status_filter)
|
|
51
|
+
ret_list = []
|
|
52
|
+
for scenario in resp.get("scenarios", []):
|
|
53
|
+
scenario["project"] = project
|
|
54
|
+
ret_list.append(ScenarioMetadata(id=scenario["uuid"],
|
|
55
|
+
version=scenario["version"],
|
|
56
|
+
project=project,
|
|
57
|
+
name=scenario["name"],
|
|
58
|
+
description=scenario.get("description"),
|
|
59
|
+
created_at=scenario.get("created_at"),
|
|
60
|
+
updated_at=scenario.get("updated_at")))
|
|
61
|
+
return ret_list
|
|
62
|
+
|
|
63
|
+
def get_scenario(scenario_id: str,
|
|
64
|
+
version: int | None = None,
|
|
65
|
+
project: str = DEFAULT_PROJECT,
|
|
66
|
+
seed: int | None=None,
|
|
67
|
+
|
|
68
|
+
base_url: str | None = None,
|
|
69
|
+
api_key: str | None = None,
|
|
70
|
+
timeout: float | None = None,) -> Scenario:
|
|
71
|
+
api_client = HumaLabApiClient(base_url=base_url,
|
|
72
|
+
api_key=api_key,
|
|
73
|
+
timeout=timeout)
|
|
74
|
+
scenario_resp = api_client.get_scenario(
|
|
75
|
+
project_name=project,
|
|
76
|
+
uuid=scenario_id, version=version)
|
|
77
|
+
scenario = Scenario()
|
|
78
|
+
|
|
79
|
+
scenario.init(scenario=scenario_resp["yaml_content"],
|
|
80
|
+
seed=seed,
|
|
81
|
+
scenario_id=f"{scenario_id}:{version}" if version is not None else scenario_id)
|
|
82
|
+
return scenario
|