flexmeasures.api.common.utils.validators

Functions

flexmeasures.api.common.utils.validators.assets_required(generic_asset_type_name: str, plural_name: str | None = None, groups_name='groups')

Decorator which specifies that a GET or POST request must specify one or more assets. It parses relevant form data and sets the “generic_asset_name_groups” keyword param. Example:

@app.route(‘/postMeterData’) @assets_required(“connection”, plural_name=”connections”) def post_meter_data(generic_asset_name_groups):

return ‘Meter data posted’

Given this example, the message must specify one or more assets as “connections”. If that is the case, then the assets are passed to the function as generic_asset_name_groups.

Connections can be listed in one of the following ways: - value of ‘connection’ key (for a single asset) - values of ‘connections’ key (for multiple assets that have the same timeseries data) - values of the ‘connection’ and/or ‘connections’ keys listed under the ‘groups’ key

(for multiple assets with different timeseries data)

flexmeasures.api.common.utils.validators.get_data_downsampling_allowed(entity_type: str, fm_scheme: str)

Decorator which allows downsampling of data which a GET request returns. It checks for a form parameter “resolution”. If that is given and is a multiple of the sensor’s event_resolution, downsampling is performed on the data. This is done by setting the “resolution” keyword parameter, which is obeyed by collect_time_series_data and used in resampling.

The original resolution of the data is the event_resolution of the sensor. Therefore, the decorator should follow after the assets_required decorator.

Example:

@app.route(‘/getMeterData’) @assets_required(“connection”) @get_data_downsampling_allowed(“connection”) def get_meter_data(generic_asset_name_groups, resolution):

return data

flexmeasures.api.common.utils.validators.include_current_user_source_id(source_ids: List[int]) List[int]

Includes the source id of the current user.

flexmeasures.api.common.utils.validators.optional_duration_accepted(default_duration: timedelta)

Decorator which specifies that a GET or POST request accepts an optional duration. It parses relevant form data and sets the “duration” keyword param.

Example:

@app.route(‘/getDeviceMessage’) @optional_duration_accepted(timedelta(hours=6)) def get_device_message(duration):

return ‘Here is your message’

The message may specify a duration to overwrite the default duration of 6 hours.

flexmeasures.api.common.utils.validators.optional_horizon_accepted(ex_post: bool = False, infer_missing: bool = True, infer_missing_play: bool = False, accept_repeating_interval: bool = False)

Decorator which specifies that a GET or POST request accepts an optional horizon. The horizon should be in accordance with the ISO 8601 standard. It parses relevant form data and sets the “horizon” keyword param (a timedelta).

Interpretation for GET requests: - Denotes “at least <horizon> before the fact (positive horizon),

or at most <horizon> after the fact (negative horizon)”

  • This results in the filter belief_horizon_window = (horizon, None)

Interpretation for POST requests: - Denotes “at <horizon> before the fact (positive horizon),

or at <horizon> after the fact (negative horizon)”

  • this results in the assignment belief_horizon = horizon

For example:

@app.route(‘/postMeterData’) @optional_horizon_accepted() def post_meter_data(horizon):

return ‘Meter data posted’

Parameters:
  • ex_post – if True, only non-positive horizons are allowed.

  • infer_missing – if True, servers assume that the belief_horizon of posted values is 0 hours. This setting is meant to be used for POST requests.

  • infer_missing_play – if True, servers in play mode assume that the belief_horizon of posted values is 0 hours. This setting is meant to be used for POST requests.

  • accept_repeating_interval – if True, the “rolling” keyword param is also set (this was used for POST requests before v2.0)

flexmeasures.api.common.utils.validators.optional_prior_accepted(ex_post: bool = False, infer_missing: bool = True, infer_missing_play: bool = False)

Decorator which specifies that a GET or POST request accepts an optional prior. It parses relevant form data and sets the “prior” keyword param.

Interpretation for GET requests: - Denotes “at least before <prior>” - This results in the filter belief_time_window = (None, prior)

Interpretation for POST requests: - Denotes “recorded <prior> to some datetime, - this results in the assignment belief_time = prior

Parameters:
  • ex_post – if True, only ex-post datetimes are allowed.

  • infer_missing – if True, servers assume that the belief_time of posted values is server time. This setting is meant to be used for POST requests.

  • infer_missing_play – if True, servers in play mode assume that the belief_time of posted values is server time. This setting is meant to be used for POST requests.

flexmeasures.api.common.utils.validators.optional_user_sources_accepted(default_source: int | str | list[int | str] | None = None)

Decorator which specifies that a GET or POST request accepts an optional source or list of data sources. It parses relevant form data and sets the “user_source_ids” keyword parameter.

Data originating from the requesting user is included by default. That is, user_source_ids always includes the source id of the requesting user.

Each source should either be a known USEF role name or a user id. We’ll parse them as a list of source ids.

Case 1: If a request states one or more data sources, then we’ll only query those, in addition to the user’s own data. Default sources specified in the decorator (see example below) are ignored.

Case 2: If a request does not state any data sources, a list of default sources will be used.

Case 2A: Default sources can be specified in the decorator (see example below).

Case 2B: If no default sources are specified in the decorator, all sources are included.

Example:

@app.route(‘/getMeterData’) @optional_sources_accepted(“MDC”) def get_meter_data(user_source_ids):

return ‘Meter data posted’

The source ids then include the user’s own id, and ids of other users that are registered as a Meter Data Company.

If the message specifies:

{
    "sources": ["Prosumer", "ESCo"]
}

The source ids then include the user’s own id, and ids of other users whose organisation account is registered as a Prosumer and/or Energy Service Company.

flexmeasures.api.common.utils.validators.parse_duration(duration_str: str, start: datetime | None = None) timedelta | Duration | None

Parses the ‘duration’ string into a Duration object. If needed, try deriving the timedelta from the actual time span (e.g. in case duration is 1 year). If the string is not a valid ISO 8601 time interval, return None.

TODO: Deprecate for DurationField.

flexmeasures.api.common.utils.validators.parse_horizon(horizon_str: str) Tuple[timedelta | None, bool]

Validates whether a horizon string represents a valid ISO 8601 (repeating) time interval.

Examples:

horizon = “PT6H” horizon = “R/PT6H” horizon = “-PT10M”

Returns horizon as timedelta and a boolean indicating whether the repetitive indicator “R/” was used. If horizon_str could not be parsed with various methods, then horizon will be None

flexmeasures.api.common.utils.validators.parse_isodate_str(start: str) datetime | None

Validates whether the string ‘start’ is a valid ISO 8601 datetime.

flexmeasures.api.common.utils.validators.period_required(fn)

Decorator which specifies that a GET or POST request must specify a time period (by start and duration). It parses relevant form data and sets the “start” and “duration” keyword params. Example:

@app.route(‘/postMeterData’) @period_required def post_meter_data(period):

return ‘Meter data posted’

The message must specify a ‘start’ and a ‘duration’ in accordance with the ISO 8601 standard. This decorator should not be used together with optional_duration_accepted.

flexmeasures.api.common.utils.validators.post_data_checked_for_required_resolution(entity_type: str, fm_scheme: str)

Decorator which checks that a POST request receives time series data with the event resolutions required by the sensor. It sets the “resolution” keyword argument. If the resolution in the data is a multiple of the sensor resolution, values are upsampled to the sensor resolution. Finally, this decorator also checks if all sensors have the same event_resolution and complains otherwise.

The resolution of the data is inferred from the duration and the number of values. Therefore, the decorator should follow after the values_required, period_required and assets_required decorators. Example:

@app.route(‘/postMeterData’) @values_required @period_required @assets_required(“connection”) @post_data_checked_for_required_resolution(“connection”) def post_meter_data(value_groups, start, duration, generic_asset_name_groups, resolution)

return ‘Meter data posted’

flexmeasures.api.common.utils.validators.type_accepted(message_type: str)

Decorator which specifies that a GET or POST request must specify the specified message type. Example:

@app.route(‘/postMeterData’) @type_accepted(‘PostMeterDataRequest’) def post_meter_data():

return ‘Meter data posted’

The message must specify ‘PostMeterDataRequest’ as its ‘type’.

Parameters:

message_type – The message type.

flexmeasures.api.common.utils.validators.unit_required(fn)

Decorator which specifies that a GET or POST request must specify a unit. It parses relevant form data and sets the “unit keyword param. Example:

@app.route(‘/postMeterData’) @unit_required def post_meter_data(unit):

return ‘Meter data posted’

The message must specify a ‘unit’.

flexmeasures.api.common.utils.validators.units_accepted(quantity: str, *units: str)

Decorator which specifies that a GET or POST request must specify one of the specified physical units. First parameter specifies the physical or economical quantity. It parses relevant form data and sets the “unit” keyword param. Example:

@app.route(‘/postMeterData’) @units_accepted(“power”, ‘MW’, ‘MWh’) def post_meter_data(unit):

return ‘Meter data posted’

The message must either specify ‘MW’ or ‘MWh’ as the unit.

Parameters:
  • quantity – The physical or economic quantity

  • units – The possible units.

flexmeasures.api.common.utils.validators.valid_sensor_units(sensor: str) List[str]

Returns the accepted units for this sensor.

flexmeasures.api.common.utils.validators.validate_user_sources(sources: int | str | List[int | str]) List[int]

Return a list of user-based data source ids, given: - one or more user ids - one or more account role names

flexmeasures.api.common.utils.validators.values_required(fn)

Decorator which specifies that a GET or POST request must specify one or more values. It parses relevant form data and sets the “value_groups” keyword param. Example:

@app.route(‘/postMeterData’) @values_required def post_meter_data(value_groups):

return ‘Meter data posted’

The message must specify one or more values. If that is the case, then the values are passed to the function as value_groups.