---
title: Models
source: https://infrared.city/docs/sdk/1.0/python/models/
---

# Models

## Latitude  `module-attribute`

```python
Latitude = Annotated[float, Field(ge=-90, le=90)]
```

Latitude in degrees, from -90 to 90.

## Longitude  `module-attribute`

```python
Longitude = Annotated[float, Field(ge=-180, le=180)]
```

Longitude in degrees, from -180 to 180.

## DataList  `module-attribute`

```python
DataList = Annotated[list[float], Field(min_length=1)]
```

A non-empty list of floats.

## Hour  `module-attribute`

```python
Hour = Annotated[int, Field(ge=0, le=23)]
```

Hour of the day, 0 to 23.

## Month  `module-attribute`

```python
Month = Annotated[int, Field(ge=1, le=12)]
```

Month of the year, 1 to 12.

## Day  `module-attribute`

```python
Day = Annotated[int, Field(ge=1, le=31)]
```

Day of the month, 1 to 31.

## Payload

Bases: `BaseModel`

Base class of the SDK's request payloads.

A payload is immutable and validated on creation. Unknown fields are rejected, and surrounding whitespace in strings is stripped. Fields are serialized under their `kebab-case` aliases by default; the alias and the Python field name are both accepted on input.

### to_dict

```python
to_dict(*, by_alias: bool = True, exclude_none: bool = True) -> dict
```

Return the payload as a plain `dict`.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `by_alias` | `bool` | Use the wire (`kebab-case`) field names instead of the Python names. | `True` |
| `exclude_none` | `bool` | Leave out fields whose value is `None`. | `True` |

Returns:

| Type | Description |
| --- | --- |
| `dict` | The payload as built-in types. |

### to_json

```python
to_json(*, by_alias: bool = True, exclude_none: bool = True) -> str
```

Return the payload as a JSON string.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `by_alias` | `bool` | Use the wire (`kebab-case`) field names instead of the Python names. | `True` |
| `exclude_none` | `bool` | Leave out fields whose value is `None`. | `True` |

Returns:

| Type | Description |
| --- | --- |
| `str` | The payload as JSON. |

### to_gzip

```python
to_gzip()
```

Return the payload's JSON, UTF-8 encoded and gzip-compressed.

Returns:

| Type | Description |
| --- | --- |
| `bytes` | The compressed JSON of `to_json()`. |

## TimePeriod

Bases: `[Payload](#infrared_sdk.models.Payload)`

One analysis window, as the six integers the filter takes.

Warnings

A window is a date span with a daily hour range, not one continuous stretch of time: the hours the model counts. "1 March 08:00 to 30 September 18:00" selects hours 08 to 18 of every day from 1 March to 30 September. The hours are EPW local standard time: no daylight-saving hour is added or removed.

A window may cross the year end (for example 1 December to 28 February); it selects December, January and February of the typical year, in calendar order of the year.

Malformed values are refused: a month outside 1-12, an hour outside 0-23, a day outside its own month's length. The check happens before the tiles are built and acquired, and therefore before anything is billed.

A single-hour window (`start == end`) is valid: it selects one hour of each day in the date span.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `start_month` | `int` | First month of the window, 1 to 12. |
| `start_day` | `int` | First day of the window, 1 to 31 and within the month's length. 29 February is accepted because the window carries no year. |
| `start_hour` | `int` | First hour of the daily range, 0 to 23. |
| `end_month` | `int` | Last month of the window, 1 to 12. A month before `start_month` crosses the year end. |
| `end_day` | `int` | Last day of the window, 1 to 31 and within the month's length. |
| `end_hour` | `int` | Last hour of the daily range, 0 to 23, inclusive. |

## Location

Bases: `[Payload](#infrared_sdk.models.Payload)`

A point on Earth.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `latitude` | `float` | Latitude in degrees, from -90 to 90. |
| `longitude` | `float` | Longitude in degrees, from -180 to 180. |

## WeatherDataPoint

Bases: `[Payload](#infrared_sdk.models.Payload)`

One hourly weather record.

Each field is the EPW column of the same name, with the EPW column's units. Every field is optional and `None` means no reading. Numeric strings are converted to floats, and empty strings and the tokens `null`, `none`, `na`, `n/a` and `nan` become `None`. Unknown keys are ignored.

Warnings

The pre-0.10 key `znithLuminance` is still accepted for `zenithLuminance` with a `DeprecationWarning`.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `dryBulbTemperature` | `(float, optional)` | Dry-bulb air temperature. |
| `dewPointTemperature` | `(float, optional)` | Dew-point temperature. |
| `relativeHumidity` | `(float, optional)` | Relative humidity. |
| `atmosphericStationPressure` | `(float, optional)` | Atmospheric pressure at the station. |
| `extraterrestrialHorizontalRadiation` | `(float, optional)` | Extraterrestrial radiation on a horizontal surface. |
| `extraterrestrialDirectNormalRadiation` | `(float, optional)` | Extraterrestrial direct normal radiation. |
| `horizontalInfraredRadiationIntensity` | `(float, optional)` | Horizontal infrared radiation intensity from the sky. |
| `globalHorizontalRadiation` | `(float, optional)` | Global horizontal radiation. |
| `directNormalRadiation` | `(float, optional)` | Direct normal radiation. |
| `diffuseHorizontalRadiation` | `(float, optional)` | Diffuse horizontal radiation. |
| `globalHorizontalIlluminance` | `(float, optional)` | Global horizontal illuminance. |
| `directNormalIlluminance` | `(float, optional)` | Direct normal illuminance. |
| `diffuseHorizontalIlluminance` | `(float, optional)` | Diffuse horizontal illuminance. |
| `zenithLuminance` | `(float, optional)` | Luminance at the zenith. |
| `windDirection` | `(float, optional)` | Wind direction. |
| `windSpeed` | `(float, optional)` | Wind speed. |
| `totalSkyCover` | `(float, optional)` | Total sky cover. |
| `opaqueSkyCover` | `(float, optional)` | Opaque sky cover. |
| `visibility` | `(float, optional)` | Horizontal visibility. |
| `ceilingHeight` | `(float, optional)` | Cloud ceiling height. |
| `presentWeatherObservation` | `(float, optional)` | Present weather observation indicator. |
| `presentWeatherCodes` | `(float, optional)` | Present weather codes. |
| `precipitableWater` | `(float, optional)` | Precipitable water. |
| `aerosolOpticalDepth` | `(float, optional)` | Aerosol optical depth. |
| `snowDepth` | `(float, optional)` | Snow depth. |
| `daysSinceLastSnowfall` | `(float, optional)` | Days since the last snowfall. |
| `albedo` | `(float, optional)` | Ground albedo. |
| `liquidPrecipitationDepth` | `(float, optional)` | Depth of liquid precipitation. |
| `liquidPrecipitationQuantity` | `(float, optional)` | Quantity of liquid precipitation. |

### coerce_numeric_strings  `classmethod`

```python
coerce_numeric_strings(v)
```

- None stays None
- numbers stay numbers
- numeric strings -> float
- empty strings -> None
- 'null', 'na', 'nan' -> None
- non-numeric strings -> ValueError

## require_env

```python
require_env(name: str, defaultValue: Optional[str] = None) -> str
```

Read a required environment variable.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `name` | `str` | Name of the environment variable. | *required* |
| `defaultValue` | `str` | Value to use when the variable is unset. If omitted, an unset or empty variable is an error. | `None` |

Returns:

| Type | Description |
| --- | --- |
| `str` | The value of the variable. |

Raises:

| Type | Description |
| --- | --- |
| `RuntimeError` | If the value is missing or empty. |

## to_camel_case

```python
to_camel_case(s: str) -> str
```

Convert a `snake_case` string to `camelCase`.

## to_kebab_case

```python
to_kebab_case(s: str) -> str
```

Convert a `snake_case` string to `kebab-case`.

## extract_weather_fields

```python
extract_weather_fields(
weather_data: list[WeatherDataPoint], fields: list[str]
) -> dict[str, Any]
```

Extract the given fields from weather data points into flat lists.

A gap (`None`) in a requested field raises instead of being skipped, because skipping it would shorten that column and misalign it against every other array. For a complete weather window the output is the same as in 0.5.3.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `weather_data` | `list of WeatherDataPoint` | `WeatherDataPoint` instances, plain mapping rows (for example a `dict` from `json.load` of a weather file), or a mix of both. A mapping row is read through `WeatherDataPoint` itself, so it accepts the same column spellings, including the legacy `znithLuminance` alias. | *required* |
| `fields` | `list of str` | `camelCase` attribute names of `WeatherDataPoint`, for example `["diffuseHorizontalRadiation", "directNormalRadiation"]`. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `dict` | Maps each requested field, converted to `snake_case`, to its list of float values. |

Raises:

| Type | Description |
| --- | --- |
| `ValueError` | If a requested field has no reading in one of the points, or a mapping row is not a valid weather record. |
