{"id":526,"date":"2026-03-08T12:18:22","date_gmt":"2026-03-08T04:18:22","guid":{"rendered":"https:\/\/connectword.dpdns.org\/?p=526"},"modified":"2026-03-08T12:18:22","modified_gmt":"2026-03-08T04:18:22","slug":"how-to-build-progress-monitoring-using-advanced-tqdm-for-async-parallel-pandas-logging-and-high-performance-workflows","status":"publish","type":"post","link":"https:\/\/connectword.dpdns.org\/?p=526","title":{"rendered":"How to Build Progress Monitoring Using Advanced tqdm for Async, Parallel, Pandas, Logging, and High-Performance Workflows"},"content":{"rendered":"<p>In this tutorial, we explore <a href=\"https:\/\/github.com\/tqdm\/tqdm\"><strong>tqdm<\/strong><\/a> in depth and demonstrate how we build powerful, real-time progress tracking into modern Python workflows. We begin with nested progress bars and manual progress control, then move into practical scenarios such as streaming downloads, pandas data processing, parallel execution, structured logging, and asynchronous tasks. Throughout this tutorial, we focus on writing clean, production-ready code that runs in Colab while showcasing the advanced capabilities of tqdm beyond simple loops.<\/p>\n<div class=\"dm-code-snippet dark dm-normal-version default no-background-mobile\">\n<div class=\"control-language\">\n<div class=\"dm-buttons\">\n<div class=\"dm-buttons-left\">\n<div class=\"dm-button-snippet red-button\"><\/div>\n<div class=\"dm-button-snippet orange-button\"><\/div>\n<div class=\"dm-button-snippet green-button\"><\/div>\n<\/div>\n<div class=\"dm-buttons-right\"><a><span class=\"dm-copy-text\">Copy Code<\/span><span class=\"dm-copy-confirmed\">Copied<\/span><span class=\"dm-error-message\">Use a different Browser<\/span><\/a><\/div>\n<\/div>\n<pre class=\" no-line-numbers\"><code class=\" no-wrap language-php\">!pip -q install -U tqdm\n\n\nimport time, math, random, asyncio, hashlib, logging\nimport pandas as pd\nimport requests\n\n\nfrom tqdm.auto import tqdm, trange\nfrom tqdm.contrib.concurrent import thread_map, process_map\nfrom tqdm.contrib.logging import logging_redirect_tqdm\nimport tqdm as tqdm_pkg\n\n\nprint(\"tqdm version:\", tqdm_pkg.__version__)\nprint(\"pandas version:\", pd.__version__)\nprint(\"requests version:\", requests.__version__)<\/code><\/pre>\n<\/div>\n<\/div>\n<p>We install and configure tqdm in a Colab-safe manner while preserving the existing environment dependencies. We import all required libraries, including concurrency and logging helpers from tqdm.contrib. We also print version information to verify that our runtime setup is stable before proceeding.<\/p>\n<div class=\"dm-code-snippet dark dm-normal-version default no-background-mobile\">\n<div class=\"control-language\">\n<div class=\"dm-buttons\">\n<div class=\"dm-buttons-left\">\n<div class=\"dm-button-snippet red-button\"><\/div>\n<div class=\"dm-button-snippet orange-button\"><\/div>\n<div class=\"dm-button-snippet green-button\"><\/div>\n<\/div>\n<div class=\"dm-buttons-right\"><a><span class=\"dm-copy-text\">Copy Code<\/span><span class=\"dm-copy-confirmed\">Copied<\/span><span class=\"dm-error-message\">Use a different Browser<\/span><\/a><\/div>\n<\/div>\n<pre class=\" no-line-numbers\"><code class=\" no-wrap language-php\">print(\"1) Nested progress bars (position\/leave) + tqdm.write()\")\nouter = trange(5, desc=\"Outer loop\", leave=True)\nfor i in outer:\n   inner = trange(20, desc=f\"Inner loop {i}\", leave=False, position=1)\n   for j in inner:\n       time.sleep(0.01)\n       if j in (0, 10, 19):\n           tqdm.write(f\"  note: i={i}, j={j}\")\nprint()\n\n\nprint(\"2) Manual progress (unknown -&gt; known total, update(), set_postfix())\")\nitems = list(range(1, 101))\npbar = tqdm(total=None, desc=\"Processing (discovering total)\", unit=\"item\")\nseen = 0\nfor x in items:\n   time.sleep(0.005)\n   seen += 1\n   if seen == 25:\n       pbar.total = len(items)\n       pbar.refresh()\n   pbar.update(1)\n   if x % 20 == 0:\n       pbar.set_postfix(last=x, sqrt=round(math.sqrt(x), 3))\npbar.close()\nprint()<\/code><\/pre>\n<\/div>\n<\/div>\n<p>We demonstrate nested progress bars and show how we manage multiple levels of iteration cleanly using position and leave. We also explore manual progress control by dynamically setting totals and updating progress explicitly. By using set_postfix, we enrich the progress bar with live metadata as it runs.<\/p>\n<div class=\"dm-code-snippet dark dm-normal-version default no-background-mobile\">\n<div class=\"control-language\">\n<div class=\"dm-buttons\">\n<div class=\"dm-buttons-left\">\n<div class=\"dm-button-snippet red-button\"><\/div>\n<div class=\"dm-button-snippet orange-button\"><\/div>\n<div class=\"dm-button-snippet green-button\"><\/div>\n<\/div>\n<div class=\"dm-buttons-right\"><a><span class=\"dm-copy-text\">Copy Code<\/span><span class=\"dm-copy-confirmed\">Copied<\/span><span class=\"dm-error-message\">Use a different Browser<\/span><\/a><\/div>\n<\/div>\n<pre class=\" no-line-numbers\"><code class=\" no-wrap language-php\">print(\"3) Download with streaming progress\")\nurl = \"https:\/\/raw.githubusercontent.com\/tqdm\/tqdm\/master\/README.rst\"\nout_path = \"\/content\/tqdm_README.rst\"\n\n\nwith requests.get(url, stream=True, timeout=30) as r:\n   r.raise_for_status()\n   total = int(r.headers.get(\"Content-Length\", 0)) or None\n   chunk = 1024 * 32\n   with open(out_path, \"wb\") as f, tqdm(\n       total=total,\n       unit=\"B\",\n       unit_scale=True,\n       unit_divisor=1024,\n       desc=\"Downloading README\",\n       miniters=1,\n   ) as bar:\n       for part in r.iter_content(chunk_size=chunk):\n           if not part:\n               continue\n           f.write(part)\n           bar.update(len(part))\n\n\nprint(\"Saved:\", out_path)\nprint()<\/code><\/pre>\n<\/div>\n<\/div>\n<p>We implement a real-world streaming download scenario using requests with chunk-based updates. We track byte-level progress with automatic unit scaling and accurate handling of content length. This shows how we efficiently and transparently monitor external I\/O operations.<\/p>\n<div class=\"dm-code-snippet dark dm-normal-version default no-background-mobile\">\n<div class=\"control-language\">\n<div class=\"dm-buttons\">\n<div class=\"dm-buttons-left\">\n<div class=\"dm-button-snippet red-button\"><\/div>\n<div class=\"dm-button-snippet orange-button\"><\/div>\n<div class=\"dm-button-snippet green-button\"><\/div>\n<\/div>\n<div class=\"dm-buttons-right\"><a><span class=\"dm-copy-text\">Copy Code<\/span><span class=\"dm-copy-confirmed\">Copied<\/span><span class=\"dm-error-message\">Use a different Browser<\/span><\/a><\/div>\n<\/div>\n<pre class=\" no-line-numbers\"><code class=\" no-wrap language-php\">print(\"4) pandas progress_apply (Series) + DataFrame row-wise progress (safe)\")\ntqdm.pandas()\n\n\ndf = pd.DataFrame({\n   \"user_id\": range(1, 2001),\n   \"value\": [random.random() for _ in range(2000)],\n})\n\n\ndef heavy_fn(v: float) -&gt; str:\n   time.sleep(0.0005)\n   s = f\"{v:.10f}\".encode(\"utf-8\")\n   return hashlib.sha256(s).hexdigest()[:10]\n\n\ndf[\"hash\"] = df[\"value\"].progress_apply(heavy_fn)\n\n\ndf2 = df[[\"value\"]].copy()\ndf2[\"hash2\"] = [\n   heavy_fn(float(v))\n   for v in tqdm(df2[\"value\"].to_list(), desc=\"Row-wise hash2\", total=len(df2))\n]\ndf[\"hash2\"] = df2[\"hash2\"]\n\n\nprint(df.head(3))\nprint()<\/code><\/pre>\n<\/div>\n<\/div>\n<p>We integrate tqdm with pandas to monitor vectorized operations using progress_apply. We implement a hashing workload to simulate realistic, computationally heavy transformations. We also demonstrate a safe row-wise progress pattern to ensure compatibility with Colab\u2019s pinned pandas version.<\/p>\n<div class=\"dm-code-snippet dark dm-normal-version default no-background-mobile\">\n<div class=\"control-language\">\n<div class=\"dm-buttons\">\n<div class=\"dm-buttons-left\">\n<div class=\"dm-button-snippet red-button\"><\/div>\n<div class=\"dm-button-snippet orange-button\"><\/div>\n<div class=\"dm-button-snippet green-button\"><\/div>\n<\/div>\n<div class=\"dm-buttons-right\"><a><span class=\"dm-copy-text\">Copy Code<\/span><span class=\"dm-copy-confirmed\">Copied<\/span><span class=\"dm-error-message\">Use a different Browser<\/span><\/a><\/div>\n<\/div>\n<pre class=\" no-line-numbers\"><code class=\" no-wrap language-php\">print(\"5) Concurrency progress: thread_map \/ process_map\")\ndef cpuish(n: int) -&gt; int:\n   x = 0\n   for i in range(50_000):\n       x = (x + (n * i)) % 1_000_003\n   return x\n\n\nnums = list(range(80))\nthread_results = thread_map(cpuish, nums, max_workers=8, desc=\"thread_map\")\nprint(\"thread_map done:\", len(thread_results))\n\n\nproc_results = process_map(cpuish, nums[:20], max_workers=2, chunksize=2, desc=\"process_map\")\nprint(\"process_map done:\", len(proc_results))\nprint()\n\n\nprint(\"6) logging_redirect_tqdm (logs won\u2019t break bars)\")\nlogger = logging.getLogger(\"demo\")\nlogger.setLevel(logging.INFO)\nhandler = logging.StreamHandler()\nhandler.setFormatter(logging.Formatter(\"%(levelname)s: %(message)s\"))\nlogger.handlers = [handler]\n\n\nwith logging_redirect_tqdm():\n   for k in tqdm(range(60), desc=\"Work with logs\"):\n       time.sleep(0.01)\n       if k in (5, 25, 45):\n           logger.info(f\"checkpoint k={k}\")\nprint()\n\n\nprint(\"7) asyncio progress (as_completed) \u2014 Colab\/Jupyter-safe\")\nasync def io_task(i: int):\n   await asyncio.sleep(random.uniform(0.02, 0.12))\n   return i, random.random()\n\n\nasync def run_async():\n   tasks = [asyncio.create_task(io_task(i)) for i in range(80)]\n   results = []\n   for fut in tqdm(asyncio.as_completed(tasks), total=len(tasks), desc=\"async tasks\"):\n       results.append(await fut)\n   return results\n\n\nresults = await run_async()\nprint(\"async done:\", len(results), \"results\")<\/code><\/pre>\n<\/div>\n<\/div>\n<p>We explore advanced execution patterns including multithreading, multiprocessing, structured logging, and asynchronous task tracking. We use thread_map and process_map to parallelize CPU-bound workloads with visible progress. Also, we handle asyncio safely in a notebook environment using top-level await, ensuring smooth progress tracking without event loop conflicts.<\/p>\n<p>In conclusion, we integrated tqdm across synchronous, parallel, logging-aware, and asynchronous environments. We saw how progress bars enhance observability, improve debugging clarity, and make long-running workloads more transparent and user-friendly. With these advanced patterns, we now have a solid foundation to incorporate robust progress monitoring into data pipelines, machine learning workflows, distributed systems, and real-world production applications.<\/p>\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n<p>Check out the\u00a0<strong><a href=\"https:\/\/github.com\/Marktechpost\/AI-Tutorial-Codes-Included\/blob\/main\/Data%20Science\/tqdm_production_progress_monitoring_marktechpost.py\" target=\"_blank\" rel=\"noreferrer noopener\">Full Codes here<\/a>.\u00a0<\/strong>Also,\u00a0feel free to follow us on\u00a0<strong><a href=\"https:\/\/x.com\/intent\/follow?screen_name=marktechpost\" target=\"_blank\" rel=\"noreferrer noopener\"><mark>Twitter<\/mark><\/a><\/strong>\u00a0and don\u2019t forget to join our\u00a0<strong><a href=\"https:\/\/www.reddit.com\/r\/machinelearningnews\/\" target=\"_blank\" rel=\"noreferrer noopener\">120k+ ML SubReddit<\/a><\/strong>\u00a0and Subscribe to\u00a0<strong><a href=\"https:\/\/www.aidevsignals.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">our Newsletter<\/a><\/strong>. Wait! are you on telegram?\u00a0<strong><a href=\"https:\/\/t.me\/machinelearningresearchnews\" target=\"_blank\" rel=\"noreferrer noopener\">now you can join us on telegram as well.<\/a><\/strong><\/p>\n<p>The post <a href=\"https:\/\/www.marktechpost.com\/2026\/03\/07\/how-to-build-progress-monitoring-using-advanced-tqdm-for-async-parallel-pandas-logging-and-high-performance-workflows\/\">How to Build Progress Monitoring Using Advanced tqdm for Async, Parallel, Pandas, Logging, and High-Performance Workflows<\/a> appeared first on <a href=\"https:\/\/www.marktechpost.com\/\">MarkTechPost<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>In this tutorial, we explore t&hellip;<\/p>\n","protected":false},"author":1,"featured_media":29,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-526","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/connectword.dpdns.org\/index.php?rest_route=\/wp\/v2\/posts\/526","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/connectword.dpdns.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/connectword.dpdns.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/connectword.dpdns.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/connectword.dpdns.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=526"}],"version-history":[{"count":0,"href":"https:\/\/connectword.dpdns.org\/index.php?rest_route=\/wp\/v2\/posts\/526\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/connectword.dpdns.org\/index.php?rest_route=\/wp\/v2\/media\/29"}],"wp:attachment":[{"href":"https:\/\/connectword.dpdns.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=526"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/connectword.dpdns.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=526"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/connectword.dpdns.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=526"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}