Metadata-Version: 2.4
Name: afrocache
Version: 0.1.1
Summary: A lightweight, simple Python caching library that manages data storage, on disk or in memory, and automated background updates.
Author-email: DigitalKelvin <developer@digitalkelvin.com>
Project-URL: Homepage, https://github.com/digitalkelvin/afrocache
Project-URL: Bug Tracker, https://github.com/digitalkelvin/afrocache/issues
Keywords: caching,python,asyncio,background-tasks,disk-cache,memory-cache,qmate,performance
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: qmate>=0.0.2
Dynamic: license-file

# AfroCache
A lightweight, simple Python caching library that manages data storage, on disk or in memory, and automated background updates.

## Features

- **Storage Engines**: Supports both volatile memory caching and persistent disk caching using JSON files.
- **Background Refresh**: Uses `QMate` to execute background re-validation tasks, ensuring data is updated without blocking the main execution path.
- **Execution Handling**: Compatible with both def (synchronous) and async def (asynchronous) functions.
- **Cache Management**: Provides utilities to invalidate specific keys, reset the entire cache, and track background task queues.
- **Diagnostics**: Tracks cache hits, modification timestamps, and expiration times for monitoring.


## Installation

#### Using `uv`:

```bash
uv add afrocache
```

#### Or via `pip`:
```bash
pip install afrocache
```


## Quick Start
### Basic Memory Caching
```py
import time
import asyncio
from afrocache import init_cache, afrocache

# Initialize cache in memory mode (default)
init_cache(storage_type="memory")

# Decorate a standard synchronous function
@afrocache(ttl=60)  # Cache results for 60 seconds
def get_slow_data(user_id: int):
    time.sleep(2)  # Simulate a heavy database lookup
    return {"user_id": user_id, "status": "active"}

# Decorate an asynchronous function
@afrocache(ttl=300)
async def fetch_api_payload(endpoint: str):
    await asyncio.sleep(1)  # Simulate a slow network call
    return {"endpoint": endpoint, "data": "payload"}
```

## 2. Enabling Disk Persistence
### Survive script restarts with disk storage:

```py
from afrocache import init_cache, afrocache

init_cache(
    storage_type="disk", 
    cache_dir="./.cache_data", 
    filename="production_store.json"
)

@afrocache(ttl=3600)
def heavy_computation():
    return sum(i * i for i in range(10_000_000))
```

## 3. Scheduled Background Refresh (QMate Integration)
`afrocache` integrates with `QMate` to schedule background updates. You can pass any valid `QMate` scheduling arguments (such as `every`, `at`, or `on`) directly into the `refresh` dictionary.

```python
from afrocache import init_cache, afrocache

init_cache(storage_type="memory")

# The cache entry will automatically re-fetch in the background 
# following the provided QMate scheduling parameters.
@afrocache(ttl=60, refresh={"at": ["06:00:00"], "on": ["Tuesday", "Thursday"]})
def get_dashboard_metrics():
    return {"active_users": 1250, "revenue_usd": 45000}
```

## API Reference

### Configuration
- `init_cache(storage_type="file", cache_dir="./.demo_data", filename="demo_store.json")`: Initializes the global cache manager configuration. Must be called once at application startup.
    - `storage_type`: `"memory"` or `"disk"`. Defaults to `"memory"`.
    - `cache_dir`: The directory path where disk files are kept. Defaults to `"data"`. [*Required if `storage_type="disk"`*]
    - `filename`: The JSON database file name for disk tracking. Defaults to `"afrocache_store.json"`.


### Decorator
- `@afrocache(ttl=86400, refresh={"at": ["20:00"]}, bypass=False)`:
    - `ttl`: Time-to-live for cached results in seconds. Defaults to 86400 (1 day).
    - `refresh`: Pass `{"at": ["06:00:00"]` to allow asynchronous stale-while-revalidate execution.
    - `bypass`: If set to True, forces the decorator to always hit the underlying function and ignore the cache entirely.

### Management
- `key_exists(key: str) -> bool`: Checks if a specific key or function execution footprint currently resides alive inside the cache.
- `invalidate_cache(key: str)`: Manually removes a specific key and cancels its associated background refresh tasks.
- `reset_cache()`: Wipes all stored data, clears background queues, and deletes the cache file if in `disk` mode.
- `get_all_cache_keys() -> list`: Returns a list of all keys currently in the cache.
- `get_cache_metadata(key: str) -> dict`: Retrieves basic metadata (key name and expiration timestamp) for a specific entry.
- `get_cache_info` -> list: Returns a detailed list of active keys, including:
    - `hits`: Number of times the cache was successfully accessed.
    - `modified`: The last time the entry was updated (formatted string).
    - `expires`: The calculated expiration time (formatted string).


## Logging & Debugging
`AfroCache` uses the standard Python logging module. Enable it to monitor cache activity.
```py
import logging

logging.basicConfig(level=logging.DEBUG)
```


## Development & Testing
#### If you are contributing to `afrocache` or running tests locally, clone the repository and leverage uv for environment management:

```bash
# Clone and enter the repo
git clone git@github.com:digitalkelvin/qmate.git
cd afrocache

# Install dependencies and sync environment
uv sync

# Run the automated test suite
uv run pytest -v

# Launch the interactive testing demo script
uv run demo/app.py
```

## License
This project is open-source software released under the MPL-2.0 License.
