Skip to main content
Pre-release

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)

Source distribution for bev-cera 0.1.0a1
File Size Uploaded
bev_cera-0.1.0a1.tar.gz 15.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for bev-cera 0.1.0a1
File Interpreter ABI Platform
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

Release history Release notifications | RSS feed

This release

0.1.0a1 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page