Skip to main content

Adaptive waiting and execution engine — replaces time.sleep() with system-aware, deterministic waiting.

Project description

NanoWait: The Adaptive Wait Engine for Python

PyPI version License: MIT Python Versions

NanoWait is a deterministic and adaptive execution wait engine designed to replace Python's standard time.sleep(). Instead of waiting for a fixed duration, NanoWait dynamically adjusts the wait time based on system load (CPU/RAM) and optionally Wi-Fi signal strength, ensuring automation scripts remain reliable even in slow or overloaded environments.

With Execution Profiles, NanoWait offers a semantic layer to manage wait behavior, allowing you to define the operational context clearly and consistently.

In summary: You request a base time (e.g., wait(5)), and NanoWait ensures a safe, context-aware wait that never exceeds the requested time and never falls below a minimum execution floor.

Cross-Platform Stability & Headless Environments

NanoWait has been optimized for cross-platform stability, especially macOS, and safe usage in headless environments (CI, RPA, servers). In headless environments, no graphical UI is instantiated, preventing crashes such as NSWindow should only be instantiated on the main thread on macOS. This ensures total stability in CI/CD pipelines, Docker, and remote execution.


🚀 Key Features

  • Adaptive Waiting: Dynamically scales wait times based on real-time system metrics.
  • Execution Profiles: Semantic presets for CI, RPA, Testing, and more.
  • Async Support: Native wait_async for non-blocking execution in asyncio environments.
  • Parallel Execution: wait_pool and wait_pool_async for multiple waits concurrently.
  • Ultra-Adaptive Auto Wait (wait_auto): Automatically computes the safest and fastest interval without manual configuration.
  • Cross-Platform Stability: Optimized for macOS and headless environments.
  • Explain Mode: Auditable decision reports for full transparency.
  • CLI Support: Powerful command-line interface for quick tasks.
  • Local Telemetry: Opt-in system for analyzing wait behavior without remote data collection.

🆕 Ultra-Adaptive Auto Wait (wait_auto) — Full Reference

wait_auto is the core default for all waits when no profile is specified (profile="auto"). It is designed for automation workflows (e.g., PyAutoGUI scripts) and removes the need to manually tune wait times.

It automatically:

  • Estimates the optimal wait time for your system.
  • Considers CPU, RAM, and optional Wi-Fi signal strength.
  • Chooses the minimal safe interval between actions.
  • Applies the selected Execution Profile automatically.
  • Logs and prints the wait decision (optional).
  • Works out-of-the-box with loops, sequences, and PyAutoGUI automation.

Parameters

Parameter Type Default Description
verbose bool False Prints interval calculation details to console.
log bool False Logs wait decision to file or system log.
telemetry bool False Records metrics like CPU, Wi-Fi, and interval for analysis.
profile str "auto" Execution profile: "default", "ci", "rpa", "fast", "auto" etc.
wifi `str None` None
min_interval float 0.05 Lower floor for waits (seconds).
max_interval `float None` None
callback `Callable None` None

Tip: When called via wait(), wait_auto is used automatically if no profile is provided.


Basic Usage

from nano_wait import wait

# Simple wait_auto usage (default auto profile)
interval = wait(verbose=True)
print(f"Interval calculated: {interval:.3f}s")

Integration with PyAutoGUI

import pyautogui
from nano_wait import wait

# Example automation sequence using auto wait
pyautogui.click(100, 200)
wait()  # Computes next safe interval automatically
pyautogui.write("Hello, world!")
wait(verbose=True)  # Logs the decision
pyautogui.press("enter")

Tip: wait_auto ensures your automation adapts to CPU load and network conditions automatically.


Using wait_auto in Loops

from nano_wait import wait
import pyautogui

# Repeated actions with adaptive interval
for i in range(5):
    pyautogui.moveTo(100 + i*10, 200 + i*10)
    wait()  # Interval adapts per iteration

Async Integration with wait_async

import asyncio
from nano_wait import wait_async

async def perform_tasks():
    print("Task 1 started")
    await wait_async(smart=True, verbose=True)
    print("Task 1 finished, adaptive wait applied")

asyncio.run(perform_tasks())

Note: wait_auto logic is embedded in wait_async when used with profile="auto".


Advanced Features

Telemetry Example

from nano_wait import wait

interval = wait(verbose=True, telemetry=True)
print(f"Adaptive interval recorded: {interval:.3f}s")
  • Records CPU, Wi-Fi, and wait interval for later analysis.
  • Compatible with the TelemetryDashboard for live visualization.

Explain Mode Example

from nano_wait import wait

report = wait(2, explain=True)
print(report)
  • Returns an ExplainReport object.
  • Contains factor, bias, requested and actual interval, CPU/Wi-Fi scores, and timestamp.

Best Practices

  1. Use wait_auto() for all automation scripts to avoid hard-coded delays.
  2. Combine with PyAutoGUI for UI automation.
  3. Enable telemetry and verbose during testing for optimal tuning.
  4. Use explain=True for debugging or auditing wait decisions.

💡 Quick Start

Standard Adaptive Wait

from nano_wait import wait
import time

# Adaptive wait (up to 5 seconds, adjusted by system load)
start = time.time()
wait(5)
print(f"nano_wait.wait(): {time.time() - start:.2f}s")

NanoWait never waits longer than the requested base time and applies a minimum internal delay of 50ms to prevent excessive CPU usage.


🌐 Parallel Execution (wait_pool)

Run multiple adaptive waits in parallel, ideal for batch automation or concurrent UI interactions.

import psutil
from nano_wait import wait_pool

def heavy_load():
    return psutil.cpu_percent() > 80

results = wait_pool([1, 2, 3], cancel_if=heavy_load)

⚡️ Asynchronous Support (wait_async)

NanoWait supports asynchronous environments like FastAPI, asyncio bots, or web scrapers.

import asyncio
from nano_wait import wait_async

async def main():
    result = await wait_async(2, smart=True)
    print(f"Wait finished in: {result:.3f}s")

asyncio.run(main())

⚙️ Core API Reference

Function Sync Async Parallel Cancelable
wait
wait_async
wait_pool
wait_pool_async
wait_auto

Note: wait_auto is now integrated into wait() as the default when no profile is provided.


🛠️ Installation

pip install nano_wait

Required Dependencies

pip install psutil pywifi

Optional — Vision Mode

Visual waiting is available in a dedicated package:

pip install nano-wait-vision

Note: Without Vision Mode, NanoWait will raise a runtime error if visual functions are requested.


📄 License

Distributed under the MIT License. See LICENSE for more information.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nano_wait-5.0.2.tar.gz (19.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nano_wait-5.0.2-py3-none-any.whl (19.1 kB view details)

Uploaded Python 3

File details

Details for the file nano_wait-5.0.2.tar.gz.

File metadata

  • Download URL: nano_wait-5.0.2.tar.gz
  • Upload date:
  • Size: 19.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for nano_wait-5.0.2.tar.gz
Algorithm Hash digest
SHA256 4b2c1db6425ce8b5e471e4173a445d555ad746e9291f9ced5aedb5165c60f03d
MD5 94242053c3ff835224ea2d2600913402
BLAKE2b-256 e14960aed98bfd57c2041428efe98316d83b481feb3a1e2457aeb01cec93af2c

See more details on using hashes here.

File details

Details for the file nano_wait-5.0.2-py3-none-any.whl.

File metadata

  • Download URL: nano_wait-5.0.2-py3-none-any.whl
  • Upload date:
  • Size: 19.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for nano_wait-5.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 a02e942ad38be277f1a1fe079ac4786465fec9bec890cd27d606ef00389e02aa
MD5 8562478675191f7a05b4d66667556e5b
BLAKE2b-256 7a7863429ae5e46d3c885ee18fbcde0db6c3e51e17632fc39cf7c5e8cdfe97b6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page