Metadata-Version: 2.4
Name: redenlab-extract
Version: 1.3.0
Summary: Python SDK for RedenLab ML inference service
Project-URL: Homepage, https://redenlab.com
Project-URL: Repository, https://git-codecommit.us-west-2.amazonaws.com/v1/repos/redenlab-extract
Author-email: RedenLab <contact@redenlab.com>
License: MIT
License-File: LICENSE
Keywords: audio,extraction,inference,ml,sagemaker,speech
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: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.10
Requires-Dist: numpy>=1.20.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: requests>=2.31.0
Requires-Dist: soundfile>=0.12.0
Requires-Dist: tenacity>=8.2.0
Provides-Extra: dev
Requires-Dist: black>=23.7.0; extra == 'dev'
Requires-Dist: mypy>=1.5.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
Requires-Dist: pytest-mock>=3.11.0; extra == 'dev'
Requires-Dist: pytest>=7.4.0; extra == 'dev'
Requires-Dist: responses>=0.23.0; extra == 'dev'
Requires-Dist: ruff>=0.0.285; extra == 'dev'
Requires-Dist: types-pyyaml>=6.0.0; extra == 'dev'
Requires-Dist: types-requests>=2.31.0; extra == 'dev'
Provides-Extra: test
Requires-Dist: pytest-cov>=4.1.0; extra == 'test'
Requires-Dist: pytest-mock>=3.11.0; extra == 'test'
Requires-Dist: pytest>=7.4.0; extra == 'test'
Requires-Dist: responses>=0.23.0; extra == 'test'
Description-Content-Type: text/markdown

# RedenLab Extract SDK

Python SDK for RedenLab's ML inference service. Run machine learning models on audio files using RedenLab's proprietary endpoints.

## Features

- JWT-based authentication — browser login for humans, env vars for machines
- Simple session + client pattern: upload once, run any model
- Async job management with polling and progress callbacks
- Automatic chunking for long audio files
- Built-in retry logic and error handling

## Installation

```bash
pip install redenlab-extract
```

## Authentication

The SDK uses JWT tokens issued by AWS Cognito. Two modes are auto-detected:

### Human / Interactive (PKCE)

Run once from the terminal:

```bash
redenlab login
```

This opens a browser, authenticates you, and stores tokens in
`~/.redenlab-ml/credentials.yaml`. The SDK refreshes tokens silently — you
only need to run `redenlab login` again if your session expires.

### Machine / Headless (Client Credentials)

Set environment variables before running your script:

```bash
export REDENLAB_CLIENT_ID=your-client-id
export REDENLAB_CLIENT_SECRET=your-client-secret
```

The SDK detects these and fetches a token automatically. No browser, no disk tokens.

> **Priority:** if both env vars are set, Client Credentials is used regardless of
> any stored PKCE tokens.

## Quick Start

```python
from redenlab_extract import RedenLabSession, intelligibility_client, run_inference

session = RedenLabSession()
client = intelligibility_client(session, model_name="als-intelligibility-v1")

result = run_inference(session, client, "audio.wav")
print(result["result"]["intelligibility_score"])
```

```python
from redenlab_extract import RedenLabSession, TranscribeClient, run_inference

session = RedenLabSession()
client = TranscribeClient(session, language_code="en-US")

result = run_inference(session, client, "audio.wav")
print(result["transcript"])
```

## Available Models

### Intelligibility

```python
from redenlab_extract import intelligibility_client

client = intelligibility_client(session, model_name="als-intelligibility-v1")
# model_name options: "als-intelligibility-v1", "als-intelligibility-v2",
#                     "ataxia-intelligibility"
```

### Naturalness

```python
from redenlab_extract import naturalness_client

client = naturalness_client(session, model_name="als-naturalness-v1")
# model_name options: "als-naturalness-v1", "als-naturalness-v2",
#                     "ataxia-naturalness"
```

### Transcription (AWS Transcribe)

```python
from redenlab_extract import TranscribeClient

client = TranscribeClient(
    session,
    language_code="en-US",   # optional, defaults to "en-US"
    max_speaker_count=4,      # optional, defaults to 10
)
```

### WhisperX

```python
from redenlab_extract import whisperX_client

client = whisperX_client(session, diarize=True, batch_size=16)
```

### Speaker Counter

```python
from redenlab_extract import speaker_counter_client

client = speaker_counter_client(session)
```

### Speaker Diarization

```python
from redenlab_extract import speaker_diarization_client

client = speaker_diarization_client(session)
```

### Sylber Time

```python
from redenlab_extract import sylber_time_client

client = sylber_time_client(session)
```

## Usage Patterns

### Level 1 — `run_inference()` (recommended)

Handles upload, chunking, and inference in one call:

```python
from redenlab_extract import RedenLabSession, intelligibility_client, run_inference

session = RedenLabSession()
client = intelligibility_client(session, model_name="als-intelligibility-v1")

result = run_inference(session, client, "audio.wav")
```

Long files are chunked automatically and results are aggregated.

### Level 2 — Upload → Submit → Poll

Useful for batch processing or when you want to decouple upload from inference:

```python
# Upload
asset = session.upload("audio.wav")

# Submit (with retry for async S3 processing)
job_id = client._submit_with_upload_wait(asset)

# Poll
result = client.poll(job_id, timeout=600)
```

### Level 3 — Batch processing

Submit all jobs first, then poll concurrently:

```python
# Upload and submit all files
assets = [session.upload(f) for f in audio_files]
job_ids = [client._submit_with_upload_wait(asset) for asset in assets]

# Poll each
results = [client.poll(job_id) for job_id in job_ids]
```

### Progress callbacks

```python
def on_progress(status):
    print(f"Status: {status['status']}")

result = run_inference(session, client, "audio.wav", progress_callback=on_progress)
```

### Chunked inference (long files)

`run_inference()` chunks automatically. For manual control:

```python
from redenlab_extract import run_chunked_inference, aggregate_results

chunks = run_chunked_inference(session, client, "long_audio.wav", chunk_duration=50)
result = aggregate_results(chunks, score_key="intelligibility_score")
```

### Backend warmup

SageMaker-backed models (intelligibility, naturalness) may be cold after inactivity:

```python
health = client.health()
if not health["ready"]:
    client.warmup()  # submits a dummy job to wake the endpoint
```

## Configuration

### Base URL

Resolved in priority order:

| Source | How |
|---|---|
| Constructor | `RedenLabSession(base_url="https://...")` |
| Environment variable | `REDENLAB_ML_BASE_URL=https://...` |
| Config file | `~/.redenlab-ml/config.yaml` → `base_url: ...` |
| Service discovery | Automatic fallback |

### Config file (`~/.redenlab-ml/config.yaml`)

```yaml
base_url: https://your-api-gateway-url.amazonaws.com/prod  # optional
```

### Credentials file (`~/.redenlab-ml/credentials.yaml`)

Written automatically by `redenlab login`. Do not edit manually.

## Supported File Types

- WAV (`.wav`)
- FLAC (`.flac`)
- MP3 (`.mp3`)
- OGG (`.ogg`)
- M4A (`.m4a`)

## Requirements

- Python 3.10+
- `requests`
- `tenacity`
- `pyyaml`

Optional (for audio chunking):
- `soundfile`
- `numpy`

## Support

- Email: support@redenlab.com
- Website: https://redenlab.com

## License

MIT License — see [LICENSE](LICENSE) for details.

## Changelog

See [CHANGELOG.md](CHANGELOG.md) for version history.
