jpayne@69: Metadata-Version: 2.1 jpayne@69: Name: tqdm jpayne@69: Version: 4.67.1 jpayne@69: Summary: Fast, Extensible Progress Meter jpayne@69: Maintainer-email: tqdm developers jpayne@69: License: MPL-2.0 AND MIT jpayne@69: Project-URL: homepage, https://tqdm.github.io jpayne@69: Project-URL: repository, https://github.com/tqdm/tqdm jpayne@69: Project-URL: changelog, https://tqdm.github.io/releases jpayne@69: Project-URL: wiki, https://github.com/tqdm/tqdm/wiki jpayne@69: Keywords: progressbar,progressmeter,progress,bar,meter,rate,eta,console,terminal,time jpayne@69: Classifier: Development Status :: 5 - Production/Stable jpayne@69: Classifier: Environment :: Console jpayne@69: Classifier: Environment :: MacOS X jpayne@69: Classifier: Environment :: Other Environment jpayne@69: Classifier: Environment :: Win32 (MS Windows) jpayne@69: Classifier: Environment :: X11 Applications jpayne@69: Classifier: Framework :: IPython jpayne@69: Classifier: Framework :: Jupyter jpayne@69: Classifier: Intended Audience :: Developers jpayne@69: Classifier: Intended Audience :: Education jpayne@69: Classifier: Intended Audience :: End Users/Desktop jpayne@69: Classifier: Intended Audience :: Other Audience jpayne@69: Classifier: Intended Audience :: System Administrators jpayne@69: Classifier: License :: OSI Approved :: MIT License jpayne@69: Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0) jpayne@69: Classifier: Operating System :: MacOS jpayne@69: Classifier: Operating System :: MacOS :: MacOS X jpayne@69: Classifier: Operating System :: Microsoft jpayne@69: Classifier: Operating System :: Microsoft :: MS-DOS jpayne@69: Classifier: Operating System :: Microsoft :: Windows jpayne@69: Classifier: Operating System :: POSIX jpayne@69: Classifier: Operating System :: POSIX :: BSD jpayne@69: Classifier: Operating System :: POSIX :: BSD :: FreeBSD jpayne@69: Classifier: Operating System :: POSIX :: Linux jpayne@69: Classifier: Operating System :: POSIX :: SunOS/Solaris jpayne@69: Classifier: Operating System :: Unix jpayne@69: Classifier: Programming Language :: Python jpayne@69: Classifier: Programming Language :: Python :: 3 jpayne@69: Classifier: Programming Language :: Python :: 3.7 jpayne@69: Classifier: Programming Language :: Python :: 3.8 jpayne@69: Classifier: Programming Language :: Python :: 3.9 jpayne@69: Classifier: Programming Language :: Python :: 3.10 jpayne@69: Classifier: Programming Language :: Python :: 3.11 jpayne@69: Classifier: Programming Language :: Python :: 3.12 jpayne@69: Classifier: Programming Language :: Python :: 3 :: Only jpayne@69: Classifier: Programming Language :: Python :: Implementation jpayne@69: Classifier: Programming Language :: Python :: Implementation :: IronPython jpayne@69: Classifier: Programming Language :: Python :: Implementation :: PyPy jpayne@69: Classifier: Programming Language :: Unix Shell jpayne@69: Classifier: Topic :: Desktop Environment jpayne@69: Classifier: Topic :: Education :: Computer Aided Instruction (CAI) jpayne@69: Classifier: Topic :: Education :: Testing jpayne@69: Classifier: Topic :: Office/Business jpayne@69: Classifier: Topic :: Other/Nonlisted Topic jpayne@69: Classifier: Topic :: Software Development :: Build Tools jpayne@69: Classifier: Topic :: Software Development :: Libraries jpayne@69: Classifier: Topic :: Software Development :: Libraries :: Python Modules jpayne@69: Classifier: Topic :: Software Development :: Pre-processors jpayne@69: Classifier: Topic :: Software Development :: User Interfaces jpayne@69: Classifier: Topic :: System :: Installation/Setup jpayne@69: Classifier: Topic :: System :: Logging jpayne@69: Classifier: Topic :: System :: Monitoring jpayne@69: Classifier: Topic :: System :: Shells jpayne@69: Classifier: Topic :: Terminals jpayne@69: Classifier: Topic :: Utilities jpayne@69: Requires-Python: >=3.7 jpayne@69: Description-Content-Type: text/x-rst jpayne@69: License-File: LICENCE jpayne@69: Requires-Dist: colorama; platform_system == "Windows" jpayne@69: Provides-Extra: dev jpayne@69: Requires-Dist: pytest>=6; extra == "dev" jpayne@69: Requires-Dist: pytest-cov; extra == "dev" jpayne@69: Requires-Dist: pytest-timeout; extra == "dev" jpayne@69: Requires-Dist: pytest-asyncio>=0.24; extra == "dev" jpayne@69: Requires-Dist: nbval; extra == "dev" jpayne@69: Provides-Extra: discord jpayne@69: Requires-Dist: requests; extra == "discord" jpayne@69: Provides-Extra: slack jpayne@69: Requires-Dist: slack-sdk; extra == "slack" jpayne@69: Provides-Extra: telegram jpayne@69: Requires-Dist: requests; extra == "telegram" jpayne@69: Provides-Extra: notebook jpayne@69: Requires-Dist: ipywidgets>=6; extra == "notebook" jpayne@69: jpayne@69: |Logo| jpayne@69: jpayne@69: tqdm jpayne@69: ==== jpayne@69: jpayne@69: |Py-Versions| |Versions| |Conda-Forge-Status| |Docker| |Snapcraft| jpayne@69: jpayne@69: |Build-Status| |Coverage-Status| |Branch-Coverage-Status| |Codacy-Grade| |Libraries-Rank| |PyPI-Downloads| jpayne@69: jpayne@69: |LICENCE| |OpenHub-Status| |binder-demo| |awesome-python| jpayne@69: jpayne@69: ``tqdm`` derives from the Arabic word *taqaddum* (تقدّم) which can mean "progress," jpayne@69: and is an abbreviation for "I love you so much" in Spanish (*te quiero demasiado*). jpayne@69: jpayne@69: Instantly make your loops show a smart progress meter - just wrap any jpayne@69: iterable with ``tqdm(iterable)``, and you're done! jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: from tqdm import tqdm jpayne@69: for i in tqdm(range(10000)): jpayne@69: ... jpayne@69: jpayne@69: ``76%|████████████████████████        | 7568/10000 [00:33<00:10, 229.00it/s]`` jpayne@69: jpayne@69: ``trange(N)`` can be also used as a convenient shortcut for jpayne@69: ``tqdm(range(N))``. jpayne@69: jpayne@69: |Screenshot| jpayne@69: |Video| |Slides| |Merch| jpayne@69: jpayne@69: It can also be executed as a module with pipes: jpayne@69: jpayne@69: .. code:: sh jpayne@69: jpayne@69: $ seq 9999999 | tqdm --bytes | wc -l jpayne@69: 75.2MB [00:00, 217MB/s] jpayne@69: 9999999 jpayne@69: jpayne@69: $ tar -zcf - docs/ | tqdm --bytes --total `du -sb docs/ | cut -f1` \ jpayne@69: > backup.tgz jpayne@69: 32%|██████████▍ | 8.89G/27.9G [00:42<01:31, 223MB/s] jpayne@69: jpayne@69: Overhead is low -- about 60ns per iteration (80ns with ``tqdm.gui``), and is jpayne@69: unit tested against performance regression. jpayne@69: By comparison, the well-established jpayne@69: `ProgressBar `__ has jpayne@69: an 800ns/iter overhead. jpayne@69: jpayne@69: In addition to its low overhead, ``tqdm`` uses smart algorithms to predict jpayne@69: the remaining time and to skip unnecessary iteration displays, which allows jpayne@69: for a negligible overhead in most cases. jpayne@69: jpayne@69: ``tqdm`` works on any platform jpayne@69: (Linux, Windows, Mac, FreeBSD, NetBSD, Solaris/SunOS), jpayne@69: in any console or in a GUI, and is also friendly with IPython/Jupyter notebooks. jpayne@69: jpayne@69: ``tqdm`` does not require any dependencies (not even ``curses``!), just jpayne@69: Python and an environment supporting ``carriage return \r`` and jpayne@69: ``line feed \n`` control characters. jpayne@69: jpayne@69: ------------------------------------------ jpayne@69: jpayne@69: .. contents:: Table of contents jpayne@69: :backlinks: top jpayne@69: :local: jpayne@69: jpayne@69: jpayne@69: Installation jpayne@69: ------------ jpayne@69: jpayne@69: Latest PyPI stable release jpayne@69: ~~~~~~~~~~~~~~~~~~~~~~~~~~ jpayne@69: jpayne@69: |Versions| |PyPI-Downloads| |Libraries-Dependents| jpayne@69: jpayne@69: .. code:: sh jpayne@69: jpayne@69: pip install tqdm jpayne@69: jpayne@69: Latest development release on GitHub jpayne@69: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ jpayne@69: jpayne@69: |GitHub-Status| |GitHub-Stars| |GitHub-Commits| |GitHub-Forks| |GitHub-Updated| jpayne@69: jpayne@69: Pull and install pre-release ``devel`` branch: jpayne@69: jpayne@69: .. code:: sh jpayne@69: jpayne@69: pip install "git+https://github.com/tqdm/tqdm.git@devel#egg=tqdm" jpayne@69: jpayne@69: Latest Conda release jpayne@69: ~~~~~~~~~~~~~~~~~~~~ jpayne@69: jpayne@69: |Conda-Forge-Status| jpayne@69: jpayne@69: .. code:: sh jpayne@69: jpayne@69: conda install -c conda-forge tqdm jpayne@69: jpayne@69: Latest Snapcraft release jpayne@69: ~~~~~~~~~~~~~~~~~~~~~~~~ jpayne@69: jpayne@69: |Snapcraft| jpayne@69: jpayne@69: There are 3 channels to choose from: jpayne@69: jpayne@69: .. code:: sh jpayne@69: jpayne@69: snap install tqdm # implies --stable, i.e. latest tagged release jpayne@69: snap install tqdm --candidate # master branch jpayne@69: snap install tqdm --edge # devel branch jpayne@69: jpayne@69: Note that ``snap`` binaries are purely for CLI use (not ``import``-able), and jpayne@69: automatically set up ``bash`` tab-completion. jpayne@69: jpayne@69: Latest Docker release jpayne@69: ~~~~~~~~~~~~~~~~~~~~~ jpayne@69: jpayne@69: |Docker| jpayne@69: jpayne@69: .. code:: sh jpayne@69: jpayne@69: docker pull tqdm/tqdm jpayne@69: docker run -i --rm tqdm/tqdm --help jpayne@69: jpayne@69: Other jpayne@69: ~~~~~ jpayne@69: jpayne@69: There are other (unofficial) places where ``tqdm`` may be downloaded, particularly for CLI use: jpayne@69: jpayne@69: |Repology| jpayne@69: jpayne@69: .. |Repology| image:: https://repology.org/badge/tiny-repos/python:tqdm.svg jpayne@69: :target: https://repology.org/project/python:tqdm/versions jpayne@69: jpayne@69: Changelog jpayne@69: --------- jpayne@69: jpayne@69: The list of all changes is available either on GitHub's Releases: jpayne@69: |GitHub-Status|, on the jpayne@69: `wiki `__, or on the jpayne@69: `website `__. jpayne@69: jpayne@69: jpayne@69: Usage jpayne@69: ----- jpayne@69: jpayne@69: ``tqdm`` is very versatile and can be used in a number of ways. jpayne@69: The three main ones are given below. jpayne@69: jpayne@69: Iterable-based jpayne@69: ~~~~~~~~~~~~~~ jpayne@69: jpayne@69: Wrap ``tqdm()`` around any iterable: jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: from tqdm import tqdm jpayne@69: from time import sleep jpayne@69: jpayne@69: text = "" jpayne@69: for char in tqdm(["a", "b", "c", "d"]): jpayne@69: sleep(0.25) jpayne@69: text = text + char jpayne@69: jpayne@69: ``trange(i)`` is a special optimised instance of ``tqdm(range(i))``: jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: from tqdm import trange jpayne@69: jpayne@69: for i in trange(100): jpayne@69: sleep(0.01) jpayne@69: jpayne@69: Instantiation outside of the loop allows for manual control over ``tqdm()``: jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: pbar = tqdm(["a", "b", "c", "d"]) jpayne@69: for char in pbar: jpayne@69: sleep(0.25) jpayne@69: pbar.set_description("Processing %s" % char) jpayne@69: jpayne@69: Manual jpayne@69: ~~~~~~ jpayne@69: jpayne@69: Manual control of ``tqdm()`` updates using a ``with`` statement: jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: with tqdm(total=100) as pbar: jpayne@69: for i in range(10): jpayne@69: sleep(0.1) jpayne@69: pbar.update(10) jpayne@69: jpayne@69: If the optional variable ``total`` (or an iterable with ``len()``) is jpayne@69: provided, predictive stats are displayed. jpayne@69: jpayne@69: ``with`` is also optional (you can just assign ``tqdm()`` to a variable, jpayne@69: but in this case don't forget to ``del`` or ``close()`` at the end: jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: pbar = tqdm(total=100) jpayne@69: for i in range(10): jpayne@69: sleep(0.1) jpayne@69: pbar.update(10) jpayne@69: pbar.close() jpayne@69: jpayne@69: Module jpayne@69: ~~~~~~ jpayne@69: jpayne@69: Perhaps the most wonderful use of ``tqdm`` is in a script or on the command jpayne@69: line. Simply inserting ``tqdm`` (or ``python -m tqdm``) between pipes will pass jpayne@69: through all ``stdin`` to ``stdout`` while printing progress to ``stderr``. jpayne@69: jpayne@69: The example below demonstrate counting the number of lines in all Python files jpayne@69: in the current directory, with timing information included. jpayne@69: jpayne@69: .. code:: sh jpayne@69: jpayne@69: $ time find . -name '*.py' -type f -exec cat \{} \; | wc -l jpayne@69: 857365 jpayne@69: jpayne@69: real 0m3.458s jpayne@69: user 0m0.274s jpayne@69: sys 0m3.325s jpayne@69: jpayne@69: $ time find . -name '*.py' -type f -exec cat \{} \; | tqdm | wc -l jpayne@69: 857366it [00:03, 246471.31it/s] jpayne@69: 857365 jpayne@69: jpayne@69: real 0m3.585s jpayne@69: user 0m0.862s jpayne@69: sys 0m3.358s jpayne@69: jpayne@69: Note that the usual arguments for ``tqdm`` can also be specified. jpayne@69: jpayne@69: .. code:: sh jpayne@69: jpayne@69: $ find . -name '*.py' -type f -exec cat \{} \; | jpayne@69: tqdm --unit loc --unit_scale --total 857366 >> /dev/null jpayne@69: 100%|█████████████████████████████████| 857K/857K [00:04<00:00, 246Kloc/s] jpayne@69: jpayne@69: Backing up a large directory? jpayne@69: jpayne@69: .. code:: sh jpayne@69: jpayne@69: $ tar -zcf - docs/ | tqdm --bytes --total `du -sb docs/ | cut -f1` \ jpayne@69: > backup.tgz jpayne@69: 44%|██████████████▊ | 153M/352M [00:14<00:18, 11.0MB/s] jpayne@69: jpayne@69: This can be beautified further: jpayne@69: jpayne@69: .. code:: sh jpayne@69: jpayne@69: $ BYTES=$(du -sb docs/ | cut -f1) jpayne@69: $ tar -cf - docs/ \ jpayne@69: | tqdm --bytes --total "$BYTES" --desc Processing | gzip \ jpayne@69: | tqdm --bytes --total "$BYTES" --desc Compressed --position 1 \ jpayne@69: > ~/backup.tgz jpayne@69: Processing: 100%|██████████████████████| 352M/352M [00:14<00:00, 30.2MB/s] jpayne@69: Compressed: 42%|█████████▎ | 148M/352M [00:14<00:19, 10.9MB/s] jpayne@69: jpayne@69: Or done on a file level using 7-zip: jpayne@69: jpayne@69: .. code:: sh jpayne@69: jpayne@69: $ 7z a -bd -r backup.7z docs/ | grep Compressing \ jpayne@69: | tqdm --total $(find docs/ -type f | wc -l) --unit files \ jpayne@69: | grep -v Compressing jpayne@69: 100%|██████████████████████████▉| 15327/15327 [01:00<00:00, 712.96files/s] jpayne@69: jpayne@69: Pre-existing CLI programs already outputting basic progress information will jpayne@69: benefit from ``tqdm``'s ``--update`` and ``--update_to`` flags: jpayne@69: jpayne@69: .. code:: sh jpayne@69: jpayne@69: $ seq 3 0.1 5 | tqdm --total 5 --update_to --null jpayne@69: 100%|████████████████████████████████████| 5.0/5 [00:00<00:00, 9673.21it/s] jpayne@69: $ seq 10 | tqdm --update --null # 1 + 2 + ... + 10 = 55 iterations jpayne@69: 55it [00:00, 90006.52it/s] jpayne@69: jpayne@69: FAQ and Known Issues jpayne@69: -------------------- jpayne@69: jpayne@69: |GitHub-Issues| jpayne@69: jpayne@69: The most common issues relate to excessive output on multiple lines, instead jpayne@69: of a neat one-line progress bar. jpayne@69: jpayne@69: - Consoles in general: require support for carriage return (``CR``, ``\r``). jpayne@69: jpayne@69: * Some cloud logging consoles which don't support ``\r`` properly jpayne@69: (`cloudwatch `__, jpayne@69: `K8s `__) may benefit from jpayne@69: ``export TQDM_POSITION=-1``. jpayne@69: jpayne@69: - Nested progress bars: jpayne@69: jpayne@69: * Consoles in general: require support for moving cursors up to the jpayne@69: previous line. For example, jpayne@69: `IDLE `__, jpayne@69: `ConEmu `__ and jpayne@69: `PyCharm `__ (also jpayne@69: `here `__, jpayne@69: `here `__, and jpayne@69: `here `__) jpayne@69: lack full support. jpayne@69: * Windows: additionally may require the Python module ``colorama`` jpayne@69: to ensure nested bars stay within their respective lines. jpayne@69: jpayne@69: - Unicode: jpayne@69: jpayne@69: * Environments which report that they support unicode will have solid smooth jpayne@69: progressbars. The fallback is an ``ascii``-only bar. jpayne@69: * Windows consoles often only partially support unicode and thus jpayne@69: `often require explicit ascii=True `__ jpayne@69: (also `here `__). This is due to jpayne@69: either normal-width unicode characters being incorrectly displayed as jpayne@69: "wide", or some unicode characters not rendering. jpayne@69: jpayne@69: - Wrapping generators: jpayne@69: jpayne@69: * Generator wrapper functions tend to hide the length of iterables. jpayne@69: ``tqdm`` does not. jpayne@69: * Replace ``tqdm(enumerate(...))`` with ``enumerate(tqdm(...))`` or jpayne@69: ``tqdm(enumerate(x), total=len(x), ...)``. jpayne@69: The same applies to ``numpy.ndenumerate``. jpayne@69: * Replace ``tqdm(zip(a, b))`` with ``zip(tqdm(a), b)`` or even jpayne@69: ``zip(tqdm(a), tqdm(b))``. jpayne@69: * The same applies to ``itertools``. jpayne@69: * Some useful convenience functions can be found under ``tqdm.contrib``. jpayne@69: jpayne@69: - `No intermediate output in docker-compose `__: jpayne@69: use ``docker-compose run`` instead of ``docker-compose up`` and ``tty: true``. jpayne@69: jpayne@69: - Overriding defaults via environment variables: jpayne@69: e.g. in CI/cloud jobs, ``export TQDM_MININTERVAL=5`` to avoid log spam. jpayne@69: This override logic is handled by the ``tqdm.utils.envwrap`` decorator jpayne@69: (useful independent of ``tqdm``). jpayne@69: jpayne@69: If you come across any other difficulties, browse and file |GitHub-Issues|. jpayne@69: jpayne@69: Documentation jpayne@69: ------------- jpayne@69: jpayne@69: |Py-Versions| |README-Hits| (Since 19 May 2016) jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: class tqdm(): jpayne@69: """ jpayne@69: Decorate an iterable object, returning an iterator which acts exactly jpayne@69: like the original iterable, but prints a dynamically updating jpayne@69: progressbar every time a value is requested. jpayne@69: """ jpayne@69: jpayne@69: @envwrap("TQDM_") # override defaults via env vars jpayne@69: def __init__(self, iterable=None, desc=None, total=None, leave=True, jpayne@69: file=None, ncols=None, mininterval=0.1, jpayne@69: maxinterval=10.0, miniters=None, ascii=None, disable=False, jpayne@69: unit='it', unit_scale=False, dynamic_ncols=False, jpayne@69: smoothing=0.3, bar_format=None, initial=0, position=None, jpayne@69: postfix=None, unit_divisor=1000, write_bytes=False, jpayne@69: lock_args=None, nrows=None, colour=None, delay=0): jpayne@69: jpayne@69: Parameters jpayne@69: ~~~~~~~~~~ jpayne@69: jpayne@69: * iterable : iterable, optional jpayne@69: Iterable to decorate with a progressbar. jpayne@69: Leave blank to manually manage the updates. jpayne@69: * desc : str, optional jpayne@69: Prefix for the progressbar. jpayne@69: * total : int or float, optional jpayne@69: The number of expected iterations. If unspecified, jpayne@69: len(iterable) is used if possible. If float("inf") or as a last jpayne@69: resort, only basic progress statistics are displayed jpayne@69: (no ETA, no progressbar). jpayne@69: If ``gui`` is True and this parameter needs subsequent updating, jpayne@69: specify an initial arbitrary large positive number, jpayne@69: e.g. 9e9. jpayne@69: * leave : bool, optional jpayne@69: If [default: True], keeps all traces of the progressbar jpayne@69: upon termination of iteration. jpayne@69: If ``None``, will leave only if ``position`` is ``0``. jpayne@69: * file : ``io.TextIOWrapper`` or ``io.StringIO``, optional jpayne@69: Specifies where to output the progress messages jpayne@69: (default: sys.stderr). Uses ``file.write(str)`` and ``file.flush()`` jpayne@69: methods. For encoding, see ``write_bytes``. jpayne@69: * ncols : int, optional jpayne@69: The width of the entire output message. If specified, jpayne@69: dynamically resizes the progressbar to stay within this bound. jpayne@69: If unspecified, attempts to use environment width. The jpayne@69: fallback is a meter width of 10 and no limit for the counter and jpayne@69: statistics. If 0, will not print any meter (only stats). jpayne@69: * mininterval : float, optional jpayne@69: Minimum progress display update interval [default: 0.1] seconds. jpayne@69: * maxinterval : float, optional jpayne@69: Maximum progress display update interval [default: 10] seconds. jpayne@69: Automatically adjusts ``miniters`` to correspond to ``mininterval`` jpayne@69: after long display update lag. Only works if ``dynamic_miniters`` jpayne@69: or monitor thread is enabled. jpayne@69: * miniters : int or float, optional jpayne@69: Minimum progress display update interval, in iterations. jpayne@69: If 0 and ``dynamic_miniters``, will automatically adjust to equal jpayne@69: ``mininterval`` (more CPU efficient, good for tight loops). jpayne@69: If > 0, will skip display of specified number of iterations. jpayne@69: Tweak this and ``mininterval`` to get very efficient loops. jpayne@69: If your progress is erratic with both fast and slow iterations jpayne@69: (network, skipping items, etc) you should set miniters=1. jpayne@69: * ascii : bool or str, optional jpayne@69: If unspecified or False, use unicode (smooth blocks) to fill jpayne@69: the meter. The fallback is to use ASCII characters " 123456789#". jpayne@69: * disable : bool, optional jpayne@69: Whether to disable the entire progressbar wrapper jpayne@69: [default: False]. If set to None, disable on non-TTY. jpayne@69: * unit : str, optional jpayne@69: String that will be used to define the unit of each iteration jpayne@69: [default: it]. jpayne@69: * unit_scale : bool or int or float, optional jpayne@69: If 1 or True, the number of iterations will be reduced/scaled jpayne@69: automatically and a metric prefix following the jpayne@69: International System of Units standard will be added jpayne@69: (kilo, mega, etc.) [default: False]. If any other non-zero jpayne@69: number, will scale ``total`` and ``n``. jpayne@69: * dynamic_ncols : bool, optional jpayne@69: If set, constantly alters ``ncols`` and ``nrows`` to the jpayne@69: environment (allowing for window resizes) [default: False]. jpayne@69: * smoothing : float, optional jpayne@69: Exponential moving average smoothing factor for speed estimates jpayne@69: (ignored in GUI mode). Ranges from 0 (average speed) to 1 jpayne@69: (current/instantaneous speed) [default: 0.3]. jpayne@69: * bar_format : str, optional jpayne@69: Specify a custom bar string formatting. May impact performance. jpayne@69: [default: '{l_bar}{bar}{r_bar}'], where jpayne@69: l_bar='{desc}: {percentage:3.0f}%|' and jpayne@69: r_bar='| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, ' jpayne@69: '{rate_fmt}{postfix}]' jpayne@69: Possible vars: l_bar, bar, r_bar, n, n_fmt, total, total_fmt, jpayne@69: percentage, elapsed, elapsed_s, ncols, nrows, desc, unit, jpayne@69: rate, rate_fmt, rate_noinv, rate_noinv_fmt, jpayne@69: rate_inv, rate_inv_fmt, postfix, unit_divisor, jpayne@69: remaining, remaining_s, eta. jpayne@69: Note that a trailing ": " is automatically removed after {desc} jpayne@69: if the latter is empty. jpayne@69: * initial : int or float, optional jpayne@69: The initial counter value. Useful when restarting a progress jpayne@69: bar [default: 0]. If using float, consider specifying ``{n:.3f}`` jpayne@69: or similar in ``bar_format``, or specifying ``unit_scale``. jpayne@69: * position : int, optional jpayne@69: Specify the line offset to print this bar (starting from 0) jpayne@69: Automatic if unspecified. jpayne@69: Useful to manage multiple bars at once (eg, from threads). jpayne@69: * postfix : dict or ``*``, optional jpayne@69: Specify additional stats to display at the end of the bar. jpayne@69: Calls ``set_postfix(**postfix)`` if possible (dict). jpayne@69: * unit_divisor : float, optional jpayne@69: [default: 1000], ignored unless ``unit_scale`` is True. jpayne@69: * write_bytes : bool, optional jpayne@69: Whether to write bytes. If (default: False) will write unicode. jpayne@69: * lock_args : tuple, optional jpayne@69: Passed to ``refresh`` for intermediate output jpayne@69: (initialisation, iterating, and updating). jpayne@69: * nrows : int, optional jpayne@69: The screen height. If specified, hides nested bars outside this jpayne@69: bound. If unspecified, attempts to use environment height. jpayne@69: The fallback is 20. jpayne@69: * colour : str, optional jpayne@69: Bar colour (e.g. 'green', '#00ff00'). jpayne@69: * delay : float, optional jpayne@69: Don't display until [default: 0] seconds have elapsed. jpayne@69: jpayne@69: Extra CLI Options jpayne@69: ~~~~~~~~~~~~~~~~~ jpayne@69: jpayne@69: * delim : chr, optional jpayne@69: Delimiting character [default: '\n']. Use '\0' for null. jpayne@69: N.B.: on Windows systems, Python converts '\n' to '\r\n'. jpayne@69: * buf_size : int, optional jpayne@69: String buffer size in bytes [default: 256] jpayne@69: used when ``delim`` is specified. jpayne@69: * bytes : bool, optional jpayne@69: If true, will count bytes, ignore ``delim``, and default jpayne@69: ``unit_scale`` to True, ``unit_divisor`` to 1024, and ``unit`` to 'B'. jpayne@69: * tee : bool, optional jpayne@69: If true, passes ``stdin`` to both ``stderr`` and ``stdout``. jpayne@69: * update : bool, optional jpayne@69: If true, will treat input as newly elapsed iterations, jpayne@69: i.e. numbers to pass to ``update()``. Note that this is slow jpayne@69: (~2e5 it/s) since every input must be decoded as a number. jpayne@69: * update_to : bool, optional jpayne@69: If true, will treat input as total elapsed iterations, jpayne@69: i.e. numbers to assign to ``self.n``. Note that this is slow jpayne@69: (~2e5 it/s) since every input must be decoded as a number. jpayne@69: * null : bool, optional jpayne@69: If true, will discard input (no stdout). jpayne@69: * manpath : str, optional jpayne@69: Directory in which to install tqdm man pages. jpayne@69: * comppath : str, optional jpayne@69: Directory in which to place tqdm completion. jpayne@69: * log : str, optional jpayne@69: CRITICAL|FATAL|ERROR|WARN(ING)|[default: 'INFO']|DEBUG|NOTSET. jpayne@69: jpayne@69: Returns jpayne@69: ~~~~~~~ jpayne@69: jpayne@69: * out : decorated iterator. jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: class tqdm(): jpayne@69: def update(self, n=1): jpayne@69: """ jpayne@69: Manually update the progress bar, useful for streams jpayne@69: such as reading files. jpayne@69: E.g.: jpayne@69: >>> t = tqdm(total=filesize) # Initialise jpayne@69: >>> for current_buffer in stream: jpayne@69: ... ... jpayne@69: ... t.update(len(current_buffer)) jpayne@69: >>> t.close() jpayne@69: The last line is highly recommended, but possibly not necessary if jpayne@69: ``t.update()`` will be called in such a way that ``filesize`` will be jpayne@69: exactly reached and printed. jpayne@69: jpayne@69: Parameters jpayne@69: ---------- jpayne@69: n : int or float, optional jpayne@69: Increment to add to the internal counter of iterations jpayne@69: [default: 1]. If using float, consider specifying ``{n:.3f}`` jpayne@69: or similar in ``bar_format``, or specifying ``unit_scale``. jpayne@69: jpayne@69: Returns jpayne@69: ------- jpayne@69: out : bool or None jpayne@69: True if a ``display()`` was triggered. jpayne@69: """ jpayne@69: jpayne@69: def close(self): jpayne@69: """Cleanup and (if leave=False) close the progressbar.""" jpayne@69: jpayne@69: def clear(self, nomove=False): jpayne@69: """Clear current bar display.""" jpayne@69: jpayne@69: def refresh(self): jpayne@69: """ jpayne@69: Force refresh the display of this bar. jpayne@69: jpayne@69: Parameters jpayne@69: ---------- jpayne@69: nolock : bool, optional jpayne@69: If ``True``, does not lock. jpayne@69: If [default: ``False``]: calls ``acquire()`` on internal lock. jpayne@69: lock_args : tuple, optional jpayne@69: Passed to internal lock's ``acquire()``. jpayne@69: If specified, will only ``display()`` if ``acquire()`` returns ``True``. jpayne@69: """ jpayne@69: jpayne@69: def unpause(self): jpayne@69: """Restart tqdm timer from last print time.""" jpayne@69: jpayne@69: def reset(self, total=None): jpayne@69: """ jpayne@69: Resets to 0 iterations for repeated use. jpayne@69: jpayne@69: Consider combining with ``leave=True``. jpayne@69: jpayne@69: Parameters jpayne@69: ---------- jpayne@69: total : int or float, optional. Total to use for the new bar. jpayne@69: """ jpayne@69: jpayne@69: def set_description(self, desc=None, refresh=True): jpayne@69: """ jpayne@69: Set/modify description of the progress bar. jpayne@69: jpayne@69: Parameters jpayne@69: ---------- jpayne@69: desc : str, optional jpayne@69: refresh : bool, optional jpayne@69: Forces refresh [default: True]. jpayne@69: """ jpayne@69: jpayne@69: def set_postfix(self, ordered_dict=None, refresh=True, **tqdm_kwargs): jpayne@69: """ jpayne@69: Set/modify postfix (additional stats) jpayne@69: with automatic formatting based on datatype. jpayne@69: jpayne@69: Parameters jpayne@69: ---------- jpayne@69: ordered_dict : dict or OrderedDict, optional jpayne@69: refresh : bool, optional jpayne@69: Forces refresh [default: True]. jpayne@69: kwargs : dict, optional jpayne@69: """ jpayne@69: jpayne@69: @classmethod jpayne@69: def write(cls, s, file=sys.stdout, end="\n"): jpayne@69: """Print a message via tqdm (without overlap with bars).""" jpayne@69: jpayne@69: @property jpayne@69: def format_dict(self): jpayne@69: """Public API for read-only member access.""" jpayne@69: jpayne@69: def display(self, msg=None, pos=None): jpayne@69: """ jpayne@69: Use ``self.sp`` to display ``msg`` in the specified ``pos``. jpayne@69: jpayne@69: Consider overloading this function when inheriting to use e.g.: jpayne@69: ``self.some_frontend(**self.format_dict)`` instead of ``self.sp``. jpayne@69: jpayne@69: Parameters jpayne@69: ---------- jpayne@69: msg : str, optional. What to display (default: ``repr(self)``). jpayne@69: pos : int, optional. Position to ``moveto`` jpayne@69: (default: ``abs(self.pos)``). jpayne@69: """ jpayne@69: jpayne@69: @classmethod jpayne@69: @contextmanager jpayne@69: def wrapattr(cls, stream, method, total=None, bytes=True, **tqdm_kwargs): jpayne@69: """ jpayne@69: stream : file-like object. jpayne@69: method : str, "read" or "write". The result of ``read()`` and jpayne@69: the first argument of ``write()`` should have a ``len()``. jpayne@69: jpayne@69: >>> with tqdm.wrapattr(file_obj, "read", total=file_obj.size) as fobj: jpayne@69: ... while True: jpayne@69: ... chunk = fobj.read(chunk_size) jpayne@69: ... if not chunk: jpayne@69: ... break jpayne@69: """ jpayne@69: jpayne@69: @classmethod jpayne@69: def pandas(cls, *targs, **tqdm_kwargs): jpayne@69: """Registers the current `tqdm` class with `pandas`.""" jpayne@69: jpayne@69: def trange(*args, **tqdm_kwargs): jpayne@69: """Shortcut for `tqdm(range(*args), **tqdm_kwargs)`.""" jpayne@69: jpayne@69: Convenience Functions jpayne@69: ~~~~~~~~~~~~~~~~~~~~~ jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: def tqdm.contrib.tenumerate(iterable, start=0, total=None, jpayne@69: tqdm_class=tqdm.auto.tqdm, **tqdm_kwargs): jpayne@69: """Equivalent of `numpy.ndenumerate` or builtin `enumerate`.""" jpayne@69: jpayne@69: def tqdm.contrib.tzip(iter1, *iter2plus, **tqdm_kwargs): jpayne@69: """Equivalent of builtin `zip`.""" jpayne@69: jpayne@69: def tqdm.contrib.tmap(function, *sequences, **tqdm_kwargs): jpayne@69: """Equivalent of builtin `map`.""" jpayne@69: jpayne@69: Submodules jpayne@69: ~~~~~~~~~~ jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: class tqdm.notebook.tqdm(tqdm.tqdm): jpayne@69: """IPython/Jupyter Notebook widget.""" jpayne@69: jpayne@69: class tqdm.auto.tqdm(tqdm.tqdm): jpayne@69: """Automatically chooses beween `tqdm.notebook` and `tqdm.tqdm`.""" jpayne@69: jpayne@69: class tqdm.asyncio.tqdm(tqdm.tqdm): jpayne@69: """Asynchronous version.""" jpayne@69: @classmethod jpayne@69: def as_completed(cls, fs, *, loop=None, timeout=None, total=None, jpayne@69: **tqdm_kwargs): jpayne@69: """Wrapper for `asyncio.as_completed`.""" jpayne@69: jpayne@69: class tqdm.gui.tqdm(tqdm.tqdm): jpayne@69: """Matplotlib GUI version.""" jpayne@69: jpayne@69: class tqdm.tk.tqdm(tqdm.tqdm): jpayne@69: """Tkinter GUI version.""" jpayne@69: jpayne@69: class tqdm.rich.tqdm(tqdm.tqdm): jpayne@69: """`rich.progress` version.""" jpayne@69: jpayne@69: class tqdm.keras.TqdmCallback(keras.callbacks.Callback): jpayne@69: """Keras callback for epoch and batch progress.""" jpayne@69: jpayne@69: class tqdm.dask.TqdmCallback(dask.callbacks.Callback): jpayne@69: """Dask callback for task progress.""" jpayne@69: jpayne@69: jpayne@69: ``contrib`` jpayne@69: +++++++++++ jpayne@69: jpayne@69: The ``tqdm.contrib`` package also contains experimental modules: jpayne@69: jpayne@69: - ``tqdm.contrib.itertools``: Thin wrappers around ``itertools`` jpayne@69: - ``tqdm.contrib.concurrent``: Thin wrappers around ``concurrent.futures`` jpayne@69: - ``tqdm.contrib.slack``: Posts to `Slack `__ bots jpayne@69: - ``tqdm.contrib.discord``: Posts to `Discord `__ bots jpayne@69: - ``tqdm.contrib.telegram``: Posts to `Telegram `__ bots jpayne@69: - ``tqdm.contrib.bells``: Automagically enables all optional features jpayne@69: jpayne@69: * ``auto``, ``pandas``, ``slack``, ``discord``, ``telegram`` jpayne@69: jpayne@69: Examples and Advanced Usage jpayne@69: --------------------------- jpayne@69: jpayne@69: - See the `examples `__ jpayne@69: folder; jpayne@69: - import the module and run ``help()``; jpayne@69: - consult the `wiki `__; jpayne@69: jpayne@69: * this has an jpayne@69: `excellent article `__ jpayne@69: on how to make a **great** progressbar; jpayne@69: jpayne@69: - check out the `slides from PyData London `__, or jpayne@69: - run the |binder-demo|. jpayne@69: jpayne@69: Description and additional stats jpayne@69: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ jpayne@69: jpayne@69: Custom information can be displayed and updated dynamically on ``tqdm`` bars jpayne@69: with the ``desc`` and ``postfix`` arguments: jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: from tqdm import tqdm, trange jpayne@69: from random import random, randint jpayne@69: from time import sleep jpayne@69: jpayne@69: with trange(10) as t: jpayne@69: for i in t: jpayne@69: # Description will be displayed on the left jpayne@69: t.set_description('GEN %i' % i) jpayne@69: # Postfix will be displayed on the right, jpayne@69: # formatted automatically based on argument's datatype jpayne@69: t.set_postfix(loss=random(), gen=randint(1,999), str='h', jpayne@69: lst=[1, 2]) jpayne@69: sleep(0.1) jpayne@69: jpayne@69: with tqdm(total=10, bar_format="{postfix[0]} {postfix[1][value]:>8.2g}", jpayne@69: postfix=["Batch", {"value": 0}]) as t: jpayne@69: for i in range(10): jpayne@69: sleep(0.1) jpayne@69: t.postfix[1]["value"] = i / 2 jpayne@69: t.update() jpayne@69: jpayne@69: Points to remember when using ``{postfix[...]}`` in the ``bar_format`` string: jpayne@69: jpayne@69: - ``postfix`` also needs to be passed as an initial argument in a compatible jpayne@69: format, and jpayne@69: - ``postfix`` will be auto-converted to a string if it is a ``dict``-like jpayne@69: object. To prevent this behaviour, insert an extra item into the dictionary jpayne@69: where the key is not a string. jpayne@69: jpayne@69: Additional ``bar_format`` parameters may also be defined by overriding jpayne@69: ``format_dict``, and the bar itself may be modified using ``ascii``: jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: from tqdm import tqdm jpayne@69: class TqdmExtraFormat(tqdm): jpayne@69: """Provides a `total_time` format parameter""" jpayne@69: @property jpayne@69: def format_dict(self): jpayne@69: d = super().format_dict jpayne@69: total_time = d["elapsed"] * (d["total"] or 0) / max(d["n"], 1) jpayne@69: d.update(total_time=self.format_interval(total_time) + " in total") jpayne@69: return d jpayne@69: jpayne@69: for i in TqdmExtraFormat( jpayne@69: range(9), ascii=" .oO0", jpayne@69: bar_format="{total_time}: {percentage:.0f}%|{bar}{r_bar}"): jpayne@69: if i == 4: jpayne@69: break jpayne@69: jpayne@69: .. code:: jpayne@69: jpayne@69: 00:00 in total: 44%|0000. | 4/9 [00:00<00:00, 962.93it/s] jpayne@69: jpayne@69: Note that ``{bar}`` also supports a format specifier ``[width][type]``. jpayne@69: jpayne@69: - ``width`` jpayne@69: jpayne@69: * unspecified (default): automatic to fill ``ncols`` jpayne@69: * ``int >= 0``: fixed width overriding ``ncols`` logic jpayne@69: * ``int < 0``: subtract from the automatic default jpayne@69: jpayne@69: - ``type`` jpayne@69: jpayne@69: * ``a``: ascii (``ascii=True`` override) jpayne@69: * ``u``: unicode (``ascii=False`` override) jpayne@69: * ``b``: blank (``ascii=" "`` override) jpayne@69: jpayne@69: This means a fixed bar with right-justified text may be created by using: jpayne@69: ``bar_format="{l_bar}{bar:10}|{bar:-10b}right-justified"`` jpayne@69: jpayne@69: Nested progress bars jpayne@69: ~~~~~~~~~~~~~~~~~~~~ jpayne@69: jpayne@69: ``tqdm`` supports nested progress bars. Here's an example: jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: from tqdm.auto import trange jpayne@69: from time import sleep jpayne@69: jpayne@69: for i in trange(4, desc='1st loop'): jpayne@69: for j in trange(5, desc='2nd loop'): jpayne@69: for k in trange(50, desc='3rd loop', leave=False): jpayne@69: sleep(0.01) jpayne@69: jpayne@69: For manual control over positioning (e.g. for multi-processing use), jpayne@69: you may specify ``position=n`` where ``n=0`` for the outermost bar, jpayne@69: ``n=1`` for the next, and so on. jpayne@69: However, it's best to check if ``tqdm`` can work without manual ``position`` jpayne@69: first. jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: from time import sleep jpayne@69: from tqdm import trange, tqdm jpayne@69: from multiprocessing import Pool, RLock, freeze_support jpayne@69: jpayne@69: L = list(range(9)) jpayne@69: jpayne@69: def progresser(n): jpayne@69: interval = 0.001 / (n + 2) jpayne@69: total = 5000 jpayne@69: text = f"#{n}, est. {interval * total:<04.2}s" jpayne@69: for _ in trange(total, desc=text, position=n): jpayne@69: sleep(interval) jpayne@69: jpayne@69: if __name__ == '__main__': jpayne@69: freeze_support() # for Windows support jpayne@69: tqdm.set_lock(RLock()) # for managing output contention jpayne@69: p = Pool(initializer=tqdm.set_lock, initargs=(tqdm.get_lock(),)) jpayne@69: p.map(progresser, L) jpayne@69: jpayne@69: Note that in Python 3, ``tqdm.write`` is thread-safe: jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: from time import sleep jpayne@69: from tqdm import tqdm, trange jpayne@69: from concurrent.futures import ThreadPoolExecutor jpayne@69: jpayne@69: L = list(range(9)) jpayne@69: jpayne@69: def progresser(n): jpayne@69: interval = 0.001 / (n + 2) jpayne@69: total = 5000 jpayne@69: text = f"#{n}, est. {interval * total:<04.2}s" jpayne@69: for _ in trange(total, desc=text): jpayne@69: sleep(interval) jpayne@69: if n == 6: jpayne@69: tqdm.write("n == 6 completed.") jpayne@69: tqdm.write("`tqdm.write()` is thread-safe in py3!") jpayne@69: jpayne@69: if __name__ == '__main__': jpayne@69: with ThreadPoolExecutor() as p: jpayne@69: p.map(progresser, L) jpayne@69: jpayne@69: Hooks and callbacks jpayne@69: ~~~~~~~~~~~~~~~~~~~ jpayne@69: jpayne@69: ``tqdm`` can easily support callbacks/hooks and manual updates. jpayne@69: Here's an example with ``urllib``: jpayne@69: jpayne@69: **``urllib.urlretrieve`` documentation** jpayne@69: jpayne@69: | [...] jpayne@69: | If present, the hook function will be called once jpayne@69: | on establishment of the network connection and once after each block read jpayne@69: | thereafter. The hook will be passed three arguments; a count of blocks jpayne@69: | transferred so far, a block size in bytes, and the total size of the file. jpayne@69: | [...] jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: import urllib, os jpayne@69: from tqdm import tqdm jpayne@69: urllib = getattr(urllib, 'request', urllib) jpayne@69: jpayne@69: class TqdmUpTo(tqdm): jpayne@69: """Provides `update_to(n)` which uses `tqdm.update(delta_n)`.""" jpayne@69: def update_to(self, b=1, bsize=1, tsize=None): jpayne@69: """ jpayne@69: b : int, optional jpayne@69: Number of blocks transferred so far [default: 1]. jpayne@69: bsize : int, optional jpayne@69: Size of each block (in tqdm units) [default: 1]. jpayne@69: tsize : int, optional jpayne@69: Total size (in tqdm units). If [default: None] remains unchanged. jpayne@69: """ jpayne@69: if tsize is not None: jpayne@69: self.total = tsize jpayne@69: return self.update(b * bsize - self.n) # also sets self.n = b * bsize jpayne@69: jpayne@69: eg_link = "https://caspersci.uk.to/matryoshka.zip" jpayne@69: with TqdmUpTo(unit='B', unit_scale=True, unit_divisor=1024, miniters=1, jpayne@69: desc=eg_link.split('/')[-1]) as t: # all optional kwargs jpayne@69: urllib.urlretrieve(eg_link, filename=os.devnull, jpayne@69: reporthook=t.update_to, data=None) jpayne@69: t.total = t.n jpayne@69: jpayne@69: Inspired by `twine#242 `__. jpayne@69: Functional alternative in jpayne@69: `examples/tqdm_wget.py `__. jpayne@69: jpayne@69: It is recommend to use ``miniters=1`` whenever there is potentially jpayne@69: large differences in iteration speed (e.g. downloading a file over jpayne@69: a patchy connection). jpayne@69: jpayne@69: **Wrapping read/write methods** jpayne@69: jpayne@69: To measure throughput through a file-like object's ``read`` or ``write`` jpayne@69: methods, use ``CallbackIOWrapper``: jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: from tqdm.auto import tqdm jpayne@69: from tqdm.utils import CallbackIOWrapper jpayne@69: jpayne@69: with tqdm(total=file_obj.size, jpayne@69: unit='B', unit_scale=True, unit_divisor=1024) as t: jpayne@69: fobj = CallbackIOWrapper(t.update, file_obj, "read") jpayne@69: while True: jpayne@69: chunk = fobj.read(chunk_size) jpayne@69: if not chunk: jpayne@69: break jpayne@69: t.reset() jpayne@69: # ... continue to use `t` for something else jpayne@69: jpayne@69: Alternatively, use the even simpler ``wrapattr`` convenience function, jpayne@69: which would condense both the ``urllib`` and ``CallbackIOWrapper`` examples jpayne@69: down to: jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: import urllib, os jpayne@69: from tqdm import tqdm jpayne@69: jpayne@69: eg_link = "https://caspersci.uk.to/matryoshka.zip" jpayne@69: response = getattr(urllib, 'request', urllib).urlopen(eg_link) jpayne@69: with tqdm.wrapattr(open(os.devnull, "wb"), "write", jpayne@69: miniters=1, desc=eg_link.split('/')[-1], jpayne@69: total=getattr(response, 'length', None)) as fout: jpayne@69: for chunk in response: jpayne@69: fout.write(chunk) jpayne@69: jpayne@69: The ``requests`` equivalent is nearly identical: jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: import requests, os jpayne@69: from tqdm import tqdm jpayne@69: jpayne@69: eg_link = "https://caspersci.uk.to/matryoshka.zip" jpayne@69: response = requests.get(eg_link, stream=True) jpayne@69: with tqdm.wrapattr(open(os.devnull, "wb"), "write", jpayne@69: miniters=1, desc=eg_link.split('/')[-1], jpayne@69: total=int(response.headers.get('content-length', 0))) as fout: jpayne@69: for chunk in response.iter_content(chunk_size=4096): jpayne@69: fout.write(chunk) jpayne@69: jpayne@69: **Custom callback** jpayne@69: jpayne@69: ``tqdm`` is known for intelligently skipping unnecessary displays. To make a jpayne@69: custom callback take advantage of this, simply use the return value of jpayne@69: ``update()``. This is set to ``True`` if a ``display()`` was triggered. jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: from tqdm.auto import tqdm as std_tqdm jpayne@69: jpayne@69: def external_callback(*args, **kwargs): jpayne@69: ... jpayne@69: jpayne@69: class TqdmExt(std_tqdm): jpayne@69: def update(self, n=1): jpayne@69: displayed = super().update(n) jpayne@69: if displayed: jpayne@69: external_callback(**self.format_dict) jpayne@69: return displayed jpayne@69: jpayne@69: ``asyncio`` jpayne@69: ~~~~~~~~~~~ jpayne@69: jpayne@69: Note that ``break`` isn't currently caught by asynchronous iterators. jpayne@69: This means that ``tqdm`` cannot clean up after itself in this case: jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: from tqdm.asyncio import tqdm jpayne@69: jpayne@69: async for i in tqdm(range(9)): jpayne@69: if i == 2: jpayne@69: break jpayne@69: jpayne@69: Instead, either call ``pbar.close()`` manually or use the context manager syntax: jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: from tqdm.asyncio import tqdm jpayne@69: jpayne@69: with tqdm(range(9)) as pbar: jpayne@69: async for i in pbar: jpayne@69: if i == 2: jpayne@69: break jpayne@69: jpayne@69: Pandas Integration jpayne@69: ~~~~~~~~~~~~~~~~~~ jpayne@69: jpayne@69: Due to popular demand we've added support for ``pandas`` -- here's an example jpayne@69: for ``DataFrame.progress_apply`` and ``DataFrameGroupBy.progress_apply``: jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: import pandas as pd jpayne@69: import numpy as np jpayne@69: from tqdm import tqdm jpayne@69: jpayne@69: df = pd.DataFrame(np.random.randint(0, 100, (100000, 6))) jpayne@69: jpayne@69: # Register `pandas.progress_apply` and `pandas.Series.map_apply` with `tqdm` jpayne@69: # (can use `tqdm.gui.tqdm`, `tqdm.notebook.tqdm`, optional kwargs, etc.) jpayne@69: tqdm.pandas(desc="my bar!") jpayne@69: jpayne@69: # Now you can use `progress_apply` instead of `apply` jpayne@69: # and `progress_map` instead of `map` jpayne@69: df.progress_apply(lambda x: x**2) jpayne@69: # can also groupby: jpayne@69: # df.groupby(0).progress_apply(lambda x: x**2) jpayne@69: jpayne@69: In case you're interested in how this works (and how to modify it for your jpayne@69: own callbacks), see the jpayne@69: `examples `__ jpayne@69: folder or import the module and run ``help()``. jpayne@69: jpayne@69: Keras Integration jpayne@69: ~~~~~~~~~~~~~~~~~ jpayne@69: jpayne@69: A ``keras`` callback is also available: jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: from tqdm.keras import TqdmCallback jpayne@69: jpayne@69: ... jpayne@69: jpayne@69: model.fit(..., verbose=0, callbacks=[TqdmCallback()]) jpayne@69: jpayne@69: Dask Integration jpayne@69: ~~~~~~~~~~~~~~~~ jpayne@69: jpayne@69: A ``dask`` callback is also available: jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: from tqdm.dask import TqdmCallback jpayne@69: jpayne@69: with TqdmCallback(desc="compute"): jpayne@69: ... jpayne@69: arr.compute() jpayne@69: jpayne@69: # or use callback globally jpayne@69: cb = TqdmCallback(desc="global") jpayne@69: cb.register() jpayne@69: arr.compute() jpayne@69: jpayne@69: IPython/Jupyter Integration jpayne@69: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ jpayne@69: jpayne@69: IPython/Jupyter is supported via the ``tqdm.notebook`` submodule: jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: from tqdm.notebook import trange, tqdm jpayne@69: from time import sleep jpayne@69: jpayne@69: for i in trange(3, desc='1st loop'): jpayne@69: for j in tqdm(range(100), desc='2nd loop'): jpayne@69: sleep(0.01) jpayne@69: jpayne@69: In addition to ``tqdm`` features, the submodule provides a native Jupyter jpayne@69: widget (compatible with IPython v1-v4 and Jupyter), fully working nested bars jpayne@69: and colour hints (blue: normal, green: completed, red: error/interrupt, jpayne@69: light blue: no ETA); as demonstrated below. jpayne@69: jpayne@69: |Screenshot-Jupyter1| jpayne@69: |Screenshot-Jupyter2| jpayne@69: |Screenshot-Jupyter3| jpayne@69: jpayne@69: The ``notebook`` version supports percentage or pixels for overall width jpayne@69: (e.g.: ``ncols='100%'`` or ``ncols='480px'``). jpayne@69: jpayne@69: It is also possible to let ``tqdm`` automatically choose between jpayne@69: console or notebook versions by using the ``autonotebook`` submodule: jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: from tqdm.autonotebook import tqdm jpayne@69: tqdm.pandas() jpayne@69: jpayne@69: Note that this will issue a ``TqdmExperimentalWarning`` if run in a notebook jpayne@69: since it is not meant to be possible to distinguish between ``jupyter notebook`` jpayne@69: and ``jupyter console``. Use ``auto`` instead of ``autonotebook`` to suppress jpayne@69: this warning. jpayne@69: jpayne@69: Note that notebooks will display the bar in the cell where it was created. jpayne@69: This may be a different cell from the one where it is used. jpayne@69: If this is not desired, either jpayne@69: jpayne@69: - delay the creation of the bar to the cell where it must be displayed, or jpayne@69: - create the bar with ``display=False``, and in a later cell call jpayne@69: ``display(bar.container)``: jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: from tqdm.notebook import tqdm jpayne@69: pbar = tqdm(..., display=False) jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: # different cell jpayne@69: display(pbar.container) jpayne@69: jpayne@69: The ``keras`` callback has a ``display()`` method which can be used likewise: jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: from tqdm.keras import TqdmCallback jpayne@69: cbk = TqdmCallback(display=False) jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: # different cell jpayne@69: cbk.display() jpayne@69: model.fit(..., verbose=0, callbacks=[cbk]) jpayne@69: jpayne@69: Another possibility is to have a single bar (near the top of the notebook) jpayne@69: which is constantly re-used (using ``reset()`` rather than ``close()``). jpayne@69: For this reason, the notebook version (unlike the CLI version) does not jpayne@69: automatically call ``close()`` upon ``Exception``. jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: from tqdm.notebook import tqdm jpayne@69: pbar = tqdm() jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: # different cell jpayne@69: iterable = range(100) jpayne@69: pbar.reset(total=len(iterable)) # initialise with new `total` jpayne@69: for i in iterable: jpayne@69: pbar.update() jpayne@69: pbar.refresh() # force print final status but don't `close()` jpayne@69: jpayne@69: Custom Integration jpayne@69: ~~~~~~~~~~~~~~~~~~ jpayne@69: jpayne@69: To change the default arguments (such as making ``dynamic_ncols=True``), jpayne@69: simply use built-in Python magic: jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: from functools import partial jpayne@69: from tqdm import tqdm as std_tqdm jpayne@69: tqdm = partial(std_tqdm, dynamic_ncols=True) jpayne@69: jpayne@69: For further customisation, jpayne@69: ``tqdm`` may be inherited from to create custom callbacks (as with the jpayne@69: ``TqdmUpTo`` example `above <#hooks-and-callbacks>`__) or for custom frontends jpayne@69: (e.g. GUIs such as notebook or plotting packages). In the latter case: jpayne@69: jpayne@69: 1. ``def __init__()`` to call ``super().__init__(..., gui=True)`` to disable jpayne@69: terminal ``status_printer`` creation. jpayne@69: 2. Redefine: ``close()``, ``clear()``, ``display()``. jpayne@69: jpayne@69: Consider overloading ``display()`` to use e.g. jpayne@69: ``self.frontend(**self.format_dict)`` instead of ``self.sp(repr(self))``. jpayne@69: jpayne@69: Some submodule examples of inheritance: jpayne@69: jpayne@69: - `tqdm/notebook.py `__ jpayne@69: - `tqdm/gui.py `__ jpayne@69: - `tqdm/tk.py `__ jpayne@69: - `tqdm/contrib/slack.py `__ jpayne@69: - `tqdm/contrib/discord.py `__ jpayne@69: - `tqdm/contrib/telegram.py `__ jpayne@69: jpayne@69: Dynamic Monitor/Meter jpayne@69: ~~~~~~~~~~~~~~~~~~~~~ jpayne@69: jpayne@69: You can use a ``tqdm`` as a meter which is not monotonically increasing. jpayne@69: This could be because ``n`` decreases (e.g. a CPU usage monitor) or ``total`` jpayne@69: changes. jpayne@69: jpayne@69: One example would be recursively searching for files. The ``total`` is the jpayne@69: number of objects found so far, while ``n`` is the number of those objects which jpayne@69: are files (rather than folders): jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: from tqdm import tqdm jpayne@69: import os.path jpayne@69: jpayne@69: def find_files_recursively(path, show_progress=True): jpayne@69: files = [] jpayne@69: # total=1 assumes `path` is a file jpayne@69: t = tqdm(total=1, unit="file", disable=not show_progress) jpayne@69: if not os.path.exists(path): jpayne@69: raise IOError("Cannot find:" + path) jpayne@69: jpayne@69: def append_found_file(f): jpayne@69: files.append(f) jpayne@69: t.update() jpayne@69: jpayne@69: def list_found_dir(path): jpayne@69: """returns os.listdir(path) assuming os.path.isdir(path)""" jpayne@69: listing = os.listdir(path) jpayne@69: # subtract 1 since a "file" we found was actually this directory jpayne@69: t.total += len(listing) - 1 jpayne@69: # fancy way to give info without forcing a refresh jpayne@69: t.set_postfix(dir=path[-10:], refresh=False) jpayne@69: t.update(0) # may trigger a refresh jpayne@69: return listing jpayne@69: jpayne@69: def recursively_search(path): jpayne@69: if os.path.isdir(path): jpayne@69: for f in list_found_dir(path): jpayne@69: recursively_search(os.path.join(path, f)) jpayne@69: else: jpayne@69: append_found_file(path) jpayne@69: jpayne@69: recursively_search(path) jpayne@69: t.set_postfix(dir=path) jpayne@69: t.close() jpayne@69: return files jpayne@69: jpayne@69: Using ``update(0)`` is a handy way to let ``tqdm`` decide when to trigger a jpayne@69: display refresh to avoid console spamming. jpayne@69: jpayne@69: Writing messages jpayne@69: ~~~~~~~~~~~~~~~~ jpayne@69: jpayne@69: This is a work in progress (see jpayne@69: `#737 `__). jpayne@69: jpayne@69: Since ``tqdm`` uses a simple printing mechanism to display progress bars, jpayne@69: you should not write any message in the terminal using ``print()`` while jpayne@69: a progressbar is open. jpayne@69: jpayne@69: To write messages in the terminal without any collision with ``tqdm`` bar jpayne@69: display, a ``.write()`` method is provided: jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: from tqdm.auto import tqdm, trange jpayne@69: from time import sleep jpayne@69: jpayne@69: bar = trange(10) jpayne@69: for i in bar: jpayne@69: # Print using tqdm class method .write() jpayne@69: sleep(0.1) jpayne@69: if not (i % 3): jpayne@69: tqdm.write("Done task %i" % i) jpayne@69: # Can also use bar.write() jpayne@69: jpayne@69: By default, this will print to standard output ``sys.stdout``. but you can jpayne@69: specify any file-like object using the ``file`` argument. For example, this jpayne@69: can be used to redirect the messages writing to a log file or class. jpayne@69: jpayne@69: Redirecting writing jpayne@69: ~~~~~~~~~~~~~~~~~~~ jpayne@69: jpayne@69: If using a library that can print messages to the console, editing the library jpayne@69: by replacing ``print()`` with ``tqdm.write()`` may not be desirable. jpayne@69: In that case, redirecting ``sys.stdout`` to ``tqdm.write()`` is an option. jpayne@69: jpayne@69: To redirect ``sys.stdout``, create a file-like class that will write jpayne@69: any input string to ``tqdm.write()``, and supply the arguments jpayne@69: ``file=sys.stdout, dynamic_ncols=True``. jpayne@69: jpayne@69: A reusable canonical example is given below: jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: from time import sleep jpayne@69: import contextlib jpayne@69: import sys jpayne@69: from tqdm import tqdm jpayne@69: from tqdm.contrib import DummyTqdmFile jpayne@69: jpayne@69: jpayne@69: @contextlib.contextmanager jpayne@69: def std_out_err_redirect_tqdm(): jpayne@69: orig_out_err = sys.stdout, sys.stderr jpayne@69: try: jpayne@69: sys.stdout, sys.stderr = map(DummyTqdmFile, orig_out_err) jpayne@69: yield orig_out_err[0] jpayne@69: # Relay exceptions jpayne@69: except Exception as exc: jpayne@69: raise exc jpayne@69: # Always restore sys.stdout/err if necessary jpayne@69: finally: jpayne@69: sys.stdout, sys.stderr = orig_out_err jpayne@69: jpayne@69: def some_fun(i): jpayne@69: print("Fee, fi, fo,".split()[i]) jpayne@69: jpayne@69: # Redirect stdout to tqdm.write() (don't forget the `as save_stdout`) jpayne@69: with std_out_err_redirect_tqdm() as orig_stdout: jpayne@69: # tqdm needs the original stdout jpayne@69: # and dynamic_ncols=True to autodetect console width jpayne@69: for i in tqdm(range(3), file=orig_stdout, dynamic_ncols=True): jpayne@69: sleep(.5) jpayne@69: some_fun(i) jpayne@69: jpayne@69: # After the `with`, printing is restored jpayne@69: print("Done!") jpayne@69: jpayne@69: Redirecting ``logging`` jpayne@69: ~~~~~~~~~~~~~~~~~~~~~~~ jpayne@69: jpayne@69: Similar to ``sys.stdout``/``sys.stderr`` as detailed above, console ``logging`` jpayne@69: may also be redirected to ``tqdm.write()``. jpayne@69: jpayne@69: Warning: if also redirecting ``sys.stdout``/``sys.stderr``, make sure to jpayne@69: redirect ``logging`` first if needed. jpayne@69: jpayne@69: Helper methods are available in ``tqdm.contrib.logging``. For example: jpayne@69: jpayne@69: .. code:: python jpayne@69: jpayne@69: import logging jpayne@69: from tqdm import trange jpayne@69: from tqdm.contrib.logging import logging_redirect_tqdm jpayne@69: jpayne@69: LOG = logging.getLogger(__name__) jpayne@69: jpayne@69: if __name__ == '__main__': jpayne@69: logging.basicConfig(level=logging.INFO) jpayne@69: with logging_redirect_tqdm(): jpayne@69: for i in trange(9): jpayne@69: if i == 4: jpayne@69: LOG.info("console logging redirected to `tqdm.write()`") jpayne@69: # logging restored jpayne@69: jpayne@69: Monitoring thread, intervals and miniters jpayne@69: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ jpayne@69: jpayne@69: ``tqdm`` implements a few tricks to increase efficiency and reduce overhead. jpayne@69: jpayne@69: - Avoid unnecessary frequent bar refreshing: ``mininterval`` defines how long jpayne@69: to wait between each refresh. ``tqdm`` always gets updated in the background, jpayne@69: but it will display only every ``mininterval``. jpayne@69: - Reduce number of calls to check system clock/time. jpayne@69: - ``mininterval`` is more intuitive to configure than ``miniters``. jpayne@69: A clever adjustment system ``dynamic_miniters`` will automatically adjust jpayne@69: ``miniters`` to the amount of iterations that fit into time ``mininterval``. jpayne@69: Essentially, ``tqdm`` will check if it's time to print without actually jpayne@69: checking time. This behaviour can be still be bypassed by manually setting jpayne@69: ``miniters``. jpayne@69: jpayne@69: However, consider a case with a combination of fast and slow iterations. jpayne@69: After a few fast iterations, ``dynamic_miniters`` will set ``miniters`` to a jpayne@69: large number. When iteration rate subsequently slows, ``miniters`` will jpayne@69: remain large and thus reduce display update frequency. To address this: jpayne@69: jpayne@69: - ``maxinterval`` defines the maximum time between display refreshes. jpayne@69: A concurrent monitoring thread checks for overdue updates and forces one jpayne@69: where necessary. jpayne@69: jpayne@69: The monitoring thread should not have a noticeable overhead, and guarantees jpayne@69: updates at least every 10 seconds by default. jpayne@69: This value can be directly changed by setting the ``monitor_interval`` of jpayne@69: any ``tqdm`` instance (i.e. ``t = tqdm.tqdm(...); t.monitor_interval = 2``). jpayne@69: The monitor thread may be disabled application-wide by setting jpayne@69: ``tqdm.tqdm.monitor_interval = 0`` before instantiation of any ``tqdm`` bar. jpayne@69: jpayne@69: jpayne@69: Merch jpayne@69: ----- jpayne@69: jpayne@69: You can buy `tqdm branded merch `__ now! jpayne@69: jpayne@69: Contributions jpayne@69: ------------- jpayne@69: jpayne@69: |GitHub-Commits| |GitHub-Issues| |GitHub-PRs| |OpenHub-Status| |GitHub-Contributions| |CII Best Practices| jpayne@69: jpayne@69: All source code is hosted on `GitHub `__. jpayne@69: Contributions are welcome. jpayne@69: jpayne@69: See the jpayne@69: `CONTRIBUTING `__ jpayne@69: file for more information. jpayne@69: jpayne@69: Developers who have made significant contributions, ranked by *SLoC* jpayne@69: (surviving lines of code, jpayne@69: `git fame `__ ``-wMC --excl '\.(png|gif|jpg)$'``), jpayne@69: are: jpayne@69: jpayne@69: ==================== ======================================================== ==== ================================ jpayne@69: Name ID SLoC Notes jpayne@69: ==================== ======================================================== ==== ================================ jpayne@69: Casper da Costa-Luis `casperdcl `__ ~80% primary maintainer |Gift-Casper| jpayne@69: Stephen Larroque `lrq3000 `__ ~9% team member jpayne@69: Martin Zugnoni `martinzugnoni `__ ~3% jpayne@69: Daniel Ecer `de-code `__ ~2% jpayne@69: Richard Sheridan `richardsheridan `__ ~1% jpayne@69: Guangshuo Chen `chengs `__ ~1% jpayne@69: Helio Machado `0x2b3bfa0 `__ ~1% jpayne@69: Kyle Altendorf `altendky `__ <1% jpayne@69: Noam Yorav-Raphael `noamraph `__ <1% original author jpayne@69: Matthew Stevens `mjstevens777 `__ <1% jpayne@69: Hadrien Mary `hadim `__ <1% team member jpayne@69: Mikhail Korobov `kmike `__ <1% team member jpayne@69: ==================== ======================================================== ==== ================================ jpayne@69: jpayne@69: Ports to Other Languages jpayne@69: ~~~~~~~~~~~~~~~~~~~~~~~~ jpayne@69: jpayne@69: A list is available on jpayne@69: `this wiki page `__. jpayne@69: jpayne@69: jpayne@69: LICENCE jpayne@69: ------- jpayne@69: jpayne@69: Open Source (OSI approved): |LICENCE| jpayne@69: jpayne@69: Citation information: |DOI| jpayne@69: jpayne@69: |README-Hits| (Since 19 May 2016) jpayne@69: jpayne@69: .. |Logo| image:: https://tqdm.github.io/img/logo.gif jpayne@69: .. |Screenshot| image:: https://tqdm.github.io/img/tqdm.gif jpayne@69: .. |Video| image:: https://tqdm.github.io/img/video.jpg jpayne@69: :target: https://tqdm.github.io/video jpayne@69: .. |Slides| image:: https://tqdm.github.io/img/slides.jpg jpayne@69: :target: https://tqdm.github.io/PyData2019/slides.html jpayne@69: .. |Merch| image:: https://tqdm.github.io/img/merch.jpg jpayne@69: :target: https://tqdm.github.io/merch jpayne@69: .. |Build-Status| image:: https://img.shields.io/github/actions/workflow/status/tqdm/tqdm/test.yml?branch=master&label=tqdm&logo=GitHub jpayne@69: :target: https://github.com/tqdm/tqdm/actions/workflows/test.yml jpayne@69: .. |Coverage-Status| image:: https://img.shields.io/coveralls/github/tqdm/tqdm/master?logo=coveralls jpayne@69: :target: https://coveralls.io/github/tqdm/tqdm jpayne@69: .. |Branch-Coverage-Status| image:: https://codecov.io/gh/tqdm/tqdm/branch/master/graph/badge.svg jpayne@69: :target: https://codecov.io/gh/tqdm/tqdm jpayne@69: .. |Codacy-Grade| image:: https://app.codacy.com/project/badge/Grade/3f965571598f44549c7818f29cdcf177 jpayne@69: :target: https://www.codacy.com/gh/tqdm/tqdm/dashboard jpayne@69: .. |CII Best Practices| image:: https://bestpractices.coreinfrastructure.org/projects/3264/badge jpayne@69: :target: https://bestpractices.coreinfrastructure.org/projects/3264 jpayne@69: .. |GitHub-Status| image:: https://img.shields.io/github/tag/tqdm/tqdm.svg?maxAge=86400&logo=github&logoColor=white jpayne@69: :target: https://github.com/tqdm/tqdm/releases jpayne@69: .. |GitHub-Forks| image:: https://img.shields.io/github/forks/tqdm/tqdm.svg?logo=github&logoColor=white jpayne@69: :target: https://github.com/tqdm/tqdm/network jpayne@69: .. |GitHub-Stars| image:: https://img.shields.io/github/stars/tqdm/tqdm.svg?logo=github&logoColor=white jpayne@69: :target: https://github.com/tqdm/tqdm/stargazers jpayne@69: .. |GitHub-Commits| image:: https://img.shields.io/github/commit-activity/y/tqdm/tqdm.svg?logo=git&logoColor=white jpayne@69: :target: https://github.com/tqdm/tqdm/graphs/commit-activity jpayne@69: .. |GitHub-Issues| image:: https://img.shields.io/github/issues-closed/tqdm/tqdm.svg?logo=github&logoColor=white jpayne@69: :target: https://github.com/tqdm/tqdm/issues?q= jpayne@69: .. |GitHub-PRs| image:: https://img.shields.io/github/issues-pr-closed/tqdm/tqdm.svg?logo=github&logoColor=white jpayne@69: :target: https://github.com/tqdm/tqdm/pulls jpayne@69: .. |GitHub-Contributions| image:: https://img.shields.io/github/contributors/tqdm/tqdm.svg?logo=github&logoColor=white jpayne@69: :target: https://github.com/tqdm/tqdm/graphs/contributors jpayne@69: .. |GitHub-Updated| image:: https://img.shields.io/github/last-commit/tqdm/tqdm/master.svg?logo=github&logoColor=white&label=pushed jpayne@69: :target: https://github.com/tqdm/tqdm/pulse jpayne@69: .. |Gift-Casper| image:: https://img.shields.io/badge/dynamic/json.svg?color=ff69b4&label=gifts%20received&prefix=%C2%A3&query=%24..sum&url=https%3A%2F%2Fcaspersci.uk.to%2Fgifts.json jpayne@69: :target: https://cdcl.ml/sponsor jpayne@69: .. |Versions| image:: https://img.shields.io/pypi/v/tqdm.svg jpayne@69: :target: https://tqdm.github.io/releases jpayne@69: .. |PyPI-Downloads| image:: https://img.shields.io/pypi/dm/tqdm.svg?label=pypi%20downloads&logo=PyPI&logoColor=white jpayne@69: :target: https://pepy.tech/project/tqdm jpayne@69: .. |Py-Versions| image:: https://img.shields.io/pypi/pyversions/tqdm.svg?logo=python&logoColor=white jpayne@69: :target: https://pypi.org/project/tqdm jpayne@69: .. |Conda-Forge-Status| image:: https://img.shields.io/conda/v/conda-forge/tqdm.svg?label=conda-forge&logo=conda-forge jpayne@69: :target: https://anaconda.org/conda-forge/tqdm jpayne@69: .. |Snapcraft| image:: https://img.shields.io/badge/snap-install-82BEA0.svg?logo=snapcraft jpayne@69: :target: https://snapcraft.io/tqdm jpayne@69: .. |Docker| image:: https://img.shields.io/badge/docker-pull-blue.svg?logo=docker&logoColor=white jpayne@69: :target: https://hub.docker.com/r/tqdm/tqdm jpayne@69: .. |Libraries-Rank| image:: https://img.shields.io/librariesio/sourcerank/pypi/tqdm.svg?logo=koding&logoColor=white jpayne@69: :target: https://libraries.io/pypi/tqdm jpayne@69: .. |Libraries-Dependents| image:: https://img.shields.io/librariesio/dependent-repos/pypi/tqdm.svg?logo=koding&logoColor=white jpayne@69: :target: https://github.com/tqdm/tqdm/network/dependents jpayne@69: .. |OpenHub-Status| image:: https://www.openhub.net/p/tqdm/widgets/project_thin_badge?format=gif jpayne@69: :target: https://www.openhub.net/p/tqdm?ref=Thin+badge jpayne@69: .. |awesome-python| image:: https://awesome.re/mentioned-badge.svg jpayne@69: :target: https://github.com/vinta/awesome-python jpayne@69: .. |LICENCE| image:: https://img.shields.io/pypi/l/tqdm.svg jpayne@69: :target: https://raw.githubusercontent.com/tqdm/tqdm/master/LICENCE jpayne@69: .. |DOI| image:: https://img.shields.io/badge/DOI-10.5281/zenodo.595120-blue.svg jpayne@69: :target: https://doi.org/10.5281/zenodo.595120 jpayne@69: .. |binder-demo| image:: https://mybinder.org/badge_logo.svg jpayne@69: :target: https://mybinder.org/v2/gh/tqdm/tqdm/master?filepath=DEMO.ipynb jpayne@69: .. |Screenshot-Jupyter1| image:: https://tqdm.github.io/img/jupyter-1.gif jpayne@69: .. |Screenshot-Jupyter2| image:: https://tqdm.github.io/img/jupyter-2.gif jpayne@69: .. |Screenshot-Jupyter3| image:: https://tqdm.github.io/img/jupyter-3.gif jpayne@69: .. |README-Hits| image:: https://cgi.cdcl.ml/hits?q=tqdm&style=social&r=https://github.com/tqdm/tqdm&l=https://tqdm.github.io/img/favicon.png&f=https://tqdm.github.io/img/logo.gif jpayne@69: :target: https://cgi.cdcl.ml/hits?q=tqdm&a=plot&r=https://github.com/tqdm/tqdm&l=https://tqdm.github.io/img/favicon.png&f=https://tqdm.github.io/img/logo.gif&style=social