API Docs
Welcome to the Python SDK reference docs. The SDK enables Python developers to speed up and ease the integration with Blockbax. It makes interfacing with our HTTP API even easier where you can easily get, create, update and delete resources without the intricacies of having to deal with HTTP requests and responses.
The Python SDK exposes a HttpClient
class and resources as Pydantic model
. The HttpClient
automatically injects the given access key and project ID per HTTP call and has built in mechanisms to catch and present any errors returned by the Blockbax API.
You can easily install the Python SDK through pip.
Installation
pip install blockbax-sdk
To start using the Python SDK you first have to setup a HTTP client for your Blockbax project. Make sure you have created an access key with the appropriate permissions. Currently, you can interact with the following resource types:
Client setup
import blockbax_sdk as blockbax
project_id = "75ef0782-c63b-4afe-8e59-091f33cd88dd"
access_token = "0eVKlsqYH4QauFyij2LP6gfkFwZnK5Ta"
http_client = blockbax.HttpClient(
project_id = project_id,
access_token = access_token
)
The Python SDK defines the following errors.
BlockbaxHTTPError
BlockbaxClientError
BlockbaxServerError
BlockbaxUnauthorizedError
The most common error is the BlockbaxHTTPError
which is thrown whenever the HTTP client encounters an error. This error is also used as the base class for all other errors that can occur during HTTP requests. Two subtypes of the BlockbaxHTTPError
class are the BlockbaxClientError
& BlockbaxServerError
which are thrown for HTTP status codes 4xx
and 5xx
respectively. Additionally the BlockbaxUnauthorizedError
error is thrown for every failed request whenever the configured access key is unauthorized to do so.
BlockbaxHTTPError
provides you with information such as:
ValueError
is used whenever a numeric value is given that could not be stored as a Decimal. The Python SDK automatically rounds decimals to 8 digits after the decimal point and throws the ValueError
for any numeric value given with more than 20 digits before the decimal point. It’s important to note that the built in Python float
in some rare occasions can not always be precise enough when dealing with very big values.
Errors usage
from blockbax_sdk import errors
try:
http_client.update_subject(subject = new_subject)
except errors.BlockbaxHTTPError as error:
# Handle error
Due to the distributed nature of the Blockbax Platform, the HTTP API requests can return a 502
, 503
and 504
status code incidentally which can be safely retried. The Python SDK has a retry mechanism that automatically retries these errors for a maximum of 3 times using an exponential back-off mechanism. After the request has failed more than 3 times a BlockbaxServerError
is thrown.
The Blockbax Platform uses rate limits to avoid resource starvation. All endpoints are rate limited except the endpoint for sending measurements. Once a rate limit is hit a 429
response code is returned for all subsequent requests until the limit is reset. The Python SDK automatically handles these responses and has a mechanism to wait until the rate limit is reset to retry the failed request and continue processing. Please visit our API documentation for more information.
We have introduced significant improvements in version 1.0.0. Our internal models have undergone essential refactoring from using Python Data Classes to leveraging the more powerful Pydantic models. We’ve tried minimizing backward incompatible changes, there are some attribute name or type adjustments we deemed necessary (see details below). The HttpClient, as the main entrypoint to the SDK, remains fully backward compatible.
Breaking changes
- Python Data Classes have been replaced Pydantic models. If your code relies on specific behavior of Data Classes, such as overrides, please review and make necessary adjustments.
- UUID fields within internal models have transitioned from string to UUID type. Still HTTPClient gracefully accepts both string and UUID representations for UUID fields. For instance
http_client.get_metric(UUID("26a9badb-954f-45fd-a810-f7d23430cf96"))
andhttp_client.get_metric("26a9badb-954f-45fd-a810-f7d23430cf96")
are both accepted.- The
properties
field in the Subject model is now of typeList[SubjectProperty]
, aligning the model with raw responses from the HTTP API.- The previously used
Subject.properties.get()
method on subject properties is removed. Instead, useSubject.get_property_by_type_id(my_type_id)
to retrieve a subject property if it exists.
create_subject_type
the attribute parent_ids
is marked deprecated and should be replaced with parent_subject_type_ids
.get_subjects
the attribute subject_external_id
is marked deprecated and should be replaced with external_id
.create_subject
the attribute parent_id
is marked deprecated and should be replaced with parent_subject_id
.Added support for events and event triggers. With these changes, the Python SDK now supports all methods of the Blockbax HTTP API.
suppressed
field.endDate
.Queueing, batching, and sending measurements have been improved to ensure all measurements for a subject are batched and send in strictly increasing time order to avoid timing issues.
Breaking change
The option for limiting what is send from the queue has been removed (
ingestion_ids
argument fromsend_measurements()
method). This is obsolete with the current improvements. Contact us if you have any questions or concerns.
Methods to create, update, delete and get property types.
Gets property types, optionally with arguments for filtering.
name
[optional, default=None]: The name of the property type to filter on.external_id
[optional, default=None]: The external id of the property type to filter on.Returns: List of PropertyType
Get all property types:
all_property_types = http_client.get_property_types()
Get a select list of property types:
property_type_name_of_interest = "My Property type"
select_list_of_property_types = http_client.get_property_types(
name = property_type_name_of_interest
)
Gets a specific property type.
id_
[required]: Property type ID to fetch.Returns: PropertyType
Get a property type by ID:
my_property_type_id = "e85f1b55-07bd-40d5-85a5-04c07dd3f12f"
single_property_type = http_client.get_property_type(
id_ = my_property_type_id
)
Creates a property type
name
[required]: The name of the property type.external_id
[required]: The external id of the property type.data_type
[required]: The type of the property type. Can be “TEXT”, “NUMBER”, “LOCATION”, “MAP_LAYER or “IMAGE”.predefined_values
[required]: Defines whether it is possible to create values for this property type in the resource itself (for value true) or they are automatically created when adding a value to a subject (for value false).values
[optional, default=[] ]: List of predefined values. A property type can be created with or without predefined values. Each list item can be either a dictionary in the valid format or PropertyTypeValue. It is preferred to use the later as the structure will be validated before making the request.Returns: PropertyType
Create values:
# values for "TEXT" data_type
my_text_property_values = ["text_value"]
# values for "NUMBER" data_type
my_number_property_values = [1, "2"]
# values for "LOCATION" data_type
my_location_property_values = [{
"lat": 51.92517,
"lon": 4.475660,
"alt": 0 # Optional
}]
my_map_layer_property_values = [
{
"typeId": "d237162d-6da6-455e-8921-ba0c4bae4fc5",
"mapLayer": {
"imagePath" : "/projects/715b6935-e3d8-48b1-86a3-a6e2a268e1f/propertyTypes/d237162d-6da6-455e-8921-ba0c4bae4fc5/values/8a75002b-0c63-4fe8-afc0-2c05e428a76a/files/efa6753f-4981-417f-aabd-be0f43c6e4f6.png",
"leftBottom" : {
"lat": 52.37403,
"lon": 4.88969
},
"leftTop" : {
"lat": 52.37404,
"lon": 4.88969
},
"rightBottom" : {
"lat": 52.37403,
"lon": 4.88970
},
"rightTop" : {
"lat": 52.37404,
"lon": 4.88970
}
}
}]
my_image_property_values = [{
"typeId": "bae083a4-fb3a-490a-8025-312112066b66",
"image": {
"imagePath": "/projects/715b6935-e3d8-48b1-86a3-a6e2a268e1f/propertyTypes/bae083a4-fb3a-490a-8025-312112066b66/values/a8c52571-b882-4bf0-b013-f38f9621e7b6/files/ada6753f-4981-417f-aabd-be0f43c6e4c9.png"
}
}]
Create a property type:
my_property_type = http_client.create_property_type(
name = "My Property type", # Required
data_type = "NUMBER", # Required
predefined_values = True, # Required
values = my_number_property_values # Optional, default = []
)
Updates a property type.
property_type
[required]: Updated PropertyType or a dictionary with all fields. The latter will be cast to a PropertyType automatically if it is in the valid format.Returns: PropertyType
Update predefined property values:
my_property_type_id = "e85f1b55-07bd-40d5-85a5-04c07dd3f12f"
my_property_type = http_client.get_property_type(
id_ = my_property_type_id
)
new_value = 3
my_property_type.add_value(new_value)
old_value = 2
my_property_type.remove_value(old_value)
Update attributes
my_property_type.name = "My new Property value name"
Update property type:
my_property_type = http_client.update_property_type(my_property_type)
Deletes a property type.
id_
[required]: Property type ID to delete.Returns: None
Delete a property type:
my_property_type_id = "e85f1b55-07bd-40d5-85a5-04c07dd3f12f"
http_client.delete_property_type(
id_ = my_property_type_id
)
Methods to create, update, delete, and get event triggers.
Gets event triggers, optionally filtered by name.
name
[optional, default=None]: Filter event triggers by name.Returns: List of EventTrigger
Get all Event triggers
all_event_triggers = http_client.get_event_triggers()
Get a selected list of Event triggers
event_trigger_name_of_interest = "My Event Trigger"
subject_type_id_of_interest = "526e8fee-ded2-410d-b562-888724d58183"
select_list_of_event_triggers = http_client.get_event_triggers(
name = event_trigger_name_of_interest
)
Gets a specific event trigger.
id_
[required]: Event Trigger ID to fetch.Returns: EventTrigger
Get a single Event trigger
my_event_trigger_id = "e7b6d3ab-34c7-4c3a-bf4d-51c854c79e95"
single_event_trigger = http_client.get_event_trigger(
id_ = my_event_trigger_id
)
Creates an event trigger.
name
[required]: The name of the event trigger.subject_type_id
[required]: The ID of the subject type associated with this event trigger.active
[required]: Whether this event trigger is active.event_rules
[required]: List of event rules associated with this event trigger. If provided as a list of dictionaries, they will be automatically cast to List[EventRule]. Using the EventRule model is preferred as it allows validation before calling the create method.
event_level
[required]: Event level.condition_sets
[required]: List of condition sets associated with this event rule.
id
[optional]: Condition set ID.description
[required]: Description of the condition set.input_conditions
[required]: List of input conditions.
type
[required]: Type of the input condition.left_operand
[required]: Left operand of the condition.comparison_operator
[required]: Comparison operator.right_operand
[required]: Right operand of the condition.evaluation_trigger
[required]: Evaluation trigger type.evaluation_constraint
[required]: Evaluation constraint type.subject_filter
[optional]: Filter of subjects for which this event trigger will generate events. If as a dictionary, it will be automatically cast to SubjectFilter. Using the SubjectFilter model is preferred for validation purposes.Returns: EventTrigger
Create Event Trigger
my_event_rules = [
{
"event_level": "OK",
"condition_sets": [
{
"id": "3b39bf8c-89ea-4b92-944d-34e33ac507b8",
"description": "Condition set description",
"input_conditions": [
{
"type": "THRESHOLD",
"left_operand": {
"type": "METRIC",
"id": "a6e924d7-885b-4045-baab-4d5e7bae1641"
},
"comparison_operator": "GREATER_THAN",
"right_operand": {
"type": "STATIC_VALUE",
"number": 100
}
}
]
}
]
}
]
my_subject_filter = {
"include": {
"subjectIds": ["253c28ab-1267-482c-addf-ade740519bd6"],
"propertyValues": None,
"subjectTypeIds": None,
},
"exclude": {
"subjectIds": ["3d5cfeef-e1e1-4be1-9218-68b0881c7538"],
"propertyValues": None,
"subjectTypeIds": None,
},
},
my_event_trigger = http_client.create_event_trigger(
name = "My Event Trigger", # Required
subject_type_id = subject_type_id_of_interest, # Required
active =True, # Required
event_rules = my_event_rules, # Required
evaluation_trigger = "INPUT_METRICS", # Required
evaluation_constraint = "NONE" # Required
subject_filter = my_subject_filter
)
Updates an event trigger.
event_trigger
[required]: Updated EventTriggerReturns: EventTrigger
Update Event Trigger
my_event_trigger_id = "e7b6d3ab-34c7-4c3a-bf4d-51c854c79e95"
my_event_trigger = http_client.get_event_trigger(
id_ = my_event_trigger_id
)
# Update event rules or other attributes
my_event_trigger.name = "My Updated Event Trigger"
my_event_trigger.event_rules[0].event_level = "WARNING"
my_updated_event_trigger = http_client.update_event_trigger(my_event_trigger)
Deletes an event trigger.
id_
[required]: Event trigger ID to delete.Returns: None
Delete Event Trigger
my_event_trigger_id = "e7b6d3ab-34c7-4c3a-bf4d-51c854c79e95"
http_client.delete_event_trigger(
id_ = my_event_trigger_id
)
Methods to retrieve events.
Gets events based on various optional filters.
active
[optional]: [optional]: Filter events by active
status.suppressed
[optional]: Filter events by the suppressed
field.from_date
[optional, default=None]: datetime
, integer unix timestamp or string parsable by the dateutil.parserto_date
[optional, default=None]: datetime
, integer unix timestamp or string parsable by the dateutil.parseronly_new
[optional]: Filter for new events only.property_value_ids
[optional]: List of property value IDs to filter on.subject_ids
[optional]: List of subject IDs to filter on.event_trigger_ids
[optional]: List of event trigger IDs to filter on.event_levels
[optional]: List of event levels to filter on.sort
[optional, default=“startDate,desc”]: Sorting criteria for results.Returns: List of Event
Get all Events
events = http_client.get_events()
Get selected Events
events = http_client.get_events(
active=True,
from_date="2024-01-01",
to_date="2024-06-30",
event_levels=["WARNING", "PROBLEM"]
)
Gets a specific event.
id_
[required]: ID of the event to fetch.Returns: Event or None if not found
Get a single Event
my_event_id = "c66e8fee-ded2-410d-b562-888724d58183"
event = http_client.get_event(id_=my_event_id)
Methods to create, update, delete and get subject types.
Gets subject types, optionally with arguments for filtering.
name
[optional, default=None]: Filter subject types by name.property_types_ids
[optional, default=None]: A list of strings that contain property type IDs to filter on.Returns: List of SubjectType
Get all Subject types
all_subject_types = http_client.get_subject_types()
Get a select list of Subject types
subject_type_name_of_interest = "My Subject Type"
property_types_ids_of_interest = [
"e85f1b55-07bd-40d5-85a5-04c07dd3f12f",
"5c2df77a-b700-460b-a87d-5adc03f915bb"
]
select_list_of_subject_types = http_client.get_subject_types(
name = subject_type_name_of_interest,
property_types_ids = property_types_ids_of_interest
)
Gets a specific subject type.
id_
[required]: Subject Type ID to fetch.Returns: SubjectType
Get a single Subject type
my_subject_type_id = "526e8fee-ded2-410d-b562-888724d58183"
single_subject = http_client.get_subject_type(
id_ = my_subject_type_id
)
Creates a subject type
name
[required]: The name of the subject type.parent_ids
[optional, default=None ]: The IDs of the parent subject types of this subject type.parent_id
[deprecated]: The ID of the parent subject type of this subject type.primary_location
[optional, default=None ]: The primary location metric or property type of this subject type, for displaying the location of subjects on the map.
type
[required]: PROPERTY_TYPE
.id
[required]: The property type ID to use as primary location.property_types
[optional, default=None ]: List of property type dictionary’s associated with this subject type.
id
[required]: ID of the property type.required
[required]: Whether the property type is required to have a value for subjects belong to this subject type.visible
[optional]: Whether the property type is visible in the client in this subject type.Returns: SubjectType
Create Primary location (PROPERTY_TYPE
):
my_primary_location = {
"type" : "PROPERTY_TYPE",
"id" : "5c2df77a-b700-460b-a87d-5adc03f915bb"
}
Create Property Types:
my_property_types = [
{
"id": "e85f1b55-07bd-40d5-85a5-04c07dd3f12f",
"required": True,
},{
"id": "e5f7ec09-4af4-4ac1-8837-124a0b7c9e37",
"required": False,
"visible": True
},{
"id": "5c2df77a-b700-460b-a87d-5adc03f915bb",
"required": False,
"visible" : False
}]
Create Subject Type:
my_parent_subject_type_id = "f8874ab2-1695-4e11-a7f1-47eba57f0053"
my_subject_type = http_client.create_subject_type(
name = "My subject type", # Required
parent_ids = [my_parent_subject_type_id], # Optional
primary_location = my_primary_location, # Optional
property_types = my_property_types # Optional
)
Updates a subject type.
subject_type
[required]: Updated SubjectTypeReturns: SubjectType
Update Property types:
my_subject_type_id = "526e8fee-ded2-410d-b562-888724d58183"
my_subject_type = http_client.get_subject_type(
subject_type_id = my_subject_type_id
)
# Add new property types
my_new_property_types = [{
"id" : "54a6850f-a7ae-40ba-8934-aba1fbddbeab",
"required" : True,
"visible" : True
}]
my_subject_type.add_property_types(my_new_property_types)
# Remove property types
property_type_ids_to_remove = ["e5f7ec09-4af4-4ac1-8837-124a0b7c9e37"]
my_subject_type.remove_property_types(property_type_ids_to_remove)
Create Primary location (METRIC
):
my_primary_location = {
"type" : "METRIC",
"id" : "a6e924d7-885b-4045-baab-4d5e7bae1641"
}
Update attributes
# Update Primary location
my_subject_type.primary_location = my_primary_location
# Update name
my_subject_type.name = "My New Subject Type"
# update parent subject type ID
my_subject_type.parent_ids = ["d1b01ef9-868b-43c5-b3c0-10a884105899"]
Update Subject Type:
my_subject_type = http_client.update_subject_type(my_subject_type)
Deletes a subject type.
id_
[required]: Subject type ID to delete.Returns: None
Delete Subject Type
my_subject_type_id = "526e8fee-ded2-410d-b562-888724d58183"
http_client.delete_subject_type(
id_ = my_subject_type_id
)
Methods to create, update, delete and get metrics.
Gets metrics, optionally with arguments for filtering.
name
[optional, default=None]: Filter property types by name.external_id
[optional, default=None]: Filter metrics by external ID.subject_type_ids
[optional, default=None]: Filter on a list of subject type IDs.Returns: List of Metric
Get all Metrics
all_metrics = http_client.get_metrics()
Get a select list of Metrics
metrics_name_of_interest = "My Metric"
metrics_external_id_of_interest = "my-metric"
subject_type_ids_of_interest = [
"526e8fee-ded2-410d-b562-888724d58183",
"5dc020a2-e43c-49d7-a294-838108e8021a"
]
select_list_of_metrics = http_client.get_metrics(
name = metrics_name_of_interest,
external_id = metrics_external_id_of_interest,
subject_type_ids = subject_type_ids_of_interest
)
Get a single Metric
my_metric_id = "fca1f5c9-e78a-48a3-b5b0-e0ee969a743b"
single_metric = http_client.get_metric(
id_ = my_metric_id
)
Creates a metric.
subject_type_id
[required]: Subject type ID that this metric belongs to. Determines which subjects, property types and metrics are connected.name
[required]: The name of the metric.data_type
[required]: The data type of the metric. Choose from: NUMBER
or LOCATION
.type_
[required]: The type of the metric. Currently only the INGESTED
type is supported.discrete
[optional, default=False] Whether this metric has discrete values. This is used by the web app to optimize visualization.unit
[optional, default=None]: The unit of the metric.precision
[optional, default=8]: The precision to show in the client for the metric, from 0 to 8.visible
[optional, default=True]: Whether this metric is visible in the client.external_id
[optional, default=None]: The external ID of the subject. This can be used when sending measurements to avoid the source systems (e.g. sensors) need to know which IDs are internally used in the Blockbax Platform. If left empty the external ID will be derived from the given name but it is recommended that one is given.Returns: Metric
Create Metric:
subject_type_id = "526e8fee-ded2-410d-b562-888724d58183"
my_metric = http_client.create_metric(
subject_type_id = subject_type_id, # Required
name = "My metric", # Required
data_type = "NUMBER", # Required
type_ = "INGESTED" # Required
unit = "K", # Optional, default = ""
precision = 2, # Optional, default = 8
visible = True, # Optional, default = True
discrete = False, # Optional, default = False
external_id = "example" # Optional, default: derived from name
)
Update Attributes
my_metric_id = "fca1f5c9-e78a-48a3-b5b0-e0ee969a743b"
my_metric = http_client.get_metric(
id_ = my_metric_id
)
my_metric.name = "Updated Metric name"
my_metric.unit = "K"
my_metric.precision = 2
my_metric.visible = False
my_metric.external_id = "updated-metric-external-id"
Update Metric
http_client.update_metric(my_metric)
Deletes a metric.
id_
[required]: Metric ID to deleteReturns: None
Delete Metric
my_metric_id = "3c47681d-c782-45b2-8544-55eba5b398af"
http_client.delete_metric(
id_ = my_metric_id
)
Methods to create, update, delete and get subjects.
Gets subjects, optionally with arguments for filtering.
name
[optional, default=None]: Filter subjects by name.external_id
[optional, default=None]: Filter subjects by external ID.subject_ids:
[optional, default=None]: Filter on a list of subject IDs.subject_ids_mode
: [optional, default=“SELF”]: Determines how the subjectIds parameter is applied. Choose from: “SELF” (only those ids), “CHILDREN” (only the direct children) or “ALL” (the subjects themselves and all subjects that have them in their composition anywhere in the tree).subject_type_ids
[optional, default=None]: Filter on a list of subject type IDs.property_value_ids
[optional, default=None]: Filter property value IDs using a string or a combination of a list with tuples. For strings use a ,
separator for OR and ;
for AND, e.g. <A>,<B>;<C>
translates to (A OR B) AND C. Instead of a string, IDs can be encapsulate in a tuple
for OR and encapsulate IDs in a list
for AND. e.g. [(A, B),C]
translates to <A>,<B>;<C>
a.k.a (A OR B) AND C.Returns: Subject
Get all Subjects:
all_subjects = http_client.get_subjects()
Get a select list of Subjects:
subject_name_of_interest = "My Subject"
subject_external_id_of_interest = "my-subject"
subject_ids_of_interest = ["fca1f5c9-e78a-48a3-b5b0-e0ee969a743b"]
subject_type_ids_of_interest = ["my-subject-external-id"]
property_value_id_1 = "c287dc1c-0715-4fe5-a693-224f80b6fde3"
property_value_id_2 = "5666c0d6-e984-4bf4-af78-abd23fd660bc"
property_value_id_3 = "5c02e7ae-217c-4f36-b684-6797d2af2034"
subject_ids_mode = "CHILDREN"
property_value_ids_of_interest = f"{property_value_id_1},{property_value_id_2};{property_value_id_3}"
# Or
property_value_ids_of_interest = [(property_value_id_1,property_value_id_2),property_value_id_3]
select_list_of_subjects = http_client.get_subjects(
name = subject_name_of_interest,
external_id = subject_external_id_of_interest,
subject_ids = subject_ids_of_interest,
subject_ids_mode = subject_ids_mode,
subject_type_ids = subject_type_ids_of_interest,
property_value_ids_of_interest = property_value_ids_of_interest
)
Gets a specific subject.
id_
[required]: Subject ID to fetch.Returns: Subject
Get a single Subject:
my_subject_id = "fca1f5c9-e78a-48a3-b5b0-e0ee969a743b"
single_subject = http_client.get_subject(
id_ = my_subject_id
)
Creates a subject.
subject_type_id
[required]: Subject type that this subjects belongs to. Determines which subjects, property types and metrics are connected.name
[required]: The name of the subject.parent_id
[optional, default=None]: The ID of the parent subject of this subject. Required if the subject type has a parent subject type. Not allowed otherwise.properties
[optional, default=None]: List of the properties of this subject.ingestion_id_overrides
[optional, default={} ]: Dictionary of metric ID ingestion ID pairs, ingestion ID’s belonging to metrics that are defined in the Subject Type but are not defined here will be automatically derived from the subject and metric external ID.external_id
[optional, default=None]: The external ID of the subject. This can be used when sending measurements to avoid the source systems (e.g. sensors) need to know which IDs are internally used in the Blockbax Platform. If left empty the external ID will be derived from the given name but it is recommended that one is given.Returns: Subject
Create ingestion ID’s to overwrite:
my_metric_id = "fca1f5c9-e78a-48a3-b5b0-e0ee969a743b"
ingestion_ids_to_override = {
my_metric_id: "my-new-ingestion-id"
}
Create Property values:
# "TEXT" data_type defined by property_type
my_property_type_id = "59e4dd81-5704-4973-8bc4-8f377f9c487c"
text_property = {
"typeId": my_property_type_id,
"text": "my_property_value"
}
# "NUMBER" data_type defined by property_type
my_property_type_id = "e85f1b55-07bd-40d5-85a5-04c07dd3f12f"
number_property = {
"typeId": my_property_type_id,
"number": 1
}
# "LOCATION" data_type defined by property_type
my_property_type_id = "5c2df77a-b700-460b-a87d-5adc03f915bb"
location_property = {
"typeId": my_property_type_id,
"location": {
"lat": 51.925171,
"lon": 4.475660,
"alt": 0 # Optional
}
}
my_property_type_id = "d237162d-6da6-455e-8921-ba0c4bae4fc5"
map_layer_property = {
"typeId": my_property_type_id,
"mapLayer": {
"imagePath" : "/projects/715b6935-e3d8-48b1-86a3-a6e2a268e1f/propertyTypes/d237162d-6da6-455e-8921-ba0c4bae4fc5/values/8a75002b-0c63-4fe8-afc0-2c05e428a76a/files/efa6753f-4981-417f-aabd-be0f43c6e4f6.png",
"leftBottom" : {
"lat": 52.37403,
"lon": 4.88969
},
"leftTop" : {
"lat": 52.37404,
"lon": 4.88969
},
"rightBottom" : {
"lat": 52.37403,
"lon": 4.88970
},
"rightTop" : {
"lat": 52.37404,
"lon": 4.88970
}
}
}
my_property_type_id = "bae083a4-fb3a-490a-8025-312112066b66"
image_property = {
"typeId": my_property_type_id,
"image": {
"imagePath": "/projects/715b6935-e3d8-48b1-86a3-a6e2a268e1f/propertyTypes/bae083a4-fb3a-490a-8025-312112066b66/values/a8c52571-b882-4bf0-b013-f38f9621e7b6/files/ada6753f-4981-417f-aabd-be0f43c6e4c9.png"
}
}
my_property_type_id ="fc13e380-aee1-46c3-a125-2a7831b6d492"
inherited_property = {
"typeId": my_property_type_id,
"inherit": True
}
new_properties = [
text_property,
number_property,
location_property,
map_layer_property,
image_property,
inherited_property,
]
Create Subject
my_subject_type_id = "526e8fee-ded2-410d-b562-888724d58183"
my_parent_subject_id = "8e9e140c-3223-493a-bbfc-cc214fa44ae6"
my_subject = http_client.create_subject(
subject_type_id = my_subject_type_id, # Required
name = "My Subject", # Required
parent_id = my_parent_subject_id # Optional
properties = new_properties, # Optional
ingestion_id_overrides = ingestion_ids_to_override, # Optional
external_id = "my-subject-external-id" # Optional
)
Update properties
my_subject_id = "fca1f5c9-e78a-48a3-b5b0-e0ee969a743b"
my_subject = http_client.get_subject(
id_ = my_subject_id
)
# Create new or update already existing properties
# "TEXT" data_type defined by property_type
my_property_type_id = "a8c89d3f-8fa2-480d-a013-8ff9adc16a4c"
text_property = {
"typeId": my_property_type_id,
"text": "my_property_value"
}
# "NUMBER" data_type defined by property_type
my_property_type_id = "e85f1b55-07bd-40d5-85a5-04c07dd3f12f"
number_property = {
"typeId": my_property_type_id,
"number": 6
}
# "LOCATION" data_type defined by property_type
my_property_type_id = "5c2df77a-b700-460b-a87d-5adc03f915bb"
location_property = {
"typeId": my_property_type_id,
"location": {
"lat": 51.997903,
"lon": 4.3721174,
"alt": 0 # Optional
}
}
updated_properties = [
text_property,
number_property,
location_property
]
# You can add or update property values like this
my_subject.set_properties(updated_properties)
# You can remove property values like this
my_property_type_ids_to_remove = ["e85f1b55-07bd-40d5-85a5-04c07dd3f12f"]
my_subject.remove_properties(my_property_type_ids_to_remove)
Update ingestion IDs
# You can add or update already existing ingestion IDs like this
my_metric_id = "3c47681d-c782-45b2-8544-55eba5b398af"
my_updated_ingestion_id = "my-updated-ingestion-id"
my_subject.set_ingestion_id(my_metric_id, my_ingestion_id)
# You can remove an ingestion ID like this:
my_metric_id_to_remove = "9a754b09-311c-4f80-b94e-1d36f6e81e26"
my_subject.remove_ingestion_id(my_metric_id_to_remove)
Update attributes
# Update name
my_subject.name = "New Name"
# Update external ID
my_subject.external_id = "New external ID"
# Update parent subject ID
my_subject.parent_id = "261d7154-04d6-4333-bd73-33e0f1592840"
update Subject
my_subject = http_client.update_subject(my_subject)
Deletes a subject.
id_
[required]: Subject ID to delete.Returns: None
Delete Subject
my_subject_id = "fca1f5c9-e78a-48a3-b5b0-e0ee969a743b"
http_client.delete_subject(
id_ = my_subject_id
)
Methods to queue, send and get measurements
Queues measurements to send.
ingestion_id
[required]: Ingestion IDdate
[optional, default=None]:
datetime
, Unix timestamp (float or int), or string parsable
by the dateutil.parser. If no date is passed,
the current date will be used. Numeric values for date
will first be attempted to be parsed as epoch seconds. If
the value is too large for seconds, it will be interpreted
as epoch milliseconds.number
[optional, default=None]: Decimal number, must be filled if location
and text
are None
.text
[optional, default=None]: String text, must be filled if number
and location
are None
.location
[optional, default=None]: Location or dictionary, must be filled if number
and text
are None
.Returns: None
Raises:
ValidationError
: Raised when the specified number cannot be converted to a Decimal
, or if a valid datetime
cannot be derived from the provided date
argument.Queue a number measurement:
http_client.queue_measurement(
ingestion_id = "my_number_ingestion",
date = datetime(2024, 1, 1, tzinfo=timezone.utc),
number = 1
)
Queue a text measurement:
http_client.queue_measurement(
ingestion_id= "my_text_ingestion",
date=1704067200000,
text="Sample measurement"
)
Queue a location value:
my_location = {
"lat":51.925171,
"lon":4.475660,
"alt":0 # Optional
}
http_client.queue_measurement(
ingestion_id = "my_location_ingestion",
date = "2024-01-01T00:00:00+00:00",
location = my_location
)
Sends queued measurements.
This method takes no arguments.
Returns: None
Send all queued measurements:
http_client.send_measurements()
Gets measurements with arguments for filtering.
subject_ids
[optional, default=[] ]: List of IDs of the subjects. When passing a fromDate or toDate, this must only contain one subject ID.metric_ids
[optional, default=[] ]: List of IDs of the metrics. When passing a fromDate or toDate, this must only contain one metric ID.from_date
[optional, default=None]: datetime
, integer unix timestamp or string parsable by the dateutil.parserto_date
[optional, default=None]: datetime
, integer unix timestamp or string parsable by the dateutil.parserorder
[optional, default=asc]: Ordering of measurements based on the date (asc or desc).Returns: List of Series
Get all latest measurements:
my_series = http_client.get_measurements()
Get specific measurements:
subject_ids = ["fca1f5c9-e78a-48a3-b5b0-e0ee969a743b"]
metric_ids = ["3c47681d-c782-45b2-8544-55eba5b398af"]
# measurements from last two hours
to_date = datetime.datetime.utcnow()
from_date = to_date - datetime.timedelta(hours=2)
order = "asc"
my_series = http_client.get_measurements(
subjects=subjects, # Optional iff 'from_date' or 'to_date' is None else only 1 allowed
metrics=metrics, # Optional iff 'from_date' or 'to_date' is None else only 1 allowed
from_date=from_date,# Optional
to_date=to_date, # Optional
order=order, # Optional, default = asc
)
Subclasses of BlockbaxModel which extend Pydantic BaseModel, providing methods to handle responses from and format requests for the Blockbax API.
A PropertyType
model representing a property type.
id
: UUIDname
: strexternal_id
: strcreated_date
: datetimeupdated_date
: datetimedata_type
: strpredefined_values
: boolvalues
: List[PropertyTypeValue]add_value(value: Any, caption: Optional[str] = None) -> None
: Store a predefined value. Optionally store its corresponding caption.
ValueError
: Raised when given number could not be converted to a Decimal
ValueError
: Raised when predefined_values
is set to True
remove_value(value: Any) -> None
: Remove a predefined value.
ValueError
: Raised when predefined_values
is set to True
change_value(old_value: Any, new_value: Any) -> None
: Changes the value of an already existing property value.
ValueError
: Raised when predefined_values
is set to True
change_caption(value: Any, caption: str) -> None
: Changes the caption of an already existing property value.
ValueError
: Raised when predefined_values
is set to True
contains_value(value: Any) -> bool
: Returns True
if Property type has a Property value equal to the given value.Type aliases for NumberPropertyTypeValue
,TextPropertyTypeValue
,LocationPropertyTypeValue
,MapLayerPropertyTypeValue
,ImagePropertyTypeValue
,UnknownDataTypePropertyTypeValue
. Each of these fields are inherited from their corresponding data type mixin and property type value base. For instance the NumberPropertyTypeValue
can contain attributes of id, caption, inherit from PropertyTypeValueBase
and should contain the number
field from number mixin.
The utility type adapter property_type_value_adapter
from the same module that contains mentioned type aliases can be used to create a valid property type value from the Python object. For example property_type_value_adapter.model_validate({“text”:“hello world!”}) creates an instance of TextPropertyTypeValue
.
Base model for all property type value models.
id
[optional, default=None]: UUID; automatically converted to UUID if string is passed.caption
[optional, default=None]: strinherit
[optional, default=None]: boolExample
# Add a value
my_new_number_value = 2
caption = "two"
PropertyType.add_value(my_new_number_value, caption)
# Change a value
old_value = 2
new_value = 3
PropertyType.change_value(old_value, new_value)
value = 3
caption = "Three"
PropertyType.change_caption(value, caption)
# Check if the property type contains a value
existing_value = 3
PropertyType.contains_value(existing_value)
> True
# Remove a value
my_old_location_value = {
"lat":51.925171,
"lon":4.475660,
}
PropertyType.remove_value(my_old_location_value)
A SubjectType
model representing a subject type.
id
: UUIDname
: strcreated_date
: datetimeupdated_date
[optional, default=None]: datetimeparent_subject_type_ids
[optional, default=None]: List[UUID]primary_location
[optional, default=None]: SubjectTypePrimaryLocationproperty_types
[optional, default=None]: List[SubjectTypePropertyType]add_property_types(property_type: List[dict]) -> None
: Adds new property types to its property_types
attribute.remove_property_types(property_type_ids: List[Union[UUID, str]]) -> None
: Removes property types from its property_types
attribute by ID.contains_property_type(property_type_id: Union[UUID, str]) -> bool
: Returns True
if the Subject type defines a property type with given ID.Property type value of a SubjectType
.
id
[optional, default=None]: UUID; automatically converted to UUID if string is passed.caption
[optional, default=None]: strinherit
[optional, default=None]: booltype
: Literal[“PROPERTY_TYPE”, “METRIC”]id
: UUID; automatically converted to UUID if string is passed.Example
my_new_property_types = [{
"id" : "54a6850f-a7ae-40ba-8934-aba1fbddbeab",
"required" : True,
"visible" : True
}]
SubjectType.add_property_types(my_new_property_types)
property_type_ids_to_remove = ["e5f7ec09-4af4-4ac1-8837-124a0b7c9e37"]
SubjectType.remove_property_types(property_type_ids_to_remove)
existing_property_type_id = "54a6850f-a7ae-40ba-8934-aba1fbddbeab"
SubjectType.contains_property_type(existing_property_type_id)
> True
A Metric
model representing a metric.
id
: UUIDcreated_date
: datetimesubject_type_id
: UUIDname
: strdata_type
: Literal[“NUMBER”, “TEXT”, “LOCATION”]type
: Literal[“INGESTED”, “CALCULATED”, “SIMULATED”]updated_date
[optional, default=None ]: datetimeunit
[optional, default=None ]: strprecision
[optional, default=None ]: intvisible
[default=True ]: booldiscrete
[default=False ]: boolexternal_id
[optional, default=None ]: str. Optional for creating metric. Always populated in returned values.mapping_level
[optional, default=None ]: Literal[“OWN”, “CHILD”]A Subject
model representing a subject.
id
: UUIDname
: strsubject_type_id
: UUIDexternal_id
: strcreated_date
: datetimeproperties
[optional, default=[]]: List[SubjectProperty]ingestion_ids
[optional, default=[]]: List[IngestionDetails]updated_date
[optional, default=None]: datetimeparent_subject_id
[optional, default=None]: UUIDget_property_by_type_id(property_type_id: Union[UUID, str]) -> Optional[SubjectProperty]
: Gets a property by the property type id if the subject has a property of that property type.
ValueError
: Raised when given number could not be converted to a Decimal
set_properties(property_values: List[Union[Dict[Any, Any], SubjectProperty]]) -> None
: Store a property values in properties
attribute.
ValueError
: Raised when given number could not be converted to a Decimal
remove_properties(property_type_ids: List[Union[UUID, str]]) -> None
: Remove a property value from properties
attribute.override_ingestion_id(metric_id: Union[UUID, str], ingestion_id: str) -> None
: Stored an ingestion ID to override in ingestion_ids
attribute per metric ID and sets deriveIngestionId
to False
.derive_ingestion_id(metric_id: Union[UUID, str]) -> None
: Remove an ingestion ID to override in ingestion_ids
attribute per metric ID and sets deriveIngestionId
to True
.get_ingestion_id(metric_id: Union[UUID, str]) -> Optional[str]
: Get the first matched ingestion id with a specific metric id.get_metric_id(ingestion_id: str) -> Optional[UUID]
: Get the metric id of an ingestion id.has_ingestion_ids(ingestion_ids: List[str]) -> bool
: If the subject has all passed ingestion ids.has_ingestion_id(ingestion_id: str) -> bool
: If the subject has a specific passed ingestion id.has_metric_id(metric_id: Union[UUID, str]) -> bool
: If the subject has an ingestion id with the passed metric id.Type aliases for NumberSubjectProperty
,TextSubjectProperty
,LocationSubjectProperty
,MapLayerSubjectProperty
,ImageSubjectProperty
,PreDefinedSubjectProperty
, UnknownDataTypeSubjectProperty
. Each of these fields are inherited from their corresponding data type mixin and subject property base. For instance the NumberSubjectProperty
can contain attributes of type_id, caption, inherit from SubjectPropertyBase
and should contain the number
field from number mixin.
The utility type adapter subject_property_adapter
from the same module that contains mentioned type aliases can be used to create a valid subject property value from the Python object. For example subject_property_adapter.model_validate({“typeID”:“A valid UUID”, “text”:“hello world!”}) creates an instance of TextPropertyTypeValue
.
Base model for all subject property models.
type_id
[optional, default=None]: UUID; automatically converted to UUID if string is passed.value_id
[optional, default=None]: UUID; automatically converted to UUID if string is passed.caption
[optional, default=None]: strinherit
[optional, default=None]: boolmetric_id
: UUIDderive_ingestion_id
[optional, default=False]: boolingestion_id
[optional, default=None]: strProperty value Example
# dictionary's representing different types to property values:
# "TEXT" data_type defined by property_type
my_property_type_id = "a8c89d3f-8fa2-480d-a013-8ff9adc16a4c"
text_property = {
"typeId": my_property_type_id,
"text": "my_property_value"
}
# "NUMBER" data_type defined by property_type
my_property_type_id = "e85f1b55-07bd-40d5-85a5-04c07dd3f12f"
number_property = {
"typeId": my_property_type_id,
"number": 6
}
# "LOCATION" data_type defined by property_type
my_property_type_id = "5c2df77a-b700-460b-a87d-5adc03f915bb"
location_property = {
"typeId": my_property_type_id,
"location": {
"lat": 51.997903,
"lon": 4.3721174,
"alt": 0 # Optional
}
}
updated_properties = [
text_property,
number_property,
location_property
]
# You can add property values like this
Subject.set_properties(updated_properties)
# You can remove property values like this
my_property_type_ids_to_remove = ["e85f1b55-07bd-40d5-85a5-04c07dd3f12f"]
Subject.remove_properties(my_property_type_ids_to_remove)
Property value Example
# add ingestion IDs
my_metric_id = "f4870f59-2e4b-4fc5-8d83-477fcf1f4fe2"
my_new_ingestion_id = "my-ingestion-id"
Subject.set_ingestion_id(my_metric_id, my_ingestion_id)
# Remove ingestion ID:
my_metric_id_to_remove = "9a754b09-311c-4f80-b94e-1d36f6e81e26"
Subject.remove_ingestion_id(my_metric_id_to_remove)
An Iterable Series
model representing a series of measurements that belong to a combination of a subject and metric ID.
subject_id
: Subject IDmetric_id
: Metric IDmeasurements
: List of MeasurementExample
# Iterate over measurements
for measurement in my_series:
date = measurement.date
value = measurement.get_value()
A Measurement
model representing either a number or location measurement.
Depending on the data type a subclass of the Measurement
will be returned.
This subclass will only contain either one of the following attributes: text
, number
or location
.
date
: [optional, default=None ]: Integer unix timestampnumber
[optional, default=None ]: Decimallocation
[optional, default=None ]: dicttext
[optional, default=None ]: strget_value() -> Any
: Get value stored in either the number
, location
or text
attribute.Example
my_value = Measurement.get_value()
A Event
model representing an event.
id
: UUIDevent_trigger_id
: UUIDevent_trigger_version
: intevent_level
: Literal[“OK”, “INFORMATION”, “WARNING”, “PROBLEM”]subject_id
: UUIDcondition_set_ids
: List[UUID]start_date
: datetimeend_date
[optional]: datetime = Nonesuppressed
: boolA EventTrigger
model representing an event trigger.
created_date
: datetimesubject_type_id
: UUIDname
: strversion
: intactive
: boolevaluation_trigger
: Literal[“INPUT_METRICS”, “SUBJECT_METRICS”]evaluation_constraint
: Literal[“NONE”, “ALL_TIMESTAMPS_MATCH”]event_rules
: List[EventRule]id
[optional]: UUIDupdated_date
[optional]: datetimesubject_filter
[optional]: SubjectFilterA EventRule
model representing an event rule.
event_level
: Literal[“OK”, “INFORMATION”, “WARNING”, “PROBLEM”]condition_sets
: List[ConditionSet]A ConditionSet
model representing a set of conditions for an event rule.
id
: Optional[Union[UUID, str]] = Nonedescription
: strinput_conditions
: List[InputCondition]duration_condition
: Optional[DurationCondition] = Noneoccurrence_condition
: Optional[OccurrenceCondition] = Noneday_time_condition
: Optional[DayTimeCondition] = NoneA InputCondition
model representing a condition used in an event rule.
type
: Literal[“THRESHOLD”, “TEXT_MATCH”, “GEOFENCE”]left_operand
: Operandcomparison_operator
: Literal[
“LESS_THAN”,
“LESS_THAN_OR_EQUALS”,
“EQUALS”,
“NOT_EQUALS”,
“GREATER_THAN_OR_EQUALS”,
“GREATER_THAN”,
“CONTAINS”,
“NOT_CONTAINS”,
“STARTS_WITH”,
“NOT_STARTS_WITH”,
“ENDS_WITH”,
“NOT_ENDS_WITH”,
“MATCHES_REGEX”,
“NOT_MATCHES_REGEX”,
]right_operand
: Operandoffset
: OffsetA DurationCondition
model representing a duration-based condition used in an event rule.
period
: PeriodAn OccurrenceCondition
model representing an occurrence-based condition used in an event rule.
period
: Periodoccurrences
: intA DayTimeCondition
model representing a day-time based condition used in an event rule.
MONDAY
: Optional[List[DayTimeConditionRange]]TUESDAY
: Optional[List[DayTimeConditionRange]]WEDNESDAY
: Optional[List[DayTimeConditionRange]]THURSDAY
: Optional[List[DayTimeConditionRange]]FRIDAY
: Optional[List[DayTimeConditionRange]]SATURDAY
: Optional[List[DayTimeConditionRange]]SUNDAY
: Optional[List[DayTimeConditionRange]]A DayTimeConditionRange
model representing a time range within a day for DayTimeCondition
.
from_time
: strto_time
: strA Period
model representing a time period with a specific unit and amount.
unit
: Literal[“MILLISECOND”, “SECOND”, “MINUTE”, “HOUR”, “DAY”, “WEEK”]amount
: intA Operand
model representing different types of operands used in conditions or calculations.
type
: Literal[“METRIC”, “PROPERTY_TYPE”, “STATIC_VALUE”, “VALUE_CHANGE”, “CALCULATION”]id
: Optional[Union[MetricId, PropertyTypeId, str]] = Nonenumber
: Optional[Union[int, float, Decimal, str]] = Nonetext
: Optional[str] = Nonelocation
: Optional[Location] = Nonearea
: Optional[Area] = Noneaggregation
: Optional[Aggregation] = Noneleft_operand
: Optional[Operand] = Nonearithmetic_operator
: Optional[Literal[
“ADDITION”,
“MULTIPLICATION”,
“DIVISION”,
“DISTANCE”,
“DIFFERENCE”,
“ABSOLUTE_DIFFERENCE”,
“PERCENTAGE_DIFFERENCE”,
“ABSOLUTE_PERCENTAGE_DIFFERENCE”,
]] = Noneright_operand
: Optional[Operand] = Noneoffset
: Optional[Offset] = NoneRepresents an aggregation function with its period.
function
: Literal[“MIN”, “MAX”, “SUM”, “COUNT”, “AVG”]period
: PeriodRepresents an offset function with its type and optional period.
type
: Literal[“PREVIOUS_VALUE”, “PERIOD”]period
: Optional[Period]Represents a subject filter that can include or exclude certain subjects based on the specified filter items.
include
: Optional[SubjectFilterItem]exclude
: Optional[SubjectFilterItem]Represents a filter item for subjects, allowing for filtering by subject IDs and property values.
subject_ids
: Optional[List[Union[UUID, str]]]property_values
: Optional[List[SubjectPropertyValuesFilter]]Represents a filter for subject property values based on type ID and associated value IDs.
type_id
: Union[UUID, str]value_ids
: List[Union[UUID, str]]Mixins, models, and adapters used by higher level methods and models.
number
and the method of get_value()
.Mixin model DataTypeMixinABC
. This mixin extends Blockbax base model and provides abstract methods that are implemented in all of the data types.
get_value() -> Any
: Get value stored in either the text
, number
, location
, map_layer
or image
attribute.get_data_type() -> str
: Returns the string indicating the property value data type, either: text
, number
, location
, mapLayer
or image
Mixin model TextTypeMixin
. Store text value in the text field.
text
: strMixin model NumberTypeMixin
. Store number value in the number field.
number
: Union[int, float, Decimal]Mixin model LocationTypeMixin
. Store location value in the location field.
location
: LocationMixin model MapLayerTypeMixin
. Store map layer value in the map_layer field.
map_layer
: MapLayerMixin model ImageTypeMixin
. Store image value in the image field.
image
: ImageMixin model AreaTypeMixin
. Store area value in the area field.
area
:Area[#area]Store location value in the Location
model.
lat
: Latitude (-90 to 90 for the integer part and 8 digits behind the decimal point).lon
: Longitude (-180 to 180 for the integer part and 8 digits behind the decimal point).alt
[optional, default=None ]: Altitude (-180 to 180 for the integer part and 8 digits behind the decimal point).Store map_layer value in the MapLayer
model.
image_data
: Base64 encoded image file that can be a gif, png or jpeg with a max size of 5 MB.image_path
: In the returned JSON imageData is turned into an imagePath in the format /projects/{projectId}/propertyTypes/{propertyTypeId}/values/{valueId}/files/{imageFile} which can then be retrieved from there.left_bottom
: Locationleft_top
: Locationright_bottom
: Locationright_top
: LocationStore image value in the Image
model.
image_data
: Base64 encoded image file that can be a gif, png or jpeg with a max size of 5 MB.image_path
: In the returned JSON imageData is turned into an imagePath in the format /projects/{projectId}/propertyTypes/{propertyTypeId}/values/{valueId}/files/{imageFile} which can then be retrieved from there.Store polygon value in the Polygon
model.
outerRing
: List[Location] of the outer ring coordinates of the polygon with a lat and lon value that must express a valid polygon that is drawn counter-clockwise. The last coordinate should be the same as the first.