artefacts-cli 0.8.0__tar.gz → 0.9.3__tar.gz

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 (88) hide show
  1. artefacts_cli-0.9.3/.pyre_configuration +10 -0
  2. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/CHANGELOG.md +33 -1
  3. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/PKG-INFO +10 -3
  4. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/README.md +4 -0
  5. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/artefacts/cli/__init__.py +67 -19
  6. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/artefacts/cli/app.py +196 -171
  7. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/artefacts/cli/app_containers.py +97 -25
  8. artefacts_cli-0.9.3/artefacts/cli/app_containers.pyi +3 -0
  9. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/artefacts/cli/bagparser.py +4 -0
  10. artefacts_cli-0.9.3/artefacts/cli/config.py +62 -0
  11. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/artefacts/cli/constants.py +7 -0
  12. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/artefacts/cli/containers/__init__.py +5 -5
  13. artefacts_cli-0.9.3/artefacts/cli/containers/docker_cm.py +175 -0
  14. artefacts_cli-0.9.3/artefacts/cli/containers/docker_utils.py +98 -0
  15. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/artefacts/cli/containers/utils.py +20 -8
  16. artefacts_cli-0.9.3/artefacts/cli/helpers.py +55 -0
  17. artefacts_cli-0.9.3/artefacts/cli/i18n.py +35 -0
  18. artefacts_cli-0.9.3/artefacts/cli/locales/art.pot +524 -0
  19. artefacts_cli-0.9.3/artefacts/cli/locales/base.pot +995 -0
  20. artefacts_cli-0.9.3/artefacts/cli/locales/click.pot +496 -0
  21. artefacts_cli-0.9.3/artefacts/cli/locales/ja_JP/LC_MESSAGES/artefacts.po +1028 -0
  22. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/artefacts/cli/other.py +1 -0
  23. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/artefacts/cli/ros1.py +21 -6
  24. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/artefacts/cli/ros2.py +10 -3
  25. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/artefacts/cli/utils.py +8 -4
  26. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/artefacts/cli/utils_ros.py +35 -9
  27. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/artefacts/cli/version.py +2 -2
  28. artefacts_cli-0.9.3/artefacts/copava/__init__.py +1 -0
  29. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/artefacts_cli.egg-info/PKG-INFO +10 -3
  30. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/artefacts_cli.egg-info/SOURCES.txt +15 -1
  31. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/artefacts_cli.egg-info/requires.txt +4 -1
  32. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/pyproject.toml +10 -4
  33. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/pytest.ini +1 -1
  34. artefacts_cli-0.9.3/tests/cli/containers/test_docker.py +162 -0
  35. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/tests/cli/test_app_containers.py +4 -3
  36. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/tests/cli/test_cli.py +4 -5
  37. artefacts_cli-0.9.3/tests/cli/test_other.py +51 -0
  38. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/tests/cli/test_ros2.py +23 -9
  39. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/tests/cli/test_utils.py +5 -15
  40. artefacts_cli-0.9.3/tests/cli/test_utils_ros.py +43 -0
  41. artefacts_cli-0.9.3/tests/cli/test_warp_run.py +139 -0
  42. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/tests/conftest.py +38 -2
  43. artefacts_cli-0.9.3/tests/fixtures/test_junit.xml +17 -0
  44. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/tests/utils/docker_mock.py +4 -0
  45. artefacts_cli-0.8.0/artefacts/cli/containers/docker.py +0 -119
  46. artefacts_cli-0.8.0/tests/cli/test_other.py +0 -22
  47. artefacts_cli-0.8.0/tests/cli/test_utils_ros.py +0 -9
  48. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/README_INTERNAL.md +0 -0
  49. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/artefacts/__init__.py +0 -0
  50. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/artefacts/cli/errors.py +0 -0
  51. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/artefacts/cli/logger.py +0 -0
  52. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/artefacts/cli/parameters.py +0 -0
  53. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/artefacts/wrappers/artefacts_ros1_meta.launch +0 -0
  54. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/artefacts.yaml +0 -0
  55. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/artefacts_cli.egg-info/dependency_links.txt +0 -0
  56. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/artefacts_cli.egg-info/entry_points.txt +0 -0
  57. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/artefacts_cli.egg-info/top_level.txt +0 -0
  58. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/bin/release +0 -0
  59. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/infra-tests/test_run_remote.yaml +0 -0
  60. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/infra-tests/turtlesim1/ros_workspace/src/turtle_odometry/CMakeLists.txt +0 -0
  61. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/infra-tests/turtlesim1/ros_workspace/src/turtle_odometry/launch/test_meta.launch +0 -0
  62. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/infra-tests/turtlesim1/ros_workspace/src/turtle_odometry/launch/test_turtle.launch +0 -0
  63. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/infra-tests/turtlesim1/ros_workspace/src/turtle_odometry/launch/turtle_odometry.launch +0 -0
  64. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/infra-tests/turtlesim1/ros_workspace/src/turtle_odometry/package.xml +0 -0
  65. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/infra-tests/turtlesim1/ros_workspace/src/turtle_odometry/setup.py +0 -0
  66. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/infra-tests/turtlesim1/ros_workspace/src/turtle_odometry/src/TestTurtle.py +0 -0
  67. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/infra-tests/turtlesim1/ros_workspace/src/turtle_odometry/src/__init__.py +0 -0
  68. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/infra-tests/turtlesim1/ros_workspace/src/turtle_odometry/src/turtle_odom.py +0 -0
  69. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/infra-tests/turtlesim1/ros_workspace/src/turtle_odometry/src/turtle_post_process.py +0 -0
  70. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/infra-tests/turtlesim1/ros_workspace/src/turtle_odometry/src/turtle_trajectory.py +0 -0
  71. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/infra-tests/turtlesim1/ros_workspace/src/turtle_odometry/test/viz_turtle_odom.xml +0 -0
  72. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/infra-tests/turtlesim2/launch_turtle.py +0 -0
  73. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/infra-tests/turtlesim2/sample_node.py +0 -0
  74. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/setup.cfg +0 -0
  75. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/tests/__init__.py +0 -0
  76. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/tests/cli/__init__.py +0 -0
  77. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/tests/cli/containers/__init__.py +0 -0
  78. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/tests/cli/containers/test_utils.py +0 -0
  79. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/tests/cli/test_config_validation.py +0 -0
  80. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/tests/cli/test_parameters.py +0 -0
  81. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/tests/cli/test_ros1.py +0 -0
  82. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/tests/cli/test_warp.py +0 -0
  83. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/tests/fixtures/artefacts_deprecated.yaml +0 -0
  84. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/tests/fixtures/artefacts_ros1.yaml +0 -0
  85. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/tests/fixtures/bad_launch_test.py +0 -0
  86. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/tests/fixtures/warp-env-param.yaml +0 -0
  87. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/tests/fixtures/warp.yaml +0 -0
  88. {artefacts_cli-0.8.0 → artefacts_cli-0.9.3}/tests/test_config_validation.py +0 -0
@@ -0,0 +1,10 @@
1
+ {
2
+ "site_package_search_strategy": "pep561",
3
+ "search_path": ["./venv/lib/python3.*/site-packages/"],
4
+ "source_directories": [
5
+ {
6
+ "import_root": ".",
7
+ "source": "artefacts"
8
+ }
9
+ ]
10
+ }
@@ -7,6 +7,35 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.9.3] - 2025-06-03
11
+
12
+ ### Removed
13
+
14
+ - Removed unique scenario names for `run-remote` jobs as no longer required by dashboard
15
+
16
+ ## [0.9.2] - 2025-05-27
17
+
18
+ ### Added
19
+
20
+ - Deeper and tentatively complete localisation of the CLI framework (#262)
21
+ - ROS tests can be recorded as "error" rather than just fail or success (#267)
22
+
23
+ ### Fixed
24
+
25
+ - Compliance with the Artefacts API protocol on reporting common scenario names
26
+ across parameterised runs.
27
+
28
+ ## [0.9.1] - 2025-04-30
29
+
30
+ ### Added
31
+
32
+ - Runs in container accept and pass options to the underlying container engine (#246)
33
+ - Internationalisation of command output and Japanese support (#139)
34
+
35
+ ### Fixed
36
+
37
+ - Compliance with the Artefacts API protocol on upload/no-upload option (#217)
38
+
10
39
  ## [0.8.0] - 2025-04-04
11
40
 
12
41
  ### Added
@@ -76,6 +105,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
76
105
  - Local metrics errors do not block publication of results.
77
106
  - Introduction of Black formatting.
78
107
 
79
- [unreleased]: https://github.com/art-e-fact/artefacts-client/compare/0.7.0...HEAD
108
+ [unreleased]: https://github.com/art-e-fact/artefacts-client/compare/0.9.2...HEAD
109
+ [0.9.2]: https://github.com/art-e-fact/artefacts-client/releases/tag/0.9.2
110
+ [0.9.1]: https://github.com/art-e-fact/artefacts-client/releases/tag/0.9.1
111
+ [0.8.0]: https://github.com/art-e-fact/artefacts-client/releases/tag/0.8.0
80
112
  [0.7.0]: https://github.com/art-e-fact/artefacts-client/releases/tag/0.7.0
81
113
  [0.5.8]: https://github.com/art-e-fact/artefacts-client/releases/tag/0.5.8
@@ -1,26 +1,28 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: artefacts_cli
3
- Version: 0.8.0
3
+ Version: 0.9.3
4
4
  Author-email: FD <fabian@artefacts.com>, AGC <alejandro@artefacts.com>, TN <tomo@artefacts.com>, EP <eric@artefacts.com>
5
+ License-Expression: Apache-2.0
5
6
  Project-URL: Homepage, https://github.com/art-e-fact/artefacts-client
6
7
  Project-URL: Bug Tracker, https://github.com/art-e-fact/artefacts-client/issues
7
8
  Project-URL: Changelog, https://github.com/art-e-fact/artefacts-client/CHANGELOG.md
8
9
  Classifier: Programming Language :: Python :: 3
9
- Classifier: License :: OSI Approved :: Apache Software License
10
10
  Classifier: Operating System :: OS Independent
11
11
  Requires-Python: >=3.8
12
12
  Description-Content-Type: text/markdown
13
13
  Requires-Dist: artefacts-c2d>=1.7.1
14
14
  Requires-Dist: artefacts-copava>=0.1.11
15
- Requires-Dist: click>=8.0.4
15
+ Requires-Dist: artefacts-click
16
16
  Requires-Dist: gitignore_parser>=0.1.11
17
17
  Requires-Dist: junitparser>=2.5
18
18
  Requires-Dist: mcap
19
19
  Requires-Dist: mcap-ros2-support
20
20
  Requires-Dist: PyYAML>=6.0
21
21
  Requires-Dist: requests>=2.27.1
22
+ Requires-Dist: rospkg
22
23
  Provides-Extra: dev
23
24
  Requires-Dist: awscli; extra == "dev"
25
+ Requires-Dist: babel==2.17.0; extra == "dev"
24
26
  Requires-Dist: build; extra == "dev"
25
27
  Requires-Dist: docker; extra == "dev"
26
28
  Requires-Dist: lark; extra == "dev"
@@ -37,6 +39,7 @@ Requires-Dist: pytest-env; extra == "dev"
37
39
  Requires-Dist: pytest-mock; extra == "dev"
38
40
  Requires-Dist: python-markdown-math; extra == "dev"
39
41
  Requires-Dist: ruff>=0.9.2; extra == "dev"
42
+ Requires-Dist: setuptools_scm>=8; extra == "dev"
40
43
  Requires-Dist: twine; extra == "dev"
41
44
 
42
45
  # Artefacts CLI
@@ -102,3 +105,7 @@ mkdocs serve -a 127.0.0.1:7000
102
105
  ```
103
106
 
104
107
  The docs are automatically deployed by the documentation workflow.
108
+
109
+ ## Development notes
110
+
111
+ We use Pyre for static analysis. If it does not work out of the box, please consider adapting the `.pyre_configuration` file included with this repository. One assumption is that developers work in a virtual environment under `./venv`.
@@ -61,3 +61,7 @@ mkdocs serve -a 127.0.0.1:7000
61
61
  ```
62
62
 
63
63
  The docs are automatically deployed by the documentation workflow.
64
+
65
+ ## Development notes
66
+
67
+ We use Pyre for static analysis. If it does not work out of the box, please consider adapting the `.pyre_configuration` file included with this repository. One assumption is that developers work in a virtual environment under `./venv`.
@@ -1,13 +1,15 @@
1
+ from datetime import datetime, timezone
1
2
  from importlib.metadata import version, PackageNotFoundError
2
- import json
3
+ from typing import Optional
4
+ import copy
3
5
  import glob
4
- from datetime import datetime, timezone
5
- import os
6
+ import json
6
7
  import math
8
+ import os
7
9
  import requests
8
- import copy
9
- from typing import Optional
10
10
 
11
+ from .config import APIConf
12
+ from .i18n import localise
11
13
  from .parameters import iter_grid
12
14
  from .logger import logger
13
15
 
@@ -21,7 +23,13 @@ except PackageNotFoundError:
21
23
 
22
24
  __version__ = get_version()
23
25
  except Exception as e:
24
- logger.warning(f"Could not determine package version: {e}. Default to 0.0.0")
26
+ logger.warning(
27
+ localise(
28
+ "Could not determine package version: {error_message}. Default to 0.0.0".format(
29
+ error_message=e
30
+ )
31
+ )
32
+ )
25
33
  __version__ = "0.0.0"
26
34
 
27
35
 
@@ -35,7 +43,7 @@ class WarpJob:
35
43
  def __init__(
36
44
  self,
37
45
  project_id,
38
- api_conf,
46
+ api_conf: APIConf,
39
47
  jobname,
40
48
  jobconf,
41
49
  dryrun=False,
@@ -86,7 +94,13 @@ class WarpJob:
86
94
  msg = response.json()["message"]
87
95
  logger.warning(msg)
88
96
  raise AuthenticationError(msg)
89
- logger.warning(f"Error on job creation: {response.status_code}")
97
+ logger.warning(
98
+ localise(
99
+ "Error on job creation: {status_code}".format(
100
+ status_code=response.status_code
101
+ )
102
+ )
103
+ )
90
104
  logger.warning(response.text)
91
105
  raise AuthenticationError(str(response.status_code))
92
106
  self.job_id = response.json()["job_id"]
@@ -117,22 +131,25 @@ class WarpJob:
117
131
  return
118
132
 
119
133
  def new_run(self, scenario):
120
- run = WarpRun(self, scenario, self.n_runs)
134
+ run = WarpRun(self, scenario["name"], scenario, self.n_runs)
121
135
  self.n_runs += 1
122
136
  return run
123
137
 
124
138
 
125
139
  class WarpRun:
126
- def __init__(self, job, scenario, run_n):
140
+ def __init__(self, job: WarpJob, name: str, params: dict, run_n: int):
127
141
  self.job = job
128
142
  self.start = datetime.now(timezone.utc).timestamp()
129
143
  self.uploads = {}
130
- self.params = scenario
144
+ self.scenario_name = name
145
+ self.params = params
131
146
  self.metrics = {}
132
147
  self.run_n = run_n
133
148
  self.output_path = self.params.get(
134
149
  "output_path", f"{self.job.output_path}/{self.run_n}"
135
150
  )
151
+ self.test_results = None
152
+ self.success = False
136
153
  self.logger = logger
137
154
  os.makedirs(self.output_path, exist_ok=True)
138
155
  data = {
@@ -141,6 +158,7 @@ class WarpRun:
141
158
  "start": round(self.start),
142
159
  "tests": [],
143
160
  "params": json.dumps(self.params),
161
+ "scenario_name": self.scenario_name,
144
162
  }
145
163
 
146
164
  if self.job.dryrun:
@@ -158,7 +176,13 @@ class WarpRun:
158
176
  msg = response.json()["message"]
159
177
  self.logger.warning(msg)
160
178
  raise AuthenticationError(msg)
161
- self.logger.warning(f"Error on scenario creation: {response.status_code}")
179
+ self.logger.warning(
180
+ localise(
181
+ "Error on scenario creation: {status_code}".format(
182
+ status_code=response.status_code
183
+ )
184
+ )
185
+ )
162
186
  self.logger.warning(response.text)
163
187
  raise AuthenticationError(str(response.status_code))
164
188
  return
@@ -236,8 +260,10 @@ class WarpRun:
236
260
 
237
261
  def stop(self):
238
262
  end = datetime.now(timezone.utc).timestamp()
263
+
239
264
  if self.job.dryrun:
240
265
  return
266
+
241
267
  # Log metadata
242
268
  data = {
243
269
  "job_id": self.job.job_id,
@@ -248,18 +274,24 @@ class WarpRun:
248
274
  "duration": math.ceil(end - self.start),
249
275
  "tests": self.test_results,
250
276
  "success": self.success,
251
- "uploads": self.uploads,
252
277
  "metrics": self.metrics,
278
+ "scenario_name": self.scenario_name,
253
279
  }
280
+ if not self.job.noupload:
281
+ data["uploads"] = self.uploads
282
+
254
283
  response = requests.put(
255
284
  f"{self.job.api_conf.api_url}/{self.job.project_id}/job/{self.job.job_id}/run/{self.run_n}",
256
285
  json=data,
257
286
  headers=self.job.api_conf.headers,
258
287
  )
288
+
259
289
  # use s3 presigned urls to upload the artifacts
260
290
  if self.job.noupload:
261
291
  print(
262
- "noupload: job artifacts are not uploaded to cloud, including the ones specified in output_dirs"
292
+ localise(
293
+ "Files generated by the job are not uploaded to Artefacts, including the ones specified in output_dirs"
294
+ )
263
295
  )
264
296
  else:
265
297
  upload_urls = response.json()["upload_urls"]
@@ -268,7 +300,13 @@ class WarpRun:
268
300
  upload_info = upload_urls[key]
269
301
  file_size_mb = os.path.getsize(file_name) / 1024 / 1024
270
302
  try:
271
- print(f"Uploading {file_name} ({file_size_mb:.2f} MB)")
303
+ print(
304
+ localise(
305
+ "Uploading {file_name} ({file_size:.2f} MB)".format(
306
+ file_name=file_name, file_size=file_size_mb
307
+ )
308
+ )
309
+ )
272
310
  # TODO: add a retry policy
273
311
  requests.post(
274
312
  upload_info["url"],
@@ -277,15 +315,25 @@ class WarpRun:
277
315
  )
278
316
  except OverflowError:
279
317
  self.logger.warning(
280
- f"File too large: {file_name} could not be uploaded"
318
+ localise(
319
+ "File too large: {file_name} could not be uploaded".format(
320
+ file_name=file_name
321
+ )
322
+ )
281
323
  )
282
324
  except Exception as e:
283
- self.logger.warning(f"Error uploading {file_name}: {e}, skipping")
325
+ self.logger.warning(
326
+ localise(
327
+ "Error uploading {file_name}: {error_message}, skipping".format(
328
+ file_name=file_name, error_message=e
329
+ )
330
+ )
331
+ )
284
332
 
285
333
 
286
334
  def init_job(
287
335
  project_id: str,
288
- api_token: str,
336
+ api_conf: APIConf,
289
337
  jobname: str,
290
338
  jobconf: dict,
291
339
  dryrun: bool = False,
@@ -297,7 +345,7 @@ def init_job(
297
345
  ):
298
346
  return WarpJob(
299
347
  project_id,
300
- api_token,
348
+ api_conf,
301
349
  jobname,
302
350
  jobconf,
303
351
  dryrun,