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
pip install soasap
For local development:
pip install -e ".[dev]"
Quick Start
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)
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)
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
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:
create_soasap_client(
api_key="...",
cache_directory="/custom/path",
)
Error handling
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
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
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
Metadata
Release files for soasap 1.0.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| soasap-1.0.3.tar.gz | 12.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| soasap-1.0.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 27.9 kB
Release files / soasap-1.0.3.tar.gz
| Download URL | soasap-1.0.3.tar.gz |
|---|---|
| Size | 12.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2b7ef70b7e9cee1be898d99e908ae36960891eba5953c868ba41635b84865132
|
|
BLAKE2b-256 checksum How to use checksums |
234052440d8fa395700f6d66985c6edbe2acdde58b1ddcd6fecbd89bf858d0e2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.5
|
Release files / soasap-1.0.3-py3-none-any.whl
| Download URL | soasap-1.0.3-py3-none-any.whl |
|---|---|
| Size | 15.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6087790197c03f01a5d52fa4df4f128fc0e1e8ba9616810f446ded3c7be0af7c
|
|
BLAKE2b-256 checksum How to use checksums |
e3265989406ddc49cece4b52735bcbee51ee3ac6478d6a498a8d00229cd87699
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.5
|