caic_python package#

Submodules#

caic_python.client module#

An async HTTP client to interface with the CAIC website.

CAIC Website Avy Obs request:

 /**
 * @param startDatetime a utc date string in format YYYY-MM-DD HH:mm:ss
 * @param endDatetime a utc date string in format YYYY-MM-DD HH:mm:ss
 * @param header the caic auth header (shared between all of the pagination requests should be fine)
 * @param page offset page
 * @return raw caic response json (including pagination data so we can call this function again if there is more data)
 */
async getCaicPaginated (startDatetime, endDatetime, headers, page = 1) {
    queryArgs = new URLSearchParams({
    per: 1000,
    page,
    observed_after: startDatetime,
    observed_before: endDatetime,
    t: Date.now()
    });
    const result = await fetch(`https://api.avalanche.state.co.us/api/avalanche_observations?${queryArgs}`, { headers });
    return await result.json();
},

There’s a V2 of the avalanche_observations endpoint that we should switch to:

https://api.avalanche.state.co.us/api/v2/avalanche_observations?

A field reports example API call:

https://api.avalanche.state.co.us/api/v2/observation_reports?page=1&per=250&r[observed_at_gteq]=2023-05-14T06%3A00%3A00.000Z&r[observed_at_lteq]=2023-05-22T05%3A59%3A59.999Z&r[sorts][]=observed_at+desc&r[sorts][]=created_at+desc
https://api.avalanche.state.co.us/api/v2/observation_reports?page=1&per=250&r[backcountry_zone_title_in][]=Front+Range&r[snowpack_observations_cracking_in][]=Minor&r[snowpack_observations_collapsing_in][]=Rumbling&r[observed_at_gteq]=2023-05-14T06:00:00.000Z&r[observed_at_lteq]=2023-05-22T05:59:59.999Z&r[sorts][]=observed_at+desc&r[sorts][]=created_at+desc
https://api.avalanche.state.co.us/api/v2/observation_reports?page=1&per=250&r[observed_at_gteq]=2023-05-14T06:00:00.000Z&r[observed_at_lteq]=2023-05-22T05:59:59.999Z&r[saw_avalanche_eq]=true&r[sorts][]=observed_at%20desc&r[sorts][]=created_at%20desc

A forecast API call - must use the proxy for these - the avid API is behind auth:

https://avalanche.state.co.us/api-proxy/avid?_api_proxy_uri=/products/all?datetime=2023-01-22T12:00:00.000Z&includeExpired=true

Weather dispatches API call - also a different domain:

https://m.avalanche.state.co.us/api/dispatches/current?type=zone-weather-forecast

Example weather plot download:

https://classic.avalanche.state.co.us/caic/obs_stns/hplot.php?title=VailResort%20CAVMM%20(10303%20ft)%20-%20Vail%20&%20Summit%20County&st=CAVMM&date=2023-05-22-06

Example Wind Rose download:

https://classic.avalanche.state.co.us/caic/obs_stns/windrose.php?st=UP396&date=2023-01-12+17&elev=6325&unit=e&area=caic

Example Weather Station Tables - would require webpage scraping, but may be helpful:

https://classic.avalanche.state.co.us/caic/obs_stns/zones.php?date=2023-05-25+17&stnlink=hourly&unit=e&flag=on&area=caic&span=6
class caic_python.client.CaicApiEndpoints#

Bases: object

Endpoints for the CAIC API (api.avalanche.state.co.us).

AVY_OBS: str = '/api/v2/avalanche_observations'#
OBS_REPORT: str = '/api/v2/observation_reports'#
SNOWPACK_OBS: str = '/api/v2/snowpack_observations'#
V1_AVY_OBS: str = '/api/avalanche_observations'#
WEATHER_OBS: str = '/api/v2/weather_observations'#
ZONES: str = '/api/v2/zones'#
ZONES_MAP: str = '/api/v2/zones/map'#
class caic_python.client.CaicClient#

Bases: object

An async HTTP client for the CAIC API(s).

async avy_forecast(date: str) list[AvalancheForecast | RegionalDiscussionForecast]#

Get the avalanche forecasts as they were on the given date.

Forecasts cover the date given + the following two days.

Parameters#

datestr

The date that the avalanche forecast was produced for.

Returns#

list[models.AvalancheForecast | models.RegionalDiscussionForecast]

A list of returned forecasts. The list should contain two types. The localized forecast for detailed areas of CO, and the regional discussion pieces that cover broader portions of the state.

async avy_obs(start: str, end: str, page_limit: int = 1000, ver1: bool = False) list[AvalancheObservation]#

Query for avalanche observations on the CAIC website.

Supports both the v1 and v2 APIs. FWIW, the website still uses v1 for this particular endpoint. My guess is because it supports proper pagination unlike v2, which supports pagination but does not return pagination info in response objects so clients have to guess when they’re done paging.

start and end arguments should be in this format - YYYY-MM-DD HH:mm:ss. However, the return of a datetime.datetime.isoformat() call works as well.

Parameters#

startstr

Query for avalanches observed after at this day (and time).

endstr

Query for avalanches observed before this day (and time).

page_limitint, optional

Limit per page results to this amount, by default 1000.

ver1bool, optional

Use the v1 endpoint instead, not recommended, by default False.

Returns#

list[models.AvalancheObservation]

A list of all avalanche observations returned by the query.

async avy_observation(obs_id: str) AvalancheObservation | None#

Get a single avalanche observation by UUID.

Parameters#

obs_idstr

The UUID of the avalanche observation.

Returns#

models.AvalancheObservation | None

The retrieved avalanche observation, or None if there was an error validating response.

async bc_zone(zone_slug: str) BackcountryZone | None#

Get a single backcountry zone by UUID.

Parameters#

zone_slugstr

The zone’s slug name.

Returns#

models.BackcountryZone | None

The backcountry zone, or None if there was an error validating response.

async close() None#

Close the underlying session.

async field_report(report_id: str) FieldReport | None#

Get a single CAIC Feild Report (aka Observation Report) by UUID.

Parameters#

report_idstr

The UUID of the field report to retrieve.

Returns#

models.FieldReport | None

The retrieved field report, or None if there was an error validating response.

async field_reports(start: str, end: str, bc_zones: list[str] = [], cracking_obs: list[str] = [], collapsing_obs: list[str] = [], query: str = '', avy_seen: bool | None = None, page_limit: int = 100) list[FieldReport]#

Search CAIC field reports.

Replicates the search on the CAIC View Field Reports page.

Parameters#

startstr

The start time for the query (observations after this date[+time]).

endstr

The end time for the query (observations before this date[+time]).

bc_zoneslist[str], optional

One or more Backcountry Zones to limit the search results by. Should be one of enums.BCZoneTitles. By default [].

cracking_obslist[str], optional

One or more Cracking Observations to limit the search results by. Should be one of enums.CrackingObsNames. By default [].

collapsing_obslist[str], optional

One or more Collapsing Observations to limit the search results by. Should be one of enums.CollapsingObsNames. By default [].

querystr, optional

A query string to limit searches by, by default “”.

avy_seenbool | None, optional

Whether an avalanche was seen, or None to disable this search modifier, by default None.

page_limitint, optional

Limit the number of pages returned by the API. Must be at least 1 or a value error is raised. By default 100.

Returns#

list[models.FieldReport]

All field reports returned by the search.

Raises#

ValueError

If page_limit is less than 1.

async highway_zone(zone_slug: str) HighwayZone | None#

Get a single highway zone by UUID.

Parameters#

zone_slugstr

The zone’s slug name.

Returns#

models.HighwayZone | None

The highway zone, or None if there was an error validating response.

async snowpack_observation(obs_id: str) SnowpackObservation | None#

Get a single snowpack observation by UUID.

Parameters#

obs_idstr

The ID of the snowpack observation.

Returns#

models.SnowpackObservation | None

The retrieved snowpack observation, or None if there was an error validating response.

async weather_observation(obs_id: str) WeatherObservation | None#

Get a single weather observation by UUID.

Parameters#

obs_idstr

The UUID of the weather observation.

Returns#

models.WeatherObservation | None

The retrieved weather observation, or None if there was an error validating response.

class caic_python.client.CaicURLs#

Bases: object

All the different CAIC URLs that the client needs.

With the exception of the attr for the “home” site’s URL, the other class attrs are named after their subdomain.

API: str = 'https://api.avalanche.state.co.us'#
CLSC: str = 'https://classic.avalanche.state.co.us'#
HOME: str = 'https://avalanche.state.co.us'#
M: str = 'https://m.avalanche.state.co.us'#
class caic_python.client.ProxyEndpoints#

Bases: object

The known CAIC proxy URLs.

Some underlying APIs (eg. avid) require auth, and this proxy auths for you.

AVID: str = '/api-proxy/avid'#
DATA: str = '/api-proxy/caic_data_api'#
class caic_python.client.SyncCaicClient#

Bases: object

A syncronous HTTP client for the CAIC API(s).

avy_forecast(date: str) list[AvalancheForecast | RegionalDiscussionForecast]#

Get the avalanche forecasts as they were on the given date.

Forecasts cover the date given + the following two days.

Parameters#

datestr

The date that the avalanche forecast was produced for.

Returns#

list[models.AvalancheForecast | models.RegionalDiscussionForecast]

A list of returned forecasts. The list should contain two types. The localized forecast for detailed areas of CO, and the regional discussion pieces that cover broader portions of the state.

avy_obs(start: str, end: str, page_limit: int = 1000, ver1: bool = False) list[AvalancheObservation]#

Query for avalanche observations on the CAIC website.

Supports both the v1 and v2 APIs. FWIW, the website still uses v1 for this particular endpoint. My guess is because it supports proper pagination unlike v2, which supports pagination but does not return pagination info in response objects so clients have to guess when they’re done paging.

start and end arguments should be in this format - YYYY-MM-DD HH:mm:ss. However, the return of a datetime.datetime.isoformat() call works as well.

Parameters#

startstr

Query for avalanches observed after at this day (and time).

endstr

Query for avalanches observed before this day (and time).

page_limitint, optional

Limit per page results to this amount, by default 1000.

ver1bool, optional

Use the v1 endpoint instead, not recommended, by default False.

Returns#

list[models.AvalancheObservation]

A list of all avalanche observations returned by the query.

avy_observation(obs_id: str) AvalancheObservation | None#

Get a single avalanche observation by UUID.

Parameters#

obs_idstr

The UUID of the avalanche observation.

Returns#

models.AvalancheObservation | None

The retrieved avalanche observation, or None if there was an error validating response.

bc_zone(zone_slug: str) BackcountryZone | None#

Get a single backcountry zone by UUID.

Parameters#

zone_slugstr

The zone’s slug name.

Returns#

models.BackcountryZone | None

The backcountry zone, or None if there was an error validating response.

close() None#

Close the underlying session.

field_report(report_id: str) FieldReport | None#

Get a single CAIC Feild Report (aka Observation Report) by UUID.

Parameters#

report_idstr

The UUID of the field report to retrieve.

Returns#

models.FieldReport | None

The retrieved field report, or None if there was an error validating response.

field_reports(start: str, end: str, bc_zones: list[str] = [], cracking_obs: list[str] = [], collapsing_obs: list[str] = [], query: str = '', avy_seen: bool | None = None, page_limit: int = 100) list[FieldReport]#

Search CAIC field reports.

Replicates the search on the CAIC View Field Reports page.

Parameters#

startstr

The start time for the query (observations after this date[+time]).

endstr

The end time for the query (observations before this date[+time]).

bc_zoneslist[str], optional

One or more Backcountry Zones to limit the search results by. Should be one of enums.BCZoneTitles. By default [].

cracking_obslist[str], optional

One or more Cracking Observations to limit the search results by. Should be one of enums.CrackingObsNames. By default [].

collapsing_obslist[str], optional

One or more Collapsing Observations to limit the search results by. Should be one of enums.CollapsingObsNames. By default [].

querystr, optional

A query string to limit searches by, by default “”.

avy_seenbool | None, optional

Whether an avalanche was seen, or None to disable this search modifier, by default None.

page_limitint, optional

Limit the number of pages returned by the API. Must be at least 1 or a value error is raised. By default 100.

Returns#

list[models.FieldReport]

All field reports returned by the search.

Raises#

ValueError

If page_limit is less than 1.

highway_zone(zone_slug: str) HighwayZone | None#

Get a single highway zone by UUID.

Parameters#

zone_slugstr

The zone’s slug name.

Returns#

models.HighwayZone | None

The highway zone, or None if there was an error validating response.

snowpack_observation(obs_id: str) SnowpackObservation | None#

Get a single snowpack observation by UUID.

Parameters#

obs_idstr

The ID of the snowpack observation.

Returns#

models.SnowpackObservation | None

The retrieved snowpack observation, or None if there was an error validating response.

weather_observation(obs_id: str) WeatherObservation | None#

Get a single weather observation by UUID.

Parameters#

obs_idstr

The UUID of the weather observation.

Returns#

models.WeatherObservation | None

The retrieved weather observation, or None if there was an error validating response.

caic_python.client.list_to_plus_args(argslist: list) str#

Join a list of strings using +.

caic_python.definitions module#

Mappings of abbreviations to definitions/long-names.

See more on the CAIC website

caic_python.definitions.ASPECT_DESC = {'ALL': 'All aspects', 'All': 'All aspects', 'E': 'East', 'N': 'North', 'NE': 'Northeast', 'NW': 'Northwest', 'S': 'South', 'SE': 'Southeast', 'SW': 'Southwest', 'U': 'Unknown', 'UNK': 'Unknown', 'W': 'West'}#

The codes for types of avalanche triggers mapped to their descriptive names.

caic_python.definitions.AVALANCHE_TYPES = {'C': 'Cornice Fall', 'G': 'Glide', 'HS': 'Hard Slab', 'I': 'Ice Fall', 'L': 'Loose', 'R': 'Roof', 'SF': 'Slush Flow', 'SS': 'Soft Slab', 'U': 'Unknown', 'WL': 'Wet Loose', 'WS': 'Wet Slab'}#

The codes for types of avalanches mapped to their descriptive names.

caic_python.definitions.D_SIZE_DESC = {'D1': 'Relatively harmless to people', 'D1.5': 'Relatively harmless to people ', 'D2': 'Could bury, injure, or kill a person', 'D2.5': 'Could bury, injure, or kill a person', 'D3': 'Could bury and destroy a car, damage a truck, destroy a wood frame house, or break a few trees', 'D3.5': 'Could bury and destroy a car, damage a truck, destroy a wood frame house, or break a few trees', 'D4': 'Could destroy a railway car, large truck, several buildings, or a substantial amount of trees', 'D4.5': 'Could destroy a railway car, large truck, several buildings, or a substantial amount of trees', 'D5': 'Could gouge the landscape, largest snow avalanche known', 'U': 'Unknown', 'UNK': 'Unknown'}#

The codes for avalanche D size mapped to their descriptive names.

caic_python.definitions.ELEV_DESC = {'<TL': 'Below treeline', '>TL': 'Above Treeline', 'TL': 'Near Treeline'}#

The codes for elevation bands mapped to their descriptive names.

The API returns the < and > URL encoded - so this object isn’t useful for comparing to API responses.

caic_python.definitions.PRIMARY_TRIGGER_DESC = {'A': 'Unknown', 'AA': 'Artillery', 'AB': 'An explosive detonated above the surface (air blast)', 'AC': 'Cornice fall triggered by explosive action', 'AE': 'An explosive thrown or placed on or under the snow surface by hand', 'AF': 'Foot penetration', 'AH': 'Explosive placed via helicopter', 'AI': 'Snowshoer', 'AK': 'Snowcat', 'AL': 'Avalauncher', 'AM': 'Snowmobile', 'AO': 'Unclassified artificial trigger (Specified in comments)', 'AP': 'Pre-placed, remotely detonated explosive charge', 'AR': 'Snowboarder', 'AS': 'Skier', 'AU': 'Unknown artificial trigger', 'AV': 'Vehicle (Specified in comments)', 'AW': 'Wildlife', 'AX': 'Gas exploder', 'N': 'Natural', 'UKN': 'Unknown'}#

The codes for types of primary avalanche triggers mapped to their descriptive names.

caic_python.definitions.R_SIZE_DESC = {'R1': 'Very small, relative to the path', 'R2': 'Small, relative to the path', 'R3': 'Medium, relative to the path', 'R4': 'Large, relative to the path', 'R5': 'Major or maximum, relative to path', 'U': 'Unknown', 'UNK': 'Unknown'}#

The codes for avalanche R size mapped to their descriptive names.

caic_python.definitions.SECONDARY_TRIGGER_DESC = {'c': 'A controlled or intentional release', 'r': 'A remote avalanche released by the indicated trigger', 'u': 'An unintentional release', 'y': 'An avalanche released in sympathy with another avalanche'}#

The codes for types of secondary avalanche triggers mapped to their descriptive names.

caic_python.enums module#

Shared enums for typing/validation.

The CAIC API can return multiple values when the particular code is not known. It is up to callers to normalize these values. They can be any of the following:

U
Un
Unknown
Unkn
UNKNOWN
UNK
---
--
class caic_python.enums.Aspect(value)#

Bases: Enum

Slope aspect values.

ALL: str = 'ALL'#
All: str = 'All'#
DASHES2: str = '--'#
DASHES3: str = '---'#
E: str = 'E'#
N: str = 'N'#
NE: str = 'NE'#
NW: str = 'NW'#
S: str = 'S'#
SE: str = 'SE'#
SW: str = 'SW'#
U: str = 'U'#
UNK: str = 'UNK'#
UNKNOWN: str = 'UNKNOWN'#
Un: str = 'Un'#
Unkn: str = 'Unkn'#
Unknown: str = 'Unknown'#
W: str = 'W'#
class caic_python.enums.BCZoneTitles(value)#

Bases: Enum

Titles for backcountry zones.

ASPEN = 'Aspen'#
FRONT_RANGE = 'Front Range'#
GRAND_MESA = 'Grand Mesa'#
GUNNINSON = 'Gunnison'#
N_SAN_JAUN = 'Northern San Juan'#
SANGRE = 'Sangre de Cristo'#
SAWATCH = 'Sawatch'#
STEAMBOAT = 'Steamboat & Flat Tops'#
S_SAN_JAUN = 'Southern San Juan'#
VAIL_SUMMIT = 'Vail & Summit County'#
class caic_python.enums.DSize(value)#

Bases: Enum

Avalanche desctructive size values.

Because these can have half values, P is a substitute for decimals.

D1: str = 'D1'#
D1P5: str = 'D1.5'#
D2: str = 'D2'#
D2P5: str = 'D2.5'#
D3: str = 'D3'#
D3P5: str = 'D3.5'#
D4: str = 'D4'#
D4P5: str = 'D4.5'#
D5: str = 'D5'#
DASHES2: str = '--'#
DASHES3: str = '---'#
U: str = 'U'#
UNK: str = 'UNK'#
UNKNOWN: str = 'UNKNOWN'#
Un: str = 'Un'#
Unkn: str = 'Unkn'#
Unknown: str = 'Unknown'#
class caic_python.enums.DetailsTypes(value)#

Bases: Enum

The types of details objects from Field Reports.

AVY = 'avalanche_detail'#
SNOW = 'snowpack_detail'#
WEATHER = 'weather_detail'#
class caic_python.enums.ObsTypes(value)#

Bases: Enum

The types that CAIC observation objects can have.

AVY_OBS: str = 'avalanche_observation'#
BC_ZONE: str = 'backcountry_zone'#
HWY_ZONE: str = 'highway_zone'#
IMAGE_ASSET: str = 'image_asset'#
OBS_REPORT: str = 'observation_report'#
REPORT_OBS: str = 'report_observation'#
SNOWPACK_OBS: str = 'snowpack_observation'#
SNOWPIT_ASSET: str = 'snowpit_asset'#
VIDEO_ASSET: str = 'video_asset'#
WEATHER_OBS: str = 'weather_observation'#
class caic_python.enums.PrimaryTrigger(value)#

Bases: Enum

Avalanche primary trigger codes.

A: str = 'A'#
AA: str = 'AA'#
AB: str = 'AB'#
AC: str = 'AC'#
AE: str = 'AE'#
AF: str = 'AF'#
AH: str = 'AH'#
AI: str = 'AI'#
AK: str = 'AK'#
AL: str = 'AL'#
AM: str = 'AM'#
AN: str = 'AN'#
AO: str = 'AO'#
AP: str = 'AP'#
AR: str = 'AR'#
AS: str = 'AS'#
AU: str = 'AU'#
AV: str = 'AV'#
AW: str = 'AW'#
AX: str = 'AX'#
DASHES2: str = '--'#
DASHES3: str = '---'#
N: str = 'N'#
U: str = 'U'#
UKN: str = 'UKN'#
UNKNOWN: str = 'UNKNOWN'#
Un: str = 'Un'#
Unkn: str = 'Unkn'#
Unknown: str = 'Unknown'#
class caic_python.enums.RSize(value)#

Bases: Enum

Avalanche relative size values.

DASHES2: str = '--'#
DASHES3: str = '---'#
R1: str = 'R1'#
R2: str = 'R2'#
R3: str = 'R3'#
R4: str = 'R4'#
R5: str = 'R5'#
U: str = 'U'#
UNK: str = 'UNK'#
UNKNOWN: str = 'UNKNOWN'#
Un: str = 'Un'#
Unkn: str = 'Unkn'#
Unknown: str = 'Unknown'#
class caic_python.enums.ReportsSearchAvyObs(value)#

Bases: Enum

Avalanche observation options in a Field Reports search.

CAUGHT = 'Caught'#
SAW = 'Saw'#
TRIGGERED = 'Triggered'#
class caic_python.enums.ReportsSearchCollapseObs(value)#

Bases: Enum

Collapsing observation options in a Field Reports search.

MINOR = 'Minor'#
MODERATE = 'Moderate'#
NONE = 'None'#
RUMBLING = 'Rumbling'#
UNKNOWN = 'Unknown'#
class caic_python.enums.ReportsSearchCrackObs(value)#

Bases: Enum

Cracking observation options in a Field Reports search.

MINOR = 'Minor'#
MODERATE = 'Moderate'#
NONE = 'None'#
SHOOTING = 'Shooting'#
UNKNOWN = 'Unknown'#
class caic_python.enums.SecondaryTrigger(value)#

Bases: Enum

Avalanche secondary trigger codes.

DASHES2: str = '--'#
DASHES3: str = '---'#
U: str = 'U'#
UNK: str = 'UNK'#
UNKNOWN: str = 'UNKNOWN'#
Un: str = 'Un'#
Unkn: str = 'Unkn'#
Unknown: str = 'Unknown'#
c: str = 'c'#
r: str = 'r'#
u: str = 'u'#
y: str = 'y'#
class caic_python.enums.TypeCode(value)#

Bases: Enum

Avalanche type codes.

C: str = 'C'#
DASHES2: str = '--'#
DASHES3: str = '---'#
G: str = 'G'#
HS: str = 'HS'#
I: str = 'I'#
L: str = 'L'#
R: str = 'R'#
SF: str = 'SF'#
SS: str = 'SS'#
U: str = 'U'#
UNK: str = 'UNK'#
UNKNOWN: str = 'UNKNOWN'#
Un: str = 'Un'#
Unkn: str = 'Unkn'#
Unknown: str = 'Unknown'#
WL: str = 'WL'#
WS: str = 'WS'#

caic_python.errors module#

caic-python errors.

exception caic_python.errors.CaicRequestException#

Bases: Exception

An exception that ocurred during a request to the CAIC website.

caic_python.models module#

Pydantic models used by caic-python.

class caic_python.models.AvalancheDetail(*, id: str, type: DetailsTypes, description: str | None = None, classic_id: int | None = None)#

Bases: DetailObject

Summary details of an observed avalanche.

model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class caic_python.models.AvalancheForecast(*, id: str, title: str, type: Literal['avalancheforecast'], polygons: list, areaId: str, forecaster: str, issueDateTime: datetime, expiryDateTime: datetime, weatherSummary: ForecastSummary, snowpackSummary: ForecastSummary, avalancheSummary: ForecastSummary, avalancheProblems: AvalancheProblems, terrainAndTravelAdvice: dict, confidence: ForecastConfidences, communication: ForecastComms, dangerRatings: DangerRatings, media: ForecastMedia)#

Bases: BaseModel

A CAIC avalanche forecast.

areaId: str#
avalancheProblems: AvalancheProblems#
avalancheSummary: ForecastSummary#
communication: ForecastComms#
confidence: ForecastConfidences#
dangerRatings: DangerRatings#
expiryDateTime: datetime#
forecaster: str#
id: str#
issueDateTime: datetime#
media: ForecastMedia#
model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

polygons: list#
snowpackSummary: ForecastSummary#
terrainAndTravelAdvice: dict#
title: str#
type: Literal['avalancheforecast']#
weatherSummary: ForecastSummary#
class caic_python.models.AvalancheObservation(*, id: str, type: str | None = None, backcountry_zone_id: str | None = None, backcountry_zone: BackcountryZone | None = None, highway_zone_id: str | None = None, observed_at: datetime | None = None, created_at: datetime | None = None, updated_at: datetime | None = None, latitude: float | None = None, longitude: float | None = None, classic_id: int | None = None, classic_observation_report_id: int | None = None, classic_observation_report_url: str | None = None, observation_report_status: str | None = None, observation_report_url: str | None = None, comments: str | None = None, location: str | None = None, lastname: str | None = None, full_name: str | None = None, date_known: str | None = None, time_known: str | None = None, op_name: str | None = None, is_locked: bool | None = None, number: int | None = None, hw_op_bc: str | None = None, path: str | None = None, landmark: str | None = None, type_code: TypeCode | None = None, problem_type: str | None = None, aspect: Aspect | None = None, elevation: str | None = None, relative_size: RSize | None = None, destructive_size: DSize | None = None, primary_trigger: PrimaryTrigger | None = None, secondary_trigger: SecondaryTrigger | None = None, is_incident: bool | None = None, area: str | None = None, angle_average: float | None = None, angle_maximum: float | None = None, elevation_feet: int | None = None, surface: str | None = None, weak_layer: str | None = None, grain_type: str | None = None, crown_average: float | None = None, crown_maximum: float | None = None, crown_units: str | None = None, width_average: float | None = None, width_maximum: float | None = None, width_units: str | None = None, vertical_average: float | None = None, vertical_maximum: float | None = None, vertical_units: str | None = None, terminus: str | None = None, road_status: str | None = None, road_depth: float | None = None, road_units: str | None = None, road_depth_units: str | None = None, road_length: int | float | None = None, road_length_units: str | None = None, observation_report: ObsReport | None = None, avalanche_detail: AvalancheDetail | None = None)#

Bases: BaseModel

A single avalanche observation from the CAIC website.

angle_average: float | None#
angle_maximum: float | None#
area: str | None#
aspect: Aspect | None#
avalanche_detail: AvalancheDetail | None#
backcountry_zone: BackcountryZone | None#
backcountry_zone_id: str | None#
classic_id: int | None#
classic_observation_report_id: int | None#
classic_observation_report_url: str | None#
comments: str | None#
created_at: datetime | None#
crown_average: float | None#
crown_maximum: float | None#
crown_units: str | None#
date_known: str | None#
destructive_size: DSize | None#
elevation: str | None#
elevation_feet: int | None#
async fieldobs(caic_client) FieldReport | None#

Get the associated FieldReport using the provided CaicClient.

full_name: str | None#
grain_type: str | None#
highway_zone_id: str | None#
hw_op_bc: str | None#
id: str#
is_incident: bool | None#
is_locked: bool | None#
landmark: str | None#
lastname: str | None#
latitude: float | None#
location: str | None#
longitude: float | None#
model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

number: int | None#
observation_report: ObsReport | None#
observation_report_status: str | None#
observation_report_url: str | None#
observed_at: datetime | None#
op_name: str | None#
path: str | None#
primary_trigger: PrimaryTrigger | None#
problem_type: str | None#
relative_size: RSize | None#
road_depth: float | None#
road_depth_units: str | None#
road_length: int | float | None#
road_length_units: str | None#
road_status: str | None#
road_units: str | None#
secondary_trigger: SecondaryTrigger | None#
surface: str | None#
terminus: str | None#
time_known: str | None#
type: str | None#
type_code: TypeCode | None#
updated_at: datetime | None#
vertical_average: float | None#
vertical_maximum: float | None#
vertical_units: str | None#
weak_layer: str | None#
width_average: float | None#
width_maximum: float | None#
width_units: str | None#
class caic_python.models.AvalancheProblem(*, type: str, aspectElevations: list[str], likelihood: str, expectedSize: ExpectedSize, comment: str)#

Bases: BaseModel

A described avalanche problem in a forecast.

TODO - enums here for everything

aspectElevations: list[str]#
comment: str#
expectedSize: ExpectedSize#
likelihood: str#
model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

type: str#
class caic_python.models.AvalancheProblems(*, days: list[list[AvalancheProblem]])#

Bases: BaseModel

A collection of the next few days’ avalanche problems.

days: list[list[AvalancheProblem]]#
model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class caic_python.models.BackcountryZone(*, id: str, type: ObsTypes, parent_id: str | None = None, slug: str | None = None, title: str | None = None, category: str | None = None, category_order: int | None = None, is_root: bool | None = None, is_leaf: bool | None = None, tree_level: int | None = None, parent_url: str | None = None, created_at: datetime | None = None, updated_at: datetime | None = None, url: str | None = None, geojson_url: str | None = None)#

Bases: BaseModel

A backcountry_zone object - these are in most responses.

category: str | None#
category_order: int | None#
created_at: datetime | None#
geojson_url: str | None#
id: str#
is_leaf: bool | None#
is_root: bool | None#
model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

parent_id: str | None#
parent_url: str | None#
slug: str | None#
title: str | None#
tree_level: int | None#
type: ObsTypes#
updated_at: datetime | None#
url: str | None#

Bases: BaseModel

The links portion of a V1AvyResponse.

Contains pagination info.

first: str | None#
last: str | None#
model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

next: str | None#
prev: str | None#
class caic_python.models.CaicResponseMeta(*, current_page: int, page_items: int, total_pages: int, total_count: int)#

Bases: BaseModel

The meta portion of a V1AvyResponse.

Contains pagination info.

current_page: int#
model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

page_items: int#
total_count: int#
total_pages: int#
class caic_python.models.Creator(*, id: str, type: str)#

Bases: BaseModel

The creator object of a field report.

We’ll want to track this, but it is sparse on details.

id: str#
model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

type: str#
class caic_python.models.DangerRating(*, position: int, alp: str, tln: str, btl: str, date: datetime)#

Bases: BaseModel

An avalanche forecast’s danger rating.

TODO - enums for everything here.

alp: str#
btl: str#
date: datetime#
model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

position: int#
tln: str#
class caic_python.models.DangerRatings(*, days: list[DangerRating])#

Bases: BaseModel

A list of the avalanche danger ratings for the next few days.

days: list[DangerRating]#
model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class caic_python.models.DetailObject(*, id: str, type: DetailsTypes, description: str | None = None, classic_id: int | None = None)#

Bases: BaseModel

A base for several, similar, details objects attached to a field report.

This is where classic_id ended up in the V2 API.

classic_id: int | None#
description: str | None#
id: str#
model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

type: DetailsTypes#
class caic_python.models.ExpectedSize(*, min: str, max: str)#

Bases: BaseModel

Expected avalanche size in an avalanche forecast.

max: str#
min: str#
model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class caic_python.models.FieldReport(*, id: str, type: ~caic_python.enums.ObsTypes, backcountry_zone: ~caic_python.models.BackcountryZone | None = None, url: str | None = None, creator: ~caic_python.models.Creator | None = None, avalanche_observations_count: int | None = None, avalanche_observations: list[~caic_python.models.AvalancheObservation] | None = <factory>, avalanche_detail: ~caic_python.models.AvalancheDetail | None = None, weather_observations_count: int | None = None, weather_observations: list[~caic_python.models.WeatherObservation] | None = <factory>, weather_detail: ~caic_python.models.WeatherDetail | None = None, snowpack_observations_count: int | None = None, snowpack_observations: list[~caic_python.models.SnowpackObservation] | None = <factory>, assets_count: int | None = None, assets: list[~caic_python.models.ObservationAsset] | None = <factory>, highway_zone_id: str | None = None, observed_at: ~datetime.datetime | None = None, snowpack_detail: ~caic_python.models.SnowpackDetail | None = None, observation_form: str | None = None, is_anonymous: bool | None = None, firstname: str | None = None, lastname: str | None = None, full_name: str | None = None, organization: str | None = None, status: str | None = None, date_known: str | None = None, time_known: str | None = None, hw_op_bc: str | None = None, area: str | None = None, route: str | None = None, is_locked: bool | None = None, objective: str | None = None, saw_avalanche: bool | None = None, triggered_avalanche: bool | None = None, caught_in_avalanche: bool | None = None, state: str | None = None, landmark: str | None = None, description: str | None = None, created_at: ~datetime.datetime | None = None, updated_at: ~datetime.datetime | None = None, is_anonymous_location: bool | None = None, latitude: float | None = None, longitude: float | None = None)#

Bases: BaseModel

A field (or observation) report.

area: str | None#
assets: list[ObservationAsset] | None#
assets_count: int | None#
avalanche_detail: AvalancheDetail | None#
avalanche_observations: list[AvalancheObservation] | None#
avalanche_observations_count: int | None#
backcountry_zone: BackcountryZone | None#
caught_in_avalanche: bool | None#
created_at: datetime | None#
creator: Creator | None#
date_known: str | None#
description: str | None#
firstname: str | None#
full_name: str | None#
highway_zone_id: str | None#
hw_op_bc: str | None#
id: str#
is_anonymous: bool | None#
is_anonymous_location: bool | None#
is_locked: bool | None#
landmark: str | None#
lastname: str | None#
latitude: float | None#
longitude: float | None#
model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

objective: str | None#
observation_form: str | None#
observed_at: datetime | None#
organization: str | None#
route: str | None#
saw_avalanche: bool | None#
snowpack_detail: SnowpackDetail | None#
snowpack_observations: list[SnowpackObservation] | None#
snowpack_observations_count: int | None#
state: str | None#
status: str | None#
time_known: str | None#
triggered_avalanche: bool | None#
type: ObsTypes#
updated_at: datetime | None#
url: str | None#
weather_detail: WeatherDetail | None#
weather_observations: list[WeatherObservation] | None#
weather_observations_count: int | None#
class caic_python.models.ForecastComms(*, headline: str, sms: str)#

Bases: BaseModel

Special forecast communications - not sure how this get’s used yet.

headline: str#
model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

sms: str#
class caic_python.models.ForecastConfidence(*, date: ~datetime.datetime, rating: str, statements: list[str] = <factory>)#

Bases: BaseModel

An avalanche forecast’s confidence details.

date: datetime#
model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

rating: str#
statements: list[str]#
class caic_python.models.ForecastConfidences(*, days: list[ForecastConfidence])#

Bases: BaseModel

The avalanche forecast confidence details for the next few days.

days: list[ForecastConfidence]#
model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class caic_python.models.ForecastImage(*, id: str, url: str, width: int, height: int, credit: str, caption: str, tag: str)#

Bases: BaseModel

An image attached to an avalanche forecast.

caption: str#
credit: str#
height: int#
id: str#
model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

tag: str#
url: str#
width: int#
class caic_python.models.ForecastMedia(*, Images: list[ForecastImage])#

Bases: BaseModel

All of the images attached to an avalanche forecast.

Images: list[ForecastImage]#
model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class caic_python.models.ForecastSummary(*, days: list[ForecastSummaryDay])#

Bases: BaseModel

Forecast summaries for several days - base for several forecast types.

days: list[ForecastSummaryDay]#
model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class caic_python.models.ForecastSummaryDay(*, date: datetime | None, content: str | None)#

Bases: BaseModel

An individual day’s forecast summary - base for several forecast types.

content: str | None#
date: datetime | None#
model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class caic_python.models.HighwayZone(*, id: str | None = None, type: str | None = None, parent_id: str | None = None, slug: str | None = None, title: str | None = None, category: str | None = None, category_order: int | None = None, is_root: bool | None = None, is_leaf: bool | None = None, tree_level: int | None = None, parent_url: str | None = None, children_urls: list[str] | None = <factory>, created_at: ~datetime.datetime | None = None, updated_at: ~datetime.datetime | None = None, url: str | None = None, geojson_url: str | None = None)#

Bases: BaseModel

A highway avalanche zone - similar to a BC zone but specific to CDOT/CAIC avy control.

category: str | None#
category_order: int | None#
children_urls: list[str] | None#
created_at: datetime | None#
geojson_url: str | None#
id: str | None#
is_leaf: bool | None#
is_root: bool | None#
model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

parent_id: str | None#
parent_url: str | None#
slug: str | None#
title: str | None#
tree_level: int | None#
type: str | None#
updated_at: datetime | None#
url: str | None#
class caic_python.models.ObsReport(*, id: str | None = None, status: str | None = None, is_locked: bool | None = None, is_anonymous: bool | None = None, url: str | None = None)#

Bases: BaseModel

Really a pared down FieldReport.

id: str | None#
is_anonymous: bool | None#
is_locked: bool | None#
model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

status: str | None#
url: str | None#
class caic_python.models.ObservationAsset(*, id: str, type: ~caic_python.enums.ObsTypes, status: str | None = None, caption: str | None = None, tags: list[str] | None = <factory>, is_redacted: bool | None = None, is_locked: bool | None = None, is_avalanche: bool | None = None, location_context: str | None = None, full_url: str | None = None, reduced_url: str | None = None, thumb_url: str | None = None, external_url: str | None = None, created_at: ~datetime.datetime | None = None, updated_at: ~datetime.datetime | None = None)#

Bases: BaseModel

An asset (image/video) attached to a field report.

caption: str | None#
created_at: datetime | None#
external_url: str | None#
full_url: str | None#
id: str#
is_avalanche: bool | None#
is_locked: bool | None#
is_redacted: bool | None#
location_context: str | None#
model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

reduced_url: str | None#
status: str | None#
tags: list[str] | None#
thumb_url: str | None#
type: ObsTypes#
updated_at: datetime | None#
class caic_python.models.RegionalDiscussionForecast(*, id: str, title: str, type: str, polygons: list[str], areaId: str, forecaster: str, issueDateTime: datetime, expiryDateTime: datetime, message: str, communications: ForecastComms, media: ForecastMedia)#

Bases: BaseModel

An avalanche forecast discussion covering a regional area.

areaId: str#
communications: ForecastComms#
expiryDateTime: datetime#
forecaster: str#
id: str#
issueDateTime: datetime#
media: ForecastMedia#
message: str#
model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

polygons: list[str]#
title: str#
type: str#
class caic_python.models.SnowpackDetail(*, id: str, type: DetailsTypes, description: str | None = None, classic_id: int | None = None)#

Bases: DetailObject

Summary details of the observed snowpack.

model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class caic_python.models.SnowpackObservation(*, id: str, type: ObsTypes, backcountry_zone_id: str | None = None, backcountry_zone: BackcountryZone | None = None, highway_zone_id: str | None = None, observed_at: datetime | None = None, created_at: datetime | None = None, updated_at: datetime | None = None, latitude: float | None = None, longitude: float | None = None, comments: str | None = None, url: str | None = None, cracking: str | None = None, collapsing: str | None = None, weak_layers: str | None = None, rose: str | None = None)#

Bases: BaseModel

An observation about the snowpack in a field report.

backcountry_zone: BackcountryZone | None#
backcountry_zone_id: str | None#
collapsing: str | None#
comments: str | None#
cracking: str | None#
created_at: datetime | None#
highway_zone_id: str | None#
id: str#
latitude: float | None#
longitude: float | None#
model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

observed_at: datetime | None#
rose: str | None#
type: ObsTypes#
updated_at: datetime | None#
url: str | None#
weak_layers: str | None#
class caic_python.models.V1AvalancheObservation(*, id: str, type: ObsTypes, attributes: dict, relationships: dict)#

Bases: BaseModel

A single avalanche observation from the /api/avalanche_observations endpoint.

The /api/avalanche_observations endpoint returns a slightly different object than the v2 avalanche_observations endpoint.

This object allows us to transform to the standardized AvalancheObservation via to_obs.

attributes: dict#
id: str#
model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

relationships: dict#
to_obs() AvalancheObservation#

Convert this instance to an AvalancheObservation.

type: ObsTypes#
class caic_python.models.V1AvyResponse(*, meta: CaicResponseMeta, links: CaicResponseLinks, data: list[AvalancheObservation])#

Bases: BaseModel

A response from the CAIC API.

data: list[AvalancheObservation]#
meta: CaicResponseMeta#
model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class caic_python.models.WeatherDetail(*, id: str, type: DetailsTypes, description: str | None = None, classic_id: int | None = None)#

Bases: DetailObject

Summary details of the observed weather.

There is occasionally data here even when not in weather_observations for a field report.

model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class caic_python.models.WeatherObservation(*, id: str, type: ObsTypes, backcountry_zone_id: str | None = None, backcountry_zone: BackcountryZone | None = None, highway_zone_id: str | None = None, highway_zone: HighwayZone | None = None, observed_at: datetime | None = None, created_at: datetime | None = None, updated_at: datetime | None = None, latitude: float | None = None, longitude: float | None = None, classic_id: int | None = None, classic_observation_report_id: int | None = None, classic_observation_report_url: str | None = None, comments: str | None = None, url: str | None = None, location: str | None = None, temperature: int | float | None = None, temperature_maximum: int | float | None = None, temperature_minimum: int | float | None = None, temperature_units: str | None = None, temperature_at_negative_20cm: int | float | None = None, temperature_at_negative_20cm_units: str | None = None, relative_humidity: int | float | None = None, precipitation_rate: str | None = None, precipitation_type: str | None = None, sky_cover: str | None = None, height_of_snow: int | float | None = None, height_of_snow_units: str | None = None, height_of_new_snow_12_hours: int | float | None = None, height_of_new_snow_24_hours: int | float | None = None, height_of_new_snow_units: str | None = None, height_of_new_snow_water_equivalent_12_hours: int | float | None = None, height_of_new_snow_water_equivalent_24_hours: int | float | None = None, height_of_new_snow_water_equivalent_units: str | None = None, windspeed_ridgeline: int | float | str | None = None, wind_direction_ridgeline: str | None = None, windspeed: int | float | None = None, wind_direction: str | None = None, windspeed_units: str | None = None, maximum_gust_speed: int | float | str | None = None, maximum_gust_direction: str | None = None, maximum_gust_duration_seconds: int | float | str | None = None, blowing_snow: str | None = None, windloading: str | None = None, weather_detail: WeatherDetail | None = None)#

Bases: BaseModel

An observation about the weather in a field report.

backcountry_zone: BackcountryZone | None#
backcountry_zone_id: str | None#
blowing_snow: str | None#
classic_id: int | None#
classic_observation_report_id: int | None#
classic_observation_report_url: str | None#
comments: str | None#
created_at: datetime | None#
height_of_new_snow_12_hours: int | float | None#
height_of_new_snow_24_hours: int | float | None#
height_of_new_snow_units: str | None#
height_of_new_snow_water_equivalent_12_hours: int | float | None#
height_of_new_snow_water_equivalent_24_hours: int | float | None#
height_of_new_snow_water_equivalent_units: str | None#
height_of_snow: int | float | None#
height_of_snow_units: str | None#
highway_zone: HighwayZone | None#
highway_zone_id: str | None#
id: str#
latitude: float | None#
location: str | None#
longitude: float | None#
maximum_gust_direction: str | None#
maximum_gust_duration_seconds: int | float | str | None#
maximum_gust_speed: int | float | str | None#
model_config: ClassVar[ConfigDict] = {}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

observed_at: datetime | None#
precipitation_rate: str | None#
precipitation_type: str | None#
relative_humidity: int | float | None#
sky_cover: str | None#
temperature: int | float | None#
temperature_at_negative_20cm: int | float | None#
temperature_at_negative_20cm_units: str | None#
temperature_maximum: int | float | None#
temperature_minimum: int | float | None#
temperature_units: str | None#
type: ObsTypes#
updated_at: datetime | None#
url: str | None#
weather_detail: WeatherDetail | None#
wind_direction: str | None#
wind_direction_ridgeline: str | None#
windloading: str | None#
windspeed: int | float | None#
windspeed_ridgeline: int | float | str | None#
windspeed_units: str | None#

caic_python.utils module#

Helpful methods.

caic_python.utils.find_classic_id(report: FieldReport) int | None#

Find a classic ID from a given FieldReport.

Not every field report from the v2 API has an associated classic ID. It is nested in one of several possible child objects, which are not always present themselves. This method looks in all known locations of a FieldReport object for a classic ID. It first checks all *_details attrs, then checks each *Observation in all *_observations attrs. The first classic ID found is returned.

Parameters#

reportmodels.FieldReport

The FieldReport to search in.

Returns#

int | None

Returns the classic ID, or None if the FieldReport doesn’t have one.

Module contents#

The caic-python module.

Also defines __version__:

The current version of caic-python - set by make change-version.

Must map to pyproject.toml’s version. Using make change-version or scripts/change-version.py ensures this.

caic_python.LOGGER = <Logger caic_python (WARNING)>#

The logger used by caic-python, by default the level is logging.WARNING.

Callers may change the logging level by importing LOGGER.