Metadata-Version: 2.4
Name: soasap
Version: 1.0.3
Summary: Ultra-fast feature flags SDK for Python with O(1) sync reads, real-time SSE updates, and resilient persistent disk cache.
Project-URL: Homepage, https://soasap.com
Project-URL: Repository, https://github.com/soasap-com/soasap-python-sdk
Author: SOASAP
License-Expression: MIT
License-File: LICENSE
Keywords: feature-flags,feature-management,remote-config,soasap,sse
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.10
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == 'dev'
Description-Content-Type: text/markdown

# SOASAP Python SDK

Lightweight, production-ready feature flags SDK for Python (3.10+).

- **O(1) local evaluation** — thread-safe reads from an in-memory snapshot
- **Non-blocking startup** with persistent disk cache (no dependency on a live API at init)
- **Real-time updates** via SSE (Server-Sent Events)
- **Persistent disk cache** for instant cold starts
- **Graceful offline behavior** and resilient reconnect
- **Zero runtime dependencies**

## Why SOASAP?

Most feature flag platforms are built for enterprises. SOASAP focuses on:

- low-latency local evaluation
- minimal dependencies
- zero startup impact
- resilient offline behavior
- simple integration with Python applications

## Installation

```bash
pip install soasap
```

For local development:

```bash
pip install -e ".[dev]"
```

## Quick Start

```python
import os
from soasap import create_soasap_client

flags = create_soasap_client(
    api_key=os.environ["SOASAP_API_KEY"],
    preload=True,
)

# Sync reads — never throw, never hit the network
if flags.get_bool("new-checkout"):
    print("New checkout enabled")
```

## Startup & Synchronization

SOASAP uses a non-blocking background architecture so feature flagging **never blocks your application startup**.

### Immediate synchronization (recommended)

```python
flags = create_soasap_client(
    api_key=os.environ["SOASAP_API_KEY"],
    preload=True,
)
```

- **Cold start**: loads the last snapshot from disk; background SSE connects without blocking init.
- **Non-blocking**: network I/O runs in a daemon thread; your server keeps booting even if the API is down.

### Lazy synchronization (optional)

```python
flags = create_soasap_client(api_key=os.environ["SOASAP_API_KEY"])
```

Background synchronization starts on the **first** flag read. Until then you get disk cache or defaults.

## Typed flag access

```python
flags.get_bool("feature-x")
flags.get_number("rate-limit", 100)
flags.get_string("ui-theme", "light")
flags.get_json("checkout-config", {"enableUpsells": False, "maxItems": 10})
```

JSON keys from the dashboard are returned as stored (typically `camelCase`). Map to your types accordingly.

## Production safety

- **Immutable snapshots**: readers never see partial updates.
- **Memory cap**: SSE parser enforces a 5 MB payload limit.
- **Payload validation**: root must be a JSON object `{}`.
- **Disk debounce**: writes coalesced to at most once every ~2.5 seconds.

## Offline & failure resiliency

| Scenario                    | Behavior                         |
| --------------------------- | -------------------------------- |
| API unavailable             | Uses stale cached flags          |
| SSE disconnected            | Keeps last known snapshot        |
| First startup without cache | Returns default values           |
| Invalid payload             | Payload ignored                  |
| Disk cache failure          | In-memory mode continues         |
| Persistent network issues   | Automatic reconnect with backoff |

**Getters never throw.**

## Disk cache locations

| Platform      | Location                                      |
| ------------- | --------------------------------------------- |
| Windows       | `%LOCALAPPDATA%\soasap\cache`                 |
| Linux / macOS | `~/.local/share/soasap/cache`                 |

Override:

```python
create_soasap_client(
    api_key="...",
    cache_directory="/custom/path",
)
```

## Error handling

```python
from soasap import SoasapErrorSource, create_soasap_client

create_soasap_client(
    api_key="...",
    on_error=lambda ctx: print(
        f"[{ctx.source.value}] transient={ctx.is_transient} {ctx.exception}"
    ),
)
```

Sources: `SoasapErrorSource.NETWORK`, `.DISK`, `.PARSER`.

## Graceful shutdown

```python
flags.close()
```

Cancels SSE, flushes disk (up to 5s), and releases resources.

## Architecture

```
[Read path]  get_bool() → current_snapshot ref → O(1) lookup
                              ↑
                              | (snapshot reference swap)
[Background] SSE → SseEventParser (5MB cap) → DiskWriteCoalescer → disk
```

Use **one client instance per process**. For multi-process servers (e.g. Gunicorn), create one client per process.

## Flask example

```python
import os
from flask import Flask, g
from soasap import create_soasap_client

flags = create_soasap_client(
    api_key=os.environ["SOASAP_API_KEY"],
    preload=True,
)

app = Flask(__name__)


@app.before_request
def attach_flags():
    g.soasap = flags


@app.get("/")
def index():
    if g.soasap.get_bool("maintenance-mode"):
        return "Maintenance", 503
    return "OK"


import atexit

atexit.register(flags.close)
```

## Supported runtimes

- Python 3.10, 3.11, 3.12, 3.13+

## Design principles

- Never block application startup
- Never crash the host process
- Prefer stale data over failure
- Keep the hot path fast
- Make network failures invisible to request handlers
- Keep the API minimal and predictable

## License

MIT

## Website

[https://soasap.com](https://soasap.com)
