File: progress_bar.rst

package info (click to toggle)
python-cleo 2.2.1-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,120 kB
  • sloc: python: 8,293; makefile: 22; sh: 2
file content (219 lines) | stat: -rw-r--r-- 6,745 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
Progress Bar
############

When executing longer-running commands, it may be helpful to show progress information,
which updates as your command runs:

.. image:: progress_2.gif

To display progress details, use the ``progress_bar()`` method (which returns a ``ProgressBar`` instance),
pass it a total number of units, and advance the progress as the command executes:

.. code-block:: python

    def handle(self):
        # Create a new progress bar (50 units)
        progress = self.progress_bar(50)

        # Start and displays the progress bar
        for _ in range(50):
            # ... do some work

            # Advance the progress bar 1 unit
            progress.advance()

            # You can also advance the progress bar by more than 1 unit
            # progress.advance(3)

        # Ensure that the progress bar is at 100%
        progress.finish()

Instead of advancing the bar by a number of steps (with the ``advance()`` method),
you can also set the current progress by calling the ``set_progress()`` method.

.. tip::

    If your platform doesn't support ANSI codes, updates to the progress bar are added as new lines.
    To prevent the output from being flooded, adjust the ``set_redraw_frequency()`` accordingly.
    By default, when using a ``max``, the redraw frequency is set to *10%* of your ``max``.

If you don't know the number of steps in advance,
just omit the steps argument when using the ``progress_bar`` method:

.. code-block:: python

    progress = self.progress_bar()

The progress will then be displayed as a throbber:

.. code-block:: text

    # no max steps (displays it like a throbber)
       0 [>---------------------------]
       5 [----->----------------------]
       5 [============================]

    # max steps defined
     0/3 [>---------------------------]   0%
     1/3 [=========>------------------]  33%
     3/3 [============================] 100%

Whenever your task is finished, don't forget to call ``finish()``
to ensure that the progress bar display is refreshed with a 100% completion.

.. note::

    If you want to output something while the progress bar is running, call ``clear()`` first.
    After you're done, call ``display()`` to show the progress bar again.


Customizing the Progress Bar
============================

Built-in Formats
----------------

By default, the information rendered on a progress bar depends
on the current level of verbosity of the ``IO`` instance:

.. code-block:: text

    # Verbosity.NORMAL (CLI with no verbosity flag)
     0/3 [>---------------------------]   0%
     1/3 [=========>------------------]  33%
     3/3 [============================] 100%

    # Verbosity.VERBOSE (-v)
     0/3 [>---------------------------]   0%  1 sec
     1/3 [=========>------------------]  33%  1 sec
     3/3 [============================] 100%  1 sec

    # Verbosity.VERY_VERBOSE (-vv)
     0/3 [>---------------------------]   0%  1 sec
     1/3 [=========>------------------]  33%  1 sec
     3/3 [============================] 100%  1 sec

    # Verbosity.DEBUG (-vvv)
     0/3 [>---------------------------]   0%  1 sec/1 sec  1.0 MB
     1/3 [=========>------------------]  33%  1 sec/1 sec  1.0 MB
     3/3 [============================] 100%  1 sec/1 sec  1.0 MB

.. note::

    If you call a command with the quiet flag (``-q``), the progress bar won't be displayed.

Instead of relying on the verbosity mode of the current command,
you can also force a format via ``set_format()``:

.. code-block:: python

    progress.set_format('verbose')

The built-in formats are the following:

* ``normal``
* ``verbose``
* ``very_verbose``
* ``debug``

If you don't set the number of steps for your progress bar, use the ``_nomax`` variants:

* ``normal_nomax``
* ``verbose_nomax``
* ``very_verbose_nomax``
* ``debug_nomax``

Custom Formats
--------------

Instead of using the built-in formats, you can also set your own:

.. code-block:: python

    progress.set_format('%bar%')

This sets the format to only display the progress bar itself:

.. code-block:: text

    >---------------------------
    =========>------------------
    ============================

A progress bar format is a string that contains specific placeholders
(a name enclosed with the ``%`` character); the placeholders are replaced based
on the current progress of the bar. Here is a list of the built-in placeholders:

* ``current``: The current step
* ``max``: The maximum number of steps (or 0 if no max is defined)
* ``bar``: The bar itself
* ``percent``: The percentage of completion (not available if no max is defined)
* ``elapsed``: The time elapsed since the start of the progress bar
* ``remaining``: The remaining time to complete the task (not available if no max is defined)
* ``estimated``: The estimated time to complete the task (not available if no max is defined)
* ``memory``: The current memory usage
* ``message``: The current message attached to the progress bar

For instance, here is how you could set the format to be the same as the ``debug`` one:

.. code-block:: python

    progress.set_format(' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s% %memory:6s%')

Notice the ``:6s`` part added to some placeholders?
That's how you can tweak the appearance of the bar (formatting and alignment).
The part after the colon (``:``) is used to set the format of the string.

The ``message`` placeholder is a bit special as you must set the value yourself:

.. code-block:: python

    progress.set_message('Task starts')
    progress.start()

    progress.set_message('Task in progress...')
    progress.advance()

    # ...

    progress.set_message('Task is finished')
    progress.finish()

Bar Settings
------------

Amongst the placeholders, ``bar`` is a bit special as all the characters used to display it can be customized:

.. code-block:: python

    # the finished part of the bar
    progress.set_bar_character('<comment>=</comment>')

    # the unfinished part of the bar
    progress.set_empty_bar_character(' ')

    # the progress character
    progress.set_progress_character('|')

    # the bar width
    progress.set_bar_width(50)


.. warning::

    For performance reasons, be careful if you set the total number of steps
    to a high number. For example, if you're iterating over a large number of
    items, consider setting the redraw frequency to a higher value by calling
    ``ProgressHelper.set_redraw_frequency()``, so it updates on only some iterations:

    .. code-block:: python

        progress.start(50000)

        # update every 100 iterations
        progress.set_redraw_frequency(100)

        for _ in range(50000)
            # ... do some work

            progress.advance()