This release is a pre-release and may not be stable for production use.
bev-cera
Python SDK and CLI for the external BirdsEyeView CERA API.
The SDK talks to BirdsEyeView's CERA APIs over HTTPS and authenticates with an
API key in the X-API-Key header. Credentials can be obtained by contacting
BirdsEyeView directly.
Installation
Requires Python 3.11 or later.
pip install "bev-cera==0.1.0a1"
This installs both the Python SDK and the bev-cera command-line interface.
Authentication
Set your API key in the environment:
export BEV_CERA_API_KEY="your-api-key"
To override the production API URL for staging or testing:
export BEV_CERA_BASE_URL="https://your-api-host"
Custom base URLs must use HTTPS. http://localhost with an optional port is
allowed for local testing; other HTTP URLs, credentials, queries, and fragments
are rejected.
Never commit API keys to source control.
Example usage
In-Depth v2
Use calculate() for both non-cumulative and cumulative perils. Events use
EventWithCoords, so each event must provide a non-empty location or both
latitude and longitude. A location may also be provided with either coordinate.
When dates are omitted, the API defaults start_date to today and end_date
to one calendar year after start_date, minus one day.
from bev_cera import Client, EventWithCoords
events = [
EventWithCoords(
latitude=51.5,
longitude=-0.1,
start_date="2026-01-01",
end_date="2026-01-01",
)
]
with Client() as client:
result = client.in_depth.calculate(perils=["Rain", "Hail"], events=events)
print(result.results)
For cumulative rain or snowfall, supply a window of 0 to 7 days:
with Client() as client:
result = client.in_depth.calculate(
perils=["CumulativeRain"], events=events, window_days=3
)
Lite scores
from bev_cera import Client
with Client() as client:
score = client.lite.score(latitude=51.5, longitude=-0.1)
print(score.scores.root)
Lite scores default to the return_period calculation method. Pass
calculation_method="globally_relative" only when that explicit mode is required.
Async
import asyncio
from bev_cera import AsyncClient
async def main() -> None:
async with AsyncClient() as client:
perils = await client.perils.list()
print(perils.daily)
asyncio.run(main())
In-Depth Daily
from bev_cera import Client, EventWithCoords
events = [
EventWithCoords(
location="London", start_date="2026-01-01", end_date="2026-01-01"
)
]
with Client() as client:
result = client.in_depth.daily(perils=["Rain"], events=events)
print(result.results)
Batch
from bev_cera import Client
with Client() as client:
uploaded = client.batch.upload("events.csv")
submitted = client.batch.submit(file_id=uploaded.file_id, perils=["Rain"])
status = client.batch.status(submitted.job_id)
print(status.progress_percentage, status.processed_rows, status.total_rows)
result = client.batch.wait_for(submitted.job_id)
print(result)
batch.submit() generates an idempotency key automatically and reuses it for
transport retries. Supply idempotency_key= when the same logical submission
may be retried by your own application. Use client.batch.cancel(job_id) to
cancel a pending or running job.
Retryable GET requests and idempotent requests retry transport errors and
5xx responses with exponential back-off. 429 responses are surfaced to the
caller as RateLimitError.
Status and completion responses expose attempt, processed_rows,
total_rows, and progress_percentage. Progress is per processing attempt and
reaches 100 only after the result artefacts are committed. Polling returns typed
status models; completed responses contain pre-signed result, report, and
workbook URLs rather than downloaded or parsed files.
The SDK performs an early client-side check of the configured 100,000-row CSV
limit. The server remains authoritative. Large jobs can take several hours, so
batch.wait_for() defaults to a 4 hour timeout.
Date columns are optional. Missing start_date values default to the job
submission date, and missing end_date values default to start_date plus
one calendar year minus one day. A CSV containing only a location column is
valid.
Lite Batch
from bev_cera import Client
with Client() as client:
uploaded = client.lite_batch.upload("events.csv")
submitted = client.lite_batch.submit(
file_id=uploaded.file_id,
calculation_method="return_period",
flood_plus=True,
)
result = client.lite_batch.wait_for(submitted.job_id)
print(result)
calculation_method accepts return_period (the default) or
globally_relative. The CLI exposes the same workflow under
bev-cera lite-batch upload|submit|status|cancel|run.
Error Handling
from bev_cera import AuthenticationError, Client, ValidationError
try:
with Client() as client:
client.perils.list()
except AuthenticationError:
print("Check your API key")
except ValidationError as exc:
print(exc.message)
CLI
Configure the CLI once:
bev-cera configure
Examples:
bev-cera perils
bev-cera lite --lat 51.5 --lon -0.1
bev-cera in-depth calculate --events events.json --perils Rain,Hail
bev-cera in-depth calculate --events events.json --perils CumulativeRain --window-days 3
bev-cera in-depth daily --events events.json --perils Rain,MaxWindSpeed
bev-cera batch upload events.csv
bev-cera batch run events.csv --perils Rain --no-wait
Local testing from code
To test the SDK without it being on PyPi you can follow these steps:
Get the repo locally using a git clone. Then create a new folder and uv environment for the testing of the SDK
mkdir bev-sdk-test
cd bev-sdk-test
uv init
(You may need to install uv https://docs.astral.sh/uv/getting-started/installation/)
Then setup the bev SDK in the UV environment:
uv add --editable <path_to_local_sdk>/external-weather-api/sdk
Next create a .env file to get environment variables. Use this .env schema to help you
# @type=string(startsWith=test-,uat-,prod-) @required @sensitive
BEV_CERA_API_KEY=
# @type=url
#BEV_CERA_BASE_URL=
Source the environment variables
source .env
Then edit the main.py file, created by uv, to this to test lite scores.
def main():
from bev_cera import Client
with Client() as client:
score = client.lite.score(latitude=51.5, longitude=-0.1)
print(score.scores.root)
if __name__ == "__main__":
main()
To run the application use
uv run main.py
License and service terms
The bev-cera Python SDK source in this directory and its distribution
artifacts are licensed under the MIT License.
The MIT License applies only to the client SDK. It does not license the hosted External Weather API, server-side software, weather models, datasets, API credentials, service operation, or trademarks. Access to the hosted API requires separately issued credentials and is governed by the applicable service terms.
For SDK support, contact albert.dow@birdseyeview.ai.
Metadata
Release files for bev-cera 0.1.0a1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| bev_cera-0.1.0a1.tar.gz | 15.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| bev_cera-0.1.0a1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 34.4 kB
Release files / bev_cera-0.1.0a1.tar.gz
| Download URL | bev_cera-0.1.0a1.tar.gz |
|---|---|
| Size | 15.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ba5043d307e253d610d8ecb3322fee949cf09d394aceeca729de4fbd55f0733d
|
|
BLAKE2b-256 checksum How to use checksums |
436e72b6c2d1345e4374e5ddd8b961ab470a6e3c91b347a9a88965517661c2d5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.0
|
Release files / bev_cera-0.1.0a1-py3-none-any.whl
| Download URL | bev_cera-0.1.0a1-py3-none-any.whl |
|---|---|
| Size | 19.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1fc973ad775c5cad4f261e6164be402c5cc6b22194e18cb8aa84fa9375c525cd
|
|
BLAKE2b-256 checksum How to use checksums |
46b27719d51b93187b6cce6100c60098160fa4232b71f8bbe7715f974d031cdb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.0
|