pybiolib 1.1.1881__py3-none-any.whl → 1.2.7.dev0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. biolib/__init__.py +11 -4
  2. biolib/_data_record/data_record.py +278 -0
  3. biolib/_internal/data_record/__init__.py +1 -1
  4. biolib/_internal/data_record/data_record.py +97 -151
  5. biolib/_internal/data_record/remote_storage_endpoint.py +18 -7
  6. biolib/_internal/file_utils.py +77 -0
  7. biolib/_internal/fuse_mount/__init__.py +1 -0
  8. biolib/_internal/fuse_mount/experiment_fuse_mount.py +209 -0
  9. biolib/_internal/http_client.py +31 -9
  10. biolib/_internal/lfs/__init__.py +1 -0
  11. biolib/_internal/libs/__init__.py +1 -0
  12. biolib/_internal/libs/fusepy/__init__.py +1257 -0
  13. biolib/_internal/push_application.py +6 -1
  14. biolib/_internal/runtime.py +3 -56
  15. biolib/_internal/types/__init__.py +4 -0
  16. biolib/_internal/types/app.py +9 -0
  17. biolib/_internal/types/data_record.py +40 -0
  18. biolib/_internal/types/experiment.py +10 -0
  19. biolib/_internal/types/resource.py +14 -0
  20. biolib/_internal/types/typing.py +7 -0
  21. biolib/_internal/utils/multinode.py +264 -0
  22. biolib/_runtime/runtime.py +84 -0
  23. biolib/api/__init__.py +1 -0
  24. biolib/api/client.py +39 -17
  25. biolib/app/app.py +34 -71
  26. biolib/biolib_api_client/api_client.py +9 -2
  27. biolib/biolib_api_client/app_types.py +3 -2
  28. biolib/biolib_api_client/biolib_job_api.py +6 -0
  29. biolib/biolib_api_client/job_types.py +4 -4
  30. biolib/biolib_api_client/lfs_types.py +8 -2
  31. biolib/biolib_binary_format/remote_endpoints.py +12 -10
  32. biolib/biolib_binary_format/utils.py +23 -3
  33. biolib/cli/auth.py +1 -1
  34. biolib/cli/data_record.py +45 -6
  35. biolib/cli/lfs.py +10 -6
  36. biolib/compute_node/cloud_utils/cloud_utils.py +13 -16
  37. biolib/compute_node/job_worker/executors/docker_executor.py +127 -108
  38. biolib/compute_node/job_worker/job_storage.py +17 -5
  39. biolib/compute_node/job_worker/job_worker.py +25 -15
  40. biolib/compute_node/remote_host_proxy.py +72 -84
  41. biolib/compute_node/webserver/webserver_types.py +0 -1
  42. biolib/compute_node/webserver/worker_thread.py +42 -39
  43. biolib/experiments/experiment.py +75 -44
  44. biolib/jobs/job.py +98 -19
  45. biolib/jobs/job_result.py +46 -21
  46. biolib/jobs/types.py +1 -1
  47. biolib/runtime/__init__.py +2 -1
  48. biolib/sdk/__init__.py +18 -7
  49. biolib/typing_utils.py +2 -7
  50. biolib/user/sign_in.py +2 -2
  51. biolib/utils/seq_util.py +38 -35
  52. {pybiolib-1.1.1881.dist-info → pybiolib-1.2.7.dev0.dist-info}/METADATA +1 -1
  53. {pybiolib-1.1.1881.dist-info → pybiolib-1.2.7.dev0.dist-info}/RECORD +57 -45
  54. biolib/experiments/types.py +0 -9
  55. biolib/lfs/__init__.py +0 -4
  56. biolib/lfs/utils.py +0 -153
  57. /biolib/{lfs → _internal/lfs}/cache.py +0 -0
  58. {pybiolib-1.1.1881.dist-info → pybiolib-1.2.7.dev0.dist-info}/LICENSE +0 -0
  59. {pybiolib-1.1.1881.dist-info → pybiolib-1.2.7.dev0.dist-info}/WHEEL +0 -0
  60. {pybiolib-1.1.1881.dist-info → pybiolib-1.2.7.dev0.dist-info}/entry_points.txt +0 -0
biolib/utils/seq_util.py CHANGED
@@ -1,32 +1,26 @@
1
1
  import re
2
2
  from io import BufferedIOBase
3
- from biolib.typing_utils import List, Optional, Dict, Union
4
3
 
5
- allowed_sequence_chars = set("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.")
6
-
7
-
8
- def find_invalid_sequence_characters(sequence):
9
- invalid_chars = [char for char in sequence if char not in allowed_sequence_chars]
10
- return invalid_chars
4
+ from biolib.typing_utils import Dict, List, Optional, Union
11
5
 
12
6
 
13
7
  class SeqUtilRecord:
14
8
  def __init__(
15
- self,
16
- sequence: str,
17
- sequence_id: str,
18
- description: Optional['str'],
19
- properties: Optional[Dict[str, str]] = None,
9
+ self,
10
+ sequence: str,
11
+ sequence_id: str,
12
+ description: Optional['str'],
13
+ properties: Optional[Dict[str, str]] = None,
20
14
  ):
21
15
  self.sequence = sequence
22
16
  self.id = sequence_id # pylint: disable=invalid-name
23
17
  self.description = description
24
18
 
25
19
  if properties:
26
- disallowed_pattern = re.compile(r"[=\[\]\n]")
20
+ disallowed_pattern = re.compile(r'[=\[\]\n]')
27
21
  for key, value in properties.items():
28
- assert not bool(disallowed_pattern.search(key)), "Key cannot contain characters =[] and newline"
29
- assert not bool(disallowed_pattern.search(value)), "Value cannot contain characters =[] and newline"
22
+ assert not bool(disallowed_pattern.search(key)), 'Key cannot contain characters =[] and newline'
23
+ assert not bool(disallowed_pattern.search(value)), 'Value cannot contain characters =[] and newline'
30
24
  self.properties = properties
31
25
  else:
32
26
  self.properties = {}
@@ -38,24 +32,24 @@ class SeqUtilRecord:
38
32
  class SeqUtil:
39
33
  @staticmethod
40
34
  def parse_fasta(
41
- input_file: Union[str, BufferedIOBase, None] = None,
42
- default_header: Optional[str] = None,
43
- allow_any_sequence_characters: bool = False,
44
- allow_empty_sequence: bool = False,
45
- file_name: Optional[str] = None,
35
+ input_file: Union[str, BufferedIOBase, None] = None,
36
+ default_header: Optional[str] = None,
37
+ allow_any_sequence_characters: bool = False,
38
+ allow_empty_sequence: bool = True,
39
+ file_name: Optional[str] = None,
46
40
  ) -> List[SeqUtilRecord]:
47
41
  if input_file is None:
48
42
  if file_name:
49
43
  input_file = file_name
50
44
  else:
51
- raise ValueError("input_file must be a file name (str) or a BufferedIOBase object")
45
+ raise ValueError('input_file must be a file name (str) or a BufferedIOBase object')
52
46
  if isinstance(input_file, str):
53
- with open(input_file, 'r') as file_handle:
47
+ with open(input_file) as file_handle:
54
48
  data = file_handle.read().strip()
55
49
  elif isinstance(input_file, BufferedIOBase):
56
50
  data = input_file.read().decode('utf-8')
57
51
  else:
58
- raise ValueError("input_file must be a file name (str) or a BufferedIOBase object")
52
+ raise ValueError('input_file must be a file name (str) or a BufferedIOBase object')
59
53
  if not data:
60
54
  return []
61
55
 
@@ -71,9 +65,9 @@ class SeqUtil:
71
65
  raise Exception(f'No header line found in FASTA file "{file_name}"')
72
66
 
73
67
  splitted = []
74
- tmp_data = ""
68
+ tmp_data = ''
75
69
  for line in data.splitlines():
76
- if line.startswith(">"):
70
+ if line.startswith('>'):
77
71
  if tmp_data:
78
72
  splitted.append(tmp_data)
79
73
  tmp_data = line[1:].strip() + '\n'
@@ -89,23 +83,20 @@ class SeqUtil:
89
83
  sequence_data_splitted = sequence_data.strip().split('\n')
90
84
  header_line = sequence_data_splitted[0].split()
91
85
  sequence_id = header_line[0]
92
- description = sequence_data_splitted[0][len(sequence_id):].strip()
93
- sequence = "".join([seq.strip().upper() for seq in sequence_data_splitted[1:]])
86
+ description = sequence_data_splitted[0][len(sequence_id) :].strip()
87
+ sequence = ''.join([seq.strip() for seq in sequence_data_splitted[1:]])
94
88
 
95
89
  if not allow_any_sequence_characters:
96
- invalid_sequence_characters = find_invalid_sequence_characters(sequence)
90
+ invalid_sequence_characters = SeqUtil._find_invalid_sequence_characters(sequence)
97
91
  if len(invalid_sequence_characters) > 0:
98
92
  raise Exception(
99
93
  f'Error: Invalid character ("{invalid_sequence_characters[0]}") found in sequence {sequence_id}'
100
94
  )
101
95
  if not allow_empty_sequence and len(sequence) == 0:
102
- raise Exception(
103
- f'Error: No sequence found for fasta entry {sequence_id}'
104
- )
96
+ raise Exception(f'Error: No sequence found for fasta entry {sequence_id}')
97
+
98
+ parsed_sequences.append(SeqUtilRecord(sequence=sequence, sequence_id=sequence_id, description=description))
105
99
 
106
- parsed_sequences.append(
107
- SeqUtilRecord(sequence=sequence, sequence_id=sequence_id, description=description)
108
- )
109
100
  return parsed_sequences
110
101
 
111
102
  @staticmethod
@@ -116,5 +107,17 @@ class SeqUtil:
116
107
  if record.properties:
117
108
  for key, value in record.properties.items():
118
109
  optional_description += f' [{key}={value}]'
119
- sequence = '\n'.join(record.sequence[i:i + 80] for i in range(0, len(record.sequence), 80))
110
+ sequence = '\n'.join(record.sequence[i : i + 80] for i in range(0, len(record.sequence), 80))
120
111
  file_handle.write(f'>{record.id}{optional_description}\n{sequence}\n')
112
+
113
+ @staticmethod
114
+ def _find_invalid_sequence_characters(sequence: str) -> List[str]:
115
+ allowed_sequence_chars = set('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.')
116
+ invalid_chars = [char for char in sequence if char not in allowed_sequence_chars]
117
+ return invalid_chars
118
+
119
+ @staticmethod
120
+ def _find_invalid_sequence_id_characters(sequence: str) -> List[str]:
121
+ allowed_chars = set('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.:*#')
122
+ invalid_chars = [char for char in sequence if char not in allowed_chars]
123
+ return invalid_chars
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pybiolib
3
- Version: 1.1.1881
3
+ Version: 1.2.7.dev0
4
4
  Summary: BioLib Python Client
5
5
  Home-page: https://github.com/biolib
6
6
  License: MIT
@@ -1,51 +1,67 @@
1
1
  LICENSE,sha256=F2h7gf8i0agDIeWoBPXDMYScvQOz02pAWkKhTGOHaaw,1067
2
2
  README.md,sha256=_IH7pxFiqy2bIAmaVeA-iVTyUwWRjMIlfgtUbYTtmls,368
3
- biolib/__init__.py,sha256=nfZvVkrHZLvjvvlAvFzhvem9NMfqgmw8NWaCH9HGzew,4045
3
+ biolib/__init__.py,sha256=_tThyzISH81yS9KXP_X3qEiKXmsIp5XOBcJIODfLVnc,4338
4
+ biolib/_data_record/data_record.py,sha256=CoyYRse5VdUBhQzzPfR9BkytgOsM-IZxkfMX1kyRnPk,12589
4
5
  biolib/_internal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- biolib/_internal/data_record/__init__.py,sha256=1Bk303i3rFet9veS56fIsrBYtT5X3n9vcsYMA6T6c5o,36
6
- biolib/_internal/data_record/data_record.py,sha256=oQ2R7bD1on5aPC3jXP7OOSPeuXkWEqRUR8GV4a6hsJA,6539
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
9
- biolib/_internal/push_application.py,sha256=H1PGNtVJ0vRC0li39gFMpPpjm6QeZ8Ob-7cLkLmxS_Y,10009
10
- biolib/_internal/runtime.py,sha256=un18gmB2wFOXVjKca1Oe6mZI-xGydz8C8seScNvnC2s,2197
6
+ biolib/_internal/data_record/__init__.py,sha256=fGdME6JGRU_2VxpJbYpGXYndjN-feUkmKY4fuMyq3cg,76
7
+ biolib/_internal/data_record/data_record.py,sha256=g_-jdy5-Zem3dthwxJj2OuQqkDGTyc-iGqN1rtYYD1A,4418
8
+ biolib/_internal/data_record/remote_storage_endpoint.py,sha256=eCptuZ4DMAPnaNCVDvpWXwXGI6Jac9U1N5dqU8Cj95Q,1732
9
+ biolib/_internal/file_utils.py,sha256=4jT6j7bB21c0JNn5BfnyWQib_zt0CVtJ_TiOFOStRcE,2604
10
+ biolib/_internal/fuse_mount/__init__.py,sha256=B_tM6RM2dBw-vbpoHJC4X3tOAaN1H2RDvqYJOw3xFwg,55
11
+ biolib/_internal/fuse_mount/experiment_fuse_mount.py,sha256=08aUdEq_bvqLBft_gSLjOClKDy5sBnMts1RfJf7AP_U,7012
12
+ biolib/_internal/http_client.py,sha256=Q7z7_DMI1EaVJSyevrra63piuee-NfqcAHRtQt76ZdA,5165
13
+ biolib/_internal/lfs/__init__.py,sha256=gSWo_xg61UniYgD7yNYxeT4I9uaXBCBSi3_nmZjnPpE,35
14
+ biolib/_internal/lfs/cache.py,sha256=pQS2np21rdJ6I3DpoOutnzPHpLOZgUIS8TMltUJk_k4,2226
15
+ biolib/_internal/libs/__init__.py,sha256=Jdf4tNPqe_oIIf6zYml6TiqhL_02Vyqwge6IELrAFhw,98
16
+ biolib/_internal/libs/fusepy/__init__.py,sha256=AWDzNFS-XV_5yKb0Qx7kggIhPzq1nj_BZS5y2Nso08k,41944
17
+ biolib/_internal/push_application.py,sha256=b1WvlijJYOLp7f43AoAzjINKkALM9DVB8yfSetEP4Z4,10381
18
+ biolib/_internal/runtime.py,sha256=BiHl4klUHr36MCpqKaUso4idHeBZfPAahLYRQrabFqA,486
19
+ biolib/_internal/types/__init__.py,sha256=11ZucS8jKeLGAAswXyKI7FH2KLHd6T9Sh8ZK2Ar3jlk,152
20
+ biolib/_internal/types/app.py,sha256=Mz2QGD_jESX-K9JYnLWPo4YA__Q_1FQQTk9pvidCohU,118
21
+ biolib/_internal/types/data_record.py,sha256=AHoIiwVqeHj0HozQxFRAyxk-d3XJgLWno4ic1z9eTrQ,865
22
+ biolib/_internal/types/experiment.py,sha256=D94iBdn2nS92lRW-TOs1a2WKXJD5ZtmzL4ypggKX2ys,176
23
+ biolib/_internal/types/resource.py,sha256=G-vPkZoe4Um6FPxsQZtRzAlbSW5sDW4NFkbjn21I3V4,372
24
+ biolib/_internal/types/typing.py,sha256=D4EKKEe7kDx0K6lJi-H_XLtk-8w6nu2fdqn9bvzI-Xo,288
11
25
  biolib/_internal/utils/__init__.py,sha256=p5vsIFyu-zYqBgdSMfwW9NC_jk7rXvvCbV4Bzd3As7c,630
12
- biolib/api/__init__.py,sha256=iIO8ZRdn7YDhY5cR47-Wo1YsNOK8H6RN6jn8yor5WJI,137
13
- biolib/api/client.py,sha256=MtDkH2Amr2Fko-bCR5DdookJu0yZ1q-6K_PPg4KK_Ek,2941
26
+ biolib/_internal/utils/multinode.py,sha256=UnM08GXc8U-p0eoSleer4BIgngIsn_fgh9FxRQJkIiI,8068
27
+ biolib/_runtime/runtime.py,sha256=oVgTnDDJv9L4BUP1_sd0oAj4LLyyiPSQdhp7ixWARvw,2923
28
+ biolib/api/__init__.py,sha256=mQ4u8FijqyLzjYMezMUUbbBGNB3iFmkNdjXnWPZ7Jlw,138
29
+ biolib/api/client.py,sha256=FRpdH5aI187b_I_4HUNi680v4iOP65z5f2RcUo8D8MA,3559
14
30
  biolib/app/__init__.py,sha256=cdPtcfb_U-bxb9iSL4fCEq2rpD9OjkyY4W-Zw60B0LI,37
15
- biolib/app/app.py,sha256=r63gDoH1s8uQOGITmiKOVIrYDYdMrB5nwXHNRt2Da2M,10197
31
+ biolib/app/app.py,sha256=P2RwaDAskUHzlciuTJUroqUocRwoyOLT6YbgMyCRRDI,8484
16
32
  biolib/app/search_apps.py,sha256=K4a41f5XIWth2BWI7OffASgIsD0ko8elCax8YL2igaY,1470
17
33
  biolib/biolib_api_client/__init__.py,sha256=E5EMa19wJoblwSdQPYrxc_BtIeRsAuO0L_jQweWw-Yk,182
18
- biolib/biolib_api_client/api_client.py,sha256=J03jRVvod1bgwwAZ3BZVKlUSJi43-ev2DUB0j63GZpc,7189
19
- biolib/biolib_api_client/app_types.py,sha256=rEw4HICV7ujdmlzM3BjRcMNMbiYItliivpH0rkeJx4s,2465
34
+ biolib/biolib_api_client/api_client.py,sha256=ciNx4ybpyKG5LEf4KQdGEz13r0jTxImyQat4_HDecD0,7373
35
+ biolib/biolib_api_client/app_types.py,sha256=1sXz9XnLRKNALMglNdTbew7AL6OkcUan0MPdj4xQLis,2456
20
36
  biolib/biolib_api_client/auth.py,sha256=kjm0ZHnH3I8so3su2sZbBxNHYp-ZUdrZ5lwQ0K36RSw,949
21
37
  biolib/biolib_api_client/biolib_app_api.py,sha256=DndlVxrNTes6DOaWyMINLGZQCRMWVvR7gwt5HVlyf5Y,4240
22
- biolib/biolib_api_client/biolib_job_api.py,sha256=IpFahcRzm7GNy8DJ-XHYe-x7r4Voba8o22IXw5puHn8,6782
38
+ biolib/biolib_api_client/biolib_job_api.py,sha256=7bKfav3-12ewXkEUoLdCmbWdebW8148kxfGJW9SsXZI,7125
23
39
  biolib/biolib_api_client/common_types.py,sha256=RH-1KNHqUF-EkTpfPOSTt5Mq1GPdfju_cqXDesscO1I,123
24
- biolib/biolib_api_client/job_types.py,sha256=XlDIxijxymLoJcClXhl91h1E4b2fT3pszO9wjlssD4A,1284
25
- biolib/biolib_api_client/lfs_types.py,sha256=xaGjE-yUyNVM3LyKdslJn5ZXWp6_kVCd4o-ch8Czfm4,227
40
+ biolib/biolib_api_client/job_types.py,sha256=Dl4NhU2xpgpXV-7YIoDf6WL63SLR5bni55OX8x5539M,1300
41
+ biolib/biolib_api_client/lfs_types.py,sha256=joZWP6-sa5_Ug_6xIp5fHAgEo_bqLE3rbleQocZtDcg,339
26
42
  biolib/biolib_api_client/user_state.py,sha256=XcgWV-MgVk88mIlMmnu8yHxMu8OCaw8o0tk7TVo5Hcg,637
27
43
  biolib/biolib_binary_format/__init__.py,sha256=HMl5SdX_VUWE4OQzi4Jf_yFvC7b0bSPOGPHYi9dWM2Q,185
28
44
  biolib/biolib_binary_format/base_bbf_package.py,sha256=vxRV4iKy0dXeDOlFWnMFI0hGnDBYDH5Cgh5gAfuObt8,959
29
45
  biolib/biolib_binary_format/file_in_container.py,sha256=j1eEPRxf_ew8I6G8sDiiZZxn4Wx1ppagfM9K8zTDG4U,3591
30
46
  biolib/biolib_binary_format/module_input.py,sha256=led2QhHeec_ymBPw5uEn3_3vJKI-1T8zrFQGqwEWLMY,2788
31
47
  biolib/biolib_binary_format/module_output_v2.py,sha256=J5ZO5gCSeudpE12EVDrjYrNTS2DwgszY-SVXT7Qjuyg,5913
32
- biolib/biolib_binary_format/remote_endpoints.py,sha256=aeW479pm4YQPF4hXYJoKfBq_auE1QW6r066HTcYRwOY,1447
48
+ biolib/biolib_binary_format/remote_endpoints.py,sha256=V48mwOj3eAQAKp-8DjtWUdEKUyC0WKc1pEiKTmtjrJY,1651
33
49
  biolib/biolib_binary_format/remote_stream_seeker.py,sha256=uyi6kJBU1C1DWfiuR0kRUQIY7nalG7ocgwgngd3Ul4U,1999
34
50
  biolib/biolib_binary_format/saved_job.py,sha256=nFHVFRNTNcAFGODLSiBntCtMk55QKwreUq6qLX80dI4,1125
35
51
  biolib/biolib_binary_format/stdout_and_stderr.py,sha256=WfUUJFFCBrtfXjuWIaRPiWCpuBLxfko68oxoTKhrwx8,1023
36
52
  biolib/biolib_binary_format/system_exception.py,sha256=T3iL4_cSHAHim3RSDPS8Xyb1mfteaJBZonSXuRltc28,853
37
53
  biolib/biolib_binary_format/system_status_update.py,sha256=aOELuQ0k-GtpaZTUxYd0GFomP_OInmrK585y6fuQuKE,1191
38
- biolib/biolib_binary_format/utils.py,sha256=1mZFX6KtbhvAXnzxnMJC_rYkiAjh9zhV31l68wVpA4A,4150
54
+ biolib/biolib_binary_format/utils.py,sha256=ra_plrh_Z10u98O2gW9uW2qzscQZCfq91SOznmDTY64,5170
39
55
  biolib/biolib_docker_client/__init__.py,sha256=aBfA6mtWSI5dBEfNNMD6bIZzCPloW4ghKm0wqQiljdo,1481
40
56
  biolib/biolib_download_container.py,sha256=8TmBV8iv3bCvkNlHa1SSsc4zl0wX_eaxhfnW5rvFIh8,1779
41
57
  biolib/biolib_errors.py,sha256=5m4lK2l39DafpoXBImEBD4EPH3ayXBX0JgtPzmGClow,689
42
58
  biolib/biolib_logging.py,sha256=J3E5H_LL5k6ZUim2C8gqN7E6lCBZMTpO4tnMpOPwG9U,2854
43
59
  biolib/cli/__init__.py,sha256=0v3c_J-U0k46c5ZWeQjLG_kTaKDJm81LBxQpDO2B_aI,1286
44
- biolib/cli/auth.py,sha256=wp-JQRzDgiEbxeUTxwlHfugk-9u6PiOtZiHl9brAgcA,2050
45
- biolib/cli/data_record.py,sha256=piN3QUbRAkMi4wpayghN4unFfuiNE5VCjI1gag4d8qg,1725
60
+ biolib/cli/auth.py,sha256=rpWGmXs6Fz6CGrO9K8ibPRszOdXG78Vig_boKaVCD9A,2082
61
+ biolib/cli/data_record.py,sha256=t8DfJK2EZ_SNZ9drDA_N5Jqy8DNwf9f5SlFrIaOvtv0,3501
46
62
  biolib/cli/download_container.py,sha256=HIZVHOPmslGE5M2Dsp9r2cCkAEJx__vcsDz5Wt5LRos,483
47
63
  biolib/cli/init.py,sha256=wQOfii_au-d30Hp7DdH-WVw-WVraKvA_zY4za1w7DE8,821
48
- biolib/cli/lfs.py,sha256=S9Ov-HWwtpMeRcwclh0qItnzviOaQL4aI0nnaCcZ_MM,3771
64
+ biolib/cli/lfs.py,sha256=z2qHUwink85mv9yDgifbVKkVwuyknGhMDTfly_gLKJM,4151
49
65
  biolib/cli/push.py,sha256=TFi7O9tJ3zFe0VmtVTV3Vh9_xIMHnrc41xxcaBKU46g,813
50
66
  biolib/cli/run.py,sha256=BbvXLQ-XibjQ71Y2d4URMH_8dflNVwM0i3TIWhw_u_c,1634
51
67
  biolib/cli/runtime.py,sha256=Xv-nrma5xX8NidWcvbUKcUvuN5TCarZa4A8mPVmF-z0,361
@@ -53,60 +69,56 @@ biolib/cli/start.py,sha256=rg8VVY8rboFhf1iQo3zE3WA5oh_R1VWWfYJEO1gMReY,1737
53
69
  biolib/compute_node/.gitignore,sha256=GZdZ4g7HftqfOfasFpBC5zV1YQAbht1a7EzcXD6f3zg,45
54
70
  biolib/compute_node/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
71
  biolib/compute_node/cloud_utils/__init__.py,sha256=VZSScLqaz5tg_gpMvWgwkAu9Qf-vgW_QHRoDOaAmU44,67
56
- biolib/compute_node/cloud_utils/cloud_utils.py,sha256=KIZjBnZPBtHParrR_KnRl7N343sHXMQugH9lkwAwTFk,7621
72
+ biolib/compute_node/cloud_utils/cloud_utils.py,sha256=_iaKelsmQLLwbDKVXZMXPFZayZPH9iHXc4NISFP9uzk,7462
57
73
  biolib/compute_node/job_worker/__init__.py,sha256=ipdPWaABKYrltxny15e2kK8PWdEE7VzXbkKK6wM_zDk,71
58
74
  biolib/compute_node/job_worker/cache_state.py,sha256=MwjSRzcJJ_4jybqvBL4xdgnDYSIiw4s90pNn83Netoo,4830
59
75
  biolib/compute_node/job_worker/cache_types.py,sha256=ajpLy8i09QeQS9dEqTn3T6NVNMY_YsHQkSD5nvIHccQ,818
60
76
  biolib/compute_node/job_worker/docker_image_cache.py,sha256=ansHIkJIq_EMW1nZNlW-RRLVVeKWTbzNICYaOHpKiRE,7460
61
77
  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
78
+ biolib/compute_node/job_worker/executors/docker_executor.py,sha256=LcYc4x4-vkmRM1FN1SNj7xRj4qZUNVjQWtgbYMFg3JU,28029
63
79
  biolib/compute_node/job_worker/executors/docker_types.py,sha256=VhsU1DKtJjx_BbCkVmiPZPH4ROiL1ygW1Y_s1Kbpa2o,216
64
80
  biolib/compute_node/job_worker/executors/tars/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
65
81
  biolib/compute_node/job_worker/executors/types.py,sha256=yP5gG39hr-DLnw9bOE--VHi-1arDbIYiGuV1rlTbbHI,1466
66
82
  biolib/compute_node/job_worker/job_legacy_input_wait_timeout_thread.py,sha256=_cvEiZbOwfkv6fYmfrvdi_FVviIEYr_dSClQcOQaUWM,1198
67
83
  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
84
+ biolib/compute_node/job_worker/job_storage.py,sha256=lScHI3ubcHKagSEW243tgbIWXUfbWDHDjEOPMvXxJE8,4603
85
+ biolib/compute_node/job_worker/job_worker.py,sha256=fuWoYJo9HOqLmWl8yeCXh0mhT4ebbkrWac-BVb58khs,28842
70
86
  biolib/compute_node/job_worker/large_file_system.py,sha256=XXqRlVtYhs-Ji9zQGIk5KQPXFO_Q5jJH0nnlw4GkeMY,10461
71
87
  biolib/compute_node/job_worker/mappings.py,sha256=Z48Kg4nbcOvsT2-9o3RRikBkqflgO4XeaWxTGz-CNvI,2499
72
88
  biolib/compute_node/job_worker/utilization_reporter_thread.py,sha256=7tm5Yk9coqJ9VbEdnO86tSXI0iM0omwIyKENxdxiVXk,8575
73
89
  biolib/compute_node/job_worker/utils.py,sha256=wgxcIA8yAhUPdCwyvuuJ0JmreyWmmUoBO33vWtG60xg,1282
74
- biolib/compute_node/remote_host_proxy.py,sha256=spjYghbqwX3dFrmedGvXZGXEsnwop1IbbyrXTv1PWz0,15080
90
+ biolib/compute_node/remote_host_proxy.py,sha256=ibkWqvLJJHwOM7GzYqJV613QPacU5392vjnDK8BNJIU,15213
75
91
  biolib/compute_node/socker_listener_thread.py,sha256=T5_UikA3MB9bD5W_dckYLPTgixh72vKUlgbBvj9dbM0,1601
76
92
  biolib/compute_node/socket_sender_thread.py,sha256=YgamPHeUm2GjMFGx8qk-99WlZhEs-kAb3q_2O6qByig,971
77
93
  biolib/compute_node/utils.py,sha256=M7i_WTyxbFM3Lri9RWZ_8FeQNYrQIWpKGLfp2I55oeY,4677
78
94
  biolib/compute_node/webserver/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
79
95
  biolib/compute_node/webserver/gunicorn_flask_application.py,sha256=jPfR_YvNBekLUXWo_vHFV-FIwlb8s8tacKmGHvh93qc,914
80
96
  biolib/compute_node/webserver/webserver.py,sha256=15PkRyhtdtSgFDxa0z78aPO4ciZURsFqJYi-HtUmZF8,6494
81
- biolib/compute_node/webserver/webserver_types.py,sha256=Vmt1ZDecYhGBVEYWcW1DVxee1DEPqkqyxQzbsObXWbI,420
97
+ biolib/compute_node/webserver/webserver_types.py,sha256=2t8EaFKESnves3BA_NBdnS2yAdo1qwamCFHiSt888nE,380
82
98
  biolib/compute_node/webserver/webserver_utils.py,sha256=XWvwYPbWNR3qS0FYbLLp-MDDfVk0QdaAmg3xPrT0H2s,4234
83
- biolib/compute_node/webserver/worker_thread.py,sha256=26tG73TADnOcXsAr7Iyf6smrLlCqB4x-vvmpUb8WqnA,11569
99
+ biolib/compute_node/webserver/worker_thread.py,sha256=GRRBUqXdMKvbjyLQhYlqGIbFKeU2iiEXIe5IXi9wgdg,11806
84
100
  biolib/experiments/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
85
- biolib/experiments/experiment.py,sha256=xUd3LkV5ztFIjTx_ehBu8e-flvfuQnYimFtPj1upzb0,5942
86
- biolib/experiments/types.py,sha256=n9GxdFA7cLMfHvLLqLmZzX31ELeSSkMXFoEEdFsdWGY,171
101
+ biolib/experiments/experiment.py,sha256=jIRixmQm3Gq9YdJ3I0-rE1vFukXqq6U4zXehFOJ1yZk,7614
87
102
  biolib/jobs/__init__.py,sha256=aIb2H2DHjQbM2Bs-dysFijhwFcL58Blp0Co0gimED3w,32
88
- biolib/jobs/job.py,sha256=_lYtqaTrtq3ayDvnaB9RuUMBTxCRKYGKVADUd473pWQ,15718
89
- biolib/jobs/job_result.py,sha256=8GasUmUXD8SjUYrE2N-HrDx7-AI6TEkFONH8H91t01Q,4913
90
- biolib/jobs/types.py,sha256=4OAvlhOKANzFMrZDd-mhXpEd8RaKcx8sPneZUoWhJ2U,970
91
- biolib/lfs/__init__.py,sha256=Qv8vdYeK43JecT4SsE93ZYE2VmNiZENdNpW8P9-omxs,115
92
- biolib/lfs/cache.py,sha256=pQS2np21rdJ6I3DpoOutnzPHpLOZgUIS8TMltUJk_k4,2226
93
- biolib/lfs/utils.py,sha256=HSs7F2wXklYhhv5tabfaeC5noXJyxRjbGD5IhWOVdxs,5918
94
- biolib/runtime/__init__.py,sha256=x1Ivydtu9TFTaX-Cofg_kGA-TI0zLon-ccrFiiVgBok,492
95
- biolib/sdk/__init__.py,sha256=77IBthMbwgmYymjQwLP4ny1X2ikvI1I0ocP6Eyzfyaw,1766
103
+ biolib/jobs/job.py,sha256=OfG8cLd3AjGjiMWRlJRZdVVbLsRWSX-OM5nxJhR6mPQ,19136
104
+ biolib/jobs/job_result.py,sha256=rALHiKYNaC9lHi_JJqBob1RubzNLwG9Z386kwRJjd2M,5885
105
+ biolib/jobs/types.py,sha256=qhadtH2KDC2WUOOqPiwke0YgtQY4FtuB71Stekq1k48,970
106
+ biolib/runtime/__init__.py,sha256=MlRepA11n2H-3plB5rzWyyHK2JmP6PiaP3i6x3vt0mg,506
107
+ biolib/sdk/__init__.py,sha256=amVp_jMxi2nqCcTsmL2aKUNGCAH3Yk4EzAnps9d1VH8,1928
96
108
  biolib/tables.py,sha256=acH7VjwAbadLo8P84FSnKEZxCTVsF5rEg9VPuxElNs8,872
97
109
  biolib/templates/__init__.py,sha256=Yx62sSyDCDesRQDQgmbDsLpfgEh93fWE8r9u4g2azXk,36
98
110
  biolib/templates/example_app.py,sha256=EB3E3RT4SeO_ii5nVQqJpi5KDGNE_huF1ub-e5ZFveE,715
99
- biolib/typing_utils.py,sha256=krMhxB3SedVQA3HXIrC7DBXWpHKWN5JNmXGcSrrysOc,263
111
+ biolib/typing_utils.py,sha256=ntzrlyTkUaO2OtccLYzCAGztGdca0WT5fikJUmSkT-Y,148
100
112
  biolib/user/__init__.py,sha256=Db5wtxLfFz3ID9TULSSTo77csw9tO6RtxMRvV5cqKEE,39
101
- biolib/user/sign_in.py,sha256=q-E2B3wLVwPU5plbITJXP4GDWWUzUcDpYu_y8BShNQ8,2039
113
+ biolib/user/sign_in.py,sha256=XTAmRPKfmg7VAaB8cT5wcmfxoPXeHqY8LmDiADF7zbw,2064
102
114
  biolib/utils/__init__.py,sha256=fwjciJyJicvYyZcVTzfDBgD0SKY13DeXqvTeG4qZIy8,5548
103
115
  biolib/utils/app_uri.py,sha256=Yq_-_VGugQhMMo6mM5f0G9yNlLkr0WK4j0Nrf3FE4xQ,2171
104
116
  biolib/utils/cache_state.py,sha256=u256F37QSRIVwqKlbnCyzAX4EMI-kl6Dwu6qwj-Qmag,3100
105
117
  biolib/utils/multipart_uploader.py,sha256=XvGP1I8tQuKhAH-QugPRoEsCi9qvbRk-DVBs5PNwwJo,8452
106
- biolib/utils/seq_util.py,sha256=jC5WhH63FTD7SLFJbxQGA2hOt9NTwq9zHl_BEec1Z0c,4907
118
+ biolib/utils/seq_util.py,sha256=ZQFcaE37B2dtucN2zDjOmdya_X0ITc1zBFZJNQY13XA,5183
107
119
  biolib/utils/zip/remote_zip.py,sha256=0wErYlxir5921agfFeV1xVjf29l9VNgGQvNlWOlj2Yc,23232
108
- pybiolib-1.1.1881.dist-info/LICENSE,sha256=F2h7gf8i0agDIeWoBPXDMYScvQOz02pAWkKhTGOHaaw,1067
109
- pybiolib-1.1.1881.dist-info/METADATA,sha256=oanwAPIfyI5nATML26HjNK4sjPb2ciuoyP2jLxg8Kbs,1508
110
- pybiolib-1.1.1881.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
111
- pybiolib-1.1.1881.dist-info/entry_points.txt,sha256=p6DyaP_2kctxegTX23WBznnrDi4mz6gx04O5uKtRDXg,42
112
- pybiolib-1.1.1881.dist-info/RECORD,,
120
+ pybiolib-1.2.7.dev0.dist-info/LICENSE,sha256=F2h7gf8i0agDIeWoBPXDMYScvQOz02pAWkKhTGOHaaw,1067
121
+ pybiolib-1.2.7.dev0.dist-info/METADATA,sha256=O1duMBotGWLsk_tKeihafeOizbCNQVWjCVT7SbzVTZ4,1510
122
+ pybiolib-1.2.7.dev0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
123
+ pybiolib-1.2.7.dev0.dist-info/entry_points.txt,sha256=p6DyaP_2kctxegTX23WBznnrDi4mz6gx04O5uKtRDXg,42
124
+ pybiolib-1.2.7.dev0.dist-info/RECORD,,
@@ -1,9 +0,0 @@
1
- from biolib.typing_utils import TypedDict
2
-
3
-
4
- class ExperimentDict(TypedDict):
5
- created_at: str
6
- job_count: int
7
- job_running_count: int
8
- name: str
9
- uuid: str
biolib/lfs/__init__.py DELETED
@@ -1,4 +0,0 @@
1
- from .cache import prune_lfs_cache
2
- from .utils import \
3
- push_large_file_system, \
4
- create_large_file_system
biolib/lfs/utils.py DELETED
@@ -1,153 +0,0 @@
1
- import io
2
- import os
3
- import zipfile as zf
4
- from pathlib import Path
5
-
6
- from biolib import utils, api
7
- from biolib.biolib_api_client import BiolibApiClient
8
- from biolib.biolib_api_client.lfs_types import LargeFileSystem, LargeFileSystemVersion
9
- from biolib.biolib_logging import logger
10
- from biolib.biolib_errors import BioLibError
11
- from biolib.typing_utils import List, Tuple, Iterator, Optional
12
- from biolib.utils.app_uri import parse_app_uri
13
-
14
-
15
- def get_files_and_size_of_directory(directory: str) -> Tuple[List[str], int]:
16
- data_size = 0
17
- file_list: List[str] = []
18
-
19
- for path, _, files in os.walk(directory):
20
- for file in files:
21
- file_path = os.path.join(path, file)
22
- if os.path.islink(file_path):
23
- continue # skip symlinks
24
-
25
- relative_file_path = file_path[len(directory) + 1:] # +1 to remove starting slash
26
- file_list.append(relative_file_path)
27
- data_size += os.path.getsize(file_path)
28
-
29
- return file_list, data_size
30
-
31
-
32
- def get_iterable_zip_stream(files: List[str], chunk_size: int) -> Iterator[bytes]:
33
- class ChunkedIOBuffer(io.RawIOBase):
34
- def __init__(self, chunk_size: int):
35
- super().__init__()
36
- self.chunk_size = chunk_size
37
- self.tmp_data = bytearray()
38
-
39
- def get_buffer_size(self):
40
- return len(self.tmp_data)
41
-
42
- def read_chunk(self):
43
- chunk = bytes(self.tmp_data[:self.chunk_size])
44
- self.tmp_data = self.tmp_data[self.chunk_size:]
45
- return chunk
46
-
47
- def write(self, data):
48
- data_length = len(data)
49
- self.tmp_data += data
50
- return data_length
51
-
52
- # create chunked buffer to hold data temporarily
53
- io_buffer = ChunkedIOBuffer(chunk_size)
54
-
55
- # create zip writer that will write to the io buffer
56
- zip_writer = zf.ZipFile(io_buffer, mode='w') # type: ignore
57
-
58
- for file_path in files:
59
- # generate zip info and prepare zip pointer for writing
60
- z_info = zf.ZipInfo.from_file(file_path)
61
- zip_pointer = zip_writer.open(z_info, mode='w')
62
- if Path(file_path).is_file():
63
- # read file chunk by chunk
64
- with open(file_path, 'br') as file_pointer:
65
- while True:
66
- chunk = file_pointer.read(chunk_size)
67
- if len(chunk) == 0:
68
- break
69
- # write the chunk to the zip
70
- zip_pointer.write(chunk)
71
- # if writing the chunk caused us to go over chunk_size, flush it
72
- if io_buffer.get_buffer_size() > chunk_size:
73
- yield io_buffer.read_chunk()
74
-
75
- zip_pointer.close()
76
-
77
- # flush any remaining data in the stream (e.g. zip file meta data)
78
- zip_writer.close()
79
- while True:
80
- chunk = io_buffer.read_chunk()
81
- if len(chunk) == 0:
82
- break
83
- yield chunk
84
-
85
-
86
- def create_large_file_system(lfs_uri: str) -> str:
87
- BiolibApiClient.assert_is_signed_in(authenticated_action_description='create a Large File System')
88
-
89
- uri_parsed = parse_app_uri(lfs_uri)
90
- response = api.client.post(
91
- path='/lfs/',
92
- data={
93
- 'account_handle': uri_parsed['account_handle_normalized'],
94
- 'name': uri_parsed['app_name'],
95
- },
96
- )
97
- lfs: LargeFileSystem = response.json()
98
- logger.info(f"Successfully created new Large File System '{lfs['uri']}'")
99
- return lfs['uri']
100
-
101
-
102
- def push_large_file_system(lfs_uri: str, input_dir: str, chunk_size_in_mb: Optional[int] = None) -> str:
103
- BiolibApiClient.assert_is_signed_in(authenticated_action_description='push data to a Large File System')
104
-
105
- if not os.path.isdir(input_dir):
106
- raise BioLibError(f'Could not find folder at {input_dir}')
107
-
108
- if os.path.realpath(input_dir) == '/':
109
- raise BioLibError('Pushing your root directory is not possible')
110
-
111
- original_working_dir = os.getcwd()
112
- os.chdir(input_dir)
113
- files_to_zip, data_size_in_bytes = get_files_and_size_of_directory(directory=os.getcwd())
114
-
115
- if data_size_in_bytes > 4_500_000_000_000:
116
- raise BioLibError('Attempted to push directory with a size larger than the limit of 4.5 TB')
117
-
118
- min_chunk_size_bytes = 10_000_000
119
- chunk_size_in_bytes: int
120
- if chunk_size_in_mb:
121
- chunk_size_in_bytes = chunk_size_in_mb * 1_000_000 # Convert megabytes to bytes
122
- if chunk_size_in_bytes < min_chunk_size_bytes:
123
- logger.warning('Specified chunk size is too small, using minimum of 10 MB instead.')
124
- chunk_size_in_bytes = min_chunk_size_bytes
125
- else:
126
- # Calculate chunk size based on max chunk count of 10_000, using 9_000 to be on the safe side
127
- chunk_size_in_bytes = max(min_chunk_size_bytes, int(data_size_in_bytes / 9_000))
128
-
129
- data_size_in_mb = round(data_size_in_bytes / 10 ** 6)
130
- print(f'Zipping {len(files_to_zip)} files, in total ~{data_size_in_mb}mb of data')
131
-
132
- response = api.client.post(path='/lfs/versions/', data={'resource_uri': lfs_uri})
133
- lfs_version: LargeFileSystemVersion = response.json()
134
- iterable_zip_stream = get_iterable_zip_stream(files=files_to_zip, chunk_size=chunk_size_in_bytes)
135
-
136
- multipart_uploader = utils.MultiPartUploader(
137
- use_process_pool=True,
138
- get_presigned_upload_url_request=dict(
139
- headers=None,
140
- requires_biolib_auth=True,
141
- path=f"/lfs/versions/{lfs_version['uuid']}/presigned_upload_url/",
142
- ),
143
- complete_upload_request=dict(
144
- headers=None,
145
- requires_biolib_auth=True,
146
- path=f"/lfs/versions/{lfs_version['uuid']}/complete_upload/",
147
- ),
148
- )
149
-
150
- multipart_uploader.upload(payload_iterator=iterable_zip_stream, payload_size_in_bytes=data_size_in_bytes)
151
- os.chdir(original_working_dir)
152
- logger.info(f"Successfully pushed a new LFS version '{lfs_version['uri']}'")
153
- return lfs_version['uri']
File without changes