Metadata-Version: 2.4
Name: vynfi
Version: 0.1.0
Summary: Python SDK for the VynFi synthetic financial data API
Project-URL: Homepage, https://vynfi.com
Project-URL: Documentation, https://docs.vynfi.com
Project-URL: Repository, https://github.com/VynFi/VynFi-python
Project-URL: Issues, https://github.com/VynFi/VynFi-python/issues
Author-email: VynFi <hello@vynfi.com>
License-Expression: Apache-2.0
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
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 :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: eval-type-backport>=0.1.0; python_version < '3.10'
Requires-Dist: httpx>=0.25
Requires-Dist: pydantic>=2.0
Provides-Extra: dev
Requires-Dist: mypy>=1.0; extra == 'dev'
Requires-Dist: pytest>=7; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Description-Content-Type: text/markdown

# VynFi Python SDK

The official Python client for the [VynFi](https://vynfi.com) synthetic financial data API.

## Installation

```bash
pip install vynfi
```

## Quick Start

```python
from vynfi import VynFi

client = VynFi(api_key="vf_live_...")

# Generate synthetic financial data
job = client.generate(
    tables=[{"name": "journal_entries", "rows": 5000}],
    format="json",
    sector_slug="retail",
)
print(f"Job {job.id} submitted ({job.credits_reserved} credits)")

# Poll until complete
import time
while True:
    status = client.jobs.get(job.id)
    if status.status in ("completed", "failed"):
        break
    time.sleep(2)

# Download the result
if status.status == "completed":
    client.jobs.download(job.id, "output.json")
```

## Usage

### Browse the catalog

```python
sectors = client.catalog.list_sectors()
for s in sectors:
    print(f"{s.name} ({s.slug})")

sector = client.catalog.get_sector("retail")
for table in sector.tables:
    print(f"  {table.name}: {len(table.columns)} columns")
```

### Check credit usage

```python
usage = client.usage.summary(days=30)
print(f"Balance: {usage.balance} credits")
print(f"Burn rate: {usage.burn_rate}/day")
```

### Manage API keys

```python
keys = client.api_keys.list()
new_key = client.api_keys.create(name="CI pipeline")
print(f"Key: {new_key.key}")  # Only shown once!
```

### Quality scores

```python
scores = client.quality.scores()
for s in scores:
    print(f"Job {s.job_id}: {s.overall_score:.2f}")
```

### Webhooks

```python
hook = client.webhooks.create(
    url="https://example.com/webhook",
    events=["job.completed", "job.failed"],
)
print(f"Webhook secret: {hook.secret}")
```

### Stream job progress (SSE)

```python
job = client.generate(tables=[{"name": "journal_entries", "rows": 10000}])
for event in client.jobs.stream(job.id):
    if event["event"] == "progress":
        print(f"Progress: {event['data']['percent']}%")
    elif event["event"] == "complete":
        print("Done!")
        break
```

## Error Handling

```python
from vynfi import VynFi, InsufficientCreditsError, RateLimitError

try:
    job = client.generate(tables=[{"name": "journal_entries", "rows": 1000000}])
except InsufficientCreditsError:
    print("Not enough credits")
except RateLimitError:
    print("Too many requests, retry later")
```

## Configuration

```python
client = VynFi(
    api_key="vf_live_...",
    base_url="https://api.vynfi.com",  # default
    timeout=30.0,                       # seconds
    max_retries=2,                      # retry on 429/5xx
)
```

## License

Apache 2.0
