# How QueryNotifyPrint Reports Progress in Maigret: A Technical Deep Dive

> Discover how Maigret's QueryNotifyPrint system reports scan progress. Learn about its three-phase console output, color-coded symbols, and asynchronous progress bar.

- Repository: [Soxoj/maigret](https://github.com/soxoj/maigret)
- Tags: deep-dive
- Published: 2026-04-30

---

**The `QueryNotifyPrint` notification system reports scan progress through a three-phase console output mechanism that prints color-coded status symbols alongside an asynchronous progress bar.**

Maigret, the OSINT username investigation tool, delegates all user-facing progress reporting to the `QueryNotifyPrint` class defined in [`maigret/notify.py`](https://github.com/soxoj/maigret/blob/main/maigret/notify.py). This concrete implementation of the notification API transforms asynchronous site-checking results into readable terminal output, handling everything from initial scan headers to per-site status updates while working in parallel with the `alive_progress` library.

## The Three-Phase Reporting Model

The `QueryNotifyPrint` notification system operates through distinct start, update, and finish phases that correspond to the lifecycle of a username investigation scan.

### Initialization and Start Phase

When a scan begins, the `start()` method (lines 78-92 in [`maigret/notify.py`](https://github.com/soxoj/maigret/blob/main/maigret/notify.py)) prints a colored header identifying the target identifier type and value. This method outputs a leading `[*]` symbol—or a colored `[ * ]` variant when terminal colors are enabled—to signal the beginning of the investigation.

### Per-Site Update Phase

The core reporting logic resides in the `update()` method (lines 31-100 in [`maigret/notify.py`](https://github.com/soxoj/maigret/blob/main/maigret/notify.py)), which executes after each site check completes. This method constructs a one-line status containing:

- A status symbol (`+` for claimed, `-` for available/not found, `?` for similar usernames)
- The site name
- The result URL or error message
- Optional extracted ID data rendered as an ASCII tree

To maintain clean terminal output, the method uses a carriage-return-clear sequence (`"\x1b[1K\r"`) that overwrites the current line. The implementation maps `MaigretCheckStatus` enum values to specific colors via `colorama`: green `+` for `CLAIMED`, red `-` for `AVAILABLE`, and blue `?` for similar matches.

### Completion Phase

The `finish()` method, inherited from the base `QueryNotify` class, currently executes as a no-op in [`maigret/notify.py`](https://github.com/soxoj/maigret/blob/main/maigret/notify.py). Scan termination is handled implicitly when the final update processes and the surrounding `alive_bar` context manager exits.

## Integration with the Alive Progress Bar

While `QueryNotifyPrint` handles detailed per-site reporting, the visual progress indicator comes from the `alive_progress` library integrated in [`maigret/checking.py`](https://github.com/soxoj/maigret/blob/main/maigret/checking.py) (lines 96-100). The core checking routine wraps the async executor in an `alive_bar` context manager:

```python
with alive_bar(len(tasks_dict), title="Searching", force_tty=True, disable=no_progressbar) as progress:
    async for result in executor.run(list(tasks_dict.values())):
        cur_results.append(result)
        progress()

```

This runs concurrently with the notification system, providing a visual "X / N sites processed" counter while `QueryNotifyPrint.update()` renders the detailed status lines below.

## Configuration and Control Flow

The notification object originates in [`maigret/maigret.py`](https://github.com/soxoj/maigret/blob/main/maigret/maigret.py) (lines 608-610), where CLI arguments determine the runtime configuration:

```python
query_notify = QueryNotifyPrint(
    verbose=args.verbose,
    color=not args.no_color,
    silent=args.quiet,
)
query_notify.start(username, id_type)

```

During execution, `check_site_for_username()` in [`maigret/checking.py`](https://github.com/soxoj/maigret/blob/main/maigret/checking.py) forwards results through the chain: `process_site_result()` invokes `query_notify.update(response_result['status'], site.similar_search)` (lines 721-724), passing the `MaigretCheckResult` to the notifier for immediate display.

## Practical Usage Examples

### Basic Console Reporting

```python
from maigret.maigret import maigret
from maigret.notify import QueryNotifyPrint
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("maigret")

# Initialize with color enabled

notifier = QueryNotifyPrint(color=True, verbose=False, silent=False)

# Execute scan

results = maigret(
    username="alice",
    site_dict=site_data,
    logger=logger,
    query_notify=notifier,
    timeout=5,
)

```

### Silent Mode Operation

To disable console output while retaining the progress bar, initialize with `silent=True`:

```python
silent_notifier = QueryNotifyPrint(silent=True)
maigret(
    username="target_user",
    site_dict=site_data,
    query_notify=silent_notifier,
)

```

When silent mode is active, `start()` and `update()` return immediately without printing, allowing the `alive_bar` to serve as the sole progress indicator.

## Summary

- **Three-phase architecture**: `QueryNotifyPrint` implements `start()`, `update()`, and `finish()` methods in [`maigret/notify.py`](https://github.com/soxoj/maigret/blob/main/maigret/notify.py) to bracket the scan lifecycle.
- **Color-coded output**: Status symbols (`+`, `-`, `?`) mapped to `MaigretCheckStatus` values use `colorama` for terminal highlighting (green for claimed, red for unavailable, blue for similar).
- **Line management**: The `update()` method employs `"\x1b[1K\r"` escape sequences to overwrite lines and maintain clean console output.
- **Progress bar separation**: Visual progress tracking relies on the `alive_progress` library in [`maigret/checking.py`](https://github.com/soxoj/maigret/blob/main/maigret/checking.py), running independently alongside the notification system.
- **Silent operation**: The `silent` parameter suppresses all console output from the notifier while allowing the scan to continue.

## Frequently Asked Questions

### How does QueryNotifyPrint handle terminal colors?

The class checks the `color` initialization parameter and uses `colorama.Fore` constants to apply green, red, or blue styling to status symbols. When `color=False`, output remains plain text. Color application logic resides in [`maigret/notify.py`](https://github.com/soxoj/maigret/blob/main/maigret/notify.py) between lines 55 and 77.

### What do the symbols (+, -, ?) mean in the console output?

These symbols represent the `MaigretCheckStatus` of each site check: `+` indicates a claimed account (`CLAIMED`), `-` indicates the username is available or not found (`AVAILABLE`), and `?` marks potential similar usernames identified during the scan. This mapping is implemented in the `update()` method around lines 55-66 of [`maigret/notify.py`](https://github.com/soxoj/maigret/blob/main/maigret/notify.py).

### Can I use QueryNotifyPrint without displaying the progress bar?

Yes. The notification system and progress bar operate independently. To hide the progress bar while keeping console notifications, disable the `alive_bar` via the `no_progressbar` parameter in the checking function. To hide console notifications while keeping the bar, set `silent=True` when constructing `QueryNotifyPrint`.

### Where is the scan result data formatted for display?

Result formatting occurs in `QueryNotifyPrint.update()` within [`maigret/notify.py`](https://github.com/soxoj/maigret/blob/main/maigret/notify.py). This method constructs the output string by combining the status symbol, site name, URL, and optional ASCII tree data (generated via `get_dict_ascii_tree` from [`maigret/utils.py`](https://github.com/soxoj/maigret/blob/main/maigret/utils.py)) into a single terminal line.