pybiolib 1.2.874__py3-none-any.whl → 1.2.878__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,11 +1,11 @@
1
1
  import os
2
2
  import re
3
3
  import sys
4
+ import time
4
5
  from pathlib import Path
5
6
 
6
7
  import rich.progress
7
8
  import yaml
8
- from rich.console import Console
9
9
 
10
10
  from biolib import api, utils
11
11
  from biolib._internal.data_record.push_data import (
@@ -38,9 +38,14 @@ class DockerStatusUpdate(TypedDict, total=False):
38
38
 
39
39
 
40
40
  def process_docker_status_updates(status_updates: Iterable[DockerStatusUpdate], action: str) -> None:
41
- console = Console(force_terminal=True, force_interactive=True, legacy_windows=False)
41
+ if sys.stdout.isatty():
42
+ _process_docker_status_updates_with_progress_bar(status_updates, action)
43
+ else:
44
+ _process_docker_status_updates_with_logging(status_updates, action)
42
45
 
43
- with rich.progress.Progress(console=console, refresh_per_second=20, transient=False) as progress:
46
+
47
+ def _process_docker_status_updates_with_progress_bar(status_updates: Iterable[DockerStatusUpdate], action: str) -> None:
48
+ with rich.progress.Progress() as progress:
44
49
  layer_id_to_task_id = {}
45
50
  overall_task_id = progress.add_task(description=f'[bold blue]{action} Docker image', total=None)
46
51
 
@@ -58,16 +63,12 @@ def process_docker_status_updates(status_updates: Iterable[DockerStatusUpdate],
58
63
  completed=progress_detail['current'],
59
64
  total=progress_detail['total'],
60
65
  )
61
- progress.refresh()
62
- sys.stdout.flush()
63
66
  elif update['status'] == 'Layer already exists':
64
67
  progress.update(
65
68
  completed=100,
66
69
  task_id=layer_id_to_task_id[layer_id],
67
70
  total=100,
68
71
  )
69
- progress.refresh()
70
- sys.stdout.flush()
71
72
  elif 'status' in update and 'id' in update:
72
73
  layer_id = update['id']
73
74
  status = update['status']
@@ -79,14 +80,10 @@ def process_docker_status_updates(status_updates: Iterable[DockerStatusUpdate],
79
80
  progress.update(
80
81
  task_id=layer_id_to_task_id[layer_id], description=f'[yellow]{status} layer {layer_id}'
81
82
  )
82
- progress.refresh()
83
- sys.stdout.flush()
84
83
  elif status in ['Pushing', 'Uploading']:
85
84
  progress.update(
86
85
  task_id=layer_id_to_task_id[layer_id], description=f'[cyan]{status} layer {layer_id}'
87
86
  )
88
- progress.refresh()
89
- sys.stdout.flush()
90
87
  elif status in ['Pushed', 'Uploaded']:
91
88
  progress.update(
92
89
  task_id=layer_id_to_task_id[layer_id],
@@ -94,8 +91,6 @@ def process_docker_status_updates(status_updates: Iterable[DockerStatusUpdate],
94
91
  completed=100,
95
92
  total=100,
96
93
  )
97
- progress.refresh()
98
- sys.stdout.flush()
99
94
  elif status == 'Layer already exists':
100
95
  progress.update(
101
96
  task_id=layer_id_to_task_id[layer_id],
@@ -103,18 +98,82 @@ def process_docker_status_updates(status_updates: Iterable[DockerStatusUpdate],
103
98
  completed=100,
104
99
  total=100,
105
100
  )
106
- progress.refresh()
107
- sys.stdout.flush()
108
101
  elif 'status' in update and update['status']:
109
102
  status = update['status']
110
103
  if status not in ['Preparing', 'Pushing', 'Pushed', 'Waiting', 'Layer already exists']:
111
104
  progress.update(task_id=overall_task_id, description=f'[bold blue]{action} Docker image - {status}')
112
- progress.refresh()
113
- sys.stdout.flush()
114
105
  elif 'status' not in update and 'progressDetail' not in update:
115
106
  print(update)
116
107
 
117
108
 
109
+ def _process_docker_status_updates_with_logging(status_updates: Iterable[DockerStatusUpdate], action: str) -> None:
110
+ layer_progress = {}
111
+ layer_status = {}
112
+ last_log_time = time.time()
113
+
114
+ logger.info(f'{action} Docker image...')
115
+
116
+ for update in status_updates:
117
+ current_time = time.time()
118
+
119
+ if 'progressDetail' in update and 'id' in update:
120
+ layer_id = update['id']
121
+ progress_detail = update['progressDetail']
122
+
123
+ if progress_detail and 'current' in progress_detail and 'total' in progress_detail:
124
+ current = progress_detail['current']
125
+ total = progress_detail['total']
126
+ percentage = (current / total * 100) if total > 0 else 0
127
+ layer_progress[layer_id] = percentage
128
+ layer_status[layer_id] = f'{action.lower()}'
129
+ elif update.get('status') == 'Layer already exists':
130
+ layer_progress[layer_id] = 100
131
+ layer_status[layer_id] = 'already exists'
132
+
133
+ elif 'status' in update and 'id' in update:
134
+ layer_id = update['id']
135
+ status = update['status']
136
+ layer_status[layer_id] = status.lower()
137
+
138
+ if status in ['Pushed', 'Uploaded'] or status == 'Layer already exists':
139
+ layer_progress[layer_id] = 100
140
+
141
+ elif 'status' in update and update['status']:
142
+ status = update['status']
143
+ if status not in ['Preparing', 'Pushing', 'Pushed', 'Waiting', 'Layer already exists']:
144
+ logger.info(f'{action} Docker image - {status}')
145
+
146
+ if current_time - last_log_time >= 10.0:
147
+ _log_progress_summary(action, layer_progress, layer_status)
148
+ last_log_time = current_time
149
+
150
+ _log_progress_summary(action, layer_progress, layer_status)
151
+ logger.info(f'{action} Docker image completed')
152
+
153
+
154
+ def _log_progress_summary(action: str, layer_progress: dict, layer_status: dict) -> None:
155
+ if not layer_progress and not layer_status:
156
+ return
157
+
158
+ completed_layers = sum(1 for progress in layer_progress.values() if progress >= 100)
159
+ total_layers = len(layer_progress) if layer_progress else len(layer_status)
160
+
161
+ if total_layers > 0:
162
+ overall_percentage = completed_layers / total_layers * 100
163
+ logger.info(
164
+ f'{action} progress: {completed_layers}/{total_layers} layers completed ({overall_percentage:.1f}%)'
165
+ )
166
+
167
+ active_layers = [
168
+ layer_id
169
+ for layer_id, status in layer_status.items()
170
+ if status in ['preparing', 'waiting', 'pushing', 'uploading'] and layer_progress.get(layer_id, 0) < 100
171
+ ]
172
+
173
+ if active_layers:
174
+ logger.info(f'Active layers: {", ".join(active_layers[:5])}{"..." if len(active_layers) > 5 else ""}')
175
+
176
+
118
177
  def set_app_version_as_active(
119
178
  app_version_uuid: str,
120
179
  ):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pybiolib
3
- Version: 1.2.874
3
+ Version: 1.2.878
4
4
  Summary: BioLib Python Client
5
5
  License: MIT
6
6
  Keywords: biolib
@@ -21,7 +21,7 @@ biolib/_internal/llm_instructions/.github/instructions/style-react-ts.instructio
21
21
  biolib/_internal/llm_instructions/.github/prompts/biolib_app_inputs.prompt.md,sha256=SMzXZImdID0yKjhE1fG54VrHdD8IVuwRxRKsMF-KjWs,697
22
22
  biolib/_internal/llm_instructions/.github/prompts/biolib_run_apps.prompt.md,sha256=-t1bmGr3zEFa6lKHaLcI98yq4Sg1TCMW8xbelNSHaOA,696
23
23
  biolib/_internal/llm_instructions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
- biolib/_internal/push_application.py,sha256=TaARo11N8oLsH0ptAepQ_8sqKrtr6dEg3ipItDNT7oo,15082
24
+ biolib/_internal/push_application.py,sha256=nyZ8vd4nMAqySYRBDfzCa1vAB1S2DU7sOt7H22Ph1Ss,17464
25
25
  biolib/_internal/runtime.py,sha256=BiHl4klUHr36MCpqKaUso4idHeBZfPAahLYRQrabFqA,486
26
26
  biolib/_internal/templates/__init__.py,sha256=NVbhLUMC8HITzkLvP88Qu7FHaL-SvQord-DX3gh1Ykk,24
27
27
  biolib/_internal/templates/init_template/.biolib/config.yml,sha256=y4ndTgbFvUE1UiGcIOqogT2Wm8jahGffeyU5rlCEltQ,427
@@ -140,8 +140,8 @@ biolib/utils/cache_state.py,sha256=u256F37QSRIVwqKlbnCyzAX4EMI-kl6Dwu6qwj-Qmag,3
140
140
  biolib/utils/multipart_uploader.py,sha256=XvGP1I8tQuKhAH-QugPRoEsCi9qvbRk-DVBs5PNwwJo,8452
141
141
  biolib/utils/seq_util.py,sha256=Ozk0blGtPur_D9MwShD02r_mphyQmgZkx-lOHOwnlIM,6730
142
142
  biolib/utils/zip/remote_zip.py,sha256=0wErYlxir5921agfFeV1xVjf29l9VNgGQvNlWOlj2Yc,23232
143
- pybiolib-1.2.874.dist-info/LICENSE,sha256=F2h7gf8i0agDIeWoBPXDMYScvQOz02pAWkKhTGOHaaw,1067
144
- pybiolib-1.2.874.dist-info/METADATA,sha256=2q9W-fdI4BFUX-RmWJDc48jXb3efsQuHhzrBcYy-yu8,1570
145
- pybiolib-1.2.874.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
146
- pybiolib-1.2.874.dist-info/entry_points.txt,sha256=p6DyaP_2kctxegTX23WBznnrDi4mz6gx04O5uKtRDXg,42
147
- pybiolib-1.2.874.dist-info/RECORD,,
143
+ pybiolib-1.2.878.dist-info/LICENSE,sha256=F2h7gf8i0agDIeWoBPXDMYScvQOz02pAWkKhTGOHaaw,1067
144
+ pybiolib-1.2.878.dist-info/METADATA,sha256=KbuzZ2QK3MdPKoTdKfS_BzHc-jp-OBMB2fty1BKNadg,1570
145
+ pybiolib-1.2.878.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
146
+ pybiolib-1.2.878.dist-info/entry_points.txt,sha256=p6DyaP_2kctxegTX23WBznnrDi4mz6gx04O5uKtRDXg,42
147
+ pybiolib-1.2.878.dist-info/RECORD,,