pybiolib 1.2.347__tar.gz → 1.2.406__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. {pybiolib-1.2.347 → pybiolib-1.2.406}/PKG-INFO +1 -1
  2. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/app/app.py +10 -1
  3. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/biolib_errors.py +9 -0
  4. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/job_worker/executors/docker_executor.py +14 -8
  5. {pybiolib-1.2.347 → pybiolib-1.2.406}/pyproject.toml +1 -1
  6. {pybiolib-1.2.347 → pybiolib-1.2.406}/LICENSE +0 -0
  7. {pybiolib-1.2.347 → pybiolib-1.2.406}/PYPI_README.md +0 -0
  8. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/__init__.py +0 -0
  9. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/_data_record/data_record.py +0 -0
  10. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/_internal/__init__.py +0 -0
  11. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/_internal/data_record/__init__.py +0 -0
  12. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/_internal/data_record/data_record.py +0 -0
  13. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/_internal/data_record/push_data.py +0 -0
  14. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/_internal/data_record/remote_storage_endpoint.py +0 -0
  15. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/_internal/file_utils.py +0 -0
  16. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/_internal/fuse_mount/__init__.py +0 -0
  17. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/_internal/fuse_mount/experiment_fuse_mount.py +0 -0
  18. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/_internal/http_client.py +0 -0
  19. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/_internal/lfs/__init__.py +0 -0
  20. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/_internal/lfs/cache.py +0 -0
  21. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/_internal/libs/__init__.py +0 -0
  22. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/_internal/libs/fusepy/__init__.py +0 -0
  23. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/_internal/push_application.py +0 -0
  24. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/_internal/runtime.py +0 -0
  25. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/_internal/types/__init__.py +0 -0
  26. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/_internal/types/app.py +0 -0
  27. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/_internal/types/data_record.py +0 -0
  28. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/_internal/types/experiment.py +0 -0
  29. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/_internal/types/file_node.py +0 -0
  30. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/_internal/types/resource.py +0 -0
  31. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/_internal/types/resource_version.py +0 -0
  32. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/_internal/types/typing.py +0 -0
  33. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/_internal/utils/__init__.py +0 -0
  34. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/_internal/utils/multinode.py +0 -0
  35. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/_runtime/runtime.py +0 -0
  36. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/api/__init__.py +0 -0
  37. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/api/client.py +0 -0
  38. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/app/__init__.py +0 -0
  39. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/app/search_apps.py +0 -0
  40. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/biolib_api_client/__init__.py +0 -0
  41. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/biolib_api_client/api_client.py +0 -0
  42. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/biolib_api_client/app_types.py +0 -0
  43. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/biolib_api_client/auth.py +0 -0
  44. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/biolib_api_client/biolib_app_api.py +0 -0
  45. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/biolib_api_client/biolib_job_api.py +0 -0
  46. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/biolib_api_client/common_types.py +0 -0
  47. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/biolib_api_client/job_types.py +0 -0
  48. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/biolib_api_client/lfs_types.py +0 -0
  49. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/biolib_api_client/user_state.py +0 -0
  50. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/biolib_binary_format/__init__.py +0 -0
  51. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/biolib_binary_format/base_bbf_package.py +0 -0
  52. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/biolib_binary_format/file_in_container.py +0 -0
  53. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/biolib_binary_format/module_input.py +0 -0
  54. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/biolib_binary_format/module_output_v2.py +0 -0
  55. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/biolib_binary_format/remote_endpoints.py +0 -0
  56. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/biolib_binary_format/remote_stream_seeker.py +0 -0
  57. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/biolib_binary_format/saved_job.py +0 -0
  58. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/biolib_binary_format/stdout_and_stderr.py +0 -0
  59. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/biolib_binary_format/system_exception.py +0 -0
  60. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/biolib_binary_format/system_status_update.py +0 -0
  61. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/biolib_binary_format/utils.py +0 -0
  62. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/biolib_docker_client/__init__.py +0 -0
  63. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/biolib_download_container.py +0 -0
  64. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/biolib_logging.py +0 -0
  65. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/cli/__init__.py +0 -0
  66. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/cli/auth.py +0 -0
  67. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/cli/data_record.py +0 -0
  68. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/cli/download_container.py +0 -0
  69. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/cli/init.py +0 -0
  70. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/cli/lfs.py +0 -0
  71. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/cli/push.py +0 -0
  72. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/cli/run.py +0 -0
  73. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/cli/runtime.py +0 -0
  74. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/cli/start.py +0 -0
  75. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/.gitignore +0 -0
  76. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/__init__.py +0 -0
  77. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/cloud_utils/__init__.py +0 -0
  78. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/cloud_utils/cloud_utils.py +0 -0
  79. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/job_worker/__init__.py +0 -0
  80. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/job_worker/cache_state.py +0 -0
  81. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/job_worker/cache_types.py +0 -0
  82. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/job_worker/docker_image_cache.py +0 -0
  83. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/job_worker/executors/__init__.py +0 -0
  84. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/job_worker/executors/docker_types.py +0 -0
  85. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/job_worker/executors/tars/__init__.py +0 -0
  86. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/job_worker/executors/types.py +0 -0
  87. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/job_worker/job_legacy_input_wait_timeout_thread.py +0 -0
  88. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/job_worker/job_max_runtime_timer_thread.py +0 -0
  89. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/job_worker/job_storage.py +0 -0
  90. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/job_worker/job_worker.py +0 -0
  91. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/job_worker/large_file_system.py +0 -0
  92. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/job_worker/mappings.py +0 -0
  93. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/job_worker/utilization_reporter_thread.py +0 -0
  94. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/job_worker/utils.py +0 -0
  95. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/remote_host_proxy.py +0 -0
  96. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/socker_listener_thread.py +0 -0
  97. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/socket_sender_thread.py +0 -0
  98. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/utils.py +0 -0
  99. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/webserver/__init__.py +0 -0
  100. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/webserver/gunicorn_flask_application.py +0 -0
  101. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/webserver/webserver.py +0 -0
  102. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/webserver/webserver_types.py +0 -0
  103. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/webserver/webserver_utils.py +0 -0
  104. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/compute_node/webserver/worker_thread.py +0 -0
  105. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/experiments/__init__.py +0 -0
  106. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/experiments/experiment.py +0 -0
  107. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/jobs/__init__.py +0 -0
  108. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/jobs/job.py +0 -0
  109. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/jobs/job_result.py +0 -0
  110. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/jobs/types.py +0 -0
  111. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/runtime/__init__.py +0 -0
  112. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/sdk/__init__.py +0 -0
  113. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/tables.py +0 -0
  114. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/templates/__init__.py +0 -0
  115. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/templates/example_app.py +0 -0
  116. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/typing_utils.py +0 -0
  117. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/user/__init__.py +0 -0
  118. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/user/sign_in.py +0 -0
  119. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/utils/__init__.py +0 -0
  120. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/utils/app_uri.py +0 -0
  121. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/utils/cache_state.py +0 -0
  122. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/utils/multipart_uploader.py +0 -0
  123. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/utils/seq_util.py +0 -0
  124. {pybiolib-1.2.347 → pybiolib-1.2.406}/biolib/utils/zip/remote_zip.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pybiolib
3
- Version: 1.2.347
3
+ Version: 1.2.406
4
4
  Summary: BioLib Python Client
5
5
  License: MIT
6
6
  Keywords: biolib
@@ -11,7 +11,7 @@ from biolib.biolib_api_client.app_types import App, AppVersion
11
11
  from biolib.biolib_api_client.biolib_app_api import BiolibAppApi
12
12
  from biolib.biolib_api_client.biolib_job_api import BiolibJobApi
13
13
  from biolib.biolib_binary_format import ModuleInput
14
- from biolib.biolib_errors import BioLibError
14
+ from biolib.biolib_errors import BioLibError, JobResultNonZeroExitCodeError
15
15
  from biolib.biolib_logging import logger
16
16
  from biolib.compute_node.job_worker.job_worker import JobWorker
17
17
  from biolib.experiments.experiment import Experiment
@@ -59,10 +59,14 @@ class BioLibApp:
59
59
  machine_count: Optional[int] = None,
60
60
  experiment: Optional[str] = None,
61
61
  temporary_client_secrets: Optional[Dict[str, str]] = None,
62
+ check: bool = False,
62
63
  ) -> Job:
63
64
  if experiment_id and experiment:
64
65
  raise ValueError('Only one of experiment_id and experiment can be specified')
65
66
 
67
+ if check and not blocking:
68
+ raise ValueError('The argument "check" cannot be True when blocking is False')
69
+
66
70
  if not experiment_id:
67
71
  experiment_instance = Experiment(experiment) if experiment else Experiment.get_experiment_in_context()
68
72
  experiment_id = experiment_instance.uuid if experiment_instance else None
@@ -105,6 +109,11 @@ class BioLibApp:
105
109
  )
106
110
  job._stream_logs(enable_print=enable_print) # pylint: disable=protected-access
107
111
 
112
+ if check:
113
+ exit_code = job.get_exit_code()
114
+ if exit_code != 0:
115
+ raise JobResultNonZeroExitCodeError(exit_code)
116
+
108
117
  return job
109
118
 
110
119
  def exec(self, args=None, stdin=None, files=None, machine=''):
@@ -43,3 +43,12 @@ class JobResultNotFound(JobResultError):
43
43
 
44
44
  class JobResultPermissionError(JobResultError):
45
45
  pass
46
+
47
+
48
+ class JobResultNonZeroExitCodeError(JobResultError):
49
+ """Raised when an app returns a non-zero exit code and check=True."""
50
+ def __init__(self, exit_code: int, message: Optional[str] = None):
51
+ self.exit_code = exit_code
52
+ super().__init__(
53
+ message or f'App returned non-zero exit code: {exit_code}'
54
+ )
@@ -44,8 +44,10 @@ class DockerExecutor:
44
44
  self._send_system_exception = options['send_system_exception']
45
45
  self._send_stdout_and_stderr = options['send_stdout_and_stderr']
46
46
  self._random_docker_id = compute_node_utils.random_string(15)
47
- self._reserved_system_ram = int(os.sysconf('SC_PAGE_SIZE') * os.sysconf('SC_PHYS_PAGES') * 0.06) + 500_000_000
48
- logger_no_user_data.info(f"System RAM reserved: {self._reserved_system_ram}")
47
+ total_memory_in_bytes = int(os.sysconf('SC_PAGE_SIZE') * os.sysconf('SC_PHYS_PAGES'))
48
+ system_reserved_memory = int(total_memory_in_bytes * 0.1) + 500_000_000
49
+ self._available_memory_in_bytes = total_memory_in_bytes - system_reserved_memory
50
+ logger_no_user_data.info(f'Available memory for containers: {self._available_memory_in_bytes} bytes')
49
51
 
50
52
  if utils.IS_RUNNING_IN_CLOUD:
51
53
  self._compute_process_dir = os.getenv('BIOLIB_USER_DATA_PATH')
@@ -164,7 +166,6 @@ class DockerExecutor:
164
166
  may_contain_user_data=False,
165
167
  )
166
168
 
167
-
168
169
  def _execute_helper(self, module_input) -> None:
169
170
  job_uuid = self._options['job']['public_id']
170
171
  logger_no_user_data.debug(f'Initializing container for {job_uuid}.')
@@ -250,7 +251,6 @@ class DockerExecutor:
250
251
  logger_no_user_data.debug(f'Docker container exited with code {exit_code} for {job_uuid}')
251
252
  self._save_module_output_from_container(exit_code, self._metadata_for_save_output_on_cancel)
252
253
 
253
-
254
254
  def _save_module_output_from_container(self, exit_code: int, metadata: MetadataToSaveOutput) -> None:
255
255
  full_stdout = self._docker_api_client.logs(self._container.id, stdout=True, stderr=False)
256
256
  full_stderr = self._docker_api_client.logs(self._container.id, stdout=False, stderr=True)
@@ -267,7 +267,6 @@ class DockerExecutor:
267
267
  pre_start_diff=metadata['pre_start_diff'],
268
268
  )
269
269
 
270
-
271
270
  def cleanup(self):
272
271
  # Don't clean up if already in the process of doing so, or done doing so
273
272
  if self._is_cleaning_up:
@@ -283,7 +282,7 @@ class DockerExecutor:
283
282
  logger_no_user_data.debug(f'Container state {self._docker_container.status}')
284
283
  self._save_module_output_from_container(
285
284
  exit_code=self._docker_container.attrs['State']['ExitCode'],
286
- metadata=self._metadata_for_save_output_on_cancel
285
+ metadata=self._metadata_for_save_output_on_cancel,
287
286
  )
288
287
  logger_no_user_data.debug('Saved results')
289
288
  except BaseException as error:
@@ -412,8 +411,15 @@ class DockerExecutor:
412
411
 
413
412
  if utils.IS_RUNNING_IN_CLOUD:
414
413
  cloud_job = self._options['cloud_job']
415
- create_container_args['mem_limit'] = (
416
- f'{cloud_job["reserved_memory_in_bytes"] - self._reserved_system_ram}b'
414
+ container_memory_limit_in_bytes = min(
415
+ cloud_job['reserved_memory_in_bytes'], self._available_memory_in_bytes
416
+ )
417
+ create_container_args['mem_limit'] = f'{container_memory_limit_in_bytes}b'
418
+ logger_no_user_data.debug(
419
+ 'Setting container memory limit to '
420
+ f'{container_memory_limit_in_bytes} bytes '
421
+ f'(requested: {cloud_job["reserved_memory_in_bytes"]}, '
422
+ f'available: {self._available_memory_in_bytes})'
417
423
  )
418
424
  create_container_args['nano_cpus'] = cloud_job['reserved_cpu_in_nano_shares']
419
425
  create_container_args['pids_limit'] = 10_000
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "pybiolib"
3
- version = "1.2.347"
3
+ version = "1.2.406"
4
4
  description = "BioLib Python Client"
5
5
  readme = "PYPI_README.md"
6
6
  license = "MIT"
File without changes
File without changes
File without changes
File without changes
File without changes