Skip to content

Latest commit

 

History

History
159 lines (113 loc) · 5.96 KB

File metadata and controls

159 lines (113 loc) · 5.96 KB

tqdm

A fast, minimal progress-bar library that wraps any iterable to show completion, rate, and ETA — ideal for long-running security loops like scans and brute-forcing.

Overview

tqdm (from Arabic taqaddum, "progress") adds a smart progress bar to loops by wrapping an iterable: for x in tqdm(items). It auto-calculates throughput and estimated time remaining with negligible overhead, and works in terminals, notebooks, and over parallel workers. In security tooling it gives operators feedback during host sweeps, wordlist attacks, and large file transfers that would otherwise look frozen.

Installation

pip install tqdm

Basic Usage

import time

from tqdm import tqdm

for port in tqdm(range(1, 1025), desc="scanning", unit="port"):
    time.sleep(0.001)          # stand-in for a real probe
scanning: 100%|██████████████████| 1024/1024 [00:01<00:00, 812.44port/s]

Wrapping any iterable in tqdm() gives a progress bar with rate and ETA. It writes to stderr by default, so piped stdout stays clean.

Important APIs

API Purpose
tqdm(iterable, desc=, unit=, total=) Wrap an iterable
tqdm(total=n) + bar.update(k) Manual progress for non-iterable work
bar.set_description(text) Update the label mid-run
bar.set_postfix(found=3) Show live counters beside the bar
bar.write(msg) Print a line without corrupting the bar
disable=True Turn the bar off (useful when not a TTY)
file=sys.stdout Redirect the bar; defaults to stderr
leave=False Remove the bar on completion
tqdm.contrib.concurrent.thread_map Progress over a thread pool
tqdm.contrib.concurrent.process_map Progress over a process pool

Use bar.write() rather than print() inside a loop, or output will interleave with the bar.

Example

Wrap a scan loop:

import time
from tqdm import tqdm

hosts = [f"192.168.56.{i}" for i in range(1, 21)]
for host in tqdm(hosts, desc="Sweeping", unit="host"):
    time.sleep(0.05)   # stand-in for a real probe

Output

Sweeping: 100%|██████████████████████| 20/20 [00:01<00:00, 19.8host/s]

Progress over a password wordlist with a running count:

from tqdm import tqdm

wordlist = [f"pass{i}" for i in range(1000)]
target = "pass742"
found = None

for pw in tqdm(wordlist, desc="Cracking", unit="pw"):
    if pw == target:            # stand-in for a real auth check
        found = pw
        break

print("recovered:", found)

Output

Cracking:  74%|████████████▌    | 743/1000 [00:00<00:00, 900000pw/s]
recovered: pass742

Manual updates for a chunked download:

from tqdm import tqdm

total_bytes = 5 * 1024 * 1024
chunk = 512 * 1024

with tqdm(total=total_bytes, unit="B", unit_scale=True, desc="Downloading") as bar:
    downloaded = 0
    while downloaded < total_bytes:
        downloaded += chunk           # stand-in for reading a socket
        bar.update(chunk)

Output

Downloading: 100%|█████████████████| 5.00M/5.00M [00:00<00:00, 250MB/s]

Security Use Cases

  • Scan progress — show ETA during host/port sweeps so operators know a long scan is alive, not hung.
  • Brute-force feedback — track progress and rate through password or fuzzing wordlists.
  • Bulk transfers — visualize progress when exfiltrating evidence or downloading large wordlists/tools.
  • Batch processing — monitor loops over thousands of URLs, hashes, or log lines during analysis.
  • Rate awareness — the throughput readout helps spot rate-limiting or performance bottlenecks.

Common Mistakes

  • Using print() inside a tqdm loop — it corrupts the bar. Use bar.write().
  • Not passing total= when the iterable has no length (a generator), so no percentage or ETA is shown.
  • Wrapping an already-materialised list built at high cost just to get a length.
  • Assuming the bar goes to stdout — it goes to stderr, which is correct but surprising.
  • Leaving bars enabled in non-interactive runs — cron logs fill with progress redraws; pass disable=not sys.stderr.isatty().
  • Nesting bars without position=, producing overlapping output.
  • Adding tqdm to a library rather than the application layer.

Security Considerations

[!warning] Progress output belongs on stderr Keep findings on stdout so the tool composes in a pipeline.

  • A progress bar reveals scan pacing. Screenshots of a bar in a report can disclose target counts and timing you did not intend to share.
  • set_postfix can leak data. Showing the current target hostname beside the bar puts it in any captured terminal output or CI log; keep identifiers out of the label in shared environments.
  • Disable bars in automated runs. Cron and CI logs filled with redraw sequences are hard to read and can mask real errors.
  • A progress bar is not rate limiting. It shows how fast you are going; it does not slow you down. Add an explicit delay if the target needs protection.
  • tqdm has no security function — it is presentation only, and adds a dependency to a tool that may need to run on a locked-down host.

Best Practices

  • Pass total= when wrapping generators or manual loops so the bar can show a percentage and ETA.
  • Use unit=/unit_scale=True for human-readable byte counts.
  • Prefer tqdm.write() over print() inside a loop to avoid breaking the bar.
  • Wrap the outermost loop only; nested bars (leave=False) get noisy fast.
  • Combine with [[colorama]] or a logger for colored status alongside the bar.

References

Related Topics

  • [[Rich]] — richer progress bars plus tables and layout
  • [[colorama]] — color the status text around your progress bars
  • [[Readme|Python for Security Professionals]] — course home