semvec/pypi-packages huggingface dataset:
boj-ts-api 0.2.0
Generic Python client for the Bank of Japan Time-Series Statistics API
Requires Python: >=3.10
Keywords: api, bank-of-japan, boj, statistics, time-series

# boj-ts-api

Generic Python client for the [Bank of Japan Time-Series Statistics API](https://www.stat-search.boj.or.jp/).

[![PyPI](https://img.shields.io/pypi/v/boj-ts-api)](https://pypi.org/project/boj-ts-api/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)

Low-level, typed wrapper around the three BOJ API endpoints. For a beginner-friendly interface with domain wrappers and enum-driven filtering, see [pyboj](https://github.com/obichan117/pyboj).

## Installation

```bash
pip install boj-ts-api
```

## Usage

### Fetch Data by Series Code

```python
from boj_ts_api import Client, Lang

with Client(lang=Lang.EN) as client:
    resp = client.get_data_code(
        db="CO",
        code="TK99F1000601GCQ01000",
        start_date="202401",
        end_date="202404",
    )
    for series in resp.RESULTSET:
        print(series.SERIES_CODE, series.VALUES.VALUES)
```

### Auto-Pagination

```python
with Client(lang=Lang.EN) as client:
    for series in client.iter_data_code(db="CO", code="TK99F1000601GCQ01000"):
        print(series.SERIES_CODE, len(series.VALUES.SURVEY_DATES), "data points")
```

### Fetch Data by Layer

```python
from boj_ts_api import Client, Frequency, Lang

with Client(lang=Lang.EN) as client:
    resp = client.get_data_layer(db="FM08", frequency=Frequency.D, layer="1,1")
    for series in resp.RESULTSET:
        print(series.SERIES_CODE, series.VALUES.VALUES[:5])
```

### Metadata

```python
with Client(lang=Lang.EN) as client:
    meta = client.get_metadata(db="FM08")
    for rec in meta.RESULTSET[:3]:
        print(rec.SERIES_CODE, rec.FREQUENCY, rec.NAME_OF_TIME_SERIES)
```

### Async Client

```python
import asyncio
from boj_ts_api import AsyncClient, Lang

async def main():
    async with AsyncClient(lang=Lang.EN) as client:
        resp = await client.get_data_code(db="CO", code="TK99F1000601GCQ01000")
        print(resp.RESULTSET[0].SERIES_CODE)

asyncio.run(main())
```

### CSV Output

```python
with Client(lang=Lang.EN) as client:
    csv_text = client.get_data_code_csv(db="CO", code="TK99F1000601GCQ01000")
    print(csv_text)
```

## API Surface

| Method | Description |
|--------|-------------|
| `get_data_code()` | Fetch time-series data by series code(s) |
| `iter_data_code()` | Auto-paginating iterator over series results |
| `get_data_code_csv()` | Fetch data as raw CSV text |
| `get_data_layer()` | Fetch data by hierarchy layer |
| `iter_data_layer()` | Auto-paginating iterator for layer data |
| `get_data_layer_csv()` | Fetch layer data as raw CSV text |
| `get_metadata()` | Fetch series metadata for a database |
| `get_metadata_csv()` | Fetch metadata as raw CSV text |

Both `Client` (sync) and `AsyncClient` (async) expose the same methods.

## License

MIT
geoscored 0.1.0
Python SDK for the GeoScored GEO audit API
Requires Python: >=3.10

# GeoScored Python SDK

Typed async Python client for the [GeoScored](https://geoscored.ai) GEO audit API.

## Installation

```bash
pip install geoscored
```

## Quickstart

```python
import asyncio
from geoscored import GeoScoredClient

async def main():
    async with GeoScoredClient(api_key="geo_your_key_here") as client:
        # Create a scan
        scan = await client.create_scan(
            "https://example.com",
            brand_name="Example Corp",
        )
        print(f"Scan created: {scan.id}")

        # Wait for completion
        scan = await client.poll_scan(scan.id)
        print(f"Score: {scan.overall_score} ({scan.grade})")

        # Get the full report
        report = await client.get_report(scan.id)
        for check in report.checks:
            print(f"  [{check.severity}] {check.check_name}: {check.score}")

asyncio.run(main())
```

## Sandbox mode

Use a test key (starting with `geo_test_`) to get deterministic mock responses
without creating real scans:

```python
async with GeoScoredClient(api_key="geo_test_demo") as client:
    scan = await client.create_scan("https://example.com")
    # Returns instantly with status="complete" and fixed scores
```

## API Reference

### `GeoScoredClient(api_key, base_url="https://geoscored.ai", timeout=30.0)`

All methods are async and return typed Pydantic models.

| Method | Returns | Description |
|--------|---------|-------------|
| `create_scan(url, brand_name, callback_url)` | `Scan` | Create a new GEO audit scan |
| `get_scan(scan_id)` | `Scan` | Get scan status and scores |
| `list_scans(limit, status, starting_after)` | `ScanList` | List scans with pagination |
| `get_report(scan_id)` | `Report` | Get full audit report |
| `list_checks(scan_id)` | `CheckList` | List all check results |
| `get_check(scan_id, check_id)` | `Check` | Get a specific check |
| `delete_scan(scan_id)` | `None` | Delete a scan |
| `export_scans(days)` | `ExportData` | Export scan history |
| `poll_scan(scan_id, interval, timeout)` | `Scan` | Poll until complete/failed |

### Error handling

All API errors raise `GeoScoredError` with structured fields:

```python
from geoscored import GeoScoredClient, GeoScoredError

try:
    scan = await client.get_scan("nonexistent")
except GeoScoredError as e:
    print(e.status_code)  # 404
    print(e.code)         # "scan_not_found"
    print(e.message)      # "Scan not found."
    print(e.request_id)   # "req_7f3a2b1c..."
```

## Requirements

- Python 3.10+
- httpx >= 0.28.0
- pydantic >= 2.0