pybiolib 1.1.1896__py3-none-any.whl → 1.1.1907__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.
@@ -1,6 +1,4 @@
1
1
  import os
2
- import shutil
3
- import urllib.request
4
2
  from collections import namedtuple
5
3
  from datetime import datetime
6
4
  from fnmatch import fnmatch
@@ -56,10 +54,7 @@ class DataRecord:
56
54
  remote_storage_endpoint = DataRecordRemoteStorageEndpoint(
57
55
  resource_version_uuid=app_response['app_version']['public_id'],
58
56
  )
59
- with urllib.request.urlopen(remote_storage_endpoint.get_remote_url()) as response, open(
60
- output_path, 'wb'
61
- ) as out_file:
62
- shutil.copyfileobj(response, out_file)
57
+ HttpClient.request(url=remote_storage_endpoint.get_remote_url(), response_path=output_path)
63
58
 
64
59
  def download_files(self, output_dir: str, path_filter: Optional[PathFilter] = None) -> None:
65
60
  filtered_files = self.list_files(path_filter=path_filter)
@@ -1,5 +1,6 @@
1
1
  import json
2
2
  import platform
3
+ import shutil
3
4
  import socket
4
5
  import ssl
5
6
  import subprocess
@@ -41,15 +42,23 @@ class HttpError(urllib.error.HTTPError):
41
42
 
42
43
 
43
44
  class HttpResponse:
44
- def __init__(self, response) -> None:
45
+ def __init__(self, response, response_path) -> None:
45
46
  self.headers: Dict[str, str] = dict(response.headers)
46
47
  self.status_code: int = int(response.status)
47
- self.content: bytes = response.read()
48
+ self.response_path = response_path
49
+ if self.response_path:
50
+ shutil.copyfileobj(response, self.response_path)
51
+ else:
52
+ self.content: bytes = response.read()
48
53
  self.url: str = response.geturl()
49
54
 
50
55
  @property
51
56
  def text(self) -> str:
52
- return cast(str, self.content.decode('utf-8'))
57
+ if self.response_path:
58
+ with open(self.response_path, 'rb') as fp:
59
+ return cast(str, fp.read().decode('utf-8'))
60
+ else:
61
+ return cast(str, self.content.decode('utf-8'))
53
62
 
54
63
  def json(self):
55
64
  return json.loads(self.text)
@@ -66,6 +75,7 @@ class HttpClient:
66
75
  headers: Optional[Dict[str, str]] = None,
67
76
  retries: int = 5,
68
77
  timeout_in_seconds: Optional[int] = None,
78
+ response_path: Optional[str] = None,
69
79
  ) -> HttpResponse:
70
80
  if not HttpClient.ssl_context:
71
81
  HttpClient.ssl_context = _create_ssl_context()
@@ -94,7 +104,7 @@ class HttpClient:
94
104
  context=HttpClient.ssl_context,
95
105
  timeout=timeout_in_seconds,
96
106
  ) as response:
97
- return HttpResponse(response)
107
+ return HttpResponse(response, response_path)
98
108
 
99
109
  except urllib.error.HTTPError as error:
100
110
  if error.code == 502:
@@ -83,11 +83,12 @@ class DockerExecutor:
83
83
  raise Exception('Docker container was None')
84
84
  return self._docker_container
85
85
 
86
- def execute_module(self, module_input_serialized: bytes, module_output_path: str) -> None:
86
+ def execute_module(self, module_input_path: str, module_output_path: str) -> None:
87
87
  try:
88
88
  job_uuid = self._options['job']['public_id']
89
89
  send_status_update = self._options['send_status_update']
90
- module_input = ModuleInput(module_input_serialized).deserialize()
90
+ with open(module_input_path, 'rb') as fp:
91
+ module_input = ModuleInput(fp.read()).deserialize()
91
92
 
92
93
  send_status_update(StatusUpdate(progress=55, log_message='Pulling images...'))
93
94
 
@@ -10,6 +10,7 @@ from biolib.utils.multipart_uploader import get_chunk_iterator_from_file_object
10
10
 
11
11
 
12
12
  class JobStorage:
13
+ module_input_file_name = 'input-output.bbf'
13
14
  module_output_file_name = 'module-output.bbf'
14
15
 
15
16
  @staticmethod
@@ -81,7 +82,7 @@ class JobStorage:
81
82
  )
82
83
 
83
84
  @staticmethod
84
- def get_module_input(job: CreatedJobDict) -> bytes:
85
+ def download_module_input(job: CreatedJobDict, path: str):
85
86
  job_uuid = job['public_id']
86
87
  logger_no_user_data.debug(f'Job "{job_uuid}" downloading module input...')
87
88
  presigned_download_url = BiolibJobApi.get_job_storage_download_url(
@@ -89,7 +90,5 @@ class JobStorage:
89
90
  job_auth_token=job['auth_token'],
90
91
  storage_type='input',
91
92
  )
92
- response = HttpClient.request(url=presigned_download_url)
93
- data: bytes = response.content
93
+ HttpClient.request(url=presigned_download_url, response_path=path)
94
94
  logger_no_user_data.debug(f'Job "{job_uuid}" module input downloaded')
95
- return data
@@ -133,7 +133,8 @@ class JobWorker:
133
133
  ).start()
134
134
 
135
135
  try:
136
- module_input_serialized = JobStorage.get_module_input(job=job)
136
+ module_input_path = os.path.join(self.job_temporary_dir, JobStorage.module_input_file_name)
137
+ JobStorage.download_module_input(job=job, path=module_input_path)
137
138
  except StorageDownloadFailed:
138
139
  # Expect module input to be handled in a separate ModuleInput package
139
140
  self._legacy_input_wait_timeout_thread = JobLegacyInputWaitTimeout(
@@ -147,7 +148,7 @@ class JobWorker:
147
148
  raise error
148
149
 
149
150
  try:
150
- self._run_root_job(module_input_serialized)
151
+ self._run_root_job(module_input_path)
151
152
 
152
153
  # This error occurs when trying to access the container after the job worker has cleaned it up.
153
154
  # In that case stop the computation.
@@ -165,7 +166,9 @@ class JobWorker:
165
166
  self._legacy_input_wait_timeout_thread.stop()
166
167
 
167
168
  try:
168
- self._run_root_job(package)
169
+ module_input_path = os.path.join(self.job_temporary_dir, JobStorage.module_input_file_name)
170
+ open(module_input_path, 'wb').write(package)
171
+ self._run_root_job(module_input_path)
169
172
 
170
173
  # This error occurs when trying to access the container after the job worker has cleaned it up.
171
174
  # In that case stop the computation.
@@ -331,15 +334,15 @@ class JobWorker:
331
334
  def _run_app_version(
332
335
  self,
333
336
  app_version_id: str,
334
- module_input_serialized: bytes,
337
+ module_input_path: str,
335
338
  caller_job: CreatedJobDict,
336
339
  main_module_output_path: str,
337
340
  ) -> None:
338
341
  job: CreatedJobDict = BiolibJobApi.create(app_version_id, caller_job=caller_job['public_id'])
339
342
  self._jobs[job['public_id']] = job
340
- self._run_job(job, module_input_serialized, main_module_output_path)
343
+ self._run_job(job, module_input_path, main_module_output_path)
341
344
 
342
- def _run_job(self, job: CreatedJobDict, module_input_serialized: bytes, main_module_output_path: str) -> None:
345
+ def _run_job(self, job: CreatedJobDict, module_input_path: str, main_module_output_path: str) -> None:
343
346
  job_uuid = job['public_id']
344
347
  logger_no_user_data.info(f'Job "{job_uuid}" running...')
345
348
  if self._root_job_wrapper is None:
@@ -406,7 +409,7 @@ class JobWorker:
406
409
  send_system_exception=self.send_system_exception,
407
410
  send_stdout_and_stderr=self.send_stdout_and_stderr,
408
411
  ),
409
- module_input_serialized,
412
+ module_input_path,
410
413
  main_module_output_path,
411
414
  )
412
415
 
@@ -417,15 +420,20 @@ class JobWorker:
417
420
  def _run_module(
418
421
  self,
419
422
  options: LocalExecutorOptions,
420
- module_input_serialized: bytes,
423
+ module_input_path: str,
421
424
  module_output_path: str,
422
425
  ) -> None:
423
426
  module = options['module']
424
427
  job_id = options['job']['public_id']
425
428
  logger_no_user_data.debug(f'Job "{job_id}" running module "{module["name"]}"...')
429
+
426
430
  executor_instance: DockerExecutor
427
431
  if module['environment'] == ModuleEnvironment.BIOLIB_APP.value:
432
+ if not self.job_temporary_dir:
433
+ raise BioLibError('Undefined job_temporary_dir')
428
434
  logger_no_user_data.debug(f'Job "{job_id}" starting child job...')
435
+ with open(module_input_path,'rb') as fp:
436
+ module_input_serialized = fp.read()
429
437
  module_input = ModuleInput(module_input_serialized).deserialize()
430
438
  module_input_with_runtime_zip = self._add_runtime_zip_and_command_to_module_input(options, module_input)
431
439
  module_input_with_runtime_zip_serialized = ModuleInput().serialize(
@@ -433,9 +441,11 @@ class JobWorker:
433
441
  arguments=module_input_with_runtime_zip['arguments'],
434
442
  files=module_input_with_runtime_zip['files'],
435
443
  )
444
+ module_input_path_new = os.path.join(self.job_temporary_dir, "runtime." + JobStorage.module_input_file_name)
445
+ open(module_input_path_new, 'wb').write(module_input_with_runtime_zip_serialized)
436
446
  return self._run_app_version(
437
447
  module['image_uri'],
438
- module_input_with_runtime_zip_serialized,
448
+ module_input_path_new,
439
449
  options['job'],
440
450
  module_output_path,
441
451
  )
@@ -461,7 +471,7 @@ class JobWorker:
461
471
  # Log memory and disk before pulling and executing module
462
472
  log_disk_and_memory_usage_info()
463
473
 
464
- executor_instance.execute_module(module_input_serialized, module_output_path)
474
+ executor_instance.execute_module(module_input_path, module_output_path)
465
475
 
466
476
  def _connect_to_parent(self):
467
477
  try:
@@ -587,7 +597,7 @@ class JobWorker:
587
597
  may_contain_user_data=False
588
598
  ) from exception
589
599
 
590
- def _run_root_job(self, module_input_serialized: bytes) -> str:
600
+ def _run_root_job(self, module_input_path: str) -> str:
591
601
  # Make typechecker happy
592
602
  if not self._root_job_wrapper or not self.job_temporary_dir:
593
603
  raise BioLibError('Undefined job_wrapper or job_temporary_dir')
@@ -595,7 +605,7 @@ class JobWorker:
595
605
  main_module_output_path = os.path.join(self.job_temporary_dir, JobStorage.module_output_file_name)
596
606
  self._run_job(
597
607
  job=self._root_job_wrapper['job'],
598
- module_input_serialized=module_input_serialized,
608
+ module_input_path=module_input_path,
599
609
  main_module_output_path=main_module_output_path,
600
610
  )
601
611
  self._send_status_update(StatusUpdate(progress=94, log_message='Computation finished'))
@@ -614,7 +624,9 @@ class JobWorker:
614
624
  job_temporary_dir=job_temporary_dir,
615
625
  )
616
626
  self._start_network_and_remote_host_proxies(job_dict)
617
- module_output_path = self._run_root_job(module_input_serialized)
627
+ module_input_path = os.path.join(self.job_temporary_dir, JobStorage.module_input_file_name)
628
+ open(module_input_path, 'wb').write(module_input_serialized)
629
+ module_output_path = self._run_root_job(module_input_path)
618
630
  with open(module_output_path, mode='rb') as module_output_file:
619
631
  module_output_serialized = module_output_file.read()
620
632
  return ModuleOutputV2(InMemoryIndexableBuffer(module_output_serialized))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pybiolib
3
- Version: 1.1.1896
3
+ Version: 1.1.1907
4
4
  Summary: BioLib Python Client
5
5
  Home-page: https://github.com/biolib
6
6
  License: MIT
@@ -3,9 +3,9 @@ README.md,sha256=_IH7pxFiqy2bIAmaVeA-iVTyUwWRjMIlfgtUbYTtmls,368
3
3
  biolib/__init__.py,sha256=nfZvVkrHZLvjvvlAvFzhvem9NMfqgmw8NWaCH9HGzew,4045
4
4
  biolib/_internal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  biolib/_internal/data_record/__init__.py,sha256=1Bk303i3rFet9veS56fIsrBYtT5X3n9vcsYMA6T6c5o,36
6
- biolib/_internal/data_record/data_record.py,sha256=6ap6f4RMz6FbdHbEfuazvN9ipP2nr54kA-9-W448wts,7127
6
+ biolib/_internal/data_record/data_record.py,sha256=brvr88Ri1ro-tHZ-_1S19mX5Yt4Tm7q1c5AoUZfpSNY,6990
7
7
  biolib/_internal/data_record/remote_storage_endpoint.py,sha256=LPq8Lr5FhKF9_o5K-bUdT7TeLe5XFUD0AAeTkNEVZug,1133
8
- biolib/_internal/http_client.py,sha256=cSBIzh00x2HL3BmLxt_GvDI7bWQMNytv_wOy7EXg8kI,4064
8
+ biolib/_internal/http_client.py,sha256=L1pLe4OJv1YyoZJgRWbUtofBj-aovqJpawCuFFbVYDw,4470
9
9
  biolib/_internal/push_application.py,sha256=H1PGNtVJ0vRC0li39gFMpPpjm6QeZ8Ob-7cLkLmxS_Y,10009
10
10
  biolib/_internal/runtime.py,sha256=un18gmB2wFOXVjKca1Oe6mZI-xGydz8C8seScNvnC2s,2197
11
11
  biolib/_internal/utils/__init__.py,sha256=p5vsIFyu-zYqBgdSMfwW9NC_jk7rXvvCbV4Bzd3As7c,630
@@ -59,14 +59,14 @@ biolib/compute_node/job_worker/cache_state.py,sha256=MwjSRzcJJ_4jybqvBL4xdgnDYSI
59
59
  biolib/compute_node/job_worker/cache_types.py,sha256=ajpLy8i09QeQS9dEqTn3T6NVNMY_YsHQkSD5nvIHccQ,818
60
60
  biolib/compute_node/job_worker/docker_image_cache.py,sha256=ansHIkJIq_EMW1nZNlW-RRLVVeKWTbzNICYaOHpKiRE,7460
61
61
  biolib/compute_node/job_worker/executors/__init__.py,sha256=bW6t1qi3PZTlHM4quaTLa8EI4ALTCk83cqcVJfJfJfE,145
62
- biolib/compute_node/job_worker/executors/docker_executor.py,sha256=ezXRhVBW5dYpLJjM2m5Qf-I6PrrNeBdEYjApjo7XVso,26419
62
+ biolib/compute_node/job_worker/executors/docker_executor.py,sha256=n4BEn-bdL10uVvMDwBazK14NY25Fy_IhKY1fNRoX8LI,26455
63
63
  biolib/compute_node/job_worker/executors/docker_types.py,sha256=VhsU1DKtJjx_BbCkVmiPZPH4ROiL1ygW1Y_s1Kbpa2o,216
64
64
  biolib/compute_node/job_worker/executors/tars/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
65
65
  biolib/compute_node/job_worker/executors/types.py,sha256=yP5gG39hr-DLnw9bOE--VHi-1arDbIYiGuV1rlTbbHI,1466
66
66
  biolib/compute_node/job_worker/job_legacy_input_wait_timeout_thread.py,sha256=_cvEiZbOwfkv6fYmfrvdi_FVviIEYr_dSClQcOQaUWM,1198
67
67
  biolib/compute_node/job_worker/job_max_runtime_timer_thread.py,sha256=K_xgz7IhiIjpLlXRk8sqaMyLoApcidJkgu29sJX0gb8,1174
68
- biolib/compute_node/job_worker/job_storage.py,sha256=Ol43f43W6aD2EUkA6G2i9-WxdREr5JPSjo1xFylddOQ,4030
69
- biolib/compute_node/job_worker/job_worker.py,sha256=QifGpDBn1ojJ5b43--XyXmz8YqsgNlGskh-z8mkYQqg,28147
68
+ biolib/compute_node/job_worker/job_storage.py,sha256=LNkklckDLbYgCHsK5FGrEK75Kw-H4f4JcTCAtuE9His,4035
69
+ biolib/compute_node/job_worker/job_worker.py,sha256=LH8URvDXHa2TT9yk5zUN0RKJGnf4h7WMVx70yQ8GniI,28986
70
70
  biolib/compute_node/job_worker/large_file_system.py,sha256=XXqRlVtYhs-Ji9zQGIk5KQPXFO_Q5jJH0nnlw4GkeMY,10461
71
71
  biolib/compute_node/job_worker/mappings.py,sha256=Z48Kg4nbcOvsT2-9o3RRikBkqflgO4XeaWxTGz-CNvI,2499
72
72
  biolib/compute_node/job_worker/utilization_reporter_thread.py,sha256=7tm5Yk9coqJ9VbEdnO86tSXI0iM0omwIyKENxdxiVXk,8575
@@ -105,8 +105,8 @@ biolib/utils/cache_state.py,sha256=u256F37QSRIVwqKlbnCyzAX4EMI-kl6Dwu6qwj-Qmag,3
105
105
  biolib/utils/multipart_uploader.py,sha256=XvGP1I8tQuKhAH-QugPRoEsCi9qvbRk-DVBs5PNwwJo,8452
106
106
  biolib/utils/seq_util.py,sha256=jC5WhH63FTD7SLFJbxQGA2hOt9NTwq9zHl_BEec1Z0c,4907
107
107
  biolib/utils/zip/remote_zip.py,sha256=0wErYlxir5921agfFeV1xVjf29l9VNgGQvNlWOlj2Yc,23232
108
- pybiolib-1.1.1896.dist-info/LICENSE,sha256=F2h7gf8i0agDIeWoBPXDMYScvQOz02pAWkKhTGOHaaw,1067
109
- pybiolib-1.1.1896.dist-info/METADATA,sha256=_yVGo6mNI1U75uCSkFegjMgTtSmymqhwh-VzZP1885M,1508
110
- pybiolib-1.1.1896.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
111
- pybiolib-1.1.1896.dist-info/entry_points.txt,sha256=p6DyaP_2kctxegTX23WBznnrDi4mz6gx04O5uKtRDXg,42
112
- pybiolib-1.1.1896.dist-info/RECORD,,
108
+ pybiolib-1.1.1907.dist-info/LICENSE,sha256=F2h7gf8i0agDIeWoBPXDMYScvQOz02pAWkKhTGOHaaw,1067
109
+ pybiolib-1.1.1907.dist-info/METADATA,sha256=Y7GVDjw8XNDr0aJmJECOojLgtBZ6UfAvIgOPoXtsr08,1508
110
+ pybiolib-1.1.1907.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
111
+ pybiolib-1.1.1907.dist-info/entry_points.txt,sha256=p6DyaP_2kctxegTX23WBznnrDi4mz6gx04O5uKtRDXg,42
112
+ pybiolib-1.1.1907.dist-info/RECORD,,