idmtools-platform-container 0.0.0.dev0__py3-none-any.whl → 0.0.2__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 (71) hide show
  1. docker_image/BASE_VERSION +1 -0
  2. docker_image/Dockerfile +48 -0
  3. docker_image/Dockerfile_buildenv +46 -0
  4. docker_image/ImageName +1 -0
  5. docker_image/README.md +78 -0
  6. docker_image/__init__.py +6 -0
  7. docker_image/build_docker_image.py +145 -0
  8. docker_image/debian/BASE_VERSION +1 -0
  9. docker_image/debian/Dockerfile +40 -0
  10. docker_image/debian/ImageName +1 -0
  11. docker_image/debian/README.md +48 -0
  12. docker_image/debian/pip.conf +3 -0
  13. docker_image/debian/requirements.txt +1 -0
  14. docker_image/docker_image_history.py +101 -0
  15. docker_image/pip.conf +3 -0
  16. docker_image/push_docker_image.py +62 -0
  17. docker_image/requirements.txt +1 -0
  18. docker_image/rocky_meta_runtime.txt +37 -0
  19. idmtools_platform_container/__init__.py +18 -8
  20. idmtools_platform_container/cli/__init__.py +5 -0
  21. idmtools_platform_container/cli/container.py +682 -0
  22. idmtools_platform_container/container_operations/__init__.py +5 -0
  23. idmtools_platform_container/container_operations/docker_operations.py +593 -0
  24. idmtools_platform_container/container_platform.py +375 -0
  25. idmtools_platform_container/platform_operations/__init__.py +5 -0
  26. idmtools_platform_container/platform_operations/experiment_operations.py +112 -0
  27. idmtools_platform_container/platform_operations/simulation_operations.py +58 -0
  28. idmtools_platform_container/plugin_info.py +79 -0
  29. idmtools_platform_container/utils/__init__.py +5 -0
  30. idmtools_platform_container/utils/general.py +136 -0
  31. idmtools_platform_container/utils/status.py +130 -0
  32. idmtools_platform_container-0.0.2.dist-info/METADATA +212 -0
  33. idmtools_platform_container-0.0.2.dist-info/RECORD +69 -0
  34. idmtools_platform_container-0.0.2.dist-info/entry_points.txt +5 -0
  35. idmtools_platform_container-0.0.2.dist-info/licenses/LICENSE.TXT +3 -0
  36. {idmtools_platform_container-0.0.0.dev0.dist-info → idmtools_platform_container-0.0.2.dist-info}/top_level.txt +2 -0
  37. tests/inputs/Assets/MyLib/functions.py +2 -0
  38. tests/inputs/__init__.py +0 -0
  39. tests/inputs/model.py +28 -0
  40. tests/inputs/model1.py +31 -0
  41. tests/inputs/model3.py +21 -0
  42. tests/inputs/model_file.py +18 -0
  43. tests/inputs/run.sh +1 -0
  44. tests/inputs/sleep.py +9 -0
  45. tests/test_container_cli/__init__.py +0 -0
  46. tests/test_container_cli/helper.py +57 -0
  47. tests/test_container_cli/test_base.py +14 -0
  48. tests/test_container_cli/test_cancel.py +96 -0
  49. tests/test_container_cli/test_clear_results.py +54 -0
  50. tests/test_container_cli/test_container.py +72 -0
  51. tests/test_container_cli/test_file_container_cli.py +121 -0
  52. tests/test_container_cli/test_get_detail.py +60 -0
  53. tests/test_container_cli/test_history.py +136 -0
  54. tests/test_container_cli/test_history_count.py +53 -0
  55. tests/test_container_cli/test_inspect.py +53 -0
  56. tests/test_container_cli/test_install.py +48 -0
  57. tests/test_container_cli/test_is_running.py +69 -0
  58. tests/test_container_cli/test_jobs.py +138 -0
  59. tests/test_container_cli/test_list_containers.py +99 -0
  60. tests/test_container_cli/test_packages.py +41 -0
  61. tests/test_container_cli/test_path.py +96 -0
  62. tests/test_container_cli/test_ps.py +47 -0
  63. tests/test_container_cli/test_remove_container.py +78 -0
  64. tests/test_container_cli/test_status.py +149 -0
  65. tests/test_container_cli/test_stop_container.py +71 -0
  66. tests/test_container_cli/test_sync_history.py +98 -0
  67. tests/test_container_cli/test_verify_docker.py +28 -0
  68. tests/test_container_cli/test_volume.py +28 -0
  69. idmtools_platform_container-0.0.0.dev0.dist-info/METADATA +0 -41
  70. idmtools_platform_container-0.0.0.dev0.dist-info/RECORD +0 -5
  71. {idmtools_platform_container-0.0.0.dev0.dist-info → idmtools_platform_container-0.0.2.dist-info}/WHEEL +0 -0
@@ -0,0 +1,136 @@
1
+ """
2
+ Here we implement the ContainerPlatform utils.
3
+
4
+ Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
5
+ """
6
+ import os
7
+ import uuid
8
+ import math
9
+ from pathlib import Path
10
+ from typing import Union
11
+ from datetime import datetime
12
+ import platform as platform
13
+ from logging import getLogger
14
+
15
+ logger = getLogger(__name__)
16
+ user_logger = getLogger('user')
17
+
18
+
19
+ #############################
20
+ # Utility Functions
21
+ #############################
22
+
23
+ def normalize_path(path: Union[str, Path]):
24
+ """
25
+ Normalize the binding path to handle case insensitivity and path separators for Windows.
26
+ Args:
27
+ path (str): The path to normalize.
28
+ Returns:
29
+ str: The normalized path.
30
+ """
31
+ path = str(path)
32
+ if platform.system() == 'Windows':
33
+ path = path.lower()
34
+ path = os.path.normpath(path).replace('\\', '/')
35
+ return path.rstrip('/')
36
+
37
+
38
+ def map_container_path(source_binding, destination_binding, source_path) -> str:
39
+ """
40
+ Map a source path to its corresponding destination path within the container.
41
+ Args:
42
+ source_binding (str): The source directory in the binding (e.g., /abc/my_path).
43
+ destination_binding (str): The destination directory in the container (e.g., /home/my_path).
44
+ source_path (str): The source file or folder path to map (e.g., /abc/my_path/file_or_folder_path).
45
+ Returns:
46
+ str: The corresponding destination path within the container (e.g., /home/my_path/file_or_folder_path).
47
+
48
+ Raises:
49
+ ValueError: If the source path does not start with the source binding path.
50
+ """
51
+ source_path = str(source_path)
52
+ # Normalize binding paths
53
+ normalized_source_binding = normalize_path(source_binding)
54
+ normalized_source_path = normalize_path(source_path)
55
+
56
+ # Ensure the source path starts with the source binding
57
+ if not normalized_source_path.startswith(normalized_source_binding):
58
+ raise ValueError("Source path does not start with the source binding path")
59
+
60
+ # Compute the relative path from the source binding to the source path
61
+ relative_path = os.path.relpath(source_path, source_binding)
62
+
63
+ # Combine the destination binding with the relative path
64
+ destination_path = os.path.join(destination_binding, relative_path)
65
+
66
+ # Normalize the destination path to ensure proper path separators and convert to Unix-style path
67
+ destination_path = normalize_path(destination_path)
68
+
69
+ return destination_path
70
+
71
+
72
+ # Function to convert ISO 8601 format string to a datetime object
73
+ def parse_iso8601(date_str):
74
+ """
75
+ Convert an ISO 8601 format string to a datetime object.
76
+ Args:
77
+ date_str: time string in ISO 8601 format
78
+ Returns:
79
+ datetime object
80
+ """
81
+ # Truncate the fractional seconds to a maximum of 6 digits
82
+ if '.' in date_str:
83
+ date_str = date_str[:date_str.index('.') + 7] + 'Z'
84
+ return datetime.fromisoformat(date_str.replace('Z', '+00:00'))
85
+
86
+
87
+ def format_timestamp(timestamp) -> str:
88
+ """
89
+ Format the timestamp to a human-readable format.
90
+ Args:
91
+ timestamp: timestamp in ISO 8601 format
92
+ Returns:
93
+ Human-readable timestamp
94
+ """
95
+ # Remove the 'Z' at the end and truncate the fractional seconds to 6 digits
96
+ if timestamp.endswith('Z'):
97
+ timestamp = timestamp[:-1]
98
+ if '.' in timestamp:
99
+ timestamp = timestamp[:timestamp.index('.') + 7]
100
+ dt = datetime.strptime(timestamp, "%Y-%m-%dT%H:%M:%S.%f")
101
+ formatted_timestamp = dt.strftime("%Y-%m-%d %H:%M:%S")
102
+ return formatted_timestamp
103
+
104
+
105
+ def is_valid_uuid(uuid_to_test, version=4) -> bool:
106
+ """
107
+ Check if the provided string is a valid UUID.
108
+ Args:
109
+ uuid_to_test: UUID string to test
110
+ version: test against a specific UUID version
111
+ Returns:
112
+ True/False
113
+ """
114
+ try:
115
+ # check for validity of Uuid
116
+ _ = uuid.UUID(uuid_to_test, version=version)
117
+ return True
118
+ except ValueError:
119
+ return False
120
+
121
+
122
+ def convert_byte_size(size_bytes: int) -> str:
123
+ """
124
+ Convert byte size to human-readable.
125
+ Args:
126
+ size_bytes: byte site in integer
127
+ Returns:
128
+ str: human-readable size
129
+ """
130
+ if size_bytes == 0:
131
+ return "0B"
132
+ size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
133
+ i = int(math.floor(math.log(size_bytes, 1024)))
134
+ p = math.pow(1024, i)
135
+ s = round(size_bytes / p, 2)
136
+ return "%s %s" % (s, size_name[i])
@@ -0,0 +1,130 @@
1
+ """
2
+ Here we implement the ContainerPlatform status utils.
3
+
4
+ Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
5
+ """
6
+ import os
7
+ from rich.console import Console
8
+ from typing import List, NoReturn
9
+ from logging import getLogger
10
+ from idmtools_platform_container.utils.general import normalize_path
11
+
12
+ logger = getLogger(__name__)
13
+ user_logger = getLogger('user')
14
+
15
+ #############################
16
+ # Check Status
17
+ #############################
18
+
19
+ status_mapping = {
20
+ '0': 'SUCCEEDED',
21
+ '100': 'RUNNING',
22
+ '-1': 'FAILED'
23
+ }
24
+
25
+ FILE_NAME = 'job_status.txt'
26
+
27
+
28
+ def get_simulation_status(sim_path: str) -> str:
29
+ """
30
+ Get the status of a simulation.
31
+ Args:
32
+ sim_path: Simulation Directory Path
33
+ Returns:
34
+ simulation status
35
+ """
36
+ status_file_path = os.path.join(sim_path, FILE_NAME)
37
+
38
+ if os.path.isfile(status_file_path):
39
+ with open(status_file_path, 'r') as file:
40
+ content = file.read().strip()
41
+
42
+ status = status_mapping.get(content, 'Pending')
43
+ return status
44
+ else:
45
+ return 'Pending'
46
+
47
+
48
+ def append_with_limit(lst: List, item: str, limit: int) -> List:
49
+ """
50
+ Append an item to a list with a limit.
51
+ Args:
52
+ lst: list of items
53
+ item: item to be added
54
+ limit: max number of items in the list
55
+ Returns:
56
+ list: updated list
57
+ """
58
+ if len(lst) < limit:
59
+ lst.append(item)
60
+ elif len(lst) == limit:
61
+ lst.append('...')
62
+ return lst
63
+
64
+
65
+ def summarize_status_files(exp_dir: str, max_display: int = 10, verbose: bool = False) -> NoReturn:
66
+ """
67
+ Summarize the status of simulations.
68
+ Args:
69
+ exp_dir: Experiment Directory Path
70
+ max_display: the maximum number of items to display
71
+ verbose: whether to display the simulation details
72
+ Returns:
73
+ None
74
+ """
75
+ summary = {
76
+ 'SUCCEEDED': [],
77
+ 'RUNNING': [],
78
+ 'FAILED': [],
79
+ 'PENDING': []
80
+ }
81
+
82
+ counter = {
83
+ 'SUCCEEDED': 0,
84
+ 'RUNNING': 0,
85
+ 'FAILED': 0,
86
+ 'PENDING': 0
87
+ }
88
+
89
+ total_simulation_count = 0
90
+
91
+ # Traverse through all sub-folders in the given folder path
92
+ for sub_folder in os.listdir(exp_dir):
93
+ sub_folder_path = os.path.join(exp_dir, sub_folder)
94
+
95
+ if os.path.isdir(sub_folder_path):
96
+ # Check if the sub-folder contains metadata.json
97
+ if not os.path.exists(os.path.join(sub_folder_path, 'metadata.json')):
98
+ continue
99
+ total_simulation_count += 1
100
+ status_file_path = os.path.join(sub_folder_path, FILE_NAME)
101
+
102
+ if os.path.isfile(status_file_path):
103
+ with open(status_file_path, 'r') as file:
104
+ content = file.read().strip()
105
+
106
+ status = status_mapping.get(content, 'PENDING')
107
+ summary[status] = append_with_limit(summary[status], sub_folder, max_display)
108
+ counter[status] += 1
109
+ else:
110
+ summary['PENDING'] = append_with_limit(summary['PENDING'], sub_folder, max_display)
111
+ counter['PENDING'] += 1
112
+
113
+ # Print out the results
114
+ console = Console()
115
+ console.print(f'\n[bold][cyan]Experiment Directory[/][/]: \n{normalize_path(exp_dir)}\n')
116
+ console.print(f"[bold][cyan]Simulation Count[/][/]: [yellow]{total_simulation_count}[/]\n")
117
+
118
+ for status in ['SUCCEEDED', 'FAILED', 'RUNNING', 'PENDING']:
119
+ # console.print(f"{status} ({counter[status]})")
120
+ if status == 'SUCCEEDED':
121
+ console.print(f"[bold][green]{status}[/][/] ({counter[status]})")
122
+ elif status == 'FAILED':
123
+ console.print(f"[bold][red]{status}[/][/] ({counter[status]})")
124
+ elif status == 'RUNNING':
125
+ console.print(f"[bold][cyan]{status}[/][/] ({counter[status]})")
126
+ elif status == 'PENDING':
127
+ console.print(f"[bold][grey69]{status}[/][/] ({counter[status]})")
128
+ if verbose:
129
+ for sim in summary[status]:
130
+ console.print(f"{sim:>40}")
@@ -0,0 +1,212 @@
1
+ Metadata-Version: 2.4
2
+ Name: idmtools_platform_container
3
+ Version: 0.0.2
4
+ Summary: Container platform for IDM-Tools
5
+ Author-email: Zhaowei Du <zdu@idmod.org>, Sharon Chen <shchen@idmod.org>, Clinton Collins <ccollins@idmod.org>, Benoit Raybaud <braybaud@idmod.org>, Clark Kirkman IV <ckirkman@idmod.org>, Ye Chen <yechen@idmod.org>, Mary Fisher <mafisher@idmod.org>, Mandy Izzo <mizzo@idmod.org>, Jen Schripsema <jschripsema@idmod.org>, Ross Carter <rcarter@idmod.org>
6
+ Project-URL: Homepage, https://github.com/InstituteforDiseaseModeling/idmtools
7
+ Keywords: modeling,IDM
8
+ Classifier: Programming Language :: Python :: 3.8
9
+ Classifier: Programming Language :: Python :: 3.9
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Requires-Python: >=3.8
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE.TXT
16
+ Requires-Dist: idmtools_platform_general<1.0.0,>=0.0.0
17
+ Requires-Dist: docker>5.0
18
+ Requires-Dist: rich
19
+ Provides-Extra: test
20
+ Requires-Dist: idmtools[test]; extra == "test"
21
+ Requires-Dist: idmtools_test; extra == "test"
22
+ Requires-Dist: idmtools_models; extra == "test"
23
+ Provides-Extra: packaging
24
+ Requires-Dist: flake8; extra == "packaging"
25
+ Requires-Dist: coverage; extra == "packaging"
26
+ Requires-Dist: bump2version; extra == "packaging"
27
+ Requires-Dist: twine; extra == "packaging"
28
+ Requires-Dist: natsort; extra == "packaging"
29
+ Dynamic: license-file
30
+
31
+ ![Staging: idmtools-platform-container](https://github.com/InstituteforDiseaseModeling/idmtools/workflows/Staging:%20idmtools-platform-container/badge.svg?branch=dev)
32
+
33
+ # Idmtools platform container
34
+
35
+ <!-- START doctoc generated TOC please keep comment here to allow auto update -->
36
+ <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
37
+ **Table of Contents**
38
+
39
+ - [Introduction](#introduction)
40
+ - [Pre-requisites](#pre-requisites)
41
+ - [Installation](#installation)
42
+ - [Examples for container platform](#examples-for-container-platform)
43
+ - [Initialize platform](#initialize-platform)
44
+ - [Container Examples](#container-examples)
45
+ - [Check result with CLI commands](#check-result-with-cli-commands)
46
+ - [Check result files](#check-result-files)
47
+ - [Folder structure](#folder-structure)
48
+ - [Basic CLI commands](#basic-cli-commands)
49
+ - [List running jobs](#list-running-jobs)
50
+ - [Check status](#check-status)
51
+ - [Cancel job](#cancel-job)
52
+ - [View Experiments history](#view-experiments-history)
53
+ - [Note](#note)
54
+
55
+ <!-- END doctoc generated TOC please keep comment here to allow auto update -->
56
+
57
+ # Introduction
58
+
59
+ **ContainerPlatform** is a platform designed to facilitate the execution of experiments and simulations within Docker containers. It provides a robust environment with all necessary tools and dependencies installed, allowing for seamless integration and execution of computational tasks.
60
+
61
+ ## Pre-requisites
62
+ - Python 3.8/3.9/3.10/3.11/3.12 x64-bit
63
+ - OS:
64
+ - Windows 10 Pro or Enterprise
65
+ - Linux
66
+ - macOS (10.15 Catalina or later)
67
+ - Docker or Docker Desktop(required for the container platform)
68
+ On Windows, please use Docker Desktop 4.0.0 or later
69
+ - **Mac user**: Only support Intel based **x86_64** architecture if you want to run emodpy related disease models on **Docker** container platform. Apple based ARM architecture currently is not supported.
70
+
71
+ ## Installation
72
+
73
+ - **Install python**
74
+
75
+ Ensure you have Python 3.8+ installed on your system.
76
+
77
+ - Create and activate a virtual environment:
78
+ ```
79
+ python -m venv venv
80
+ source venv/bin/activate # On macOS/Linux
81
+ venv\Scripts\activate # On Windows
82
+ ```
83
+
84
+ - Install all **container** platform related packages
85
+ ```bash
86
+ pip install idmtools[container] --index-url=https://packages.idmod.org/api/pypi/pypi-production/simple
87
+ ```
88
+ - Optional: Install all **idmtools** packages
89
+ ```bash
90
+ pip install idmtools[full] --index-url=https://packages.idmod.org/api/pypi/pypi-production/simple
91
+ ```
92
+ - To **override** existing idmtools container related packages after installing emodpy, run this command
93
+ ```bash
94
+ pip install idmtools[container] --index-url=https://packages.idmod.org/api/pypi/pypi-production/simple --force-reinstall --no-cache-dir --upgrade
95
+ ```
96
+ **Mac user**: You map need to escape the square brackets with a backslash like `\[container\]` or `\[full\]` in above command.
97
+
98
+ - Extra steps for Windows user:
99
+ - Enable **Developer Mode** on Windows
100
+
101
+ If you are running the script on Windows, you need to enable Developer Mode. To enable Developer Mode, go to Settings -> Update & Security -> For developers and select Developer Mode on, or refer to this [guide](https://learn.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development).
102
+
103
+ - Enable **long file path** for Windows
104
+
105
+ Due to the file/folder structure design outlined in the section below, if running the script on Windows, be aware of the file path length limitation (less than 255 characters).
106
+
107
+ To allow longer file paths, you can enable Long Path Support in the Windows Group Policy Editor.
108
+ Refer to this [guide](https://www.autodesk.com/support/technical/article/caas/sfdcarticles/sfdcarticles/The-Windows-10-default-path-length-limitation-MAX-PATH-is-256-characters.html) for detailed instructions.
109
+
110
+ ## Examples for container platform
111
+
112
+ ### Initialize platform
113
+ - This is the example using Container Platform
114
+ ```python
115
+ from idmtools.core.platform_factory import Platform
116
+ platform = Platform('CONTAINER', job_directory='<user job directory>')
117
+ ```
118
+ - To trigger MPI, use ntasks >=2:
119
+ ```python
120
+ from idmtools.core.platform_factory import Platform
121
+ platform = Platform('CONTAINER', job_directory='<user job directory>', ntasks=2)
122
+ ```
123
+ - More options for container platform initialization:
124
+ refer to [ContainerPlatform attributes](hhttps://docs.idmod.org/projects/idmtools/en/latest/platforms/container/index.html#containerplatform-attributes)
125
+
126
+ ### Container Examples
127
+ - idmtools examples: https://github.com/InstituteforDiseaseModeling/idmtools/tree/main/examples/platform_container
128
+ - emodpy-malaria examples: https://github.com/EMOD-Hub/emodpy-malaria/tree/main/examples-container
129
+
130
+
131
+ ### Check result with CLI commands
132
+ ```bash
133
+ idmtools container status <experiment id>
134
+ ```
135
+ ### Check result files
136
+ - on host: `<job_directory>/<suite_path>/<experiment_path>/<simulation_path>/`
137
+ - in container: `/home/container-data/<suite_path>/<experiment_path>/<simulation_path>/`
138
+
139
+
140
+ ### Folder structure
141
+ By default, `idmtools` now generates simulations with the following structure:
142
+ `job_directory/s_<suite_name>_<suite_uuid>/e_<experiment_name>_<experiment_uuid>/simulation_uuid`
143
+ - `job_directory` — The base directory that contains all suite, experiment, and simulation folders.
144
+ - `s_<suite_name>_<suite_uuid>` — The suite directory, where the suite name (truncated to a maximum of 30 characters) is prefixed with s_, followed by its unique suite UUID.
145
+ - `e_<experiment_name>_<experiment_uuid>` — The experiment directory, where the experiment name (also truncated to 30 characters) is prefixed with e_, followed by its unique experiment UUID.
146
+ - `simulation_uuid` — The simulation folder identified only by its UUID.
147
+
148
+ Suite is optional. If the user does not specify a suite, the folder will be:
149
+ `job_directory/e_<experiment_name>_<experiment_uuid>/simulation_uuid`
150
+
151
+ Examples:
152
+
153
+ If you create a suite named: `my_very_long_suite_name_for_malaria_experiment`
154
+
155
+ and an experiment named: `test_experiment_with_calibration_phase`
156
+ `idmtools` will automatically truncate both names to a maximum of 30 characters and apply the prefixes s_ for suites and e_ for experiments, resulting in a path like:
157
+ ```
158
+ job_directory/
159
+ └── s_my_very_long_suite_name_for_m_12345678-9abc-def0-1234-56789abcdef0/
160
+ └── e_test_experiment_with_calibrati_abcd1234-5678-90ef-abcd-1234567890ef/
161
+ └── 7c9e6679-7425-40de-944b-e07fc1f90ae7/
162
+ ```
163
+
164
+ Or for no suite case:
165
+ ```
166
+ job_directory/
167
+ └── e_test_experiment_with_calibrati_abcd1234-5678-90ef-abcd-1234567890ef/
168
+ └── 7c9e6679-7425-40de-944b-e07fc1f90ae7/
169
+ ```
170
+
171
+ Users can customize this structure through the idmtools.ini configuration file:
172
+ - `name_directory = False` — Excludes the suite and experiment names (and their prefixes) from the simulation path.
173
+ - `sim_name_directory = True` — Includes the simulation name in the simulation folder path when name_directory = True.
174
+
175
+ ## Basic CLI commands
176
+
177
+ **ContainerPlatform** provides several CLI commands to manage and monitor experiments and simulations. Below are some basic commands:
178
+
179
+ ### List running jobs
180
+
181
+ To list running experiment or simulation jobs:
182
+ ```bash
183
+ idmtools container jobs [<container-id>] [-l <limit>] [-n <next>]
184
+ ```
185
+
186
+ ### Check status
187
+
188
+ To check the status of an experiment or simulation:
189
+ ```bash
190
+ idmtools container status <item-id> [-c <container_id>] [-l <limit>] [--verbose/--no-verbose]
191
+ ```
192
+
193
+ ### Cancel job
194
+
195
+ To cancel an experiment or simulation job:
196
+ ```bash
197
+ idmtools container cancel <item-id> [-c <container_id>]
198
+ ```
199
+
200
+ ### View Experiments history
201
+
202
+ To view experiments history:
203
+ ```bash
204
+ idmtools container history [<container-id>] [-l <limit>] [-n <next>]
205
+ ```
206
+
207
+
208
+ ## Note
209
+
210
+ - **WorkItem** is not supported on the Container Platform as it is not needed in most cases since the code already runs on user's local computer.
211
+ - **AssetCollection** creation or referencing to an existing AssetCollection are not supported on the Container Platform with current release. If you've used the COMPS Platform, you may have scripts using these objects. You would need to update these scripts without using these objects in order to run them on the Container Platform.
212
+ - Run with **Singularity** is not needed with Container Platform. If you take existing COMPS example and try to run it with Container Platform, you may need to remove the code that setups the singularity image.
@@ -0,0 +1,69 @@
1
+ docker_image/BASE_VERSION,sha256=iu1kK_URi508hZvUvjXsrHW26HPM4057b1VLBvdVUNc,3
2
+ docker_image/Dockerfile,sha256=x6io_BemPMYjb7CriX6BbQLGA-3zeOBE-sYY0PYP0hE,1471
3
+ docker_image/Dockerfile_buildenv,sha256=clHM8WLuGHqPX01ku9Xnku6fHYWsUSm0ECeGbsbSx7k,1304
4
+ docker_image/ImageName,sha256=z7uULwoWFVCcS6LaN05T5Fc1aZ9n-ZTGP2vcM9B3JUI,23
5
+ docker_image/README.md,sha256=8jXYYLGcJPecRv9mdYBBdp2d4I-08ia_CEa0A-rtqk4,4038
6
+ docker_image/__init__.py,sha256=tKN1Oxn8Y7VjaLoKeOviyb_MNrdyTru1NRkxaKWRyM8,130
7
+ docker_image/build_docker_image.py,sha256=MIrNJ-Q1CGT4uggM8g8l2YzK0hUq3skJ0l4zILVtLvY,6336
8
+ docker_image/docker_image_history.py,sha256=rxZDRTEuxKeImtwgrvUNE_CspOy1GkhHQ0bdSjWPTog,3204
9
+ docker_image/pip.conf,sha256=MhSPF_n4_RBgWzXantlhrNKlvSI9cVXevxI0IuJbBeM,122
10
+ docker_image/push_docker_image.py,sha256=auMAnZFagzD1S1rYf5HEly3sBWG497TC7JfcxVvRixc,2976
11
+ docker_image/requirements.txt,sha256=db9pK33GEypTjh9szgb2bGSG58iI7K6r15P-ORQKkd0,14
12
+ docker_image/rocky_meta_runtime.txt,sha256=7dkzlquXN2H9r4_4HWg9WyUM0_k51dizz-a2i1PbbCg,13366
13
+ docker_image/debian/BASE_VERSION,sha256=iu1kK_URi508hZvUvjXsrHW26HPM4057b1VLBvdVUNc,3
14
+ docker_image/debian/Dockerfile,sha256=8hTe0q3GKcyWFvmhCwua0BF9SVjFmdbIx-4JlchFpns,855
15
+ docker_image/debian/ImageName,sha256=pxh7Oi9ShDj7D4Tg543SPmn0PbKRgBU2SEvt65nRNr4,24
16
+ docker_image/debian/README.md,sha256=x7VmCKVtLTaewHCsomVvb8-FudB-TmULPSGXQbJSlQ0,1950
17
+ docker_image/debian/pip.conf,sha256=hKl-m_qBXwyQ3QU_lq5tber-7MVizUomo9Kxw5Snb-I,157
18
+ docker_image/debian/requirements.txt,sha256=hI7mG_x1qwwdbWPzTyfXgI_yHCs5IzMDXhNekia2IGg,15
19
+ idmtools_platform_container/__init__.py,sha256=VKbu2chvH-WEWNujss9GhaSg6Cg3XAhxz8wNGAUelIE,494
20
+ idmtools_platform_container/container_platform.py,sha256=ypbie6NDZsV0iDtaOItWQLpbaEWm2S2pUIUVKbek8qo,14566
21
+ idmtools_platform_container/plugin_info.py,sha256=Qt_AFxw6kM-tSNerAHjw_Tr9lPhPwjLf4c8MRApVFyY,2203
22
+ idmtools_platform_container/cli/__init__.py,sha256=oZS_5RXwYEXLC3T8c7MwQHDF4uc27NPT1wOt24C4K60,115
23
+ idmtools_platform_container/cli/container.py,sha256=mSSR_FZKw1X47isTd45b-IHvfQKjwwgNTzWd0pG0jmk,24909
24
+ idmtools_platform_container/container_operations/__init__.py,sha256=LHSc16p3SrzCtTxMWFa9dHsTm9dh8f_bkkvAADprTBE,132
25
+ idmtools_platform_container/container_operations/docker_operations.py,sha256=HE33V9EkdB5HD_PVW2sEBakv-1_9CTo939V8i4QebXg,21794
26
+ idmtools_platform_container/platform_operations/__init__.py,sha256=Qkbsx1fmWVBSrLjNv7F3BB39abweyLjdVbXDhXmJ5ao,139
27
+ idmtools_platform_container/platform_operations/experiment_operations.py,sha256=UvN_nCcGHQ0R4JzTNa22U0PAFRG-eqyEBHSvy0h9p5c,4286
28
+ idmtools_platform_container/platform_operations/simulation_operations.py,sha256=z4tVDbkySah9Sd0tHExxdqgRCAy4djSqheMDBQUkxOA,2183
29
+ idmtools_platform_container/utils/__init__.py,sha256=Qkbsx1fmWVBSrLjNv7F3BB39abweyLjdVbXDhXmJ5ao,139
30
+ idmtools_platform_container/utils/general.py,sha256=KDO5rSCV9cu_9bH1Cm71GMTkRdqON1EJim0oWW_TfQQ,4542
31
+ idmtools_platform_container/utils/status.py,sha256=NIsTYLqWemBRVn9GxR8e2xla8dLc5rTlo5FmPSHkvNc,4147
32
+ idmtools_platform_container-0.0.2.dist-info/licenses/LICENSE.TXT,sha256=l9S8Ydr_LcejxKoqK8191ZAOsmVX-nJLSPoLKZDUgcg,197
33
+ tests/inputs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
+ tests/inputs/model.py,sha256=cUm56BVt7KmbzNmyUl732CvC02SFRhyziDwOJTUIpTI,534
35
+ tests/inputs/model1.py,sha256=5NPHOFBZEagyeRlFagVIDCXJoorv83t3_HmCC_83byQ,645
36
+ tests/inputs/model3.py,sha256=21m0BFiyLKMM88pc7bK7U6J6Awu3jHX4gV-X4pudwxI,592
37
+ tests/inputs/model_file.py,sha256=UwYvw7DWzWI6DggsMglOlgkxvSbCFng0VL8QwGqDJi8,375
38
+ tests/inputs/run.sh,sha256=wypwLeCqUMa2EAm6AafKT79U0iRqtLIjF8XgKEhf1Dw,19
39
+ tests/inputs/sleep.py,sha256=gNPxSpDzETWSd8STl_Nvi1RnAYXJ0zWki9Rc40YTk1g,176
40
+ tests/inputs/Assets/MyLib/functions.py,sha256=kGM70PHGJHQbn-eQlLFerRQJm8s64G2-ybiiErX2Ssk,42
41
+ tests/test_container_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
+ tests/test_container_cli/helper.py,sha256=fVsKIGV9cpS5-8AshKZktn0eS7n78qrfX-WqGWIsoWY,1439
43
+ tests/test_container_cli/test_base.py,sha256=g27tFhv6Hfq1pwJmXQkJ6p3GxocZZ6zrvZKEEVsPh_g,432
44
+ tests/test_container_cli/test_cancel.py,sha256=OPACLDyqh1NoA0fJKYTdocCHJ4Vr2Y_Ujard7tkvdUo,4339
45
+ tests/test_container_cli/test_clear_results.py,sha256=_vkduO5KHKkSFOCDVdrCZ4uR1HbV1SduAZH3qzqho3M,2869
46
+ tests/test_container_cli/test_container.py,sha256=7qDQVYLrC0dn5r3oNqAV25K5ypiGn4rgpmfMbmoT2Yw,4100
47
+ tests/test_container_cli/test_file_container_cli.py,sha256=qMO6znb5CsZw4l69hjtmwBguiJ-pn6FdYgUuHHp0-NU,5647
48
+ tests/test_container_cli/test_get_detail.py,sha256=Loul9ZDEHGKGx2gaIf4IUT9Y5ewL20iKePVjBQT45WE,2777
49
+ tests/test_container_cli/test_history.py,sha256=Q9MSGcYc5moztc7MsJ6ihazKN5w3qHL9J53boWs7dUE,7449
50
+ tests/test_container_cli/test_history_count.py,sha256=YEDMLQuWI8I3GXIsS11ZvbA7To0wwRAaVk-Ax3t4dgc,2293
51
+ tests/test_container_cli/test_inspect.py,sha256=8fS-kNxIvHZBp5vA19Xw4BW6niuTDGhkjrQn44zrJjs,2593
52
+ tests/test_container_cli/test_install.py,sha256=Thvm5mS4NazDsGlTjgWzzwa2i9PHuMHw3RkQdo00w5s,2293
53
+ tests/test_container_cli/test_is_running.py,sha256=_EWymlD_ggs56KjNf9uPpHoSUtDwsAAX3vfgV-EB5aQ,3011
54
+ tests/test_container_cli/test_jobs.py,sha256=c1BzFmxx-evpqmKydlX-6iEiwLs52ZfqW1meUxO-e7Q,6178
55
+ tests/test_container_cli/test_list_containers.py,sha256=nLNSpa1e12t7JngX0W4NVhl7jIpqKFRQ64Vs-bAQpL0,4879
56
+ tests/test_container_cli/test_packages.py,sha256=wEvmrFgbl73H8d4faSlGY2FhQlNShnG5JEiKudKNl_E,1766
57
+ tests/test_container_cli/test_path.py,sha256=j2zrXUp8apL23H5uqrlceVA5o5AdzFM2FW3U2QDg_3U,5027
58
+ tests/test_container_cli/test_ps.py,sha256=YHikTOW1xbwYglXFx65DKNviLYoGWAiayQhQ70KmEQY,2127
59
+ tests/test_container_cli/test_remove_container.py,sha256=cN-RSudBTwCZcmZeLj6RsNTf4ljZ40pn2F0zXYiRaNE,4021
60
+ tests/test_container_cli/test_status.py,sha256=aTMW5PUcyqsBP5SRmraFY2AullEdWqnzjVFAL-Z3yqE,8848
61
+ tests/test_container_cli/test_stop_container.py,sha256=YDij_oVWS0yVE3sUgARVOVL1s7zmSEU3bhgCfKiStJs,3496
62
+ tests/test_container_cli/test_sync_history.py,sha256=cs4QhU1b_cVErU_5gAp8cPfhlxiQNCnUTwZY5qCAC44,4900
63
+ tests/test_container_cli/test_verify_docker.py,sha256=DadjUIUHQHqLEpqT-Kpv-xwS-tuwr_MuQEcWzI7Jo_o,1129
64
+ tests/test_container_cli/test_volume.py,sha256=06gyO4EbOTDluxqFnrArZSQxFX5qhJ60GDF-JLA1hFo,1088
65
+ idmtools_platform_container-0.0.2.dist-info/METADATA,sha256=BYSnsZ13SrWyo1XpXJVjBbDSqA10foBavZy9c0UUeeo,9941
66
+ idmtools_platform_container-0.0.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
67
+ idmtools_platform_container-0.0.2.dist-info/entry_points.txt,sha256=3gzJFC6SgI7l7irtXt9t8ahEo5zs8Yqh0lZBi2eurEo,213
68
+ idmtools_platform_container-0.0.2.dist-info/top_level.txt,sha256=iPMwxX4IWibuh2suAyZ-K9cdu4F84wVtSNijCEUjOE8,47
69
+ idmtools_platform_container-0.0.2.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ [idmtools_cli.cli_plugins]
2
+ container = idmtools_platform_container.cli.container:container
3
+
4
+ [idmtools_platform]
5
+ idmtools_platform_container = idmtools_platform_container.plugin_info:ContainerPlatformSpecification
@@ -0,0 +1,3 @@
1
+ idmtools is licensed under the Creative Commons Attribution-Noncommercial-ShareAlike 4.0 License.
2
+
3
+ To view a copy of this license, visit https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode
@@ -1 +1,3 @@
1
+ docker_image
1
2
  idmtools_platform_container
3
+ tests
@@ -0,0 +1,2 @@
1
+ def add(a: int, b: int):
2
+ return a + b
File without changes
tests/inputs/model.py ADDED
@@ -0,0 +1,28 @@
1
+ import ast
2
+ import astor
3
+
4
+
5
+ def main():
6
+ # Sample Python code
7
+ source_code = """
8
+ def add(a, b):
9
+ return a + b
10
+ """
11
+
12
+ # Parse the source code into an AST
13
+ tree = ast.parse(source_code)
14
+
15
+ # Dump the AST tree to a string
16
+ tree_str = astor.dump_tree(tree)
17
+
18
+ # File path to save the AST dump
19
+ file_path = 'ast_dump.txt'
20
+
21
+ # Write the AST string to a file
22
+ with open(file_path, 'w') as file:
23
+ file.write(tree_str)
24
+
25
+ print(f"AST dump written to {file_path}")
26
+
27
+ if __name__ == "__main__":
28
+ main()
tests/inputs/model1.py ADDED
@@ -0,0 +1,31 @@
1
+ import ast
2
+ import astor
3
+ import os
4
+ from pathlib import Path
5
+
6
+ def main():
7
+ # Sample Python code
8
+ source_code = """
9
+ def add(a, b):
10
+ return a + b
11
+ """
12
+
13
+ # Parse the source code into an AST
14
+ tree = ast.parse(source_code)
15
+
16
+ # Dump the AST tree to a string
17
+ tree_str = astor.dump_tree(tree)
18
+
19
+ # File path to save the AST dump
20
+ file_path = 'ast_dump.txt'
21
+
22
+ # Write the AST string to a file under output dir
23
+ os.makedirs("output", exist_ok=True)
24
+ with open(Path("output") / file_path, 'w') as file:
25
+ file.write(tree_str)
26
+
27
+ print(f"AST dump written to {file_path}")
28
+
29
+ if __name__ == "__main__":
30
+ main()
31
+
tests/inputs/model3.py ADDED
@@ -0,0 +1,21 @@
1
+ import os
2
+
3
+ from MyLib.functions import add
4
+ current_dir = os.path.abspath(os.getcwd())
5
+ if __name__ == "__main__":
6
+ import json
7
+
8
+ with open("config.json", 'r') as fp:
9
+ config = json.load(fp)
10
+ parameters = config["parameters"]
11
+
12
+ result = add(parameters["a"], parameters["b"])
13
+ print(result)
14
+ print(config["parameters"])
15
+
16
+ output_dir = os.path.join(current_dir, "output")
17
+ if not os.path.exists(output_dir):
18
+ os.mkdir(output_dir)
19
+ with open(os.path.join(output_dir, "result.txt"), "w") as fp:
20
+ fp.write("result:")
21
+ fp.write(str(result))
@@ -0,0 +1,18 @@
1
+ import os
2
+ import sys
3
+ import ast
4
+ import inspect
5
+
6
+ dir_path = os.path.dirname(__file__) # working
7
+ sys.path.append(os.path.join(dir_path, "site-packages")) # Need to site-packages level!!!
8
+
9
+ import astor
10
+
11
+
12
+ def dump_tree():
13
+ src = inspect.getsource(ast)
14
+ expr_ast = ast.parse(src)
15
+ print(astor.dump_tree(expr_ast)) # one line
16
+
17
+ if __name__ == "__main__":
18
+ dump_tree()