Metadata-Version: 2.4
Name: releasepace
Version: 1.0.1
Summary: Official Python SDK for ReleasePace feature flags
License: MIT
Project-URL: Homepage, https://releasepace.io
Project-URL: Repository, https://github.com/releasepace/releasepace-python
Project-URL: Documentation, https://docs.releasepace.io/sdks/python
Keywords: feature-flags,feature-toggles,releasepace
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: requests
Requires-Dist: requests>=2.28; extra == "requests"
Provides-Extra: django
Requires-Dist: django>=3.2; extra == "django"
Provides-Extra: fastapi
Requires-Dist: fastapi>=0.100; extra == "fastapi"
Dynamic: license-file

# releasepace

Official Python SDK for [ReleasePace](https://releasepace.io) — production-grade feature flags.

[![PyPI](https://img.shields.io/pypi/v/releasepace)](https://pypi.org/project/releasepace/)
[![Python](https://img.shields.io/pypi/pyversions/releasepace)](https://pypi.org/project/releasepace/)
[![license](https://img.shields.io/badge/license-MIT-blue)](LICENSE)

Zero required dependencies — uses Python stdlib `urllib` by default, `requests` optionally.

---

## Installation

```bash
pip install releasepace

# With requests (recommended for production)
pip install "releasepace[requests]"
```

---

## Quick start

```python
from releasepace import ReleasePace

# Context manager (recommended — auto-disconnects)
with ReleasePace(api_key='rp_live_xxxxxxxxxxxx', environment='production') as rp:
    if rp.is_enabled('new-checkout'):
        render_new_checkout()

    label = rp.get_string('cta-label', default='Get started')
    limit = rp.get_number('rate-limit', default=100)
    cfg   = rp.get_json('feature-config', default={})
```

---

## Django / Flask integration

```python
# settings.py / app factory — create once, reuse everywhere
import atexit
from releasepace import ReleasePace

rp = ReleasePace(api_key='rp_live_xxx', environment='production')
rp.connect()
atexit.register(rp.disconnect)

# views.py
def checkout_view(request):
    if rp.is_enabled('new-checkout'):
        return render(request, 'checkout_v2.html')
    return render(request, 'checkout.html')
```

---

## API reference

### `ReleasePace(api_key, **options)`

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `api_key` | `str` | required | SDK key from your dashboard |
| `environment` | `str` | `"production"` | Environment slug |
| `api_url` | `str` | `https://api.releasepace.io` | Override API URL |
| `poll_interval` | `float` | `30.0` | Seconds between polls |
| `context` | `dict` | `{}` | Evaluation context (`userId`, `country`…) |
| `on_update` | `callable` | `None` | Called with `List[Flag]` when flags change |
| `on_error` | `callable` | `None` | Called with `Exception` on fetch errors |

### Methods

| Method | Returns | Description |
|--------|---------|-------------|
| `connect()` | `ReleasePace` | Fetch flags, start background polling |
| `disconnect()` | `None` | Stop polling |
| `refresh()` | `None` | Force immediate re-fetch |
| `is_enabled(key)` | `bool` | Check boolean flag |
| `get_string(key, default='')` | `str` | Get string flag value |
| `get_number(key, default=0)` | `float` | Get number flag value |
| `get_json(key, default=None)` | `Any` | Get JSON flag value |
| `get_value(key, default=None)` | `Any` | Get any flag value |
| `get_all_flags()` | `List[Flag]` | Get all flags |
| `set_context(**kwargs)` | `None` | Update evaluation context |

---

## Gradual rollouts

```python
rp.set_context(userId='user-123')
if rp.is_enabled('new-feature'):
    # Same user always gets same result (sticky bucketing)
    ...
```

---

## Self-hosting

```python
rp = ReleasePace(
    api_key='rp_live_xxx',
    api_url='https://api.yourdomain.com',
)
```

---


## Author

**[Aryaa Tiwari](https://github.com/AryaaTiwari)** — [LinkedIn](https://www.linkedin.com/in/aryaa-tiwari/)

## License

MIT © [ReleasePace](https://releasepace.io)
