machineconfig 1.95__py3-none-any.whl → 1.96__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 machineconfig might be problematic. Click here for more details.

Files changed (499) hide show
  1. machineconfig/cluster/cloud_manager.py +445 -343
  2. machineconfig/cluster/data_transfer.py +63 -57
  3. machineconfig/cluster/distribute.py +284 -280
  4. machineconfig/cluster/file_manager.py +234 -237
  5. machineconfig/cluster/job_params.py +133 -133
  6. machineconfig/cluster/loader_runner.py +183 -149
  7. machineconfig/cluster/remote_machine.py +269 -252
  8. machineconfig/cluster/script_execution.py +215 -209
  9. machineconfig/cluster/script_notify_upon_completion.py +50 -43
  10. machineconfig/cluster/self_ssh.py +52 -54
  11. machineconfig/cluster/sessions_managers/__init__.py +0 -0
  12. machineconfig/cluster/sessions_managers/archive/__init__.py +0 -0
  13. machineconfig/{jobs/python → cluster/sessions_managers/archive}/create_zellij_template.py +5 -3
  14. machineconfig/cluster/sessions_managers/archive/session_managers.py +184 -0
  15. machineconfig/cluster/sessions_managers/demo_rich_zellij.py +0 -0
  16. machineconfig/cluster/sessions_managers/enhanced_command_runner.py +160 -0
  17. machineconfig/cluster/sessions_managers/wt_local.py +494 -0
  18. machineconfig/cluster/sessions_managers/wt_local_manager.py +577 -0
  19. machineconfig/cluster/sessions_managers/wt_remote.py +288 -0
  20. machineconfig/cluster/sessions_managers/wt_remote_manager.py +483 -0
  21. machineconfig/cluster/sessions_managers/wt_utils/layout_generator.py +196 -0
  22. machineconfig/cluster/sessions_managers/wt_utils/process_monitor.py +418 -0
  23. machineconfig/cluster/sessions_managers/wt_utils/remote_executor.py +175 -0
  24. machineconfig/cluster/sessions_managers/wt_utils/session_manager.py +300 -0
  25. machineconfig/cluster/sessions_managers/wt_utils/status_reporter.py +228 -0
  26. machineconfig/cluster/sessions_managers/zellij_local.py +418 -0
  27. machineconfig/cluster/sessions_managers/zellij_local_manager.py +533 -0
  28. machineconfig/cluster/sessions_managers/zellij_remote.py +229 -0
  29. machineconfig/cluster/sessions_managers/zellij_remote_manager.py +188 -0
  30. machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +64 -0
  31. machineconfig/cluster/sessions_managers/zellij_utils/layout_generator.py +126 -0
  32. machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +334 -0
  33. machineconfig/cluster/sessions_managers/zellij_utils/remote_executor.py +68 -0
  34. machineconfig/cluster/sessions_managers/zellij_utils/session_manager.py +119 -0
  35. machineconfig/cluster/sessions_managers/zellij_utils/status_reporter.py +85 -0
  36. machineconfig/cluster/templates/cli_click.py +0 -1
  37. machineconfig/cluster/templates/cli_gooey.py +102 -104
  38. machineconfig/cluster/templates/run_cloud.py +51 -51
  39. machineconfig/cluster/templates/run_cluster.py +103 -59
  40. machineconfig/cluster/templates/run_remote.py +57 -58
  41. machineconfig/cluster/templates/utils.py +69 -36
  42. machineconfig/jobs/__pycache__/__init__.cpython-311.pyc +0 -0
  43. machineconfig/jobs/python/__pycache__/__init__.cpython-311.pyc +0 -0
  44. machineconfig/jobs/python/check_installations.py +258 -190
  45. machineconfig/jobs/python/create_bootable_media.py +7 -3
  46. machineconfig/jobs/python/python_cargo_build_share.py +50 -50
  47. machineconfig/jobs/python/python_ve_symlink.py +6 -6
  48. machineconfig/jobs/python/vscode/__pycache__/select_interpreter.cpython-311.pyc +0 -0
  49. machineconfig/jobs/python/vscode/api.py +1 -1
  50. machineconfig/jobs/python/vscode/link_ve.py +2 -2
  51. machineconfig/jobs/python/vscode/select_interpreter.py +9 -5
  52. machineconfig/jobs/python/vscode/sync_code.py +8 -5
  53. machineconfig/jobs/python_custom_installers/__pycache__/__init__.cpython-311.pyc +0 -0
  54. machineconfig/jobs/python_custom_installers/archive/ngrok.py +1 -1
  55. machineconfig/jobs/python_custom_installers/dev/alacritty.py +3 -2
  56. machineconfig/jobs/python_custom_installers/dev/brave.py +7 -3
  57. machineconfig/jobs/python_custom_installers/dev/bypass_paywall.py +3 -4
  58. machineconfig/jobs/python_custom_installers/dev/code.py +3 -1
  59. machineconfig/jobs/python_custom_installers/dev/cursor.py +66 -5
  60. machineconfig/jobs/python_custom_installers/dev/docker_desktop.py +0 -1
  61. machineconfig/jobs/python_custom_installers/dev/espanso.py +13 -9
  62. machineconfig/jobs/python_custom_installers/dev/goes.py +2 -8
  63. machineconfig/jobs/python_custom_installers/dev/lvim.py +3 -2
  64. machineconfig/jobs/python_custom_installers/dev/nerdfont.py +1 -1
  65. machineconfig/jobs/python_custom_installers/dev/redis.py +7 -3
  66. machineconfig/jobs/python_custom_installers/dev/wezterm.py +8 -4
  67. machineconfig/jobs/python_custom_installers/dev/winget.py +194 -0
  68. machineconfig/jobs/python_custom_installers/{dev/docker.py → docker.py} +8 -3
  69. machineconfig/jobs/python_custom_installers/gh.py +4 -3
  70. machineconfig/jobs/python_custom_installers/hx.py +9 -8
  71. machineconfig/jobs/python_custom_installers/scripts/linux/vscode.sh +97 -30
  72. machineconfig/jobs/python_custom_installers/{dev/warp-cli.py → warp-cli.py} +1 -1
  73. machineconfig/jobs/python_generic_installers/__pycache__/__init__.cpython-311.pyc +0 -0
  74. machineconfig/jobs/python_generic_installers/config.json +133 -9
  75. machineconfig/jobs/python_generic_installers/dev/config.json +208 -37
  76. machineconfig/jobs/python_generic_installers/update.py +3 -0
  77. machineconfig/jobs/python_linux_installers/__pycache__/__init__.cpython-311.pyc +0 -0
  78. machineconfig/jobs/python_linux_installers/config.json +42 -6
  79. machineconfig/jobs/python_linux_installers/dev/config.json +79 -11
  80. machineconfig/jobs/python_windows_installers/config.json +6 -0
  81. machineconfig/profile/__pycache__/__init__.cpython-311.pyc +0 -0
  82. machineconfig/profile/__pycache__/create.cpython-311.pyc +0 -0
  83. machineconfig/profile/__pycache__/shell.cpython-311.pyc +0 -0
  84. machineconfig/profile/create.py +5 -5
  85. machineconfig/profile/create_hardlinks.py +5 -5
  86. machineconfig/profile/shell.py +44 -17
  87. machineconfig/scripts/__pycache__/__init__.cpython-311.pyc +0 -0
  88. machineconfig/scripts/__pycache__/__init__.cpython-313.pyc +0 -0
  89. machineconfig/scripts/linux/fire_agents +27 -0
  90. machineconfig/scripts/linux/wifi_conn +24 -0
  91. machineconfig/scripts/python/__pycache__/__init__.cpython-311.pyc +0 -0
  92. machineconfig/scripts/python/__pycache__/__init__.cpython-313.pyc +0 -0
  93. machineconfig/scripts/python/__pycache__/cloud_copy.cpython-311.pyc +0 -0
  94. machineconfig/scripts/python/__pycache__/cloud_mount.cpython-311.pyc +0 -0
  95. machineconfig/scripts/python/__pycache__/cloud_sync.cpython-311.pyc +0 -0
  96. machineconfig/scripts/python/__pycache__/croshell.cpython-311.pyc +0 -0
  97. machineconfig/scripts/python/__pycache__/devops.cpython-311.pyc +0 -0
  98. machineconfig/scripts/python/__pycache__/devops_backup_retrieve.cpython-311.pyc +0 -0
  99. machineconfig/scripts/python/__pycache__/devops_devapps_install.cpython-311.pyc +0 -0
  100. machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-311.pyc +0 -0
  101. machineconfig/scripts/python/__pycache__/fire_agents.cpython-311.pyc +0 -0
  102. machineconfig/scripts/python/__pycache__/fire_jobs.cpython-311.pyc +0 -0
  103. machineconfig/scripts/python/__pycache__/fire_jobs.cpython-313.pyc +0 -0
  104. machineconfig/scripts/python/__pycache__/get_zellij_cmd.cpython-311.pyc +0 -0
  105. machineconfig/scripts/python/__pycache__/repos.cpython-311.pyc +0 -0
  106. machineconfig/scripts/python/archive/im2text.py +1 -3
  107. machineconfig/scripts/python/choose_wezterm_theme.py +3 -3
  108. machineconfig/scripts/python/cloud_copy.py +10 -10
  109. machineconfig/scripts/python/cloud_manager.py +77 -99
  110. machineconfig/scripts/python/cloud_mount.py +13 -12
  111. machineconfig/scripts/python/cloud_repo_sync.py +14 -11
  112. machineconfig/scripts/python/croshell.py +24 -21
  113. machineconfig/scripts/python/devops.py +12 -17
  114. machineconfig/scripts/python/devops_add_identity.py +32 -10
  115. machineconfig/scripts/python/devops_add_ssh_key.py +10 -10
  116. machineconfig/scripts/python/devops_backup_retrieve.py +9 -8
  117. machineconfig/scripts/python/devops_devapps_install.py +6 -6
  118. machineconfig/scripts/python/devops_update_repos.py +4 -3
  119. machineconfig/scripts/python/dotfile.py +10 -7
  120. machineconfig/scripts/python/fire_agents.py +69 -0
  121. machineconfig/scripts/python/fire_jobs.py +56 -65
  122. machineconfig/scripts/python/ftpx.py +8 -8
  123. machineconfig/scripts/python/get_zellij_cmd.py +3 -3
  124. machineconfig/scripts/python/gh_models.py +6 -4
  125. machineconfig/scripts/python/helpers/__pycache__/__init__.cpython-311.pyc +0 -0
  126. machineconfig/scripts/python/helpers/__pycache__/__init__.cpython-313.pyc +0 -0
  127. machineconfig/scripts/python/helpers/__pycache__/cloud_helpers.cpython-311.pyc +0 -0
  128. machineconfig/scripts/python/helpers/__pycache__/helpers2.cpython-311.pyc +0 -0
  129. machineconfig/scripts/python/helpers/__pycache__/helpers4.cpython-311.pyc +0 -0
  130. machineconfig/scripts/python/helpers/__pycache__/helpers4.cpython-313.pyc +0 -0
  131. machineconfig/scripts/python/helpers/__pycache__/repo_sync_helpers.cpython-311.pyc +0 -0
  132. machineconfig/scripts/python/helpers/cloud_helpers.py +12 -12
  133. machineconfig/scripts/python/helpers/helpers2.py +9 -8
  134. machineconfig/scripts/python/helpers/helpers4.py +23 -35
  135. machineconfig/scripts/python/helpers/repo_sync_helpers.py +17 -16
  136. machineconfig/scripts/python/mount_nfs.py +8 -11
  137. machineconfig/scripts/python/mount_nw_drive.py +4 -4
  138. machineconfig/scripts/python/mount_ssh.py +2 -2
  139. machineconfig/scripts/python/onetimeshare.py +56 -57
  140. machineconfig/scripts/python/pomodoro.py +55 -55
  141. machineconfig/scripts/python/repos.py +26 -18
  142. machineconfig/scripts/python/scheduler.py +70 -53
  143. machineconfig/scripts/python/snapshot.py +21 -24
  144. machineconfig/scripts/python/start_slidev.py +6 -5
  145. machineconfig/scripts/python/start_terminals.py +3 -1
  146. machineconfig/scripts/python/viewer.py +5 -4
  147. machineconfig/scripts/python/viewer_template.py +138 -140
  148. machineconfig/scripts/python/wifi_conn.py +412 -60
  149. machineconfig/scripts/python/wsl_windows_transfer.py +18 -3
  150. machineconfig/settings/linters/.pylintrc +6 -7
  151. machineconfig/settings/lvim/windows/config.lua +0 -0
  152. machineconfig/settings/shells/bash/init.sh +6 -0
  153. machineconfig/settings/shells/ipy/profiles/default/startup/playext.py +7 -6
  154. machineconfig/settings/shells/pwsh/init.ps1 +6 -6
  155. machineconfig/settings/shells/wt/settings.json +51 -266
  156. machineconfig/setup_linux/web_shortcuts/interactive.sh +5 -2
  157. machineconfig/setup_windows/wt_and_pwsh/set_pwsh_theme.py +3 -6
  158. machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py +11 -9
  159. machineconfig/utils/ai/url2md.py +2 -2
  160. machineconfig/utils/cloud/onedrive/setup_oauth.py +59 -0
  161. machineconfig/utils/cloud/onedrive/transaction.py +796 -0
  162. machineconfig/utils/code.py +22 -13
  163. machineconfig/utils/installer.py +78 -35
  164. machineconfig/utils/installer_utils/installer_abc.py +7 -6
  165. machineconfig/utils/installer_utils/installer_class.py +44 -25
  166. machineconfig/utils/io_save.py +107 -0
  167. machineconfig/utils/links.py +19 -15
  168. machineconfig/utils/options.py +4 -8
  169. machineconfig/utils/path.py +91 -78
  170. machineconfig/utils/path_reduced.py +608 -0
  171. machineconfig/utils/procs.py +110 -45
  172. machineconfig/utils/scheduling.py +312 -222
  173. machineconfig/utils/utils.py +7 -7
  174. machineconfig/utils/utils2.py +42 -0
  175. machineconfig/utils/utils5.py +84 -0
  176. machineconfig/utils/ve.py +49 -87
  177. {machineconfig-1.95.dist-info → machineconfig-1.96.dist-info}/METADATA +2 -2
  178. machineconfig-1.96.dist-info/RECORD +437 -0
  179. machineconfig/cluster/session_managers.py +0 -183
  180. machineconfig/cluster/templates/f.py +0 -4
  181. machineconfig/jobs/python/__pycache__/check_installations.cpython-311.pyc +0 -0
  182. machineconfig/jobs/python/__pycache__/checkout_version.cpython-311.pyc +0 -0
  183. machineconfig/jobs/python/__pycache__/python_ve_symlink.cpython-311.pyc +0 -0
  184. machineconfig/jobs/python/checkout_version.py +0 -123
  185. machineconfig/jobs/python/vscode/__pycache__/api.cpython-311.pyc +0 -0
  186. machineconfig/jobs/python/vscode/__pycache__/link_ve.cpython-311.pyc +0 -0
  187. machineconfig/jobs/python_custom_installers/__pycache__/hx.cpython-311.pyc +0 -0
  188. machineconfig/jobs/python_windows_installers/__pycache__/__init__.cpython-311.pyc +0 -0
  189. machineconfig/scripts/python/.mypy_cache/.gitignore +0 -2
  190. machineconfig/scripts/python/.mypy_cache/3.11/@plugins_snapshot.json +0 -1
  191. machineconfig/scripts/python/.mypy_cache/3.11/__future__.data.json +0 -1
  192. machineconfig/scripts/python/.mypy_cache/3.11/__future__.meta.json +0 -1
  193. machineconfig/scripts/python/.mypy_cache/3.11/_ast.data.json +0 -1
  194. machineconfig/scripts/python/.mypy_cache/3.11/_ast.meta.json +0 -1
  195. machineconfig/scripts/python/.mypy_cache/3.11/_bz2.data.json +0 -1
  196. machineconfig/scripts/python/.mypy_cache/3.11/_bz2.meta.json +0 -1
  197. machineconfig/scripts/python/.mypy_cache/3.11/_codecs.data.json +0 -1
  198. machineconfig/scripts/python/.mypy_cache/3.11/_codecs.meta.json +0 -1
  199. machineconfig/scripts/python/.mypy_cache/3.11/_collections_abc.data.json +0 -1
  200. machineconfig/scripts/python/.mypy_cache/3.11/_collections_abc.meta.json +0 -1
  201. machineconfig/scripts/python/.mypy_cache/3.11/_compression.data.json +0 -1
  202. machineconfig/scripts/python/.mypy_cache/3.11/_compression.meta.json +0 -1
  203. machineconfig/scripts/python/.mypy_cache/3.11/_decimal.data.json +0 -1
  204. machineconfig/scripts/python/.mypy_cache/3.11/_decimal.meta.json +0 -1
  205. machineconfig/scripts/python/.mypy_cache/3.11/_frozen_importlib.data.json +0 -1
  206. machineconfig/scripts/python/.mypy_cache/3.11/_frozen_importlib.meta.json +0 -1
  207. machineconfig/scripts/python/.mypy_cache/3.11/_frozen_importlib_external.data.json +0 -1
  208. machineconfig/scripts/python/.mypy_cache/3.11/_frozen_importlib_external.meta.json +0 -1
  209. machineconfig/scripts/python/.mypy_cache/3.11/_io.data.json +0 -1
  210. machineconfig/scripts/python/.mypy_cache/3.11/_io.meta.json +0 -1
  211. machineconfig/scripts/python/.mypy_cache/3.11/_locale.data.json +0 -1
  212. machineconfig/scripts/python/.mypy_cache/3.11/_locale.meta.json +0 -1
  213. machineconfig/scripts/python/.mypy_cache/3.11/_stat.data.json +0 -1
  214. machineconfig/scripts/python/.mypy_cache/3.11/_stat.meta.json +0 -1
  215. machineconfig/scripts/python/.mypy_cache/3.11/_struct.data.json +0 -1
  216. machineconfig/scripts/python/.mypy_cache/3.11/_struct.meta.json +0 -1
  217. machineconfig/scripts/python/.mypy_cache/3.11/_thread.data.json +0 -1
  218. machineconfig/scripts/python/.mypy_cache/3.11/_thread.meta.json +0 -1
  219. machineconfig/scripts/python/.mypy_cache/3.11/_typeshed/__init__.data.json +0 -1
  220. machineconfig/scripts/python/.mypy_cache/3.11/_typeshed/__init__.meta.json +0 -1
  221. machineconfig/scripts/python/.mypy_cache/3.11/_typeshed/importlib.data.json +0 -1
  222. machineconfig/scripts/python/.mypy_cache/3.11/_typeshed/importlib.meta.json +0 -1
  223. machineconfig/scripts/python/.mypy_cache/3.11/_warnings.data.json +0 -1
  224. machineconfig/scripts/python/.mypy_cache/3.11/_warnings.meta.json +0 -1
  225. machineconfig/scripts/python/.mypy_cache/3.11/_weakref.data.json +0 -1
  226. machineconfig/scripts/python/.mypy_cache/3.11/_weakref.meta.json +0 -1
  227. machineconfig/scripts/python/.mypy_cache/3.11/_weakrefset.data.json +0 -1
  228. machineconfig/scripts/python/.mypy_cache/3.11/_weakrefset.meta.json +0 -1
  229. machineconfig/scripts/python/.mypy_cache/3.11/abc.data.json +0 -1
  230. machineconfig/scripts/python/.mypy_cache/3.11/abc.meta.json +0 -1
  231. machineconfig/scripts/python/.mypy_cache/3.11/argparse.data.json +0 -1
  232. machineconfig/scripts/python/.mypy_cache/3.11/argparse.meta.json +0 -1
  233. machineconfig/scripts/python/.mypy_cache/3.11/ast.data.json +0 -1
  234. machineconfig/scripts/python/.mypy_cache/3.11/ast.meta.json +0 -1
  235. machineconfig/scripts/python/.mypy_cache/3.11/binascii.data.json +0 -1
  236. machineconfig/scripts/python/.mypy_cache/3.11/binascii.meta.json +0 -1
  237. machineconfig/scripts/python/.mypy_cache/3.11/builtins.data.json +0 -1
  238. machineconfig/scripts/python/.mypy_cache/3.11/builtins.meta.json +0 -1
  239. machineconfig/scripts/python/.mypy_cache/3.11/bz2.data.json +0 -1
  240. machineconfig/scripts/python/.mypy_cache/3.11/bz2.meta.json +0 -1
  241. machineconfig/scripts/python/.mypy_cache/3.11/calendar.data.json +0 -1
  242. machineconfig/scripts/python/.mypy_cache/3.11/calendar.meta.json +0 -1
  243. machineconfig/scripts/python/.mypy_cache/3.11/codecs.data.json +0 -1
  244. machineconfig/scripts/python/.mypy_cache/3.11/codecs.meta.json +0 -1
  245. machineconfig/scripts/python/.mypy_cache/3.11/collections/__init__.data.json +0 -1
  246. machineconfig/scripts/python/.mypy_cache/3.11/collections/__init__.meta.json +0 -1
  247. machineconfig/scripts/python/.mypy_cache/3.11/collections/abc.data.json +0 -1
  248. machineconfig/scripts/python/.mypy_cache/3.11/collections/abc.meta.json +0 -1
  249. machineconfig/scripts/python/.mypy_cache/3.11/configparser.data.json +0 -1
  250. machineconfig/scripts/python/.mypy_cache/3.11/configparser.meta.json +0 -1
  251. machineconfig/scripts/python/.mypy_cache/3.11/contextlib.data.json +0 -1
  252. machineconfig/scripts/python/.mypy_cache/3.11/contextlib.meta.json +0 -1
  253. machineconfig/scripts/python/.mypy_cache/3.11/dataclasses.data.json +0 -1
  254. machineconfig/scripts/python/.mypy_cache/3.11/dataclasses.meta.json +0 -1
  255. machineconfig/scripts/python/.mypy_cache/3.11/datetime.data.json +0 -1
  256. machineconfig/scripts/python/.mypy_cache/3.11/datetime.meta.json +0 -1
  257. machineconfig/scripts/python/.mypy_cache/3.11/decimal.data.json +0 -1
  258. machineconfig/scripts/python/.mypy_cache/3.11/decimal.meta.json +0 -1
  259. machineconfig/scripts/python/.mypy_cache/3.11/dis.data.json +0 -1
  260. machineconfig/scripts/python/.mypy_cache/3.11/dis.meta.json +0 -1
  261. machineconfig/scripts/python/.mypy_cache/3.11/email/__init__.data.json +0 -1
  262. machineconfig/scripts/python/.mypy_cache/3.11/email/__init__.meta.json +0 -1
  263. machineconfig/scripts/python/.mypy_cache/3.11/email/_policybase.data.json +0 -1
  264. machineconfig/scripts/python/.mypy_cache/3.11/email/_policybase.meta.json +0 -1
  265. machineconfig/scripts/python/.mypy_cache/3.11/email/charset.data.json +0 -1
  266. machineconfig/scripts/python/.mypy_cache/3.11/email/charset.meta.json +0 -1
  267. machineconfig/scripts/python/.mypy_cache/3.11/email/contentmanager.data.json +0 -1
  268. machineconfig/scripts/python/.mypy_cache/3.11/email/contentmanager.meta.json +0 -1
  269. machineconfig/scripts/python/.mypy_cache/3.11/email/errors.data.json +0 -1
  270. machineconfig/scripts/python/.mypy_cache/3.11/email/errors.meta.json +0 -1
  271. machineconfig/scripts/python/.mypy_cache/3.11/email/header.data.json +0 -1
  272. machineconfig/scripts/python/.mypy_cache/3.11/email/header.meta.json +0 -1
  273. machineconfig/scripts/python/.mypy_cache/3.11/email/message.data.json +0 -1
  274. machineconfig/scripts/python/.mypy_cache/3.11/email/message.meta.json +0 -1
  275. machineconfig/scripts/python/.mypy_cache/3.11/email/policy.data.json +0 -1
  276. machineconfig/scripts/python/.mypy_cache/3.11/email/policy.meta.json +0 -1
  277. machineconfig/scripts/python/.mypy_cache/3.11/enum.data.json +0 -1
  278. machineconfig/scripts/python/.mypy_cache/3.11/enum.meta.json +0 -1
  279. machineconfig/scripts/python/.mypy_cache/3.11/fnmatch.data.json +0 -1
  280. machineconfig/scripts/python/.mypy_cache/3.11/fnmatch.meta.json +0 -1
  281. machineconfig/scripts/python/.mypy_cache/3.11/functools.data.json +0 -1
  282. machineconfig/scripts/python/.mypy_cache/3.11/functools.meta.json +0 -1
  283. machineconfig/scripts/python/.mypy_cache/3.11/gc.data.json +0 -1
  284. machineconfig/scripts/python/.mypy_cache/3.11/gc.meta.json +0 -1
  285. machineconfig/scripts/python/.mypy_cache/3.11/genericpath.data.json +0 -1
  286. machineconfig/scripts/python/.mypy_cache/3.11/genericpath.meta.json +0 -1
  287. machineconfig/scripts/python/.mypy_cache/3.11/getpass.data.json +0 -1
  288. machineconfig/scripts/python/.mypy_cache/3.11/getpass.meta.json +0 -1
  289. machineconfig/scripts/python/.mypy_cache/3.11/git/__init__.data.json +0 -1
  290. machineconfig/scripts/python/.mypy_cache/3.11/git/__init__.meta.json +0 -1
  291. machineconfig/scripts/python/.mypy_cache/3.11/git/cmd.data.json +0 -1
  292. machineconfig/scripts/python/.mypy_cache/3.11/git/cmd.meta.json +0 -1
  293. machineconfig/scripts/python/.mypy_cache/3.11/git/compat.data.json +0 -1
  294. machineconfig/scripts/python/.mypy_cache/3.11/git/compat.meta.json +0 -1
  295. machineconfig/scripts/python/.mypy_cache/3.11/git/config.data.json +0 -1
  296. machineconfig/scripts/python/.mypy_cache/3.11/git/config.meta.json +0 -1
  297. machineconfig/scripts/python/.mypy_cache/3.11/git/db.data.json +0 -1
  298. machineconfig/scripts/python/.mypy_cache/3.11/git/db.meta.json +0 -1
  299. machineconfig/scripts/python/.mypy_cache/3.11/git/diff.data.json +0 -1
  300. machineconfig/scripts/python/.mypy_cache/3.11/git/diff.meta.json +0 -1
  301. machineconfig/scripts/python/.mypy_cache/3.11/git/exc.data.json +0 -1
  302. machineconfig/scripts/python/.mypy_cache/3.11/git/exc.meta.json +0 -1
  303. machineconfig/scripts/python/.mypy_cache/3.11/git/index/__init__.data.json +0 -1
  304. machineconfig/scripts/python/.mypy_cache/3.11/git/index/__init__.meta.json +0 -1
  305. machineconfig/scripts/python/.mypy_cache/3.11/git/index/base.data.json +0 -1
  306. machineconfig/scripts/python/.mypy_cache/3.11/git/index/base.meta.json +0 -1
  307. machineconfig/scripts/python/.mypy_cache/3.11/git/index/fun.data.json +0 -1
  308. machineconfig/scripts/python/.mypy_cache/3.11/git/index/fun.meta.json +0 -1
  309. machineconfig/scripts/python/.mypy_cache/3.11/git/index/typ.data.json +0 -1
  310. machineconfig/scripts/python/.mypy_cache/3.11/git/index/typ.meta.json +0 -1
  311. machineconfig/scripts/python/.mypy_cache/3.11/git/index/util.data.json +0 -1
  312. machineconfig/scripts/python/.mypy_cache/3.11/git/index/util.meta.json +0 -1
  313. machineconfig/scripts/python/.mypy_cache/3.11/git/objects/__init__.data.json +0 -1
  314. machineconfig/scripts/python/.mypy_cache/3.11/git/objects/__init__.meta.json +0 -1
  315. machineconfig/scripts/python/.mypy_cache/3.11/git/objects/base.data.json +0 -1
  316. machineconfig/scripts/python/.mypy_cache/3.11/git/objects/base.meta.json +0 -1
  317. machineconfig/scripts/python/.mypy_cache/3.11/git/objects/blob.data.json +0 -1
  318. machineconfig/scripts/python/.mypy_cache/3.11/git/objects/blob.meta.json +0 -1
  319. machineconfig/scripts/python/.mypy_cache/3.11/git/objects/commit.data.json +0 -1
  320. machineconfig/scripts/python/.mypy_cache/3.11/git/objects/commit.meta.json +0 -1
  321. machineconfig/scripts/python/.mypy_cache/3.11/git/objects/fun.data.json +0 -1
  322. machineconfig/scripts/python/.mypy_cache/3.11/git/objects/fun.meta.json +0 -1
  323. machineconfig/scripts/python/.mypy_cache/3.11/git/objects/submodule/__init__.data.json +0 -1
  324. machineconfig/scripts/python/.mypy_cache/3.11/git/objects/submodule/__init__.meta.json +0 -1
  325. machineconfig/scripts/python/.mypy_cache/3.11/git/objects/submodule/base.data.json +0 -1
  326. machineconfig/scripts/python/.mypy_cache/3.11/git/objects/submodule/base.meta.json +0 -1
  327. machineconfig/scripts/python/.mypy_cache/3.11/git/objects/submodule/root.data.json +0 -1
  328. machineconfig/scripts/python/.mypy_cache/3.11/git/objects/submodule/root.meta.json +0 -1
  329. machineconfig/scripts/python/.mypy_cache/3.11/git/objects/submodule/util.data.json +0 -1
  330. machineconfig/scripts/python/.mypy_cache/3.11/git/objects/submodule/util.meta.json +0 -1
  331. machineconfig/scripts/python/.mypy_cache/3.11/git/objects/tag.data.json +0 -1
  332. machineconfig/scripts/python/.mypy_cache/3.11/git/objects/tag.meta.json +0 -1
  333. machineconfig/scripts/python/.mypy_cache/3.11/git/objects/tree.data.json +0 -1
  334. machineconfig/scripts/python/.mypy_cache/3.11/git/objects/tree.meta.json +0 -1
  335. machineconfig/scripts/python/.mypy_cache/3.11/git/objects/util.data.json +0 -1
  336. machineconfig/scripts/python/.mypy_cache/3.11/git/objects/util.meta.json +0 -1
  337. machineconfig/scripts/python/.mypy_cache/3.11/git/refs/__init__.data.json +0 -1
  338. machineconfig/scripts/python/.mypy_cache/3.11/git/refs/__init__.meta.json +0 -1
  339. machineconfig/scripts/python/.mypy_cache/3.11/git/refs/head.data.json +0 -1
  340. machineconfig/scripts/python/.mypy_cache/3.11/git/refs/head.meta.json +0 -1
  341. machineconfig/scripts/python/.mypy_cache/3.11/git/refs/log.data.json +0 -1
  342. machineconfig/scripts/python/.mypy_cache/3.11/git/refs/log.meta.json +0 -1
  343. machineconfig/scripts/python/.mypy_cache/3.11/git/refs/reference.data.json +0 -1
  344. machineconfig/scripts/python/.mypy_cache/3.11/git/refs/reference.meta.json +0 -1
  345. machineconfig/scripts/python/.mypy_cache/3.11/git/refs/remote.data.json +0 -1
  346. machineconfig/scripts/python/.mypy_cache/3.11/git/refs/remote.meta.json +0 -1
  347. machineconfig/scripts/python/.mypy_cache/3.11/git/refs/symbolic.data.json +0 -1
  348. machineconfig/scripts/python/.mypy_cache/3.11/git/refs/symbolic.meta.json +0 -1
  349. machineconfig/scripts/python/.mypy_cache/3.11/git/refs/tag.data.json +0 -1
  350. machineconfig/scripts/python/.mypy_cache/3.11/git/refs/tag.meta.json +0 -1
  351. machineconfig/scripts/python/.mypy_cache/3.11/git/remote.data.json +0 -1
  352. machineconfig/scripts/python/.mypy_cache/3.11/git/remote.meta.json +0 -1
  353. machineconfig/scripts/python/.mypy_cache/3.11/git/repo/__init__.data.json +0 -1
  354. machineconfig/scripts/python/.mypy_cache/3.11/git/repo/__init__.meta.json +0 -1
  355. machineconfig/scripts/python/.mypy_cache/3.11/git/repo/base.data.json +0 -1
  356. machineconfig/scripts/python/.mypy_cache/3.11/git/repo/base.meta.json +0 -1
  357. machineconfig/scripts/python/.mypy_cache/3.11/git/repo/fun.data.json +0 -1
  358. machineconfig/scripts/python/.mypy_cache/3.11/git/repo/fun.meta.json +0 -1
  359. machineconfig/scripts/python/.mypy_cache/3.11/git/types.data.json +0 -1
  360. machineconfig/scripts/python/.mypy_cache/3.11/git/types.meta.json +0 -1
  361. machineconfig/scripts/python/.mypy_cache/3.11/git/util.data.json +0 -1
  362. machineconfig/scripts/python/.mypy_cache/3.11/git/util.meta.json +0 -1
  363. machineconfig/scripts/python/.mypy_cache/3.11/glob.data.json +0 -1
  364. machineconfig/scripts/python/.mypy_cache/3.11/glob.meta.json +0 -1
  365. machineconfig/scripts/python/.mypy_cache/3.11/gzip.data.json +0 -1
  366. machineconfig/scripts/python/.mypy_cache/3.11/gzip.meta.json +0 -1
  367. machineconfig/scripts/python/.mypy_cache/3.11/importlib/__init__.data.json +0 -1
  368. machineconfig/scripts/python/.mypy_cache/3.11/importlib/__init__.meta.json +0 -1
  369. machineconfig/scripts/python/.mypy_cache/3.11/importlib/_abc.data.json +0 -1
  370. machineconfig/scripts/python/.mypy_cache/3.11/importlib/_abc.meta.json +0 -1
  371. machineconfig/scripts/python/.mypy_cache/3.11/importlib/_bootstrap.data.json +0 -1
  372. machineconfig/scripts/python/.mypy_cache/3.11/importlib/_bootstrap.meta.json +0 -1
  373. machineconfig/scripts/python/.mypy_cache/3.11/importlib/_bootstrap_external.data.json +0 -1
  374. machineconfig/scripts/python/.mypy_cache/3.11/importlib/_bootstrap_external.meta.json +0 -1
  375. machineconfig/scripts/python/.mypy_cache/3.11/importlib/abc.data.json +0 -1
  376. machineconfig/scripts/python/.mypy_cache/3.11/importlib/abc.meta.json +0 -1
  377. machineconfig/scripts/python/.mypy_cache/3.11/importlib/machinery.data.json +0 -1
  378. machineconfig/scripts/python/.mypy_cache/3.11/importlib/machinery.meta.json +0 -1
  379. machineconfig/scripts/python/.mypy_cache/3.11/importlib/metadata/__init__.data.json +0 -1
  380. machineconfig/scripts/python/.mypy_cache/3.11/importlib/metadata/__init__.meta.json +0 -1
  381. machineconfig/scripts/python/.mypy_cache/3.11/importlib/metadata/_meta.data.json +0 -1
  382. machineconfig/scripts/python/.mypy_cache/3.11/importlib/metadata/_meta.meta.json +0 -1
  383. machineconfig/scripts/python/.mypy_cache/3.11/importlib/readers.data.json +0 -1
  384. machineconfig/scripts/python/.mypy_cache/3.11/importlib/readers.meta.json +0 -1
  385. machineconfig/scripts/python/.mypy_cache/3.11/importlib/resources/__init__.data.json +0 -1
  386. machineconfig/scripts/python/.mypy_cache/3.11/importlib/resources/__init__.meta.json +0 -1
  387. machineconfig/scripts/python/.mypy_cache/3.11/importlib/resources/_common.data.json +0 -1
  388. machineconfig/scripts/python/.mypy_cache/3.11/importlib/resources/_common.meta.json +0 -1
  389. machineconfig/scripts/python/.mypy_cache/3.11/importlib/resources/abc.data.json +0 -1
  390. machineconfig/scripts/python/.mypy_cache/3.11/importlib/resources/abc.meta.json +0 -1
  391. machineconfig/scripts/python/.mypy_cache/3.11/inspect.data.json +0 -1
  392. machineconfig/scripts/python/.mypy_cache/3.11/inspect.meta.json +0 -1
  393. machineconfig/scripts/python/.mypy_cache/3.11/io.data.json +0 -1
  394. machineconfig/scripts/python/.mypy_cache/3.11/io.meta.json +0 -1
  395. machineconfig/scripts/python/.mypy_cache/3.11/itertools.data.json +0 -1
  396. machineconfig/scripts/python/.mypy_cache/3.11/itertools.meta.json +0 -1
  397. machineconfig/scripts/python/.mypy_cache/3.11/locale.data.json +0 -1
  398. machineconfig/scripts/python/.mypy_cache/3.11/locale.meta.json +0 -1
  399. machineconfig/scripts/python/.mypy_cache/3.11/logging/__init__.data.json +0 -1
  400. machineconfig/scripts/python/.mypy_cache/3.11/logging/__init__.meta.json +0 -1
  401. machineconfig/scripts/python/.mypy_cache/3.11/mimetypes.data.json +0 -1
  402. machineconfig/scripts/python/.mypy_cache/3.11/mimetypes.meta.json +0 -1
  403. machineconfig/scripts/python/.mypy_cache/3.11/mmap.data.json +0 -1
  404. machineconfig/scripts/python/.mypy_cache/3.11/mmap.meta.json +0 -1
  405. machineconfig/scripts/python/.mypy_cache/3.11/numbers.data.json +0 -1
  406. machineconfig/scripts/python/.mypy_cache/3.11/numbers.meta.json +0 -1
  407. machineconfig/scripts/python/.mypy_cache/3.11/opcode.data.json +0 -1
  408. machineconfig/scripts/python/.mypy_cache/3.11/opcode.meta.json +0 -1
  409. machineconfig/scripts/python/.mypy_cache/3.11/os/__init__.data.json +0 -1
  410. machineconfig/scripts/python/.mypy_cache/3.11/os/__init__.meta.json +0 -1
  411. machineconfig/scripts/python/.mypy_cache/3.11/os/path.data.json +0 -1
  412. machineconfig/scripts/python/.mypy_cache/3.11/os/path.meta.json +0 -1
  413. machineconfig/scripts/python/.mypy_cache/3.11/pathlib.data.json +0 -1
  414. machineconfig/scripts/python/.mypy_cache/3.11/pathlib.meta.json +0 -1
  415. machineconfig/scripts/python/.mypy_cache/3.11/platform.data.json +0 -1
  416. machineconfig/scripts/python/.mypy_cache/3.11/platform.meta.json +0 -1
  417. machineconfig/scripts/python/.mypy_cache/3.11/posixpath.data.json +0 -1
  418. machineconfig/scripts/python/.mypy_cache/3.11/posixpath.meta.json +0 -1
  419. machineconfig/scripts/python/.mypy_cache/3.11/re.data.json +0 -1
  420. machineconfig/scripts/python/.mypy_cache/3.11/re.meta.json +0 -1
  421. machineconfig/scripts/python/.mypy_cache/3.11/resource.data.json +0 -1
  422. machineconfig/scripts/python/.mypy_cache/3.11/resource.meta.json +0 -1
  423. machineconfig/scripts/python/.mypy_cache/3.11/shlex.data.json +0 -1
  424. machineconfig/scripts/python/.mypy_cache/3.11/shlex.meta.json +0 -1
  425. machineconfig/scripts/python/.mypy_cache/3.11/shutil.data.json +0 -1
  426. machineconfig/scripts/python/.mypy_cache/3.11/shutil.meta.json +0 -1
  427. machineconfig/scripts/python/.mypy_cache/3.11/signal.data.json +0 -1
  428. machineconfig/scripts/python/.mypy_cache/3.11/signal.meta.json +0 -1
  429. machineconfig/scripts/python/.mypy_cache/3.11/src/__init__.data.json +0 -1
  430. machineconfig/scripts/python/.mypy_cache/3.11/src/__init__.meta.json +0 -1
  431. machineconfig/scripts/python/.mypy_cache/3.11/src/machineconfig/__init__.data.json +0 -1
  432. machineconfig/scripts/python/.mypy_cache/3.11/src/machineconfig/__init__.meta.json +0 -1
  433. machineconfig/scripts/python/.mypy_cache/3.11/src/machineconfig/scripts/__init__.data.json +0 -1
  434. machineconfig/scripts/python/.mypy_cache/3.11/src/machineconfig/scripts/__init__.meta.json +0 -1
  435. machineconfig/scripts/python/.mypy_cache/3.11/src/machineconfig/scripts/python/__init__.data.json +0 -1
  436. machineconfig/scripts/python/.mypy_cache/3.11/src/machineconfig/scripts/python/__init__.meta.json +0 -1
  437. machineconfig/scripts/python/.mypy_cache/3.11/sre_compile.data.json +0 -1
  438. machineconfig/scripts/python/.mypy_cache/3.11/sre_compile.meta.json +0 -1
  439. machineconfig/scripts/python/.mypy_cache/3.11/sre_constants.data.json +0 -1
  440. machineconfig/scripts/python/.mypy_cache/3.11/sre_constants.meta.json +0 -1
  441. machineconfig/scripts/python/.mypy_cache/3.11/sre_parse.data.json +0 -1
  442. machineconfig/scripts/python/.mypy_cache/3.11/sre_parse.meta.json +0 -1
  443. machineconfig/scripts/python/.mypy_cache/3.11/stat.data.json +0 -1
  444. machineconfig/scripts/python/.mypy_cache/3.11/stat.meta.json +0 -1
  445. machineconfig/scripts/python/.mypy_cache/3.11/string.data.json +0 -1
  446. machineconfig/scripts/python/.mypy_cache/3.11/string.meta.json +0 -1
  447. machineconfig/scripts/python/.mypy_cache/3.11/struct.data.json +0 -1
  448. machineconfig/scripts/python/.mypy_cache/3.11/struct.meta.json +0 -1
  449. machineconfig/scripts/python/.mypy_cache/3.11/subprocess.data.json +0 -1
  450. machineconfig/scripts/python/.mypy_cache/3.11/subprocess.meta.json +0 -1
  451. machineconfig/scripts/python/.mypy_cache/3.11/sys/__init__.data.json +0 -1
  452. machineconfig/scripts/python/.mypy_cache/3.11/sys/__init__.meta.json +0 -1
  453. machineconfig/scripts/python/.mypy_cache/3.11/tarfile.data.json +0 -1
  454. machineconfig/scripts/python/.mypy_cache/3.11/tarfile.meta.json +0 -1
  455. machineconfig/scripts/python/.mypy_cache/3.11/tempfile.data.json +0 -1
  456. machineconfig/scripts/python/.mypy_cache/3.11/tempfile.meta.json +0 -1
  457. machineconfig/scripts/python/.mypy_cache/3.11/textwrap.data.json +0 -1
  458. machineconfig/scripts/python/.mypy_cache/3.11/textwrap.meta.json +0 -1
  459. machineconfig/scripts/python/.mypy_cache/3.11/threading.data.json +0 -1
  460. machineconfig/scripts/python/.mypy_cache/3.11/threading.meta.json +0 -1
  461. machineconfig/scripts/python/.mypy_cache/3.11/time.data.json +0 -1
  462. machineconfig/scripts/python/.mypy_cache/3.11/time.meta.json +0 -1
  463. machineconfig/scripts/python/.mypy_cache/3.11/types.data.json +0 -1
  464. machineconfig/scripts/python/.mypy_cache/3.11/types.meta.json +0 -1
  465. machineconfig/scripts/python/.mypy_cache/3.11/typing.data.json +0 -1
  466. machineconfig/scripts/python/.mypy_cache/3.11/typing.meta.json +0 -1
  467. machineconfig/scripts/python/.mypy_cache/3.11/typing_extensions.data.json +0 -1
  468. machineconfig/scripts/python/.mypy_cache/3.11/typing_extensions.meta.json +0 -1
  469. machineconfig/scripts/python/.mypy_cache/3.11/urllib/__init__.data.json +0 -1
  470. machineconfig/scripts/python/.mypy_cache/3.11/urllib/__init__.meta.json +0 -1
  471. machineconfig/scripts/python/.mypy_cache/3.11/urllib/parse.data.json +0 -1
  472. machineconfig/scripts/python/.mypy_cache/3.11/urllib/parse.meta.json +0 -1
  473. machineconfig/scripts/python/.mypy_cache/3.11/uuid.data.json +0 -1
  474. machineconfig/scripts/python/.mypy_cache/3.11/uuid.meta.json +0 -1
  475. machineconfig/scripts/python/.mypy_cache/3.11/warnings.data.json +0 -1
  476. machineconfig/scripts/python/.mypy_cache/3.11/warnings.meta.json +0 -1
  477. machineconfig/scripts/python/.mypy_cache/3.11/weakref.data.json +0 -1
  478. machineconfig/scripts/python/.mypy_cache/3.11/weakref.meta.json +0 -1
  479. machineconfig/scripts/python/.mypy_cache/3.11/zipfile/__init__.data.json +0 -1
  480. machineconfig/scripts/python/.mypy_cache/3.11/zipfile/__init__.meta.json +0 -1
  481. machineconfig/scripts/python/.mypy_cache/3.11/zlib.data.json +0 -1
  482. machineconfig/scripts/python/.mypy_cache/3.11/zlib.meta.json +0 -1
  483. machineconfig/scripts/python/.mypy_cache/CACHEDIR.TAG +0 -3
  484. machineconfig/scripts/python/__pycache__/cloud_repo_sync.cpython-311.pyc +0 -0
  485. machineconfig/scripts/python/__pycache__/gh_models.cpython-311.pyc +0 -0
  486. machineconfig/scripts/python/__pycache__/url2md.cpython-311.pyc +0 -0
  487. machineconfig/scripts/python/__pycache__/viewer.cpython-311.pyc +0 -0
  488. machineconfig/scripts/python/__pycache__/vscode_api.cpython-311.pyc +0 -0
  489. machineconfig/settings/__pycache__/__init__.cpython-311.pyc +0 -0
  490. machineconfig/settings/linters/.ruff_cache/.gitignore +0 -2
  491. machineconfig/settings/linters/.ruff_cache/CACHEDIR.TAG +0 -1
  492. machineconfig/settings/shells/ipy/profiles/default/__pycache__/__init__.cpython-311.pyc +0 -0
  493. machineconfig/settings/shells/ipy/profiles/default/startup/__pycache__/__init__.cpython-311.pyc +0 -0
  494. machineconfig/settings/shells/ipy/profiles/default/startup/__pycache__/playext.cpython-311.pyc +0 -0
  495. machineconfig/utils/ve_utils/ve1.py +0 -111
  496. machineconfig/utils/ve_utils/ve2.py +0 -155
  497. machineconfig-1.95.dist-info/RECORD +0 -712
  498. {machineconfig-1.95.dist-info → machineconfig-1.96.dist-info}/WHEEL +0 -0
  499. {machineconfig-1.95.dist-info → machineconfig-1.96.dist-info}/top_level.txt +0 -0
@@ -1,238 +1,235 @@
1
1
 
2
- from rich import inspect
3
- from rich.console import Console
4
- import pandas as pd
5
-
6
- from crocodile.core import Struct as S, install_n_import
7
- from crocodile.file_management import P, Save
8
- from crocodile.meta import MACHINE
9
- from machineconfig.cluster.loader_runner import JOB_STATUS, LAUNCH_METHOD, JobStatus
10
-
11
- from typing import Union, Any
12
- import time
13
- import os
14
- import platform
15
-
16
- console = Console()
17
-
18
-
19
- class FileManager:
20
- running_path = P("~/tmp_results/remote_machines/file_manager/running_jobs.pkl")
21
- queue_path = P("~/tmp_results/remote_machines/file_manager/queued_jobs.pkl")
22
- history_path = P("~/tmp_results/remote_machines/file_manager/history_jobs.pkl")
23
- shell_script_path_log = P("~/tmp_results/remote_machines/file_manager/last_cluster_script.txt")
24
- default_base = P("~/tmp_results/remote_machines/jobs")
25
- @staticmethod
26
- def from_pickle(path: Union[str, P]):
27
- fm = FileManager(job_id='1', remote_machine_type='Windows', lock_resources=True, max_simulataneous_jobs=1, base=None)
28
- fm.__setstate__(dict(P(path).expanduser().readit()))
29
- return fm
30
- def __getstate__(self): return self.__dict__
31
- def __setstate__(self, state: dict[str, Any]): self.__dict__ = state
32
- def __init__(self, job_id: str, remote_machine_type: MACHINE, lock_resources: bool, max_simulataneous_jobs: int = 1, base: Union[str, P, None] = None):
33
- """Log files to track execution process:
34
- * A text file that cluster deletes at the begining then write to at the end of each job.
35
- * pickle of Machine and clusters objects.
36
- """
37
- # EVERYTHING MUST REMAIN IN RELATIVE PATHS
38
- self.remote_machine_type = remote_machine_type
39
- self.job_id = job_id
40
- self.max_simulataneous_jobs = max_simulataneous_jobs
41
- self.lock_resources = lock_resources
42
-
43
- self.submission_time = pd.Timestamp.now()
44
-
45
- self.base_dir = P(base).collapseuser() if bool(base) else FileManager.default_base
46
- status: JOB_STATUS
47
- status = 'queued'
48
- self.job_root = self.base_dir.joinpath(f"{status}/{self.job_id}")
49
- @property
50
- def py_script_path(self): return self.job_root.joinpath("python/cluster_wrap.py")
51
- @property
52
- def cloud_download_py_script_path(self): return self.job_root.joinpath("python/download_data.py")
53
- @property
54
- def shell_script_path(self): return self.job_root.joinpath("shell/cluster_script" + {"Windows": ".ps1", "Linux": ".sh"}[self.remote_machine_type]) # noqa: E501
55
- @property
56
- def kwargs_path(self): return self.job_root.joinpath("data/func_kwargs.pkl")
57
- @property
58
- def file_manager_path(self): return self.job_root.joinpath("data/file_manager.pkl")
59
- @property
60
- def remote_machine_path(self): return self.job_root.joinpath("data/remote_machine.Machine.pkl")
61
- @property
62
- def remote_machine_config_path(self): return self.job_root.joinpath("data/remote_machine_config.pkl")
63
- @property
64
- def execution_log_dir(self): return self.job_root.joinpath("logs")
65
- def get_fire_command(self, launch_method: LAUNCH_METHOD):
66
- _ = launch_method
67
- script_path = self.shell_script_path.expanduser()
68
- # if launch_method == "remotely": pass # shell_script is already repared for target machine.
69
- # else:
70
- if platform.system() == "Windows" and script_path.name.endswith(".sh"):
71
- tmp = script_path.with_suffix(".ps1")
72
- tmp.write_text(script_path.read_text(), encoding="utf-8", newline=None)
73
- script_path = tmp
74
- if platform.system() == "Linux" and script_path.name.endswith(".ps1"):
75
- tmp = script_path.with_suffix(".sh")
76
- tmp.write_text(script_path.read_text(), encoding="utf-8", newline='\n')
77
- script_path = tmp
78
- return f". {script_path}"
79
- def fire_command_to_clip_memory(self, launch_method: LAUNCH_METHOD):
80
- print("Execution command copied to clipboard 📋")
81
- print(self.get_fire_command(launch_method=launch_method)); install_n_import("clipboard").copy(self.get_fire_command(launch_method=launch_method))
82
- print("\n")
83
- def get_job_status(self, session_name: str, tab_name: str) -> JOB_STATUS:
84
- pid_path = self.execution_log_dir.expanduser().joinpath("pid.txt")
85
- tmp = self.execution_log_dir.expanduser().joinpath("status.txt").read_text()
86
- status: JOB_STATUS = tmp # type: ignore
87
- if status == "running":
88
- if not pid_path.exists():
89
- print(f"Something wrong happened to job `{self.job_id}`. Its status log file says `{status}`, but pid_path doesn't exists. Moving to failed.")
90
- status = 'failed'
91
- self.execution_log_dir.expanduser().joinpath("status.txt").write_text(status)
92
- return status
93
- pid: int = int(pid_path.read_text().rstrip())
94
- import psutil
95
- try: proc = psutil.Process(pid=pid)
96
- except psutil.NoSuchProcess:
97
- print(f"Something wrong happened to job `{self.job_id}`.. Its status log file says `{status}`, but its declared `{pid=}` is dead. Moving to failed.")
98
- status = 'failed'
99
- self.execution_log_dir.expanduser().joinpath("status.txt").write_text(status)
100
- return status
101
- command = " ".join(proc.cmdline())
102
- if self.job_id not in command:
103
- print(f"Something wrong happened to job `{self.job_id}`. Its status log file says `{status}` but the `{pid=}` declared seem to belong to a different process as indicated by the firing command `{command=}`. Moving to failed.")
104
- status = 'failed'
105
- self.execution_log_dir.expanduser().joinpath("status.txt").write_text(status)
106
- return status
107
- print(f"Job `{self.job_id}` is running with {pid=} & {session_name=} & {tab_name=}.")
108
- return status
109
- return status
110
-
111
- def add_to_queue(self, job_status: JobStatus):
112
- try:
113
- queue_file: list[JobStatus] = self.queue_path.expanduser().readit()
114
- except FileNotFoundError:
115
- print("Queue file was deleted by the locking job, creating an empty one and saving it.")
116
- queue_file = []
117
- Save.pickle(obj=queue_file, path=self.queue_path.expanduser())
118
- job_ids = [job.job_id for job in queue_file]
119
- if self.job_id not in job_ids:
120
- print(f"Adding this job {self.job_id} to the queue and saving it. {len(queue_file)=}")
121
- queue_file.append(job_status)
122
- Save.pickle(obj=queue_file, path=self.queue_path.expanduser())
123
- return queue_file
124
-
125
- def get_resources_unlocking(self): # this one works at shell level in case python script failed.
126
- return f"""
127
- rm {self.running_path.collapseuser().as_posix()}
128
- echo "Unlocked resources"
129
- """
130
-
131
- def secure_resources(self):
132
- if self.lock_resources is False: return True
133
- this_job = JobStatus(job_id=self.job_id, pid=os.getpid(), submission_time=self.submission_time, start_time=None, status='locked')
134
- sleep_time_mins = 10
135
- lock_status = 'locked'
136
- while lock_status == 'locked':
137
-
138
- try: running_file: list[JobStatus] = self.running_path.expanduser().readit()
139
- except FileNotFoundError:
140
- print("Running file was deleted by the locking job, making one.")
141
- running_file = []
142
- Save.pickle(obj=running_file, path=self.running_path.expanduser())
143
-
144
- queue_file = self.add_to_queue(job_status=this_job)
145
-
146
- if len(running_file) < self.max_simulataneous_jobs:
147
- lock_status = 'unlocked'
148
- break
149
-
150
- # --------------- Clearning up queue_file from dead processes -----------------
151
- import psutil
152
- next_job_in_queue = queue_file[0] # only consider the first job in the queue
153
- try: _ = psutil.Process(next_job_in_queue.pid)
154
- except psutil.NoSuchProcess:
155
- print(f"Next job in queue {next_job_in_queue} has no associated process, removing it from the queue.")
156
- queue_file.pop(0)
157
- Save.pickle(obj=queue_file, path=self.queue_path.expanduser())
158
- continue
159
-
160
- # --------------- Clearning up running_file from dead processes -----------------
161
- found_dead_process = False
162
- assert len(running_file) > 0, "Running file is empty. This should not happen. There should be a break before this point."
163
-
164
- for running_job in running_file:
165
- try: proc = psutil.Process(pid=running_job.pid)
166
- except psutil.NoSuchProcess:
167
- print(f"Locking process with pid {running_job.pid} is dead. Ignoring this lock file.")
168
- S(running_job.__dict__).print(as_config=True, title="Ignored Lock File Details")
169
- running_file.remove(running_job)
170
- Save.pickle(obj=running_file, path=self.running_path.expanduser())
171
- found_dead_process = True
172
- continue # for for loop
173
- attrs_txt = ['status', 'memory_percent', 'exe', 'num_ctx_switches',
174
- 'ppid', 'num_threads', 'pid', 'cpu_percent', 'create_time', 'nice',
175
- 'name', 'cpu_affinity', 'cmdline', 'username', 'cwd']
176
- # if self.remote_machine_type == 'Windows': attrs_txt += ['num_handles']
177
- # environ, memory_maps, 'io_counters'
178
- attrs_objs = ['memory_info', 'memory_full_info', 'cpu_times', 'ionice', 'threads', 'open_files', 'connections']
179
- inspect(S(proc.as_dict(attrs=attrs_objs)), value=False, title=f"Process holding the Lock (pid = {running_job.pid})", docs=False, sort=False)
180
- inspect(S(proc.as_dict(attrs=attrs_txt)), value=False, title=f"Process holding the Lock (pid = {running_job.pid})", docs=False, sort=False)
181
-
182
- if found_dead_process: continue # repeat while loop logic.
183
- running_job = running_file[0] # arbitrary job in the running file.
184
- assert running_job.start_time is not None, f"Running job {running_job} has no start time. This should not happen."
185
-
186
- this_specs = {"Submission time": this_job.submission_time, "Time now": pd.Timestamp.now(),
187
- "Time spent waiting in the queue so far 🛌": pd.Timestamp.now() - this_job.submission_time,
188
- f"Time consumed by locking job so far (job_id = {running_job.job_id}) so far ⏰": pd.Timestamp.now() - running_job.start_time}
189
- S(this_specs).print(as_config=True, title=f"This Job `{this_job.job_id}` Details")
190
- console.rule(title=f"Resources are locked by another job `{running_job.job_id}`. Sleeping for {sleep_time_mins} minutes. 😴", style="bold red", characters="-")
191
- print("\n")
192
- time.sleep(sleep_time_mins * 60)
193
- self.write_lock_file(job_status=this_job)
194
- console.print(f"Resources are locked by this job `{self.job_id}`. Process pid = {os.getpid()}.", highlight=True)
195
-
196
- def write_lock_file(self, job_status: JobStatus):
197
- job_status.start_time = pd.Timestamp.now()
198
- queue_path = self.queue_path.expanduser()
199
- try: queue_file: list[JobStatus] = queue_path.readit()
200
- except FileNotFoundError as fne: raise FileNotFoundError(f"Queue file {queue_path} does not exist. This method should not be called in the first place.") from fne
201
-
202
- if job_status in queue_file: queue_file.remove(job_status)
203
- print("Removed current job from waiting queue and added it to the running queue. Saving both files.")
204
- Save.pickle(obj=queue_file, path=queue_path)
205
-
206
- running_path = self.running_path.expanduser()
207
- try: running_file: list[JobStatus] = running_path.readit()
208
- except FileNotFoundError as fne: raise FileNotFoundError(f"Queue file {running_path} does not exist. This method should not be called in the first place.") from fne
209
-
210
- assert job_status not in running_file, f"Job status {job_status} is already in the running file. This should not happen."
211
- assert len(running_file) < self.max_simulataneous_jobs, f"Number of running jobs ({len(running_file)}) is greater than the maximum allowed ({self.max_simulataneous_jobs}). This method should not be called in the first place."
212
- running_file.append(job_status)
213
- Save.pickle(obj=running_file, path=running_path)
214
-
215
- def unlock_resources(self):
216
- if self.lock_resources is False: return True
217
- running_file: list[JobStatus] = self.running_path.expanduser().readit()
218
- for job_status in running_file:
219
- if job_status.job_id == self.job_id:
220
- this_job = job_status
221
- break
222
- else:
223
- print(f"Job {self.job_id} is not in the running file. This should not happen. The file is corrupt.")
224
- this_job = None
225
- if this_job is not None:
226
- running_file.remove(this_job)
227
- console.print(f"Resources have been released by this job `{self.job_id}`. Saving new running file")
228
- Save.pickle(path=self.running_path.expanduser(), obj=running_file)
229
- start_time = pd.to_datetime(self.execution_log_dir.expanduser().joinpath("start_time.txt").readit(), utc=False)
230
- end_time = pd.Timestamp.now()
231
- item = {"job_id": self.job_id, "start_time": start_time, "end_time": end_time, "submission_time": self.submission_time}
232
- hist_file = self.history_path.expanduser()
233
- if hist_file.exists(): hist = hist_file.readit()
234
- else: hist = []
235
- hist.append(item)
236
- print(f"Saved history file to {hist_file} with {len(hist)} items.")
237
- Save.pickle(obj=hist, path=hist_file)
238
- # this is further handled by the calling script in case this function failed.
2
+ # from rich.console import Console
3
+ # from machineconfig.utils.utils2 import pprint
4
+ # from datetime import datetime
5
+
6
+
7
+ # from machineconfig.utils.io_save import save_pickle
8
+ # from machineconfig.cluster.loader_runner import JOB_STATUS, LAUNCH_METHOD, JobStatus
9
+
10
+ # from typing import Union, Any
11
+ # import time
12
+ # import os
13
+ # import platform
14
+
15
+ # console = Console()
16
+
17
+
18
+ # class FileManager:
19
+ # running_path = PathExtended("~/tmp_results/remote_machines/file_manager/running_jobs.pkl")
20
+ # queue_path = PathExtended("~/tmp_results/remote_machines/file_manager/queued_jobs.pkl")
21
+ # history_path = PathExtended("~/tmp_results/remote_machines/file_manager/history_jobs.pkl")
22
+ # shell_script_path_log = PathExtended("~/tmp_results/remote_machines/file_manager/last_cluster_script.txt")
23
+ # default_base = PathExtended("~/tmp_results/remote_machines/jobs")
24
+ # @staticmethod
25
+ # def from_pickle(path: Union[str, P]):
26
+ # fm = FileManager(job_id='1', remote_machine_type='Windows', lock_resources=True, max_simulataneous_jobs=1, base=None)
27
+ # fm.__setstate__(dict(PathExtended(path).expanduser().readit()))
28
+ # return fm
29
+ # def __getstate__(self): return self.__dict__
30
+ # def __setstate__(self, state: dict[str, Any]): self.__dict__ = state
31
+ # def __init__(self, job_id: str, remote_machine_type: MACHINE, lock_resources: bool, max_simulataneous_jobs: int = 1, base: Union[str, P, None] = None):
32
+ # """Log files to track execution process:
33
+ # * A text file that cluster deletes at the begining then write to at the end of each job.
34
+ # * pickle of Machine and clusters objects.
35
+ # """
36
+ # # EVERYTHING MUST REMAIN IN RELATIVE PATHS
37
+ # self.remote_machine_type = remote_machine_type
38
+ # self.job_id = job_id
39
+ # self.max_simulataneous_jobs = max_simulataneous_jobs
40
+ # self.lock_resources = lock_resources
41
+
42
+ # self.submission_time = datetime.now()
43
+
44
+ # self.base_dir = PathExtended(base).collapseuser() if bool(base) else FileManager.default_base
45
+ # status: JOB_STATUS
46
+ # status = 'queued'
47
+ # self.job_root = self.base_dir.joinpath(f"{status}/{self.job_id}")
48
+ # @property
49
+ # def py_script_path(self): return self.job_root.joinpath("python/cluster_wrap.py")
50
+ # @property
51
+ # def cloud_download_py_script_path(self): return self.job_root.joinpath("python/download_data.py")
52
+ # @property
53
+ # def shell_script_path(self): return self.job_root.joinpath("shell/cluster_script" + {"Windows": ".ps1", "Linux": ".sh"}[self.remote_machine_type]) # noqa: E501
54
+ # @property
55
+ # def kwargs_path(self): return self.job_root.joinpath("data/func_kwargs.pkl")
56
+ # @property
57
+ # def file_manager_path(self): return self.job_root.joinpath("data/file_manager.pkl")
58
+ # @property
59
+ # def remote_machine_path(self): return self.job_root.joinpath("data/remote_machine.Machine.pkl")
60
+ # @property
61
+ # def remote_machine_config_path(self): return self.job_root.joinpath("data/remote_machine_config.pkl")
62
+ # @property
63
+ # def execution_log_dir(self): return self.job_root.joinpath("logs")
64
+ # def get_fire_command(self, launch_method: LAUNCH_METHOD):
65
+ # _ = launch_method
66
+ # script_path = self.shell_script_path.expanduser()
67
+ # # if launch_method == "remotely": pass # shell_script is already repared for target machine.
68
+ # # else:
69
+ # if platform.system() == "Windows" and script_path.name.endswith(".sh"):
70
+ # tmp = script_path.with_suffix(".ps1")
71
+ # tmp.write_text(script_path.read_text(), encoding="utf-8", newline=None)
72
+ # script_path = tmp
73
+ # if platform.system() == "Linux" and script_path.name.endswith(".ps1"):
74
+ # tmp = script_path.with_suffix(".sh")
75
+ # tmp.write_text(script_path.read_text(), encoding="utf-8", newline='\n')
76
+ # script_path = tmp
77
+ # return f". {script_path}"
78
+ # def get_job_status(self, session_name: str, tab_name: str) -> JOB_STATUS:
79
+ # pid_path = self.execution_log_dir.expanduser().joinpath("pid.txt")
80
+ # tmp = self.execution_log_dir.expanduser().joinpath("status.txt").read_text()
81
+ # status: JOB_STATUS = tmp # type: ignore
82
+ # if status == "running":
83
+ # if not pid_path.exists():
84
+ # print(f"Something wrong happened to job `{self.job_id}`. Its status log file says `{status}`, but pid_path doesn't exists. Moving to failed.")
85
+ # status = 'failed'
86
+ # self.execution_log_dir.expanduser().joinpath("status.txt").write_text(status)
87
+ # return status
88
+ # pid: int = int(pid_path.read_text().rstrip())
89
+ # import psutil
90
+ # try: proc = psutil.Process(pid=pid)
91
+ # except psutil.NoSuchProcess:
92
+ # print(f"Something wrong happened to job `{self.job_id}`.. Its status log file says `{status}`, but its declared `{pid=}` is dead. Moving to failed.")
93
+ # status = 'failed'
94
+ # self.execution_log_dir.expanduser().joinpath("status.txt").write_text(status)
95
+ # return status
96
+ # command = " ".join(proc.cmdline())
97
+ # if self.job_id not in command:
98
+ # print(f"Something wrong happened to job `{self.job_id}`. Its status log file says `{status}` but the `{pid=}` declared seem to belong to a different process as indicated by the firing command `{command=}`. Moving to failed.")
99
+ # status = 'failed'
100
+ # self.execution_log_dir.expanduser().joinpath("status.txt").write_text(status)
101
+ # return status
102
+ # print(f"Job `{self.job_id}` is running with {pid=} & {session_name=} & {tab_name=}.")
103
+ # return status
104
+ # return status
105
+
106
+ # def add_to_queue(self, job_status: JobStatus):
107
+ # try:
108
+ # queue_file: list[JobStatus] = self.queue_path.expanduser().readit()
109
+ # except FileNotFoundError:
110
+ # print("Queue file was deleted by the locking job, creating an empty one and saving it.")
111
+ # queue_file = []
112
+ # save_pickle(obj=queue_file, path=self.queue_path.expanduser())
113
+ # job_ids = [job.job_id for job in queue_file]
114
+ # if self.job_id not in job_ids:
115
+ # print(f"Adding this job {self.job_id} to the queue and saving it. {len(queue_file)=}")
116
+ # queue_file.append(job_status)
117
+ # save_pickle(obj=queue_file, path=self.queue_path.expanduser())
118
+ # return queue_file
119
+
120
+ # def get_resources_unlocking(self): # this one works at shell level in case python script failed.
121
+ # return f"""
122
+ # rm {self.running_path.collapseuser().as_posix()}
123
+ # echo "Unlocked resources"
124
+ # """
125
+
126
+ # def secure_resources(self):
127
+ # if self.lock_resources is False: return True
128
+ # this_job = JobStatus(job_id=self.job_id, pid=os.getpid(), submission_time=self.submission_time, start_time=None, status='locked')
129
+ # sleep_time_mins = 10
130
+ # lock_status = 'locked'
131
+ # while lock_status == 'locked':
132
+
133
+ # try: running_file: list[JobStatus] = self.running_path.expanduser().readit()
134
+ # except FileNotFoundError:
135
+ # print("Running file was deleted by the locking job, making one.")
136
+ # running_file = []
137
+ # save_pickle(obj=running_file, path=self.running_path.expanduser())
138
+
139
+ # queue_file = self.add_to_queue(job_status=this_job)
140
+
141
+ # if len(running_file) < self.max_simulataneous_jobs:
142
+ # lock_status = 'unlocked'
143
+ # break
144
+
145
+ # # --------------- Clearning up queue_file from dead processes -----------------
146
+ # import psutil
147
+ # next_job_in_queue = queue_file[0] # only consider the first job in the queue
148
+ # try: _ = psutil.Process(next_job_in_queue.pid)
149
+ # except psutil.NoSuchProcess:
150
+ # print(f"Next job in queue {next_job_in_queue} has no associated process, removing it from the queue.")
151
+ # queue_file.pop(0)
152
+ # save_pickle(obj=queue_file, path=self.queue_path.expanduser())
153
+ # continue
154
+
155
+ # # --------------- Clearning up running_file from dead processes -----------------
156
+ # found_dead_process = False
157
+ # assert len(running_file) > 0, "Running file is empty. This should not happen. There should be a break before this point."
158
+
159
+ # for running_job in running_file:
160
+ # try: proc = psutil.Process(pid=running_job.pid)
161
+ # except psutil.NoSuchProcess:
162
+ # print(f"Locking process with pid {running_job.pid} is dead. Ignoring this lock file.")
163
+ # pprint(running_job.__dict__, "Ignored Lock File Details")
164
+ # running_file.remove(running_job)
165
+ # save_pickle(obj=running_file, path=self.running_path.expanduser())
166
+ # found_dead_process = True
167
+ # continue # for for loop
168
+ # attrs_txt = ['status', 'memory_percent', 'exe', 'num_ctx_switches',
169
+ # 'ppid', 'num_threads', 'pid', 'cpu_percent', 'create_time', 'nice',
170
+ # 'name', 'cpu_affinity', 'cmdline', 'username', 'cwd']
171
+ # # if self.remote_machine_type == 'Windows': attrs_txt += ['num_handles']
172
+ # # environ, memory_maps, 'io_counters'
173
+ # attrs_objs = ['memory_info', 'memory_full_info', 'cpu_times', 'ionice', 'threads', 'open_files', 'connections']
174
+ # pprint(proc.as_dict(attrs=attrs_objs), f"Process holding the Lock (pid = {running_job.pid})")
175
+ # pprint(proc.as_dict(attrs=attrs_txt), f"Process holding the Lock (pid = {running_job.pid})")
176
+
177
+ # if found_dead_process: continue # repeat while loop logic.
178
+ # running_job = running_file[0] # arbitrary job in the running file.
179
+ # assert running_job.start_time is not None, f"Running job {running_job} has no start time. This should not happen."
180
+
181
+ # now = datetime.now()
182
+ # this_specs = {"Submission time": this_job.submission_time, "Time now": now,
183
+ # "Time spent waiting in the queue so far 🛌": now - this_job.submission_time,
184
+ # f"Time consumed by locking job so far (job_id = {running_job.job_id}) so far ⏰": now - running_job.start_time}
185
+ # pprint(this_specs, f"This Job `{this_job.job_id}` Details")
186
+ # console.rule(title=f"Resources are locked by another job `{running_job.job_id}`. Sleeping for {sleep_time_mins} minutes. 😴", style="bold red", characters="-")
187
+ # print("\n")
188
+ # time.sleep(sleep_time_mins * 60)
189
+ # self.write_lock_file(job_status=this_job)
190
+ # console.print(f"Resources are locked by this job `{self.job_id}`. Process pid = {os.getpid()}.", highlight=True)
191
+
192
+ # def write_lock_file(self, job_status: JobStatus):
193
+ # job_status.start_time = datetime.now()
194
+ # queue_path = self.queue_path.expanduser()
195
+ # try: queue_file: list[JobStatus] = queue_path.readit()
196
+ # except FileNotFoundError as fne: raise FileNotFoundError(f"Queue file {queue_path} does not exist. This method should not be called in the first place.") from fne
197
+
198
+ # if job_status in queue_file: queue_file.remove(job_status)
199
+ # print("Removed current job from waiting queue and added it to the running queue. Saving both files.")
200
+ # save_pickle(obj=queue_file, path=queue_path)
201
+
202
+ # running_path = self.running_path.expanduser()
203
+ # try: running_file: list[JobStatus] = running_path.readit()
204
+ # except FileNotFoundError as fne: raise FileNotFoundError(f"Queue file {running_path} does not exist. This method should not be called in the first place.") from fne
205
+
206
+ # assert job_status not in running_file, f"Job status {job_status} is already in the running file. This should not happen."
207
+ # assert len(running_file) < self.max_simulataneous_jobs, f"Number of running jobs ({len(running_file)}) is greater than the maximum allowed ({self.max_simulataneous_jobs}). This method should not be called in the first place."
208
+ # running_file.append(job_status)
209
+ # save_pickle(obj=running_file, path=running_path)
210
+
211
+ # def unlock_resources(self):
212
+ # if self.lock_resources is False: return True
213
+ # running_file: list[JobStatus] = self.running_path.expanduser().readit()
214
+ # for job_status in running_file:
215
+ # if job_status.job_id == self.job_id:
216
+ # this_job = job_status
217
+ # break
218
+ # else:
219
+ # print(f"Job {self.job_id} is not in the running file. This should not happen. The file is corrupt.")
220
+ # this_job = None
221
+ # if this_job is not None:
222
+ # running_file.remove(this_job)
223
+ # console.print(f"Resources have been released by this job `{self.job_id}`. Saving new running file")
224
+ # save_pickle(path=self.running_path.expanduser(), obj=running_file)
225
+ # start_time_str = self.execution_log_dir.expanduser().joinpath("start_time.txt").readit()
226
+ # start_time = datetime.fromisoformat(start_time_str)
227
+ # end_time = datetime.now()
228
+ # item = {"job_id": self.job_id, "start_time": start_time, "end_time": end_time, "submission_time": self.submission_time}
229
+ # hist_file = self.history_path.expanduser()
230
+ # if hist_file.exists(): hist = hist_file.readit()
231
+ # else: hist = []
232
+ # hist.append(item)
233
+ # print(f"Saved history file to {hist_file} with {len(hist)} items.")
234
+ # save_pickle(obj=hist, path=hist_file)
235
+ # # this is further handled by the calling script in case this function failed.