Metadata-Version: 2.4
Name: bellator_si
Version: 0.4.2
Summary: Bellator Schedule Intelligence APIs
Home-page: https://github.com/Bellator-Schedule-Intelligence/bellator-si-api
Author: Bellator Schedule Intelligence
Author-email: Bellator Schedule Intelligence <team@openapitools.org>
Project-URL: Repository, https://github.com/Bellator-Schedule-Intelligence/bellator-si-api
Keywords: OpenAPI,OpenAPI-Generator,Bellator Schedule Intelligence APIs
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: urllib3<3.0.0,>=2.1.0
Requires-Dist: python-dateutil>=2.8.2
Requires-Dist: pydantic>=2
Requires-Dist: typing-extensions>=4.7.1
Dynamic: author
Dynamic: home-page

# bellator-si

Python client for the Bellator Schedule Intelligence API. Version 0.4.2.

This README is hand-maintained. The client code and `docs/` are generated from
`output/openapi-public-v0.4.2.json` by `scripts/generate-sdks.sh`.

- API reference: https://bellatorsi.com/docs/api-reference
- Default host: `https://api.bellatorsi.com`
- Source: https://github.com/Bellator-Schedule-Intelligence/bellator-si-api

## Install

```bash
pip install bellator-si==0.4.2
```

Python 3.9 or later.

## Quick start

Set your key in an environment variable. Do not put it in code.

```bash
export BELLATOR_API_KEY="your-key"
```

```python
import os

from bellator_si import ApiClient, Configuration, HealthApi

config = Configuration(api_key={"ApiKeyAuth": os.environ["BELLATOR_API_KEY"]})

with ApiClient(config) as client:
    result = HealthApi(client).health_score(
        {
            "tasks": [
                {"id": "A", "name": "Mobilize", "duration_days": 5, "predecessors": []},
                {"id": "B", "name": "Foundations", "duration_days": 10, "predecessors": ["A"]},
                {"id": "C", "name": "Structure", "duration_days": 15, "predecessors": ["B"]},
            ]
        }
    )

print(result.score, result.grade, result.status)
for finding in result.findings or []:
    print(finding.code, finding.affected_tasks)
```

`Configuration()` uses `https://api.bellatorsi.com`. Pass `host=` to point at another
environment, for example `Configuration(host="http://localhost:8000", api_key=...)`.

## Predecessors

Each item in `predecessors` can be any of these, mixed in one list:

```python
from bellator_si import DependencyLink

predecessors = [
    "T1",                                                          # finish-to-start, no lag
    "T2SS+2d",                                                     # type and lag in the string
    {"task_id": "T3", "relationship_type": "FF", "lag_days": -1},  # object
    DependencyLink(task_id="T4"),                                  # model
]
```

## Classes and methods

Method names are the API operation IDs.

| Class | Methods |
|---|---|
| `HealthApi` | `health_score`, `health_logic_audit`, `health_progress_audit`, `health_dcma_14_point`, `health_dcma_decm`, `health_planning_horizon`, `health_schedule_risk_index`, and an `_async` variant of each |
| `AnalysisApi` | `analysis_validate`, `analysis_cpm`, `analysis_resources`, `analysis_cpm_async`, `analysis_resources_async` |
| `ForensicsApi` | `forensics_delay_analysis`, `forensics_change_tracking`, `forensics_baseline_compare`, `forensics_as_planned_vs_as_built`, and an `_async` variant of each |
| `SimulationApi` | `simulation_monte_carlo`, `simulation_what_if`, and an `_async` variant of each |
| `ImportApi` | `import_mpp`, `import_xer` |
| `JobsApi` | `jobs_get`, `jobs_cancel`, `jobs_delete` |
| `AccountApi`, `UsageQuotaApi`, `WebhooksApi` | account tier, usage, and webhook registration |
| `SystemApi` | `health_check` (process liveness, not a schedule check) |

Each method also has `<name>_with_http_info` (status code and headers) and
`<name>_without_preload_content` (raw response). Per-model and per-method pages are in `docs/`.

## Async jobs

Starter and above. Submit to an `_async` method, then poll the job.

```python
import os
import time

from bellator_si import ApiClient, Configuration, HealthApi, JobsApi

config = Configuration(api_key={"ApiKeyAuth": os.environ["BELLATOR_API_KEY"]})
tasks = [
    {"id": "A", "duration_days": 5, "predecessors": []},
    {"id": "B", "duration_days": 3, "predecessors": ["A"]},
]

with ApiClient(config) as client:
    job = HealthApi(client).health_score_async({"tasks": tasks})
    while True:
        status = JobsApi(client).jobs_get(job.job_id)
        if status.status in ("completed", "failed", "cancelled"):
            break
        time.sleep(2)

print(status.status, status.result)
```

## Errors

A non-2xx response raises `bellator_si.ApiException` (or a subclass such as
`BadRequestException`). `status` is the HTTP code and `body` is an RFC 9457 problem
document (`application/problem+json`): `type`, `title`, `status`, `detail`, `code`,
`instance`, `request_id`, plus route fields such as `required_tier` or `async_endpoint`.
Branch on `code`; `type` is the page that documents it.

```python
import json
import os

from bellator_si import ApiClient, ApiException, Configuration, ForensicsApi

config = Configuration(api_key={"ApiKeyAuth": os.environ["BELLATOR_API_KEY"]})

with ApiClient(config) as client:
    try:
        ForensicsApi(client).forensics_delay_analysis(
            {"tasks": [{"id": "A", "duration_days": 5}], "status_date": "2026-03-15"}
        )
    except ApiException as error:
        problem = json.loads(error.body)
        print(error.status)              # 402 on a Free key: forensics needs Starter
        print(problem["code"])           # "TIER_REQUIRED"
        print(problem["required_tier"])  # "starter"
```

A schedule with a predecessor loop returns 400 `CIRCULAR_DEPENDENCY` from every endpoint
that computes the critical path, with the loop in `cycle`. `analysis_validate` returns it
as a `CIRCULAR_DEPENDENCY` finding instead.

## Tiers

| Tier | Tasks per request | Calls per month | Payload | Async |
|---|---|---|---|---|
| Free | 1,000 | 100 | 5 MB | No |
| Starter | 2,000 | 500 | 5 MB | Yes |
| Professional | 5,000 | 2,000 | 25 MB | Yes |
| Enterprise | 50,000 | 10,000 | 100 MB | Yes |
| Government | 100,000 | 50,000 | 500 MB | Yes |

Free covers Health and Analysis. Starter adds Forensics, Import, and async. Simulation
needs Professional. Requests over 1,000 tasks must use the `_async` methods.

## Changes in 0.4.2

- No interface changes. The API fixes results: async jobs accept dashboard keys, and
  delay analysis, as-planned vs as-built, planning horizon, resource analysis, and
  baseline-compare (`spi_schedule`) now report the measured values. See `CHANGELOG.md`.
- Docs: examples import `os` and keep the API key.

## Changes in 0.4.1

- Schedule checks are on `HealthApi`. In 0.4.0 they were on `Health0Api`, and `HealthApi`
  held only the liveness probe, which is now `SystemApi.health_check`.
- Method names are the operation IDs. For example `calculate_health_score_api_v1_health_score_post`
  is now `health_score`, and `get_async_job_status_api_v1_jobs_job_id_get` is now `jobs_get`.
- Methods no longer take `x_api_key`, `authorization`, or `x_bellator_internal_dispatch`
  arguments. Set the key once on `Configuration`.
- A plain request dict accepts string predecessors. In 0.4.0 `"T1"` failed client-side, and
  an object predecessor in a dict was sent as `null`.
- Internal endpoints (sign-up, billing, contact, feedback, sandbox, ephemeral keys) are no
  longer in the package.
