<div class="section-label"><span class="num">02</span> Python</div>
<div class="section-title">The pip package for this <em>API</em>.</div>
Install the client, set your credentials, call Grid, and read the forecast.
> [!note]
> Set <span class="mono">CSA_API_KEY</span> and <span class="mono">CSA_ACCESS_ID</span> in the environment. You can pass them to <span class="mono">RbpEngineApiClient(...)</span> instead.
Source: [rbp-engine-api-client/python](https://github.com/CambridgeSportsAnalytics/rbp-engine-api-client/tree/main/python).
## Install
Python 3.10+:
```bash
pip install "git+https://github.com/CambridgeSportsAnalytics/rbp-engine-api-client.git#subdirectory=python"
```
From a clone of that repository: `pip install -e ./python`.
## Grid
```python
from rbp_engine_api_client import RbpEngineApiClient
client = RbpEngineApiClient()
envelope = client.predict_grid(
y=[0.1, 0.2, 0.3],
X=[[1.0, 0.0], [0.0, 1.0], [1.0, 1.0]],
)
yhat = envelope["results"]["yhat"]
```
`predict_grid` submits the job and waits. The forecast is `envelope["results"]["yhat"]`. Fit and Grid insights (Impact on Fit, Impact on Prediction) sit on the same `results` object. What those numbers mean: [[Functions/Grid Prediction|Grid Prediction]] · [[Results/Grid Insights|Grid Insights]].
Example: [post_grid.py](https://github.com/CambridgeSportsAnalytics/rbp-engine-api-client/blob/main/python/examples/post_grid.py).
## MaxFit and PSR
Same pattern, different method.
```python
envelope = client.predict_maxfit(y=y, X=X)
envelope = client.predict(y=y, X=X)
```
Use MaxFit when the attribute set is fixed and you want the engine to pick the threshold. Use `predict` (PSR) when the thresholds are fixed too. Examples: [post_maxfit.py](https://github.com/CambridgeSportsAnalytics/rbp-engine-api-client/blob/main/python/examples/post_maxfit.py) · [post_predict_smoke.py](https://github.com/CambridgeSportsAnalytics/rbp-engine-api-client/blob/main/python/examples/post_predict_smoke.py).
## Options
Pass only what you want to change. Omit `options` to use defaults. Names match [[Settings/Options|Settings]]. For logistic outcomes, set `prediction_scale="logistic"`.
## Several circumstances
Pass several rows of `theta` in one call. The client waits for every row.
```python
envelope = client.predict_grid(y=y, X=X, theta=[[0.0, 1.0], [1.0, 0.0]])
```
Example: [post_predict_experiment.py](https://github.com/CambridgeSportsAnalytics/rbp-engine-api-client/blob/main/python/examples/post_predict_experiment.py).
## Submit without waiting
`post_grid`, `post_maxfit`, and `post_predict` return `{job_id, job_code}` immediately. Call `wait(receipt)` when you want the forecast.
## Large X, one field, quota
- Compact `X` over 5 MiB is uploaded for you. `x_as_reference=True` forces that path. `upload_x(X)` returns `{"s3_key": "..."}` if you want to reuse it. [[API/Limits/Payload Limits|Payload size]]
- `get_results_field(job_id, job_code, field)` returns one value (`yhat`, `insights/relevance`, …).
- `get_quota("summary")` shows what remains on your plan. [[API/Limits/Throttle Limits|Quota]]
## If something goes wrong
`RbpEngineApiError` has `status_code` and `body`.
| What you see | Meaning |
| --- | --- |
| 401 | Missing or invalid API key |
| 413 | `X` is too large |
| 429 | Out of quota; wait or raise the plan |
| 409 | The job failed while running |
| `TimeoutError` | The client stopped waiting |
Calling HTTP yourself: [post_predict_http.py](https://github.com/CambridgeSportsAnalytics/rbp-engine-api-client/blob/main/python/examples/post_predict_http.py) · [[API/Endpoints/Grid|Endpoints]].
## Related
- [[API/Clients/Introduction|Clients]] · [[API/Clients/R|R]] · [[API/Clients/MATLAB|MATLAB]]
- [[API/Introduction|API]] · [[Functions/Grid Prediction|Grid Prediction]]
<div class="btn-row center">
<a class="btn-primary" href="/API/Clients/R">R</a>
<a class="btn-ghost" href="/API/Clients/MATLAB">MATLAB</a>
</div>