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