# NanoWait: The Adaptive Wait Engine for Python

[![PyPI version](https://img.shields.io/pypi/v/nano_wait.svg)](https://pypi.org/project/nano-wait/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Python Versions](https://img.shields.io/pypi/pyversions/nano_wait.svg)](https://pypi.org/project/nano-wait/)

**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 the introduction of **Execution Profiles**, NanoWait now 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 and context-aware wait* that never exceeds the requested time and never falls below a minimum execution floor.

### Cross-Platform Stability & Headless Environments

NanoWait has undergone significant structural modifications focused on **cross-platform stability**, especially for macOS, and **safe usage in headless environments** (CI, RPA, servers). It explicitly differentiates between graphical and headless modes. In headless environments, no graphical UI is instantiated, preventing crashes like `NSWindow should only be instantiated on the main thread` on macOS with Tkinter issues. This ensures total stability in macOS, CI/CD pipelines, 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 handling multiple waits concurrently.
- **Cross-Platform Stability:** Optimized for macOS and headless environments (CI/CD, Docker).
- **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`)**: Automatically computes the safest and fastest interval for any action without manual configuration.

---

## 🛠️ Installation

Install the core package via pip:

```bash
pip install nano_wait
````

### Required Dependencies

For adaptive features (CPU/RAM/Wi-Fi awareness) to function, install the following:

```bash
pip install psutil pywifi
```

### Optional Module — Vision Mode

Visual waiting (icon/state detection) is available in a dedicated package to keep the core engine lightweight:

```bash
pip install nano-wait-vision
```

*Note: If Vision Mode is not installed, NanoWait will raise a clear runtime error when visual functionalities are requested.*

---

## 💡 Quick Start

### Standard vs. Adaptive Wait

```python
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 **50 ms** to prevent excessive CPU usage.*

---

## 🆕 Ultra-Adaptive Auto Wait (`wait_auto`)

The new `wait_auto` function is a **zero-configuration adaptive wait** designed for **PyAutoGUI or any automation workflow**.

It automatically:

* Estimates the optimal wait time for the system and network.
* Considers CPU, RAM, and 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 and sequences in automation scripts.

### Basic Usage

```python
from nano_wait.nano_wait_auto import wait_auto

# Simple auto wait (calculates safe interval)
interval = wait_auto(verbose=True)
print(f"Interval calculated: {interval:.3f}s")
```

### Advanced Usage with Smart Options

```python
from nano_wait.nano_wait_auto import wait_auto

# Auto wait with Execution Profile, optional Wi-Fi awareness, and logging
interval = wait_auto(
    wifi="MyNetwork_5G",
    profile="ci",
    verbose=True,
    log=True,
    telemetry=True
)
print(f"Interval applied: {interval:.3f}s")
```

### Integration with PyAutoGUI Example

```python
import pyautogui
from nano_wait.nano_wait_auto import wait_auto

# Example automation sequence
pyautogui.click(100, 200)
wait_auto()  # Automatically computes next safe interval
pyautogui.write("Hello, world!")
wait_auto(verbose=True)  # Logs decision
```

**Key benefit:** You don’t need to manually set times, speeds, or factors—`wait_auto` intelligently adapts to the system and environment.

---

## ⚡️ Asynchronous Support (`wait_async`)

NanoWait is fully compatible with asynchronous environments like **FastAPI**, **asyncio-based bots**, and **web scrapers**. The `wait_async` function is non-blocking, ensuring the event loop remains free.

### Usage in Async Code (Concise Example)

```python
import asyncio
from nano_wait import wait_async

async def main():
    # Non-blocking wait for up to 2 seconds
    result = await wait_async(2, smart=True)
    print(f"Wait finished in: {result:.3f}s")

if __name__ == "__main__":
    asyncio.run(main())
```

---

## 🌐 Parallel Execution (`wait_pool`)

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

### Conditional Cancellation (`cancel_if`)

```python
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)
```

---

## ⚙️ Core API Reference

| Function          | Sync | Async | Parallel | Cancelable |
| :---------------- | :--: | :---: | :------: | :--------- |
| `wait`            |   ✅  |   ❌   |     ❌    | ❌          |
| `wait_async`      |   ❌  |   ✅   |     ❌    | ❌          |
| `wait_pool`       |   ✅  |   ❌   |     ✅    | ✅          |
| `wait_pool_async` |   ❌  |   ✅   |     ✅    | ✅          |
| `wait_auto`       |   ✅  |   ❌   |     ❌    | ❌          |

---

## 📄 License

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