33
44import os as _os
55
6+ from typing import Dict as _Dict , Any as _Any
7+
68import log21 as _log21
79from log21 .Logger import Logger as _Logger
810from log21 .StreamHandler import ColorizingStreamHandler as _ColorizingStreamHandler
@@ -39,7 +41,8 @@ class ProgressBar:
3941
4042 def __init__ (self , * args , width : int = None , show_percentage : bool = True , prefix : str = '|' , suffix : str = '|' ,
4143 fill : str = '█' , empty : str = ' ' , format_ : str = None , style : str = '%' ,
42- new_line_when_complete : bool = True , colors : dict = None , logger : '_log21.Logger' = _logger ):
44+ new_line_when_complete : bool = True , colors : dict = None , logger : '_log21.Logger' = _logger ,
45+ additional_variables : _Dict [str , _Any ] = None ):
4346 """
4447 :param args: Prevents the use of positional arguments
4548 :param width: The width of the progress bar
@@ -53,6 +56,7 @@ def __init__(self, *args, width: int = None, show_percentage: bool = True, prefi
5356 :param new_line_when_complete: Whether to print a new line when the progress is complete or failed
5457 :param colors: The colors of the progress bar
5558 :param logger: The logger to use
59+ :param additional_variables: Additional variables to use in the format and their default values
5660 """
5761 self .width = width if width else _os .get_terminal_size ().columns - 1
5862 if self .width < 3 :
@@ -71,6 +75,16 @@ def __init__(self, *args, width: int = None, show_percentage: bool = True, prefi
7175 raise ValueError ('`empty` must be a single character' )
7276 if style not in ['%' , '{' ]:
7377 raise ValueError ('`style` must be either `%` or `{`' )
78+ if additional_variables :
79+ if not isinstance (additional_variables , dict ):
80+ raise TypeError ('`additional_variables` must be a dictionary' )
81+ for key , value in additional_variables .items ():
82+ if not isinstance (key , str ):
83+ raise TypeError ('`additional_variables` keys must be strings' )
84+ if not isinstance (value , str ):
85+ additional_variables [key ] = str (value )
86+ else :
87+ additional_variables = dict ()
7488
7589 self .colors = {
7690 'progress in-progress' : _gc ('LightYellow' ),
@@ -105,24 +119,30 @@ def __init__(self, *args, width: int = None, show_percentage: bool = True, prefi
105119 for key , value in colors .items ():
106120 self .colors [key ] = value
107121 self .logger = logger
122+ self .additional_variables = additional_variables
108123 self .i = 0
109124
110- def get_bar (self , progress : float , total : float ) :
125+ def get_bar (self , progress : float , total : float , ** kwargs ) -> str :
111126 if progress == total :
112- return self .progress_complete ()
127+ return self .progress_complete (** kwargs )
113128 elif progress > total or progress < 0 :
114- return self .progress_failed (progress , total )
129+ return self .progress_failed (progress , total , ** kwargs )
115130 else :
116- return self .progress_in_progress (progress , total )
131+ return self .progress_in_progress (progress , total , ** kwargs )
117132
118- def progress_in_progress (self , progress : float , total : float ):
133+ def progress_in_progress (self , progress : float , total : float , ** kwargs ):
119134 percentage = str (round (progress / total * 100 , 2 ))
120135 progress_dict = {
121136 'prefix' : self .prefix ,
122137 'bar' : '' ,
123138 'suffix' : self .suffix ,
124- 'percentage' : percentage
139+ 'percentage' : percentage ,
140+ ** self .additional_variables
125141 }
142+ for key , value in kwargs .items ():
143+ if key in ['prefix' , 'bar' , 'suffix' , 'percentage' ]:
144+ raise ValueError (f'`{ key } ` is a reserved keyword' )
145+ progress_dict [key ] = value
126146
127147 if self .style == '%' :
128148 used_characters = len (self .format % progress_dict )
@@ -142,28 +162,34 @@ def progress_in_progress(self, progress: float, total: float):
142162
143163 progress_dict = {
144164 'prefix' : self .colors ['prefix-color in-progress' ] + self .prefix + self .colors ['reset-color' ],
145- 'bar' : self .colors ['progress in-progress' ] +
146- ( self . fill * fill_length + spinner_char + self .empty * empty_length ) + self .colors ['reset-color' ],
165+ 'bar' : self .colors ['progress in-progress' ] + ( self . fill * fill_length + spinner_char +
166+ self .empty * empty_length ) + self .colors ['reset-color' ],
147167 'suffix' : self .colors ['suffix-color in-progress' ] + self .suffix + self .colors ['reset-color' ],
148- 'percentage' : self .colors ["percentage in-progress" ] + str (percentage ) + self .colors ['reset-color' ]
168+ 'percentage' : self .colors ["percentage in-progress" ] + str (percentage ) + self .colors ['reset-color' ],
169+ ** self .additional_variables
149170 }
171+ for key , value in kwargs .items ():
172+ progress_dict [key ] = value
150173
151174 if self .style == '%' :
152- bar = self .format % progress_dict
175+ return ' \r ' + self .format % progress_dict + self . colors [ 'reset-color' ]
153176 elif self .style == '{' :
154- bar = self .format .format (** progress_dict )
177+ return ' \r ' + self .format .format (** progress_dict ) + self . colors [ 'reset-color' ]
155178 else :
156179 raise ValueError ('`style` must be either `%` or `{`' )
157180
158- return '\r ' + bar + self .colors ['reset-color' ]
159-
160- def progress_complete (self ):
181+ def progress_complete (self , ** kwargs ):
161182 progress_dict = {
162183 'prefix' : self .prefix ,
163184 'bar' : '' ,
164185 'suffix' : self .suffix ,
165- 'percentage' : '100'
186+ 'percentage' : '100' ,
187+ ** self .additional_variables
166188 }
189+ for key , value in kwargs .items ():
190+ if key in ['prefix' , 'bar' , 'suffix' , 'percentage' ]:
191+ raise ValueError (f'`{ key } ` is a reserved keyword' )
192+ progress_dict [key ] = value
167193
168194 if self .style == '%' :
169195 bar_length = self .width - len (self .format % progress_dict )
@@ -176,25 +202,33 @@ def progress_complete(self):
176202 'prefix' : self .colors ['prefix-color complete' ] + self .prefix + self .colors ['reset-color' ],
177203 'bar' : self .colors ['progress complete' ] + (self .fill * bar_length ) + self .colors ['reset-color' ],
178204 'suffix' : self .colors ['suffix-color complete' ] + self .suffix + self .colors ['reset-color' ],
179- 'percentage' : self .colors ["percentage complete" ] + '100' + self .colors ['reset-color' ]
205+ 'percentage' : self .colors ["percentage complete" ] + '100' + self .colors ['reset-color' ],
206+ ** self .additional_variables
180207 }
208+ for key , value in kwargs .items ():
209+ progress_dict [key ] = value
181210
182211 if self .style == '%' :
183- bar = self .format % progress_dict
212+ return '\r ' + self .format % progress_dict + self .colors ['reset-color' ] + \
213+ ('\n ' if self .new_line_when_complete else '' )
184214 elif self .style == '{' :
185- bar = self .format .format (** progress_dict )
215+ return '\r ' + self .format .format (** progress_dict ) + self .colors ['reset-color' ] + \
216+ ('\n ' if self .new_line_when_complete else '' )
186217 else :
187218 raise ValueError ('`style` must be either `%` or `{`' )
188219
189- return '\r ' + bar + self .colors ['reset-color' ] + ('\n ' if self .new_line_when_complete else '' )
190-
191- def progress_failed (self , progress : float , total : float ):
220+ def progress_failed (self , progress : float , total : float , ** kwargs ):
192221 progress_dict = {
193222 'prefix' : self .prefix ,
194223 'bar' : '' ,
195224 'suffix' : self .suffix ,
196- 'percentage' : str (round (progress / total * 100 , 2 ))
225+ 'percentage' : str (round (progress / total * 100 , 2 )),
226+ ** self .additional_variables
197227 }
228+ for key , value in kwargs .items ():
229+ if key in ['prefix' , 'bar' , 'suffix' , 'percentage' ]:
230+ raise ValueError (f'`{ key } ` is a reserved keyword' )
231+ progress_dict [key ] = value
198232
199233 if self .style == '%' :
200234 bar_length = self .width - len (self .format % progress_dict )
@@ -212,8 +246,11 @@ def progress_failed(self, progress: float, total: float):
212246 'prefix' : self .colors ['prefix-color failed' ] + self .prefix + self .colors ['reset-color' ],
213247 'bar' : self .colors ['progress failed' ] + (bar_char * bar_length ) + self .colors ['reset-color' ],
214248 'suffix' : self .colors ['suffix-color failed' ] + self .suffix + self .colors ['reset-color' ],
215- 'percentage' : self .colors ["percentage failed" ] + progress_dict ['percentage' ] + self .colors ['reset-color' ]
249+ 'percentage' : self .colors ["percentage failed" ] + progress_dict ['percentage' ] + self .colors ['reset-color' ],
250+ ** self .additional_variables
216251 }
252+ for key , value in kwargs .items ():
253+ progress_dict [key ] = value
217254
218255 if self .style == '%' :
219256 bar = self .format % progress_dict
@@ -224,11 +261,11 @@ def progress_failed(self, progress: float, total: float):
224261
225262 return '\r ' + bar + self .colors ['reset-color' ] + ('\n ' if self .new_line_when_complete else '' )
226263
227- def __call__ (self , progress : float , total : float , logger : '_log21.Logger' = None ):
264+ def __call__ (self , progress : float , total : float , logger : '_log21.Logger' = None , ** kwargs ):
228265 if not logger :
229266 logger = self .logger
230267
231- logger .print (self .get_bar (progress , total ), end = '' )
268+ logger .print (self .get_bar (progress , total , ** kwargs ), end = '' )
232269
233- def update (self , progress : float , total : float , logger : '_log21.Logger' = None ):
234- self (progress , total , logger )
270+ def update (self , progress : float , total : float , logger : '_log21.Logger' = None , ** kwargs ):
271+ self (progress , total , logger , ** kwargs )
0 commit comments