atpbar


Nameatpbar JSON
Version 2.0.0 PyPI version JSON
download
home_pageNone
SummaryProgress bars for threading and multiprocessing tasks
upload_time2024-05-05 16:24:00
maintainerNone
docs_urlNone
authorNone
requires_python>=3.10
licenseNone
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage
            [![PyPI version](https://badge.fury.io/py/atpbar.svg)](https://badge.fury.io/py/atpbar)
[![Anaconda-Server Badge](https://anaconda.org/conda-forge/atpbar/badges/version.svg)](https://anaconda.org/conda-forge/atpbar)
[![DOI](https://zenodo.org/badge/doi/10.5281/zenodo.2567283.svg)](https://doi.org/10.5281/zenodo.2567283)

[![Test Status](https://github.com/alphatwirl/atpbar/actions/workflows/unit-test.yml/badge.svg)](https://github.com/alphatwirl/atpbar/actions/workflows/unit-test.yml)
[![Test Status](https://github.com/alphatwirl/atpbar/actions/workflows/type-check.yml/badge.svg)](https://github.com/alphatwirl/atpbar/actions/workflows/type-check.yml)
[![codecov](https://codecov.io/gh/alphatwirl/atpbar/branch/master/graph/badge.svg)](https://codecov.io/gh/alphatwirl/atpbar)

# atpbar

_Progress bars_ for threading and multiprocessing tasks on the terminal and
Jupyter Notebook.

```plaintext
 100.00% :::::::::::::::::::::::::::::::::::::::: |     7811 /     7811 |:  task 1
 100.00% :::::::::::::::::::::::::::::::::::::::: |    23258 /    23258 |:  task 0
  65.62% ::::::::::::::::::::::::::               |     8018 /    12219 |:  task 4
  60.89% ::::::::::::::::::::::::                 |    31083 /    51048 |:  task 2
  25.03% ::::::::::                               |    23884 /    95421 |:  task 3
```

_atpbar_ can display multiple progress bars simultaneously growing to show the
progress of each iteration of loops in
[threading](https://docs.python.org/3/library/threading.html) or
[multiprocessing](https://docs.python.org/3/library/multiprocessing.html)
tasks. _atpbar_ can display progress bars on the terminal and [Jupyter
Notebook](https://jupyter.org/).

_atpbar_ started its development in 2015 and was the sub-package
[_progressbar_](https://github.com/alphatwirl/alphatwirl/tree/v0.22.0/alphatwirl/progressbar)
of alphatwirl. It became an independent package in 2019.

You can try it on Jupyter Notebook online:
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/alphatwirl/notebook-atpbar-001/master?filepath=atpbar.ipynb)

---

- [Requirement](#requirement)
- [Install](#install)
- [User guide](#user-guide)
- [Quick start](#quick-start)
  - [Import libraries](#import-libraries)
  - [One loop](#one-loop)
  - [Nested loops](#nested-loops)
  - [Threading](#threading)
  - [Multiprocessing](#multiprocessing)
  - [Multiprocessing.Pool](#multiprocessingpool)
- [Features](#features)
  - [A `break` and an exception](#a-break-and-an-exception)
  - [Progress of starting threads and processes with progress bars](#progress-of-starting-threads-and-processes-with-progress-bars)
  - [On Jupyter Notebook](#on-jupyter-notebook)
  - [Non TTY device](#non-tty-device)
  - [How to disable progress bars](#how-to-disable-progress-bars)
- [License](#license)

---

## Requirement

- Python 3.10, 3.11, or 3.12

---

## Install

You can install with `pip` from [PyPI](https://pypi.org/project/atpbar/):

```bash
pip install -U atpbar
```

To install with Jupyter Notebook support, use the following command:

```bash
pip install -U atpbar[jupyter]
```

---

## User guide

### Quick start

I will show you how to use the atpbar using simple examples.

#### Import libraries

To create simple loops in the examples, we use two python standard
libraries, [time](https://docs.python.org/3/library/time.html) and
[random](https://docs.python.org/3/library/random.html). Import the
two packages as well as `atpbar`.

```python
import time, random
from atpbar import atpbar
```

#### One loop

The object `atpbar` is an iterable that can wrap another iterable and shows the
progress bars for the iterations. (The idea of making the interface iterable
was inspired by [tqdm](https://github.com/tqdm/tqdm).)

```python
n = random.randint(1000, 10000)
for i in atpbar(range(n)):
    time.sleep(0.0001)
```

The task in the above code is to sleep for `0.0001` seconds in each iteration
of the loop. The number of the iterations of the loop is randomly selected from
between `1000` and `10000`.

A progress bar will be shown by `atpbar`.

```plaintext
  51.25% ::::::::::::::::::::                     |     4132 /     8062 |:  range(0, 8062)
```

In order for `atpbar` to show a progress bar, the wrapped iterable needs to
have a length. If the length cannot be obtained by `len()`, `atpbar` won't show
a progress bar.

#### Nested loops

`atpbar` can show progress bars for nested loops as in the following example.

```python
for i in atpbar(range(4), name='Outer'):
    n = random.randint(1000, 10000)
    for j in atpbar(range(n), name='Inner {}'.format(i)):
        time.sleep(0.0001)
```

The outer loop iterates 4 times. The inner loop is similar to the loop
in the previous example---sleeps for `0.0001` seconds. You can
optionally give the keyword argument `name` to specify the label on
the progress bar.

```plaintext
 100.00% :::::::::::::::::::::::::::::::::::::::: |     3287 /     3287 |:  Inner 0
 100.00% :::::::::::::::::::::::::::::::::::::::: |     5850 /     5850 |:  Inner 1
  50.00% ::::::::::::::::::::                     |        2 /        4 |:  Outer
  34.42% :::::::::::::                            |     1559 /     4529 |:  Inner 2
```

In the snapshot of the progress bars above, the outer loop is in its 3rd
iteration. The inner loop has been completed twice and is running the third.
The progress bars for the completed tasks move up. The progress bars for the
active tasks are growing at the bottom.

#### Threading

`atpbar` can show multiple progress bars for loops concurrently iterating in
different threads.

The function `run_with_threading()` in the following code shows an
example.

```python
from atpbar import flush
import threading

def run_with_threading():
    def task(n, name):
        for _ in atpbar(range(n), name=name):
            time.sleep(0.0001)

    n_threads = 5
    threads = []

    for i in range(n_threads):
        name = 'Thread {}'.format(i)
        n = random.randint(5, 10000)
        t = threading.Thread(target=task, args=(n, name))
        t.start()
        threads.append(t)

    for t in threads:
        t.join()

    flush()


run_with_threading()
```

The task to sleep for `0.0001` seconds is defined as the function `task`. The
`task` is concurrently run five times with `threading`. `atpbar` can be used in
any thread. Five progress bars growing simultaneously will be shown. The
function `flush()` returns when the progress bars have finished updating.

```plaintext
 100.00% :::::::::::::::::::::::::::::::::::::::: |     8042 /     8042 |:  Thread 3
  33.30% :::::::::::::                            |    31967 /    95983 |:  Thread 0
  77.41% ::::::::::::::::::::::::::::::           |    32057 /    41411 |:  Thread 1
  45.78% ::::::::::::::::::                       |    31816 /    69499 |:  Thread 2
  39.93% :::::::::::::::                          |    32373 /    81077 |:  Thread 4
```

As a task completes, the progress bar for the task moves up. The
progress bars for active tasks are at the bottom.

#### Multiprocessing

`atpbar` can be used with `multiprocessing`.

The function `run_with_multiprocessing()` in the following code shows an
example.

```python
import multiprocessing
multiprocessing.set_start_method('fork', force=True)

from atpbar import register_reporter, find_reporter, flush

def run_with_multiprocessing():

    def task(n, name):
        for _ in atpbar(range(n), name=name):
            time.sleep(0.0001)

    def worker(reporter, task, queue):
        register_reporter(reporter)
        while True:
            args = queue.get()
            if args is None:
                queue.task_done()
                break
            task(*args)
            queue.task_done()

    n_processes = 4
    processes = []

    reporter = find_reporter()
    queue = multiprocessing.JoinableQueue()

    for i in range(n_processes):
        p = multiprocessing.Process(target=worker, args=(reporter, task, queue))
        p.start()
        processes.append(p)

    n_tasks = 10
    for i in range(n_tasks):
        name = 'Task {}'.format(i)
        n = random.randint(5, 10000)
        queue.put((n, name))

    for i in range(n_processes):
        queue.put(None)
    queue.join()

    flush()


run_with_multiprocessing()
```

It starts four workers in subprocesses with `multiprocessing` and have
them run ten tasks.

In order to use `atpbar` in a subprocess, the `reporter`, which can be
found in the main process by the function `find_reporter()`, needs to
be brought to the subprocess and registered there by the function
`register_reporter()`.

Simultaneously growing progress bars will be shown.

```plaintext
 100.00% :::::::::::::::::::::::::::::::::::::::: |    44714 /    44714 |:  Task 3
 100.00% :::::::::::::::::::::::::::::::::::::::: |    47951 /    47951 |:  Task 2
 100.00% :::::::::::::::::::::::::::::::::::::::: |    21461 /    21461 |:  Task 5
 100.00% :::::::::::::::::::::::::::::::::::::::: |    73721 /    73721 |:  Task 1
 100.00% :::::::::::::::::::::::::::::::::::::::: |    31976 /    31976 |:  Task 4
 100.00% :::::::::::::::::::::::::::::::::::::::: |    80765 /    80765 |:  Task 0
  58.12% :::::::::::::::::::::::                  |    20133 /    34641 |:  Task 6
  20.47% ::::::::                                 |    16194 /    79126 |:  Task 7
  47.71% :::::::::::::::::::                      |    13072 /    27397 |:  Task 8
  76.09% ::::::::::::::::::::::::::::::           |     9266 /    12177 |:  Task 9
```

#### Multiprocessing.Pool

To use `atpbar` with
[`multiprocessing.Pool`](https://docs.python.org/3/library/multiprocessing.html#multiprocessing.pool.Pool),
use `find_reporter` as the initializer and give the `reporter` as an argument
to the initializer.

```python
def task(n, name):
    for _ in atpbar(range(n), name=name):
        time.sleep(0.0001)


def run_with_multiprocessing_pool():

    n_processes = 4
    reporter = find_reporter()
    n_tasks = 10

    args = [(random.randint(5, 10000), 'Task {}'.format(i)) for i in range(n_tasks)]

    with multiprocessing.Pool(n_processes, register_reporter, (reporter,)) as pool:
        pool.starmap(task, args)

    flush()


run_with_multiprocessing_pool()
```

---

### Features

#### A `break` and an exception

When the loop ends with a `break` or an exception, the progress bar stops with
the last complete iteration.

For example, the loop in the following code breaks during the 1235th iteration.

```python
for i in atpbar(range(2000)):
    if i == 1234:
        break
    time.sleep(0.0001)
```

Since `i` starts with `0`, when `i` is `1234`, the loop is in its 1235th
iteration. The last complete iteration is 1234. The progress bar stops at 1234.

```plaintext
  61.70% ::::::::::::::::::::::::                 |     1234 /     2000 |:  range(0, 2000)
```

As an example of an exception, in the following code, an exception is
thrown during the 1235th iteration.

```python
for i in atpbar(range(2000)):
    if i == 1234:
        raise Exception
    time.sleep(0.0001)
```

The progress bar stops at the last complete iteration, 1234.

```
  61.70% ::::::::::::::::::::::::                 |     1234 /     2000 |:  range(0, 2000)
Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
Exception
```

This feature works as well with nested loops, threading, and
multiprocessing. For example, in the following code, the loops in five
threads break at 1235th iteration.

```python
from atpbar import flush
import threading

def run_with_threading():
    def task(n, name):
        for i in atpbar(range(n), name=name):
            if i == 1234:
                break
            time.sleep(0.0001)

    n_threads = 5
    threads = []

    for i in range(n_threads):
        name = 'Thread {}'.format(i)
        n = random.randint(3000, 10000)
        t = threading.Thread(target=task, args=(n, name))
        t.start()
        threads.append(t)

    for t in threads:
        t.join()

    flush()

run_with_threading()
```

All progress bars stop at 1234.

```
  18.21% :::::::                                  |     1234 /     6777 |:  Thread 0
  15.08% ::::::                                   |     1234 /     8183 |:  Thread 2
  15.25% ::::::                                   |     1234 /     8092 |:  Thread 1
  39.90% :::::::::::::::                          |     1234 /     3093 |:  Thread 4
  19.67% :::::::                                  |     1234 /     6274 |:  Thread 3
```

#### Progress of starting threads and processes with progress bars

`atpbar` can be used for a loop that starts sub-threads or sub-processes in
which `atpbar` is also used.

```python
from atpbar import flush
import threading

def run_with_threading():
    def task(n, name):
        for i in atpbar(range(n), name=name):
            time.sleep(0.0001)

    n_threads = 5
    threads = []

    for i in atpbar(range(n_threads)):
        name = 'Thread {}'.format(i)
        n = random.randint(200, 1000)
        t = threading.Thread(target=task, args=(n, name))
        t.start()
        threads.append(t)
        time.sleep(0.1)

    for t in threads:
        t.join()

    flush()

run_with_threading()
```

```
 100.00% :::::::::::::::::::::::::::::::::::::::: |      209 /      209 |:  Thread 1
 100.00% :::::::::::::::::::::::::::::::::::::::: |      699 /      699 |:  Thread 0
 100.00% :::::::::::::::::::::::::::::::::::::::: |      775 /      775 |:  Thread 2
 100.00% :::::::::::::::::::::::::::::::::::::::: |      495 /      495 |:  Thread 3
 100.00% :::::::::::::::::::::::::::::::::::::::: |        5 /        5 |:  range(0, 5)
 100.00% :::::::::::::::::::::::::::::::::::::::: |      647 /      647 |:  Thread 4
```

The `atpbar` sensibly works regardless of the order in which multiple instances
of `atpbar` in multiple threads and multiple processes start and end. The
progress bars in the example above indicate that the loops in four threads
have already ended before the loop in the main threads ended; the loop in the
last thread ended afterward.

---

#### On Jupyter Notebook

On Jupyter Notebook, `atpbar` shows progress bars based on
[widgets](https://ipywidgets.readthedocs.io).

<img src="https://raw.githubusercontent.com/alphatwirl/notebook-atpbar-001/v1.0.1/images/20190304_01_atpbar_jupyter.gif" width="800">

You can try interactively online:
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/alphatwirl/notebook-atpbar-001/master?filepath=atpbar.ipynb)

---

#### Non TTY device

If neither on Jupyter Notebook or on a TTY device, `atpbar` is not able to show
progress bars. `atpbar` occasionally prints the status.

```
03/04 09:17 :     1173 /     7685 ( 15.26%): Thread 0
03/04 09:17 :     1173 /     6470 ( 18.13%): Thread 3
03/04 09:17 :     1199 /     1199 (100.00%): Thread 4
03/04 09:18 :     1756 /     2629 ( 66.79%): Thread 2
03/04 09:18 :     1757 /     7685 ( 22.86%): Thread 0
03/04 09:18 :     1757 /     6470 ( 27.16%): Thread 3
03/04 09:19 :     2342 /     2629 ( 89.08%): Thread 2
```

---

#### How to disable progress bars

The function `disable()` disables `atpbar`; progress bars will not be shown.

```python
from atpbar import disable

disable()
```

This function needs to be called before `atpbar` or `find_reporter()` is used,
typically at the beginning of the program.

---

## License

- _atpbar_ is licensed under the BSD license.

---

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "atpbar",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": null,
    "author": null,
    "author_email": "Tai Sakuma <tai.sakuma@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/83/1f/0d5991650fd751906f2638e1926b8231dfd28b02f27d643368c8e9a4011e/atpbar-2.0.0.tar.gz",
    "platform": null,
    "description": "[![PyPI version](https://badge.fury.io/py/atpbar.svg)](https://badge.fury.io/py/atpbar)\n[![Anaconda-Server Badge](https://anaconda.org/conda-forge/atpbar/badges/version.svg)](https://anaconda.org/conda-forge/atpbar)\n[![DOI](https://zenodo.org/badge/doi/10.5281/zenodo.2567283.svg)](https://doi.org/10.5281/zenodo.2567283)\n\n[![Test Status](https://github.com/alphatwirl/atpbar/actions/workflows/unit-test.yml/badge.svg)](https://github.com/alphatwirl/atpbar/actions/workflows/unit-test.yml)\n[![Test Status](https://github.com/alphatwirl/atpbar/actions/workflows/type-check.yml/badge.svg)](https://github.com/alphatwirl/atpbar/actions/workflows/type-check.yml)\n[![codecov](https://codecov.io/gh/alphatwirl/atpbar/branch/master/graph/badge.svg)](https://codecov.io/gh/alphatwirl/atpbar)\n\n# atpbar\n\n_Progress bars_ for threading and multiprocessing tasks on the terminal and\nJupyter Notebook.\n\n```plaintext\n 100.00% :::::::::::::::::::::::::::::::::::::::: |     7811 /     7811 |:  task 1\n 100.00% :::::::::::::::::::::::::::::::::::::::: |    23258 /    23258 |:  task 0\n  65.62% ::::::::::::::::::::::::::               |     8018 /    12219 |:  task 4\n  60.89% ::::::::::::::::::::::::                 |    31083 /    51048 |:  task 2\n  25.03% ::::::::::                               |    23884 /    95421 |:  task 3\n```\n\n_atpbar_ can display multiple progress bars simultaneously growing to show the\nprogress of each iteration of loops in\n[threading](https://docs.python.org/3/library/threading.html) or\n[multiprocessing](https://docs.python.org/3/library/multiprocessing.html)\ntasks. _atpbar_ can display progress bars on the terminal and [Jupyter\nNotebook](https://jupyter.org/).\n\n_atpbar_ started its development in 2015 and was the sub-package\n[_progressbar_](https://github.com/alphatwirl/alphatwirl/tree/v0.22.0/alphatwirl/progressbar)\nof alphatwirl. It became an independent package in 2019.\n\nYou can try it on Jupyter Notebook online:\n[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/alphatwirl/notebook-atpbar-001/master?filepath=atpbar.ipynb)\n\n---\n\n- [Requirement](#requirement)\n- [Install](#install)\n- [User guide](#user-guide)\n- [Quick start](#quick-start)\n  - [Import libraries](#import-libraries)\n  - [One loop](#one-loop)\n  - [Nested loops](#nested-loops)\n  - [Threading](#threading)\n  - [Multiprocessing](#multiprocessing)\n  - [Multiprocessing.Pool](#multiprocessingpool)\n- [Features](#features)\n  - [A `break` and an exception](#a-break-and-an-exception)\n  - [Progress of starting threads and processes with progress bars](#progress-of-starting-threads-and-processes-with-progress-bars)\n  - [On Jupyter Notebook](#on-jupyter-notebook)\n  - [Non TTY device](#non-tty-device)\n  - [How to disable progress bars](#how-to-disable-progress-bars)\n- [License](#license)\n\n---\n\n## Requirement\n\n- Python 3.10, 3.11, or 3.12\n\n---\n\n## Install\n\nYou can install with `pip` from [PyPI](https://pypi.org/project/atpbar/):\n\n```bash\npip install -U atpbar\n```\n\nTo install with Jupyter Notebook support, use the following command:\n\n```bash\npip install -U atpbar[jupyter]\n```\n\n---\n\n## User guide\n\n### Quick start\n\nI will show you how to use the atpbar using simple examples.\n\n#### Import libraries\n\nTo create simple loops in the examples, we use two python standard\nlibraries, [time](https://docs.python.org/3/library/time.html) and\n[random](https://docs.python.org/3/library/random.html). Import the\ntwo packages as well as `atpbar`.\n\n```python\nimport time, random\nfrom atpbar import atpbar\n```\n\n#### One loop\n\nThe object `atpbar` is an iterable that can wrap another iterable and shows the\nprogress bars for the iterations. (The idea of making the interface iterable\nwas inspired by [tqdm](https://github.com/tqdm/tqdm).)\n\n```python\nn = random.randint(1000, 10000)\nfor i in atpbar(range(n)):\n    time.sleep(0.0001)\n```\n\nThe task in the above code is to sleep for `0.0001` seconds in each iteration\nof the loop. The number of the iterations of the loop is randomly selected from\nbetween `1000` and `10000`.\n\nA progress bar will be shown by `atpbar`.\n\n```plaintext\n  51.25% ::::::::::::::::::::                     |     4132 /     8062 |:  range(0, 8062)\n```\n\nIn order for `atpbar` to show a progress bar, the wrapped iterable needs to\nhave a length. If the length cannot be obtained by `len()`, `atpbar` won't show\na progress bar.\n\n#### Nested loops\n\n`atpbar` can show progress bars for nested loops as in the following example.\n\n```python\nfor i in atpbar(range(4), name='Outer'):\n    n = random.randint(1000, 10000)\n    for j in atpbar(range(n), name='Inner {}'.format(i)):\n        time.sleep(0.0001)\n```\n\nThe outer loop iterates 4 times. The inner loop is similar to the loop\nin the previous example---sleeps for `0.0001` seconds. You can\noptionally give the keyword argument `name` to specify the label on\nthe progress bar.\n\n```plaintext\n 100.00% :::::::::::::::::::::::::::::::::::::::: |     3287 /     3287 |:  Inner 0\n 100.00% :::::::::::::::::::::::::::::::::::::::: |     5850 /     5850 |:  Inner 1\n  50.00% ::::::::::::::::::::                     |        2 /        4 |:  Outer\n  34.42% :::::::::::::                            |     1559 /     4529 |:  Inner 2\n```\n\nIn the snapshot of the progress bars above, the outer loop is in its 3rd\niteration. The inner loop has been completed twice and is running the third.\nThe progress bars for the completed tasks move up. The progress bars for the\nactive tasks are growing at the bottom.\n\n#### Threading\n\n`atpbar` can show multiple progress bars for loops concurrently iterating in\ndifferent threads.\n\nThe function `run_with_threading()` in the following code shows an\nexample.\n\n```python\nfrom atpbar import flush\nimport threading\n\ndef run_with_threading():\n    def task(n, name):\n        for _ in atpbar(range(n), name=name):\n            time.sleep(0.0001)\n\n    n_threads = 5\n    threads = []\n\n    for i in range(n_threads):\n        name = 'Thread {}'.format(i)\n        n = random.randint(5, 10000)\n        t = threading.Thread(target=task, args=(n, name))\n        t.start()\n        threads.append(t)\n\n    for t in threads:\n        t.join()\n\n    flush()\n\n\nrun_with_threading()\n```\n\nThe task to sleep for `0.0001` seconds is defined as the function `task`. The\n`task` is concurrently run five times with `threading`. `atpbar` can be used in\nany thread. Five progress bars growing simultaneously will be shown. The\nfunction `flush()` returns when the progress bars have finished updating.\n\n```plaintext\n 100.00% :::::::::::::::::::::::::::::::::::::::: |     8042 /     8042 |:  Thread 3\n  33.30% :::::::::::::                            |    31967 /    95983 |:  Thread 0\n  77.41% ::::::::::::::::::::::::::::::           |    32057 /    41411 |:  Thread 1\n  45.78% ::::::::::::::::::                       |    31816 /    69499 |:  Thread 2\n  39.93% :::::::::::::::                          |    32373 /    81077 |:  Thread 4\n```\n\nAs a task completes, the progress bar for the task moves up. The\nprogress bars for active tasks are at the bottom.\n\n#### Multiprocessing\n\n`atpbar` can be used with `multiprocessing`.\n\nThe function `run_with_multiprocessing()` in the following code shows an\nexample.\n\n```python\nimport multiprocessing\nmultiprocessing.set_start_method('fork', force=True)\n\nfrom atpbar import register_reporter, find_reporter, flush\n\ndef run_with_multiprocessing():\n\n    def task(n, name):\n        for _ in atpbar(range(n), name=name):\n            time.sleep(0.0001)\n\n    def worker(reporter, task, queue):\n        register_reporter(reporter)\n        while True:\n            args = queue.get()\n            if args is None:\n                queue.task_done()\n                break\n            task(*args)\n            queue.task_done()\n\n    n_processes = 4\n    processes = []\n\n    reporter = find_reporter()\n    queue = multiprocessing.JoinableQueue()\n\n    for i in range(n_processes):\n        p = multiprocessing.Process(target=worker, args=(reporter, task, queue))\n        p.start()\n        processes.append(p)\n\n    n_tasks = 10\n    for i in range(n_tasks):\n        name = 'Task {}'.format(i)\n        n = random.randint(5, 10000)\n        queue.put((n, name))\n\n    for i in range(n_processes):\n        queue.put(None)\n    queue.join()\n\n    flush()\n\n\nrun_with_multiprocessing()\n```\n\nIt starts four workers in subprocesses with `multiprocessing` and have\nthem run ten tasks.\n\nIn order to use `atpbar` in a subprocess, the `reporter`, which can be\nfound in the main process by the function `find_reporter()`, needs to\nbe brought to the subprocess and registered there by the function\n`register_reporter()`.\n\nSimultaneously growing progress bars will be shown.\n\n```plaintext\n 100.00% :::::::::::::::::::::::::::::::::::::::: |    44714 /    44714 |:  Task 3\n 100.00% :::::::::::::::::::::::::::::::::::::::: |    47951 /    47951 |:  Task 2\n 100.00% :::::::::::::::::::::::::::::::::::::::: |    21461 /    21461 |:  Task 5\n 100.00% :::::::::::::::::::::::::::::::::::::::: |    73721 /    73721 |:  Task 1\n 100.00% :::::::::::::::::::::::::::::::::::::::: |    31976 /    31976 |:  Task 4\n 100.00% :::::::::::::::::::::::::::::::::::::::: |    80765 /    80765 |:  Task 0\n  58.12% :::::::::::::::::::::::                  |    20133 /    34641 |:  Task 6\n  20.47% ::::::::                                 |    16194 /    79126 |:  Task 7\n  47.71% :::::::::::::::::::                      |    13072 /    27397 |:  Task 8\n  76.09% ::::::::::::::::::::::::::::::           |     9266 /    12177 |:  Task 9\n```\n\n#### Multiprocessing.Pool\n\nTo use `atpbar` with\n[`multiprocessing.Pool`](https://docs.python.org/3/library/multiprocessing.html#multiprocessing.pool.Pool),\nuse `find_reporter` as the initializer and give the `reporter` as an argument\nto the initializer.\n\n```python\ndef task(n, name):\n    for _ in atpbar(range(n), name=name):\n        time.sleep(0.0001)\n\n\ndef run_with_multiprocessing_pool():\n\n    n_processes = 4\n    reporter = find_reporter()\n    n_tasks = 10\n\n    args = [(random.randint(5, 10000), 'Task {}'.format(i)) for i in range(n_tasks)]\n\n    with multiprocessing.Pool(n_processes, register_reporter, (reporter,)) as pool:\n        pool.starmap(task, args)\n\n    flush()\n\n\nrun_with_multiprocessing_pool()\n```\n\n---\n\n### Features\n\n#### A `break` and an exception\n\nWhen the loop ends with a `break` or an exception, the progress bar stops with\nthe last complete iteration.\n\nFor example, the loop in the following code breaks during the 1235th iteration.\n\n```python\nfor i in atpbar(range(2000)):\n    if i == 1234:\n        break\n    time.sleep(0.0001)\n```\n\nSince `i` starts with `0`, when `i` is `1234`, the loop is in its 1235th\niteration. The last complete iteration is 1234. The progress bar stops at 1234.\n\n```plaintext\n  61.70% ::::::::::::::::::::::::                 |     1234 /     2000 |:  range(0, 2000)\n```\n\nAs an example of an exception, in the following code, an exception is\nthrown during the 1235th iteration.\n\n```python\nfor i in atpbar(range(2000)):\n    if i == 1234:\n        raise Exception\n    time.sleep(0.0001)\n```\n\nThe progress bar stops at the last complete iteration, 1234.\n\n```\n  61.70% ::::::::::::::::::::::::                 |     1234 /     2000 |:  range(0, 2000)\nTraceback (most recent call last):\n  File \"<stdin>\", line 3, in <module>\nException\n```\n\nThis feature works as well with nested loops, threading, and\nmultiprocessing. For example, in the following code, the loops in five\nthreads break at 1235th iteration.\n\n```python\nfrom atpbar import flush\nimport threading\n\ndef run_with_threading():\n    def task(n, name):\n        for i in atpbar(range(n), name=name):\n            if i == 1234:\n                break\n            time.sleep(0.0001)\n\n    n_threads = 5\n    threads = []\n\n    for i in range(n_threads):\n        name = 'Thread {}'.format(i)\n        n = random.randint(3000, 10000)\n        t = threading.Thread(target=task, args=(n, name))\n        t.start()\n        threads.append(t)\n\n    for t in threads:\n        t.join()\n\n    flush()\n\nrun_with_threading()\n```\n\nAll progress bars stop at 1234.\n\n```\n  18.21% :::::::                                  |     1234 /     6777 |:  Thread 0\n  15.08% ::::::                                   |     1234 /     8183 |:  Thread 2\n  15.25% ::::::                                   |     1234 /     8092 |:  Thread 1\n  39.90% :::::::::::::::                          |     1234 /     3093 |:  Thread 4\n  19.67% :::::::                                  |     1234 /     6274 |:  Thread 3\n```\n\n#### Progress of starting threads and processes with progress bars\n\n`atpbar` can be used for a loop that starts sub-threads or sub-processes in\nwhich `atpbar` is also used.\n\n```python\nfrom atpbar import flush\nimport threading\n\ndef run_with_threading():\n    def task(n, name):\n        for i in atpbar(range(n), name=name):\n            time.sleep(0.0001)\n\n    n_threads = 5\n    threads = []\n\n    for i in atpbar(range(n_threads)):\n        name = 'Thread {}'.format(i)\n        n = random.randint(200, 1000)\n        t = threading.Thread(target=task, args=(n, name))\n        t.start()\n        threads.append(t)\n        time.sleep(0.1)\n\n    for t in threads:\n        t.join()\n\n    flush()\n\nrun_with_threading()\n```\n\n```\n 100.00% :::::::::::::::::::::::::::::::::::::::: |      209 /      209 |:  Thread 1\n 100.00% :::::::::::::::::::::::::::::::::::::::: |      699 /      699 |:  Thread 0\n 100.00% :::::::::::::::::::::::::::::::::::::::: |      775 /      775 |:  Thread 2\n 100.00% :::::::::::::::::::::::::::::::::::::::: |      495 /      495 |:  Thread 3\n 100.00% :::::::::::::::::::::::::::::::::::::::: |        5 /        5 |:  range(0, 5)\n 100.00% :::::::::::::::::::::::::::::::::::::::: |      647 /      647 |:  Thread 4\n```\n\nThe `atpbar` sensibly works regardless of the order in which multiple instances\nof `atpbar` in multiple threads and multiple processes start and end. The\nprogress bars in the example above indicate that the loops in four threads\nhave already ended before the loop in the main threads ended; the loop in the\nlast thread ended afterward.\n\n---\n\n#### On Jupyter Notebook\n\nOn Jupyter Notebook, `atpbar` shows progress bars based on\n[widgets](https://ipywidgets.readthedocs.io).\n\n<img src=\"https://raw.githubusercontent.com/alphatwirl/notebook-atpbar-001/v1.0.1/images/20190304_01_atpbar_jupyter.gif\" width=\"800\">\n\nYou can try interactively online:\n[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/alphatwirl/notebook-atpbar-001/master?filepath=atpbar.ipynb)\n\n---\n\n#### Non TTY device\n\nIf neither on Jupyter Notebook or on a TTY device, `atpbar` is not able to show\nprogress bars. `atpbar` occasionally prints the status.\n\n```\n03/04 09:17 :     1173 /     7685 ( 15.26%): Thread 0\n03/04 09:17 :     1173 /     6470 ( 18.13%): Thread 3\n03/04 09:17 :     1199 /     1199 (100.00%): Thread 4\n03/04 09:18 :     1756 /     2629 ( 66.79%): Thread 2\n03/04 09:18 :     1757 /     7685 ( 22.86%): Thread 0\n03/04 09:18 :     1757 /     6470 ( 27.16%): Thread 3\n03/04 09:19 :     2342 /     2629 ( 89.08%): Thread 2\n```\n\n---\n\n#### How to disable progress bars\n\nThe function `disable()` disables `atpbar`; progress bars will not be shown.\n\n```python\nfrom atpbar import disable\n\ndisable()\n```\n\nThis function needs to be called before `atpbar` or `find_reporter()` is used,\ntypically at the beginning of the program.\n\n---\n\n## License\n\n- _atpbar_ is licensed under the BSD license.\n\n---\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Progress bars for threading and multiprocessing tasks",
    "version": "2.0.0",
    "project_urls": {
        "Homepage": "https://github.com/alphatwirl/atpbar"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "73a418c433b8d1c937ad092e9324ce0485d8053b6a34bceed18862cbbe172bcc",
                "md5": "7504d2453285713c5627b0772a35eea4",
                "sha256": "4a0b63395d189360e46a358157026a4d6a31941707dd71d7a0555b227a87761c"
            },
            "downloads": -1,
            "filename": "atpbar-2.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "7504d2453285713c5627b0772a35eea4",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 21141,
            "upload_time": "2024-05-05T16:23:58",
            "upload_time_iso_8601": "2024-05-05T16:23:58.265887Z",
            "url": "https://files.pythonhosted.org/packages/73/a4/18c433b8d1c937ad092e9324ce0485d8053b6a34bceed18862cbbe172bcc/atpbar-2.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "831f0d5991650fd751906f2638e1926b8231dfd28b02f27d643368c8e9a4011e",
                "md5": "5ca17666805918801450e0c52c8f3cd1",
                "sha256": "b3d41eb6e0b338bf1e8b31afd70574ccab493d595cd5895aeb121646dd684b38"
            },
            "downloads": -1,
            "filename": "atpbar-2.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "5ca17666805918801450e0c52c8f3cd1",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 15977,
            "upload_time": "2024-05-05T16:24:00",
            "upload_time_iso_8601": "2024-05-05T16:24:00.101197Z",
            "url": "https://files.pythonhosted.org/packages/83/1f/0d5991650fd751906f2638e1926b8231dfd28b02f27d643368c8e9a4011e/atpbar-2.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-05-05 16:24:00",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "alphatwirl",
    "github_project": "atpbar",
    "travis_ci": false,
    "coveralls": true,
    "github_actions": true,
    "lcname": "atpbar"
}
        
Elapsed time: 0.25839s