Metadata-Version: 2.4
Name: synthera
Version: 0.2.9
Summary: Python client for Synthera AI API
Author: Synthera AI
License-File: LICENSE
Classifier: Development Status :: 4 - Beta
Classifier: License :: Other/Proprietary License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.9
Requires-Dist: httpx>=0.28.1
Requires-Dist: matplotlib>=3.8
Requires-Dist: numpy>=1.26.4
Requires-Dist: pandas>=2.1.2
Requires-Dist: pyarrow>=15.0.2
Requires-Dist: pydantic>=2.10.6
Requires-Dist: tenacity>=9.0.0
Description-Content-Type: text/markdown

# Synthera AI SDK

A Python SDK for accessing the Synthera AI API.

## Installation

The package is compatible with Python `3.9`-`3.13`.

```bash
pip install synthera
```

## Changelog

### 0.2.9

Changed
- Model and simulate response metadata: `tenors` renamed to `maturities`.

Added
- Request `views` parameter: optional yield-view constraints (point, range, min, max per curve/maturity) to filter scenarios by change in bps at end of horizon
- Response metadata `no_samples_returned` and `views_applied` when views are used
- SSL options on `SyntheraClient`: `verify_ssl` (default `True`) and `ca_bundle` (optional path). Environment variables `SYNTHERA_API_VERIFY_SSL` and `SYNTHERA_API_CA_BUNDLE` to override. Supports corporate proxies and custom CA bundles.

### 0.2.8

Changed
- Response data format: compressed feather & base64

### 0.2.7

Added
- Request `fallback_on_missing_date` parameter
- Request `conditional_vol_factor` parameter
- `version` to Client and request headers

Changed
- Request `no_of_days` parameter to `no_days`
- Request `no_of_samples` parameter to `no_samples`
- Model metadata `simulation_steps` to `max_simulate_days`
- Model metadata `conditional_steps` to `conditional_days`
- FixedIncome `model_labels` to `get_model_labels`
- FixedIncome `model_metadata` to `get_model_metadata`
- FixedIncome `simulation_past_date` to `simulate`
- FixedIncome `SimulationPastDateRestuls` to `SimulateResults`


## API Key

You are required to use an API key to access the Synthera AI API.

For ease of use, set as an environment variable: `SYNTHERA_API_KEY`:

```
export SYNTHERA_API_KEY=<api_key>
```

Or you can pass directly to the client.

## SSL / TLS

SSL verification is configurable for environments (e.g. corporate proxies or custom CA bundles).

**Constructor options:**

- `verify_ssl` — Enable or disable server certificate verification (default: `True`).
- `ca_bundle` — Path to a CA bundle file for verification (optional). When set, this path is used instead of the default system trust store.

**Environment variables (overridden by explicit constructor args):**

- `SYNTHERA_API_VERIFY_SSL` — Set to `false`, `0`, or `no` (case-insensitive) to disable verification; any other value enables it.
- `SYNTHERA_API_CA_BUNDLE` — Path to your CA bundle file (e.g. `/path/to/ca-bundle.pem`).

**Example:**

```python
# Default: verify with system CA bundle
client = SyntheraClient(api_key="<api_key>")

# Disable verification (e.g. for testing)
client = SyntheraClient(api_key="<api_key>", verify_ssl=False)

# Use a custom CA bundle (e.g. for corporate proxies)
client = SyntheraClient(
    api_key="<api_key>",
    verify_ssl=True,
    ca_bundle="/path/to/your/ca-bundle.pem",
)
```

Or via environment:

```
export SYNTHERA_API_VERIFY_SSL=false
export SYNTHERA_API_CA_BUNDLE=/path/to/ca-bundle.pem
```

## Getting Started

**Import the Synthera client**:
```python
from synthera import SyntheraClient
```

**Create a client**:
```python
client = SyntheraClient()
```

**Show client version**
```python
client.version
# Output: 0.2.8
```

**Check the connection works**:
```python
client.healthy()
# Output: True
```
Note: the health endpoint is open; the API key is not verified.

**For more advanced connection options, pass arguments to the client**:
```python
SyntheraClient(
    api_key="<api_key>",
    host="<host>",
    port=<port>,
    timeout_secs=<timeout>,
    verify_ssl=True,   # default; set False to disable SSL verification
    ca_bundle=None,    # optional path to CA bundle file
)
# Output: <SyntheraClient>
```

## Fixed Income

To run Fixed Income Yield Curve simulation.

### View Available Models

**View the model labels**:

```python
client.fixed_income.get_model_labels()
# Example output: ['YieldGAN-Augur-15days-v0.1-Q42019', 'YieldGAN-Augur-15days-v0.1-Q42024']
```

| Name | Description |
|------|-------------|
| YieldGAN | Model name |
| Augur | Dataset used for training & inference |
| 15days | Maximum simulation days |
| v0.1-Q42019 | Version (including training end period) |

### View Model Metadata

**View the metadata for a model label**:

```python
client.fixed_income.get_model_metadata(model_label="YieldGAN-Augur-15days-v0.1-Q42024")
# Example output: ModelMetadata(model_label='YieldGAN-Augur-15days-v0.1-Q42024', dataset='Augur', universe='g3_par_curves', curve_labels=['USA', 'GBR', 'DEU'], start_date_training='2000-01-01', end_date_training='2025-01-01', max_simulate_days=15, conditional_days=15, maturities=[0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 12.0, 14.0, 16.0, 18.0, 20.0, 25.0, 30.0])
```

| Name | Description |
|------|-------------|
| model_label | Unique identifier for the model |
| dataset | Dataset model is trained on (e.g. Augur Labs) |
| universe | Data universe used for training (e.g., g3_par_curves) |
| curve_labels | List of yield curve identifiers included in the model |
| start_date_training | Start date of the training data period (YYYY-MM-DD) (inclusive) |
| end_date_training | End date of the training data period (YYYY-MM-DD) (exclusive) |
| max_simulate_days | Maximum number of forward simulation days |
| conditional_days | Number of conditional simulation days |
| maturities | List of maturities (in years) for which yields are generated |


### Simulation

**Prepare input parameters.**

| Parameter | Type | Description | Values                                                    |
|-----------|------|-------------|-----------------------------------------------------------|
| model_label | string | Version of the model to use | Valid model label: "YieldGAN-\<dataset\>-\<max simulation days\>-v\<version\>" |
| curve_labels | list[string] | List of yield curves labels to simulate, using ISO 3166-1 alpha-3 country codes | List of curve names (e.g., ["USA", "GBR", "DEU"])         |
| no_days | integer | Number of days to simulate forward from the reference date | > 0 (e.g., 3, 30, 60, 120)                                |
| no_samples | integer | Number of paths to simulate | > 0 (e.g., 100, 1024, 5000)                              |
| reference_date | string | Reference date for the generation (in the past) | YYYY-MM-DD format                                         |
| fallback_on_missing_date | boolean | Whether to fallback to an available date in the dataset | true or false                                        |
| conditional_vol_factor | float | Conditional volatility factor | e.g. 0.1, 1.0, 10.0, 100                                         |
| views | object (optional) | Optional constraints to filter scenarios by yield change (in bps) at end of horizon | `yields`: dict of curve_maturity (e.g. `"USA_10.0Y"`) to view (point / range / min / max); `macro`: reserved |

For example:

```python
params = {
    "model_label": "YieldGAN-Augur-10days-v0.1-Q42024",
    "curve_labels": ["USA", "GBR"],
    "no_days": 15,
    "no_samples": 100,
    "reference_date": "2010-01-01",
    "fallback_on_missing_date": True,
    "conditional_vol_factor": 1.0,
}
```

With optional **views** to filter scenarios by yield change (in basis points) at the end of the simulation horizon:

```python
params = {
    "model_label": "YieldGAN-Augur-10days-v0.1-Q42024",
    "curve_labels": ["USA", "GBR", "DEU"],
    "no_days": 30,
    "no_samples": 1000,
    "reference_date": "2010-01-01",
    "fallback_on_missing_date": True,
    "views": {
        "yields": {
            "USA_10.0Y": {"type": "range", "min_bp": 20, "max_bp": 25},
            "DEU_2.0Y": {"type": "point", "value_bp": 10, "tolerance_bp": 2},
        },
        "macro": None,
    },
}
# When views are applied, result.ndarray.shape[0] may be less than no_samples;
# use results.metadata["no_samples_returned"] for the actual count.```

**Run simulation directly**:

```python
results = client.fixed_income.simulate(params=params)
# Output: SimulateResults
```

**View yield curves labels**:
```python
results.names
# Example output: ['USA', 'GBR']
```

**View yield curve dataframe column names**:
```python
results.column_names
# Output: ['IDX', 'SAMPLE', 'YC_0', 'YC_1', ...]
```

**View a specific yield curve dataframe, e.g. for `USA`**:
```python
results.dataframes["USA"]
# Output: pandas.DataFrame
```

**View all yield curves in a single `numpy` ndarray (order is same as `names`)**:
```python
results.ndarray
# Output: ndarray of shape (samples, countries, days, columns)
```

**View request metadata**:
```python
results.metadata
# Output: dict
```
When `views` are applied, metadata includes `no_samples_returned` (number of scenarios after filtering) and `views_applied`; `results.ndarray.shape[0]` matches `no_samples_returned`.

## Simulate Results

The `SimulateResults` object provides several utility and plotting methods for analyzing and visualizing outputs.

### Utility Methods

**Get dates:**
```python
results.get_dates()
# Output: [Timestamp('2010-01-01 00:00:00'), ...]
```

**Get yield curve column indices:**
```python
results.get_yc_indices()
# Output: [2, 3, 4, ...]
```

**Get all yield curve samples (as ndarray):**
```python
results.get_yc_samples()
# Output: ndarray of shape (samples, countries, days, maturities)
```

**Get all samples for a specific country:**
```python
results.get_country_yc_samples("USA")
# Output: ndarray of shape (samples, days, maturities)
```

**Get a single sample for a country:**
```python
results.get_yc_sample("USA", sample_num=0)
# Output: ndarray of shape (days, maturities)
```

**Get a single sample at a specific time index:**
```python
results.get_country_sample_at_t("USA", time_idx=1, sample_num=0)
# Output: ndarray of shape (maturities,)
```

### Plotting Methods

All plotting methods return a matplotlib Figure. Set `show_plot=True` to display immediately (non-Jupyter environments).

**Plot a single sample for a country at a specific time:**
```python
results.plot_country_sample_at_time("USA", time_idx=1, sample_num=0, show_plot=True)
# Output: matplotlib.figure.Figure
```

**Plot all samples for a country at a specific time:**
```python
results.plot_country_all_samples_at_time("USA", time_idx=1, show_plot=True)
# Output: matplotlib.figure.Figure
```

**Plot a single sample's yield curve evolution over time (3D):**
```python
results.plot_country_sample_yield_curve_over_time("USA", sample_num=0, show_plot=True)
# Output: matplotlib.figure.Figure
```