openjd-cli 0.4.4__tar.gz → 0.6.0__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 (32) hide show
  1. {openjd_cli-0.4.4 → openjd_cli-0.6.0}/PKG-INFO +17 -110
  2. {openjd_cli-0.4.4 → openjd_cli-0.6.0}/README.md +13 -106
  3. {openjd_cli-0.4.4 → openjd_cli-0.6.0}/hatch.toml +1 -1
  4. openjd_cli-0.4.4/openjd/cli/_run/_local_session/__init__.py → openjd_cli-0.6.0/openjd/__main__.py +5 -0
  5. openjd_cli-0.6.0/openjd/cli/__init__.py +5 -0
  6. {openjd_cli-0.4.4 → openjd_cli-0.6.0}/openjd/cli/_check/__init__.py +2 -2
  7. {openjd_cli-0.4.4 → openjd_cli-0.6.0}/openjd/cli/_check/_check_command.py +15 -3
  8. {openjd_cli-0.4.4 → openjd_cli-0.6.0}/openjd/cli/_common/__init__.py +5 -2
  9. openjd_cli-0.6.0/openjd/cli/_common/_extensions.py +34 -0
  10. {openjd_cli-0.4.4 → openjd_cli-0.6.0}/openjd/cli/_common/_validation_utils.py +4 -2
  11. {openjd_cli-0.4.4 → openjd_cli-0.6.0}/openjd/cli/_create_argparser.py +21 -0
  12. {openjd_cli-0.4.4 → openjd_cli-0.6.0}/openjd/cli/_run/__init__.py +1 -1
  13. {openjd_cli-0.4.4 → openjd_cli-0.6.0}/openjd/cli/_run/_local_session/_actions.py +23 -2
  14. openjd_cli-0.6.0/openjd/cli/_run/_local_session/_logs.py +80 -0
  15. openjd_cli-0.6.0/openjd/cli/_run/_local_session/_session_manager.py +414 -0
  16. {openjd_cli-0.4.4 → openjd_cli-0.6.0}/openjd/cli/_run/_run_command.py +186 -124
  17. {openjd_cli-0.4.4 → openjd_cli-0.6.0}/openjd/cli/_schema/_schema_command.py +1 -4
  18. {openjd_cli-0.4.4 → openjd_cli-0.6.0}/openjd/cli/_summary/_summary_command.py +6 -1
  19. {openjd_cli-0.4.4 → openjd_cli-0.6.0}/openjd/cli/_summary/_summary_output.py +15 -13
  20. {openjd_cli-0.4.4 → openjd_cli-0.6.0}/openjd/cli/_version.py +9 -4
  21. {openjd_cli-0.4.4 → openjd_cli-0.6.0}/pyproject.toml +2 -2
  22. openjd_cli-0.4.4/openjd/__main__.py +0 -26
  23. openjd_cli-0.4.4/openjd/cli/_run/_local_session/_logs.py +0 -46
  24. openjd_cli-0.4.4/openjd/cli/_run/_local_session/_session_manager.py +0 -388
  25. {openjd_cli-0.4.4 → openjd_cli-0.6.0}/.gitignore +0 -0
  26. {openjd_cli-0.4.4 → openjd_cli-0.6.0}/LICENSE +0 -0
  27. {openjd_cli-0.4.4 → openjd_cli-0.6.0}/NOTICE +0 -0
  28. {openjd_cli-0.4.4 → openjd_cli-0.6.0}/openjd/cli/_common/_job_from_template.py +0 -0
  29. {openjd_cli-0.4.4/openjd/cli → openjd_cli-0.6.0/openjd/cli/_run/_local_session}/__init__.py +0 -0
  30. {openjd_cli-0.4.4 → openjd_cli-0.6.0}/openjd/cli/_schema/__init__.py +0 -0
  31. {openjd_cli-0.4.4 → openjd_cli-0.6.0}/openjd/cli/_summary/__init__.py +0 -0
  32. {openjd_cli-0.4.4 → openjd_cli-0.6.0}/openjd/cli/py.typed +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: openjd-cli
3
- Version: 0.4.4
3
+ Version: 0.6.0
4
4
  Summary: Provides a command-line interface for working with Open Job Description templates.
5
5
  Project-URL: Homepage, https://github.com/OpenJobDescription/openjd-cli
6
6
  Project-URL: Source, https://github.com/OpenJobDescription/openjd-cli
@@ -22,8 +22,8 @@ Classifier: Programming Language :: Python :: 3.10
22
22
  Classifier: Programming Language :: Python :: 3.11
23
23
  Classifier: Programming Language :: Python :: 3.12
24
24
  Requires-Python: >=3.9
25
- Requires-Dist: openjd-model==0.4.*
26
- Requires-Dist: openjd-sessions==0.8.*
25
+ Requires-Dist: openjd-model==0.7.*
26
+ Requires-Dist: openjd-sessions<0.11,>=0.10.1
27
27
  Description-Content-Type: text/markdown
28
28
 
29
29
  ## Open Job Description - CLI
@@ -50,13 +50,13 @@ This library requires:
50
50
 
51
51
  ## Versioning
52
52
 
53
- This package's version follows [Semantic Versioning 2.0](https://semver.org/), but is still considered to be in its
53
+ This package's version follows [Semantic Versioning 2.0](https://semver.org/), but is still considered to be in its
54
54
  initial development, thus backwards incompatible versions are denoted by minor version bumps. To help illustrate how
55
55
  versions will increment during this initial development stage, they are described below:
56
56
 
57
- 1. The MAJOR version is currently 0, indicating initial development.
58
- 2. The MINOR version is currently incremented when backwards incompatible changes are introduced to the public API.
59
- 3. The PATCH version is currently incremented when bug fixes or backwards compatible changes are introduced to the public API.
57
+ 1. The MAJOR version is currently 0, indicating initial development.
58
+ 2. The MINOR version is currently incremented when backwards incompatible changes are introduced to the public API.
59
+ 3. The PATCH version is currently incremented when bug fixes or backwards compatible changes are introduced to the public API.
60
60
 
61
61
  ## Contributing
62
62
 
@@ -92,7 +92,7 @@ Template at '/path/to/job.template.json' passes validation checks!
92
92
 
93
93
  ### `summary`
94
94
 
95
- Displays summary information about a sample Job or Step, and the Steps and Tasks therein. The user may provide parameters to
95
+ Displays summary information about a sample Job or Step, and the Steps and Tasks therein. The user may provide parameters to
96
96
  customize the Job, as parameters can have an impact on the amount of Steps and Tasks that a job consists of.
97
97
 
98
98
  #### Arguments
@@ -173,7 +173,7 @@ Session ended successfully
173
173
  Job: MyJob
174
174
  Step: Step1
175
175
  Duration: 1.0 seconds
176
- Tasks run: 1
176
+ Chunks run: 1
177
177
 
178
178
  ```
179
179
 
@@ -205,109 +205,16 @@ You can download this package from:
205
205
 
206
206
  ### Verifying GitHub Releases
207
207
 
208
- You can verify the authenticity of the release artifacts using the `gpg` command line tool.
209
-
210
- 1) Download the desired release artifacts from the GitHub releases page. Make sure to download the corresponding PGP signature file (ending with `.sig`) as well.
211
- For example, if you would like to verify your download of the wheel for version `1.2.3`, you should have the following files downloaded:
212
- ```
213
- openjd_cli-1.2.3-py3-none-any.whl
214
- openjd_cli-1.2.3-py3-none-any.whl.sig
215
- ```
216
-
217
- 2) Install the `gpg` command line tool. The installation process varies by operating system. Please refer to the GnuPG website for instructions: https://gnupg.org/download/
218
-
219
- 3) Save the following contents to a file called `openjobdescription-pgp.asc`:
220
- ```
221
- -----BEGIN PGP PUBLIC KEY BLOCK-----
222
-
223
- mQINBGXGjx0BEACdChrQ/nch2aYGJ4fxHNQwlPE42jeHECqTdlc1V/mug+7qN7Pc
224
- C4NQk4t68Y72WX/NG49gRfpAxPlSeNt18c3vJ9/sWTukmonWYGK0jQGnDWjuVgFT
225
- XtvJAAQBFilQXN8h779Th2lEuD4bQX+mGB7l60Xvh7vIehE3C4Srbp6KJXskPLPo
226
- dz/dx7a+GXRiyYCYbGX4JziXSjQZRc0tIaxLn/GDm7VnXpdHcUk3qJitree61oC8
227
- agtRHCH5s56E8wt8fXzyStElMkFIZsoLDlLp5lFqT81En9ho/+K6RLBkIj0mC8G7
228
- BafpHKlxkrIgNK3pWACL93GE6xihqwkZMCAeqloVvkOTdfAKDHuDSEHwKxHG3cZ1
229
- /e1YhtkPMVF+NMeoQavykUGVUT1bRoVNdk6bYsnbUjUI1A+JNf6MqvdRJyckZqEC
230
- ylkBekBp/SFpFHvQkRCpfVizm2GSrjdZKgXpm1ZlQJyMRVzc/XPbqdSWhz52r3IC
231
- eudwReHDc+6J5rs6tg3NbFfPVfCBMSqHlu1HRewWAllIp1+y6nfL4U3iEsUvZ1Y6
232
- IV3defHIP3kNPU14ZWf3G5rvJDZrIRnjoWhDcaVmivmB/cSdDzphL5FovSI8dsPm
233
- iU/JZGQb3EvZq+nl4pOiK32hETJ/fgCCzgUA3WqGeFNUNSI9KYZgBe6daQARAQAB
234
- tDRPcGVuIEpvYiBEZXNjcmlwdGlvbiA8b3BlbmpvYmRlc2NyaXB0aW9uQGFtYXpv
235
- bi5jb20+iQJXBBMBCABBFiEEvBcWYrv5OB7Tl2sZovDwWbzECYcFAmXGjx0DGy8E
236
- BQkDwmcABQsJCAcCAiICBhUKCQgLAgMWAgECHgcCF4AACgkQovDwWbzECYcSHRAA
237
- itPYx48xnJiT6tfnult9ZGivhcXhrMlvirVYOqEtRrt0l18sjr84K8mV71eqFwMx
238
- GS7e4iQP6guqW9biQfMA5/Id8ZjE7jNbF0LUGsY6Ktj+yOlAbTR+x5qr7Svb7oEs
239
- TMB/l9HBZ1WtIRzcUk9XYqzvYQr5TT997A63F28u32RchJ+5ECAz4g/p91aWxwVo
240
- HIfN10sGzttoukJCzC10CZAVscJB+nnoUbB/o3bPak6GUxBHpMgomb0K5g4Z4fXY
241
- 4AZ9jKFoLgNcExdwteiUdSEnRorZ5Ny8sP84lwJziD3wuamVUsZ1C/KiQJBGTp5e
242
- LUY38J1oIwptw5fqjaAq2GQxEaIknWQ4fr3ZvNYUuGUt5FbHe5U5XF34gC8PK7v7
243
- bT/7sVdZZzKFScDLfH5N36M5FrXfTaXsVbfrRoa2j7U0kndyVEZyJsKVAQ8vgwbJ
244
- w/w2hKkyQLAg3l5yO5CHLGatsfSIzea4WoOAaroxiNtL9gzVXzqpw6qPEsH9hsws
245
- HsPEQWXHmDQvFTNUU14qic1Vc5fyxCBXIAGAPBd20b+219XznJ5uBKUgtvnqcItj
246
- nMYe6Btxh+pjrTA15X/p81z6sB7dkL1hPHfawLhCEzJbIPyyBTQYqY00/ap4Rj7t
247
- kzSiyzBejniFfAZ6eYBWsej7uXUsVndBF1ggZynPTeE=
248
- =iaEm
249
- -----END PGP PUBLIC KEY BLOCK-----
250
- ```
251
-
252
- 4) Import the OpenPGP key for Open Job Description by running the following command:
253
-
254
- ```
255
- gpg --import --armor openjobdescription-pgp.asc
256
- ```
257
-
258
- 5) Determine whether to trust the OpenPGP key. Some factors to consider when deciding whether or not to trust the above key are:
259
-
260
- - The internet connection you’ve used to obtain the GPG key from this website is secure
261
- - The device that you are accessing this website on is secure
262
-
263
- If you have decided to trust the OpenPGP key, then edit the key to trust with `gpg` like the following example:
264
- ```
265
- $ gpg --edit-key A2F0F059BCC40987
266
- gpg (GnuPG) 2.0.22; Copyright (C) 2013 Free Software Foundation, Inc.
267
- This is free software: you are free to change and redistribute it.
268
- There is NO WARRANTY, to the extent permitted by law.
269
-
270
-
271
- pub 4096R/BCC40987 created: 2024-02-09 expires: 2026-02-08 usage: SCEA
272
- trust: unknown validity: unknown
273
- [ unknown] (1). Open Job Description <openjobdescription@amazon.com>
274
-
275
- gpg> trust
276
- pub 4096R/BCC40987 created: 2024-02-09 expires: 2026-02-08 usage: SCEA
277
- trust: unknown validity: unknown
278
- [ unknown] (1). Open Job Description <openjobdescription@amazon.com>
279
-
280
- Please decide how far you trust this user to correctly verify other users' keys
281
- (by looking at passports, checking fingerprints from different sources, etc.)
282
-
283
- 1 = I don't know or won't say
284
- 2 = I do NOT trust
285
- 3 = I trust marginally
286
- 4 = I trust fully
287
- 5 = I trust ultimately
288
- m = back to the main menu
289
-
290
- Your decision? 5
291
- Do you really want to set this key to ultimate trust? (y/N) y
292
-
293
- pub 4096R/BCC40987 created: 2024-02-09 expires: 2026-02-08 usage: SCEA
294
- trust: ultimate validity: unknown
295
- [ unknown] (1). Open Job Description <openjobdescription@amazon.com>
296
- Please note that the shown key validity is not necessarily correct
297
- unless you restart the program.
298
-
299
- gpg> quit
300
- ```
301
-
302
- 6) Verify the signature of the Open Job Description release via `gpg --verify`. The command for verifying the example files from step 1 would be:
303
-
304
- ```
305
- gpg --verify ./openjd_cli-1.2.3-py3-none-any.whl.sig ./openjd_cli-1.2.3-py3-none-any.whl
306
- ```
208
+ See [VERIFYING_PGP_SIGNATURE](VERIFYING_PGP_SIGNATURE.md) for more information.
307
209
 
308
210
  ## Security
309
211
 
310
- See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information.
212
+ We take all security reports seriously. When we receive such reports, we will
213
+ investigate and subsequently address any potential vulnerabilities as quickly
214
+ as possible. If you discover a potential security issue in this project, please
215
+ notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/)
216
+ or directly via email to [AWS Security](aws-security@amazon.com). Please do not
217
+ create a public GitHub issue in this project.
311
218
 
312
219
  ## License
313
220
 
@@ -22,13 +22,13 @@ This library requires:
22
22
 
23
23
  ## Versioning
24
24
 
25
- This package's version follows [Semantic Versioning 2.0](https://semver.org/), but is still considered to be in its
25
+ This package's version follows [Semantic Versioning 2.0](https://semver.org/), but is still considered to be in its
26
26
  initial development, thus backwards incompatible versions are denoted by minor version bumps. To help illustrate how
27
27
  versions will increment during this initial development stage, they are described below:
28
28
 
29
- 1. The MAJOR version is currently 0, indicating initial development.
30
- 2. The MINOR version is currently incremented when backwards incompatible changes are introduced to the public API.
31
- 3. The PATCH version is currently incremented when bug fixes or backwards compatible changes are introduced to the public API.
29
+ 1. The MAJOR version is currently 0, indicating initial development.
30
+ 2. The MINOR version is currently incremented when backwards incompatible changes are introduced to the public API.
31
+ 3. The PATCH version is currently incremented when bug fixes or backwards compatible changes are introduced to the public API.
32
32
 
33
33
  ## Contributing
34
34
 
@@ -64,7 +64,7 @@ Template at '/path/to/job.template.json' passes validation checks!
64
64
 
65
65
  ### `summary`
66
66
 
67
- Displays summary information about a sample Job or Step, and the Steps and Tasks therein. The user may provide parameters to
67
+ Displays summary information about a sample Job or Step, and the Steps and Tasks therein. The user may provide parameters to
68
68
  customize the Job, as parameters can have an impact on the amount of Steps and Tasks that a job consists of.
69
69
 
70
70
  #### Arguments
@@ -145,7 +145,7 @@ Session ended successfully
145
145
  Job: MyJob
146
146
  Step: Step1
147
147
  Duration: 1.0 seconds
148
- Tasks run: 1
148
+ Chunks run: 1
149
149
 
150
150
  ```
151
151
 
@@ -177,109 +177,16 @@ You can download this package from:
177
177
 
178
178
  ### Verifying GitHub Releases
179
179
 
180
- You can verify the authenticity of the release artifacts using the `gpg` command line tool.
181
-
182
- 1) Download the desired release artifacts from the GitHub releases page. Make sure to download the corresponding PGP signature file (ending with `.sig`) as well.
183
- For example, if you would like to verify your download of the wheel for version `1.2.3`, you should have the following files downloaded:
184
- ```
185
- openjd_cli-1.2.3-py3-none-any.whl
186
- openjd_cli-1.2.3-py3-none-any.whl.sig
187
- ```
188
-
189
- 2) Install the `gpg` command line tool. The installation process varies by operating system. Please refer to the GnuPG website for instructions: https://gnupg.org/download/
190
-
191
- 3) Save the following contents to a file called `openjobdescription-pgp.asc`:
192
- ```
193
- -----BEGIN PGP PUBLIC KEY BLOCK-----
194
-
195
- mQINBGXGjx0BEACdChrQ/nch2aYGJ4fxHNQwlPE42jeHECqTdlc1V/mug+7qN7Pc
196
- C4NQk4t68Y72WX/NG49gRfpAxPlSeNt18c3vJ9/sWTukmonWYGK0jQGnDWjuVgFT
197
- XtvJAAQBFilQXN8h779Th2lEuD4bQX+mGB7l60Xvh7vIehE3C4Srbp6KJXskPLPo
198
- dz/dx7a+GXRiyYCYbGX4JziXSjQZRc0tIaxLn/GDm7VnXpdHcUk3qJitree61oC8
199
- agtRHCH5s56E8wt8fXzyStElMkFIZsoLDlLp5lFqT81En9ho/+K6RLBkIj0mC8G7
200
- BafpHKlxkrIgNK3pWACL93GE6xihqwkZMCAeqloVvkOTdfAKDHuDSEHwKxHG3cZ1
201
- /e1YhtkPMVF+NMeoQavykUGVUT1bRoVNdk6bYsnbUjUI1A+JNf6MqvdRJyckZqEC
202
- ylkBekBp/SFpFHvQkRCpfVizm2GSrjdZKgXpm1ZlQJyMRVzc/XPbqdSWhz52r3IC
203
- eudwReHDc+6J5rs6tg3NbFfPVfCBMSqHlu1HRewWAllIp1+y6nfL4U3iEsUvZ1Y6
204
- IV3defHIP3kNPU14ZWf3G5rvJDZrIRnjoWhDcaVmivmB/cSdDzphL5FovSI8dsPm
205
- iU/JZGQb3EvZq+nl4pOiK32hETJ/fgCCzgUA3WqGeFNUNSI9KYZgBe6daQARAQAB
206
- tDRPcGVuIEpvYiBEZXNjcmlwdGlvbiA8b3BlbmpvYmRlc2NyaXB0aW9uQGFtYXpv
207
- bi5jb20+iQJXBBMBCABBFiEEvBcWYrv5OB7Tl2sZovDwWbzECYcFAmXGjx0DGy8E
208
- BQkDwmcABQsJCAcCAiICBhUKCQgLAgMWAgECHgcCF4AACgkQovDwWbzECYcSHRAA
209
- itPYx48xnJiT6tfnult9ZGivhcXhrMlvirVYOqEtRrt0l18sjr84K8mV71eqFwMx
210
- GS7e4iQP6guqW9biQfMA5/Id8ZjE7jNbF0LUGsY6Ktj+yOlAbTR+x5qr7Svb7oEs
211
- TMB/l9HBZ1WtIRzcUk9XYqzvYQr5TT997A63F28u32RchJ+5ECAz4g/p91aWxwVo
212
- HIfN10sGzttoukJCzC10CZAVscJB+nnoUbB/o3bPak6GUxBHpMgomb0K5g4Z4fXY
213
- 4AZ9jKFoLgNcExdwteiUdSEnRorZ5Ny8sP84lwJziD3wuamVUsZ1C/KiQJBGTp5e
214
- LUY38J1oIwptw5fqjaAq2GQxEaIknWQ4fr3ZvNYUuGUt5FbHe5U5XF34gC8PK7v7
215
- bT/7sVdZZzKFScDLfH5N36M5FrXfTaXsVbfrRoa2j7U0kndyVEZyJsKVAQ8vgwbJ
216
- w/w2hKkyQLAg3l5yO5CHLGatsfSIzea4WoOAaroxiNtL9gzVXzqpw6qPEsH9hsws
217
- HsPEQWXHmDQvFTNUU14qic1Vc5fyxCBXIAGAPBd20b+219XznJ5uBKUgtvnqcItj
218
- nMYe6Btxh+pjrTA15X/p81z6sB7dkL1hPHfawLhCEzJbIPyyBTQYqY00/ap4Rj7t
219
- kzSiyzBejniFfAZ6eYBWsej7uXUsVndBF1ggZynPTeE=
220
- =iaEm
221
- -----END PGP PUBLIC KEY BLOCK-----
222
- ```
223
-
224
- 4) Import the OpenPGP key for Open Job Description by running the following command:
225
-
226
- ```
227
- gpg --import --armor openjobdescription-pgp.asc
228
- ```
229
-
230
- 5) Determine whether to trust the OpenPGP key. Some factors to consider when deciding whether or not to trust the above key are:
231
-
232
- - The internet connection you’ve used to obtain the GPG key from this website is secure
233
- - The device that you are accessing this website on is secure
234
-
235
- If you have decided to trust the OpenPGP key, then edit the key to trust with `gpg` like the following example:
236
- ```
237
- $ gpg --edit-key A2F0F059BCC40987
238
- gpg (GnuPG) 2.0.22; Copyright (C) 2013 Free Software Foundation, Inc.
239
- This is free software: you are free to change and redistribute it.
240
- There is NO WARRANTY, to the extent permitted by law.
241
-
242
-
243
- pub 4096R/BCC40987 created: 2024-02-09 expires: 2026-02-08 usage: SCEA
244
- trust: unknown validity: unknown
245
- [ unknown] (1). Open Job Description <openjobdescription@amazon.com>
246
-
247
- gpg> trust
248
- pub 4096R/BCC40987 created: 2024-02-09 expires: 2026-02-08 usage: SCEA
249
- trust: unknown validity: unknown
250
- [ unknown] (1). Open Job Description <openjobdescription@amazon.com>
251
-
252
- Please decide how far you trust this user to correctly verify other users' keys
253
- (by looking at passports, checking fingerprints from different sources, etc.)
254
-
255
- 1 = I don't know or won't say
256
- 2 = I do NOT trust
257
- 3 = I trust marginally
258
- 4 = I trust fully
259
- 5 = I trust ultimately
260
- m = back to the main menu
261
-
262
- Your decision? 5
263
- Do you really want to set this key to ultimate trust? (y/N) y
264
-
265
- pub 4096R/BCC40987 created: 2024-02-09 expires: 2026-02-08 usage: SCEA
266
- trust: ultimate validity: unknown
267
- [ unknown] (1). Open Job Description <openjobdescription@amazon.com>
268
- Please note that the shown key validity is not necessarily correct
269
- unless you restart the program.
270
-
271
- gpg> quit
272
- ```
273
-
274
- 6) Verify the signature of the Open Job Description release via `gpg --verify`. The command for verifying the example files from step 1 would be:
275
-
276
- ```
277
- gpg --verify ./openjd_cli-1.2.3-py3-none-any.whl.sig ./openjd_cli-1.2.3-py3-none-any.whl
278
- ```
180
+ See [VERIFYING_PGP_SIGNATURE](VERIFYING_PGP_SIGNATURE.md) for more information.
279
181
 
280
182
  ## Security
281
183
 
282
- See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information.
184
+ We take all security reports seriously. When we receive such reports, we will
185
+ investigate and subsequently address any potential vulnerabilities as quickly
186
+ as possible. If you discover a potential security issue in this project, please
187
+ notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/)
188
+ or directly via email to [AWS Security](aws-security@amazon.com). Please do not
189
+ create a public GitHub issue in this project.
283
190
 
284
191
  ## License
285
192
 
@@ -21,7 +21,7 @@ lint = [
21
21
  ]
22
22
 
23
23
  [[envs.all.matrix]]
24
- python = ["3.9", "3.10", "3.11"]
24
+ python = ["3.9", "3.10", "3.11", "3.12", "3.13"]
25
25
 
26
26
  [envs.codebuild.scripts]
27
27
  build = "hatch build"
@@ -1 +1,6 @@
1
1
  # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+
3
+ from .cli._create_argparser import main
4
+
5
+
6
+ main()
@@ -0,0 +1,5 @@
1
+ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+
3
+ from ._create_argparser import main
4
+
5
+ __all__ = ["main"]
@@ -1,7 +1,7 @@
1
1
  # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
2
 
3
3
  from .._common import add_common_arguments, CommonArgument, SubparserGroup
4
- from ._check_command import do_check
4
+ from ._check_command import add_check_arguments, do_check
5
5
 
6
6
 
7
7
  def populate_argparser(subcommands: SubparserGroup) -> None:
@@ -12,7 +12,7 @@ def populate_argparser(subcommands: SubparserGroup) -> None:
12
12
  description="Given an Open Job Description template file, parse the file and run validation checks against it to ensure that it is correctly formed.",
13
13
  )
14
14
 
15
- # `check` has no unique arguments;
16
15
  # add all arguments through `add_common_arguments`
17
16
  add_common_arguments(check_parser, {CommonArgument.PATH})
17
+ add_check_arguments(check_parser)
18
18
  check_parser.set_defaults(func=do_check)
@@ -1,6 +1,6 @@
1
1
  # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
2
 
3
- from argparse import Namespace
3
+ from argparse import ArgumentParser, Namespace
4
4
  from openjd.model import (
5
5
  DecodeValidationError,
6
6
  TemplateSpecificationVersion,
@@ -8,13 +8,25 @@ from openjd.model import (
8
8
  decode_environment_template,
9
9
  )
10
10
 
11
- from .._common import read_template, OpenJDCliResult, print_cli_result
11
+ from .._common import (
12
+ add_extensions_argument,
13
+ read_template,
14
+ OpenJDCliResult,
15
+ print_cli_result,
16
+ process_extensions_argument,
17
+ )
18
+
19
+
20
+ def add_check_arguments(run_parser: ArgumentParser):
21
+ add_extensions_argument(run_parser)
12
22
 
13
23
 
14
24
  @print_cli_result
15
25
  def do_check(args: Namespace) -> OpenJDCliResult:
16
26
  """Open a provided template file and check its schema for errors."""
17
27
 
28
+ extensions = process_extensions_argument(args.extensions)
29
+
18
30
  try:
19
31
  # Raises: RuntimeError
20
32
  template_object = read_template(args.path)
@@ -27,7 +39,7 @@ def do_check(args: Namespace) -> OpenJDCliResult:
27
39
 
28
40
  # Raises: DecodeValidationError
29
41
  if TemplateSpecificationVersion.is_job_template(template_version):
30
- decode_job_template(template=template_object)
42
+ decode_job_template(template=template_object, supported_extensions=extensions)
31
43
  elif TemplateSpecificationVersion.is_environment_template(template_version):
32
44
  decode_environment_template(template=template_object)
33
45
  else:
@@ -9,6 +9,7 @@ import json
9
9
  import yaml
10
10
  import os
11
11
 
12
+ from ._extensions import add_extensions_argument, process_extensions_argument
12
13
  from ._job_from_template import (
13
14
  job_from_template,
14
15
  get_job_params,
@@ -23,9 +24,11 @@ from ._validation_utils import (
23
24
  from openjd.model import DecodeValidationError, Job
24
25
 
25
26
  __all__ = [
27
+ "add_extensions_argument",
26
28
  "get_doc_type",
27
29
  "get_job_params",
28
30
  "get_params_from_file",
31
+ "process_extensions_argument",
29
32
  "read_template",
30
33
  "read_job_template",
31
34
  "read_environment_template",
@@ -109,10 +112,10 @@ class SubparserGroup:
109
112
  return self.group.add_parser(name, **kwargs)
110
113
 
111
114
 
112
- def generate_job(args: Namespace) -> Job:
115
+ def generate_job(args: Namespace, *, supported_extensions: list[str]) -> Job:
113
116
  try:
114
117
  # Raises: RuntimeError, DecodeValidationError
115
- template = read_job_template(args.path)
118
+ template = read_job_template(args.path, supported_extensions=supported_extensions)
116
119
  # Raises: RuntimeError
117
120
  return job_from_template(
118
121
  template,
@@ -0,0 +1,34 @@
1
+ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+
3
+ from argparse import ArgumentParser
4
+ from typing import Optional
5
+
6
+ # This is the list of Open Job Description extensions with implemented support
7
+ SUPPORTED_EXTENSIONS = ["TASK_CHUNKING"]
8
+
9
+
10
+ def add_extensions_argument(run_parser: ArgumentParser):
11
+ run_parser.add_argument(
12
+ "--extensions",
13
+ help=f"A comma-separated list of Open Job Description extension names to enable. Defaults to all that are implemented: {','.join(SUPPORTED_EXTENSIONS)}",
14
+ )
15
+
16
+
17
+ def process_extensions_argument(extensions: Optional[str]) -> list[str]:
18
+ """Process the comma-separated extensions argument and return a list of supported extensions."""
19
+
20
+ # If the option is not provided, default to all the supported extensions.
21
+ if extensions is None:
22
+ return SUPPORTED_EXTENSIONS
23
+
24
+ extensions_list = [
25
+ extension.strip().upper() for extension in extensions.split(",") if extension.strip() != ""
26
+ ]
27
+
28
+ unsupported_extensions = set(extensions_list) - set(SUPPORTED_EXTENSIONS)
29
+ if unsupported_extensions:
30
+ raise ValueError(
31
+ f"Unsupported Open Job Description extension(s): {', '.join(sorted(unsupported_extensions))}"
32
+ )
33
+
34
+ return extensions_list
@@ -53,7 +53,7 @@ def read_template(template_file: Path) -> dict[str, Any]:
53
53
  return template_object
54
54
 
55
55
 
56
- def read_job_template(template_file: Path) -> JobTemplate:
56
+ def read_job_template(template_file: Path, *, supported_extensions: list[str]) -> JobTemplate:
57
57
  """Open a JSON or YAML-formatted file and attempt to parse it into a JobTemplate object.
58
58
  Raises a RuntimeError if the file doesn't exist or can't be opened, and raises a
59
59
  DecodeValidationError if its contents can't be parsed into a valid JobTemplate.
@@ -62,7 +62,9 @@ def read_job_template(template_file: Path) -> JobTemplate:
62
62
  template_object = read_template(template_file)
63
63
 
64
64
  # Raises: DecodeValidationError
65
- template = decode_job_template(template=template_object)
65
+ template = decode_job_template(
66
+ template=template_object, supported_extensions=supported_extensions
67
+ )
66
68
 
67
69
  return template
68
70
 
@@ -1,6 +1,9 @@
1
1
  # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
2
 
3
3
  from argparse import ArgumentParser
4
+ import sys
5
+ import traceback
6
+ from typing import Optional
4
7
 
5
8
  from ._common import SubparserGroup
6
9
 
@@ -28,3 +31,21 @@ def create_argparser() -> ArgumentParser:
28
31
  populate_run_subparser(subcommands)
29
32
  populate_schema_subparser(subcommands)
30
33
  return parser
34
+
35
+
36
+ def main(arg_list: Optional[list[str]] = None) -> None:
37
+ """Main function for invoking the CLI"""
38
+ parser = create_argparser()
39
+
40
+ if arg_list is None:
41
+ arg_list = sys.argv[1:]
42
+
43
+ args = parser.parse_args(arg_list)
44
+ try:
45
+ # Raises:
46
+ # SystemExit - on failure
47
+ args.func(args)
48
+ except Exception as exc:
49
+ print(f"ERROR: {str(exc)}", file=sys.stderr)
50
+ traceback.print_exc()
51
+ sys.exit(1)
@@ -8,7 +8,7 @@ def populate_argparser(subcommands: SubparserGroup) -> None:
8
8
  """Adds the `run` command and all of its arguments to the given parser."""
9
9
  run_parser = subcommands.add(
10
10
  "run",
11
- description="Takes a Job Template and Step name, then runs Tasks from that Step.",
11
+ description="Takes a Job Template and runs the entire job or a selected Step from the job.",
12
12
  usage="openjd run JOB_TEMPLATE_PATH [arguments]",
13
13
  )
14
14
  add_common_arguments(run_parser, {CommonArgument.PATH, CommonArgument.JOB_PARAMS})
@@ -1,10 +1,27 @@
1
1
  # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
2
 
3
+ from enum import Enum
4
+
3
5
  from openjd.model import Step, TaskParameterSet
4
6
  from openjd.model.v2023_09 import Environment
5
7
  from openjd.sessions import Session
6
8
 
7
9
 
10
+ class EnvironmentType(str, Enum):
11
+ """
12
+ The three different types of environment types that can be entered/exited in a session.
13
+ """
14
+
15
+ EXTERNAL = "EXTERNAL"
16
+ JOB = "JOB"
17
+ STEP = "STEP"
18
+ ALL = "ALL"
19
+
20
+ def matches(self, other: "EnvironmentType") -> bool:
21
+ """Environment types match if they are equal, or one of them is ALL."""
22
+ return self == other or self == EnvironmentType.ALL or other == EnvironmentType.ALL
23
+
24
+
8
25
  class SessionAction:
9
26
  _session: Session
10
27
  duration: float
@@ -56,13 +73,17 @@ class EnterEnvironmentAction(SessionAction):
56
73
 
57
74
  class ExitEnvironmentAction(SessionAction):
58
75
  _id: str
76
+ _keep_session_running: bool
59
77
 
60
- def __init__(self, session: Session, id: str):
78
+ def __init__(self, session: Session, id: str, keep_session_running: bool):
61
79
  super(ExitEnvironmentAction, self).__init__(session)
62
80
  self._id = id
81
+ self._keep_session_running = keep_session_running
63
82
 
64
83
  def run(self):
65
- self._session.exit_environment(identifier=self._id)
84
+ self._session.exit_environment(
85
+ identifier=self._id, keep_session_running=self._keep_session_running
86
+ )
66
87
 
67
88
  def __str__(self):
68
89
  return f"Exit Environment '{self._id}'"
@@ -0,0 +1,80 @@
1
+ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+
3
+ from dataclasses import dataclass
4
+ from logging import Handler, LogRecord
5
+ from datetime import datetime, timezone
6
+ from enum import Enum
7
+
8
+
9
+ class LoggingTimestampFormat(str, Enum):
10
+ """
11
+ Different formats for the timestamp of each log entry
12
+ """
13
+
14
+ RELATIVE = "relative"
15
+ LOCAL = "local"
16
+ UTC = "utc"
17
+
18
+
19
+ @dataclass
20
+ class LogEntry:
21
+ """
22
+ Log information from a sample Session to return in a CLI result.
23
+ """
24
+
25
+ timestamp: str
26
+ message: str
27
+
28
+ def __str__(self) -> str:
29
+ return f"{self.timestamp}\t{self.message}"
30
+
31
+
32
+ class LocalSessionLogHandler(Handler):
33
+ """
34
+ A custom Handler that formats and records logs in a dataclass.
35
+ Used to print logs to `stdout` in real time while also storing
36
+ them in memory.
37
+
38
+ It prints a timestamp that is relative to the session start.
39
+ """
40
+
41
+ messages: list[LogEntry] = []
42
+ _should_print: bool
43
+ _session_start_timestamp: datetime
44
+ _timestamp_format: LoggingTimestampFormat
45
+
46
+ def __init__(
47
+ self,
48
+ should_print: bool,
49
+ session_start_timestamp: datetime,
50
+ timestamp_format: LoggingTimestampFormat,
51
+ ):
52
+ super(LocalSessionLogHandler, self).__init__()
53
+ self._should_print = should_print
54
+ self._session_start_timestamp = session_start_timestamp
55
+ self._timestamp_format = timestamp_format
56
+
57
+ def handle(self, record: LogRecord) -> bool:
58
+ if self._timestamp_format == LoggingTimestampFormat.RELATIVE:
59
+ timestamp = str(
60
+ datetime.fromtimestamp(record.created, timezone.utc) - self._session_start_timestamp
61
+ )
62
+ elif self._timestamp_format == LoggingTimestampFormat.LOCAL:
63
+ timestamp = str(
64
+ datetime.fromtimestamp(record.created, timezone.utc).astimezone().isoformat()
65
+ )
66
+ else:
67
+ timestamp = str(datetime.fromtimestamp(record.created, timezone.utc).isoformat())
68
+
69
+ record.created = datetime.fromtimestamp(record.created, timezone.utc).timestamp()
70
+ new_record = LogEntry(
71
+ timestamp=timestamp,
72
+ message=record.getMessage(),
73
+ )
74
+ self.messages.append(new_record)
75
+
76
+ if self._should_print:
77
+ print(new_record)
78
+
79
+ # No filters are applied to the message, so always return True
80
+ return True