Introduction
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.
Installation
Installation
pip install blockbax-sdk
You can easily install the Python SDK through pip.
Client setup
Client setup
import blockbax_sdk
project_id = "75ef0782-c63b-4afe-8e59-091f33cd88dd"
access_token = "0eVKlsqYH4QauFyij2LP6gfkFwZnK5Ta"
http_client = blockbax.HttpClient(
project_id = project_id,
access_token = access_token
)
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:
Errors
Errors usage
from blockbax_sdk import errors
try:
http_client.update_subject(subject = new_subject)
except errors.BlockbaxHTTPError as error:
# Handle error
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:
- Returned HTTP status
- Returned error details
- Detailed error message from the service
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.
Retry mechanism
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.
Request throttling
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.
Release notes
Version 1.0
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.
- For
create_subject_type
the attributeparent_ids
is marked deprecated and should be replaced withparent_subject_type_ids
. - For
get_subjects
the attributesubject_external_id
is marked deprecated and should be replaced withexternal_id
. - For
create_subject
the attributeparent_id
is marked deprecated and should be replaced withparent_subject_id
.
Property Types
Methods to create, update, delete and get property types.
Get property types
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 property types, optionally with arguments for filtering.
Arguments
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 a property type
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
)
Gets a specific property type.
Arguments
id_
[required]: Property type ID to fetch.
Returns: PropertyType
Create a property type
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 = []
)
Creates a property type
Arguments
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
Update a property type
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)
Updates a property type.
Arguments
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
Delete a property type
Delete a property type:
my_property_type_id = "e85f1b55-07bd-40d5-85a5-04c07dd3f12f"
http_client.delete_property_type(
id_ = my_property_type_id
)
Deletes a property type.
Arguments
id_
[required]: Property type ID to delete.
Returns: None
Subject Types
Methods to create, update, delete and get subject types.
Get subject types
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 subject types, optionally with arguments for filtering.
Arguments
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 a subject type
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
)
Gets a specific subject type.
Arguments
id_
[required]: Subject Type ID to fetch.
Returns: SubjectType
Create a subject type
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
)
Creates a subject type
Arguments
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
Update a subject type
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)
Updates a subject type.
Arguments
subject_type
[required]: Updated SubjectType
Returns: SubjectType
Delete a subject type
Delete Subject Type
my_subject_type_id = "526e8fee-ded2-410d-b562-888724d58183"
http_client.delete_subject_type(
id_ = my_subject_type_id
)
Deletes a subject type.
Arguments
id_
[required]: Subject type ID to delete.
Returns: None
Metrics
Methods to create, update, delete and get metrics.
Get metrics
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
)
Gets metrics, optionally with arguments for filtering.
Arguments
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 a metric
Get a single Metric
my_metric_id = "fca1f5c9-e78a-48a3-b5b0-e0ee969a743b"
single_metric = http_client.get_metric(
id_ = my_metric_id
)
Gets a specific metric.
Arguments
id_
[required]: Metric ID to fetch.
Returns: Metric
Create metrics
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
)
Creates a metric.
Arguments
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
orLOCATION
.type_
[required]: The type of the metric. Currently only theINGESTED
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
Update a metric
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)
Updates a metric.
Arguments
metric
[required]: Updated Metric
Returns: Metric
Delete a metric
Delete Metric
my_metric_id = "3c47681d-c782-45b2-8544-55eba5b398af"
http_client.delete_metric(
id_ = my_metric_id
)
Deletes a metric.
Arguments
id_
[required]: Metric ID to delete
Returns: None
Subjects
Methods to create, update, delete and get subjects.
Get subjects
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 subjects, optionally with arguments for filtering.
Arguments
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 atuple
for OR and encapsulate IDs in alist
for AND. e.g.[(A, B),C]
translates to<A>,<B>;<C>
a.k.a (A OR B) AND C.
Returns: Subject
Get a subject
Get a single Subject:
my_subject_id = "fca1f5c9-e78a-48a3-b5b0-e0ee969a743b"
single_subject = http_client.get_subject(
id_ = my_subject_id
)
Gets a specific subject.
Arguments
id_
[required]: Subject ID to fetch.
Returns: Subject
Create a 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
)
Creates a subject.
Arguments
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
Update a subject
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)
Updates a subject.
Arguments
subject
[required]: Updated Subject
Returns: Subject
Delete a subject
Delete Subject
my_subject_id = "fca1f5c9-e78a-48a3-b5b0-e0ee969a743b"
http_client.delete_subject(
id_ = my_subject_id
)
Deletes a subject.
Arguments
id_
[required]: Subject ID to delete.
Returns: None
Measurements
Methods to queue, send and get measurements
Queue a measurement
queue a number value:
# add number
my_number = 1
my_date = datetime.utcnow()
ingestion_id = "my_number_ingestion"
http_client.queue_measurement(
ingestion_id = ingestion_id,
date = date,
number = my_number
)
queue a location value:
# add location
my_location = {
"lat":51.925171,
"lon":4.475660,
"alt":0 # Optional
}
my_date = datetime.utcnow()
ingestion_id = "my_location_ingestion"
http_client.queue_measurement(
ingestion_id = ingestion_id,
date = date,
location = my_location
)
Queues measurements to send.
Arguments
ingestion_id
[required]: Ingestion IDdate
[required]:datetime
, Unix timestamp or string parsable by the dateutil.parsernumber
[optional, default=None]: Decimal number, must be filled iflocation = None
.location
[optional, default=None]: Location dictionary, must be filled ifnumber = None
.
Returns: None
Raises: ValueError
: Raised when given number could not be converted to a Decimal
Sending measurements
Send All Measurements
http_client.send_measurements()
Send select list of ingestions
ingestion_ids_to_send = ["my-first-ingestion", "my-second-ingestion"]
http_client.send_measurements(
ingestion_ids = ingestion_ids_to_send,
)
Sends queued measurements.
Arguments
ingestion_ids
[optional, default=[] ]: List of ingestion IDs to sendreset_on_success
[optional, default=True]: Option to remove the measurements on success, default will always remove measurements after they have been send
Returns: None
Get measurements
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
)
Gets measurements with arguments for filtering.
Arguments
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
Main Data Models
Subclasses of BlockbaxModel which extend Pydantic BaseModel, providing methods to handle responses from and format requests for the Blockbax API.
Property Type
Example
# 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 PropertyType
model representing a property type.
Attributes
id
: UUIDname
: strexternal_id
: strcreated_date
: datetimeupdated_date
: datetimedata_type
: strpredefined_values
: boolvalues
: List[PropertyTypeValue]
Methods
add_value(value: Any, caption: Optional[str] = None) -> None
: Store a predefined value. Optionally store its corresponding caption.- Raises:
ValueError
: Raised when given number could not be converted to aDecimal
- Raises:
ValueError
: Raised whenpredefined_values
is set toTrue
- Raises:
remove_value(value: Any) -> None
: Remove a predefined value.- Raises:
ValueError
: Raised whenpredefined_values
is set toTrue
- Raises:
change_value(old_value: Any, new_value: Any) -> None
: Changes the value of an already existing property value.- Raises:
ValueError
: Raised whenpredefined_values
is set toTrue
- Raises:
change_caption(value: Any, caption: str) -> None
: Changes the caption of an already existing property value.- Raises:
ValueError
: Raised whenpredefined_values
is set toTrue
- Raises:
contains_value(value: Any) -> bool
: ReturnsTrue
if Property type has a Property value equal to the given value.
PropertyTypeValue
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
.
PropertyTypeValueBase
Base model for all property type value models.
Attributes
id
[optional, default=None]: UUID; automatically converted to UUID if string is passed.caption
[optional, default=None]: strinherit
[optional, default=None]: bool
Subject Type
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 SubjectType
model representing a subject type.
Attributes:
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]
Methods
add_property_types(property_type: List[dict]) -> None
: Adds new property types to itsproperty_types
attribute.remove_property_types(property_type_ids: List[Union[UUID, str]]) -> None
: Removes property types from itsproperty_types
attribute by ID.contains_property_type(property_type_id: Union[UUID, str]) -> bool
: ReturnsTrue
if the Subject type defines a property type with given ID.
SubjectTypePropertyType
Property type value of a SubjectType
.
Attributes
id
[optional, default=None]: UUID; automatically converted to UUID if string is passed.caption
[optional, default=None]: strinherit
[optional, default=None]: bool
SubjectTypePrimaryLocation
Attributes
type
: Literal[“PROPERTY_TYPE”, “METRIC”]id
: UUID; automatically converted to UUID if string is passed.
Metric
A Metric
model representing a metric.
Attributes:
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”]
Subject
Property 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)
A Subject
model representing a subject.
Attributes:
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]: UUID
Methods
get_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.- Raises:
ValueError
: Raised when given number could not be converted to aDecimal
- Raises:
set_properties(property_values: List[Union[Dict[Any, Any], SubjectProperty]]) -> None
: Store a property values inproperties
attribute.- Raises:
ValueError
: Raised when given number could not be converted to aDecimal
- Raises:
remove_properties(property_type_ids: List[Union[UUID, str]]) -> None
: Remove a property value fromproperties
attribute.override_ingestion_id(metric_id: Union[UUID, str], ingestion_id: str) -> None
: Stored an ingestion ID to override iningestion_ids
attribute per metric ID and setsderiveIngestionId
toFalse
.derive_ingestion_id(metric_id: Union[UUID, str]) -> None
: Remove an ingestion ID to override iningestion_ids
attribute per metric ID and setsderiveIngestionId
toTrue
.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.
SubjectProperty
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
.
SubjectPropertyBase
Base model for all subject property models.
Attributes
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]: bool
IngestionDetails
Attributes
metric_id
: UUIDderive_ingestion_id
[optional, default=False]: boolingestion_id
[optional, default=None]: str
Series
Example
# Iterate over measurements
for measurement in my_series:
date = measurement.date
value = measurement.get_value()
An Iterable Series
model representing a series of measurements that belong to a combination of a subject and metric ID.
Attributes:
subject_id
: Subject IDmetric_id
: Metric IDmeasurements
: List of Measurement
Measurement
Example
my_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
.
Attributes:
date
: [optional, default=None ]: Integer unix timestampnumber
[optional, default=None ]: Decimallocation
[optional, default=None ]: dicttext
[optional, default=None ]: str
Methods
get_value() -> Any
: Get value stored in either thenumber
,location
ortext
attribute.
Nested Data Models
Mixins, models, and adapters used by higher level methods and models.
- Models are base data type models like Number, or Image.
- Mixins are wrappers around base models. They provide relevant fields and methods for the corresponding data type. For example a number mixin has a field of
number
and the method ofget_value()
. - Data adapters are utility Pydantic type adapters that can be used to serialize and validate data type models from parsable python objects like dictionaries.
Base mixin
Mixin model DataTypeMixinABC
. This mixin extends Blockbax base model and provides abstract methods that are implemented in all of the data types.
Methods
get_value() -> Any
: Get value stored in either thetext
,number
,location
,map_layer
orimage
attribute.get_data_type() -> str
: Returns the string indicating the property value data type, either:text
,number
,location
,mapLayer
orimage
Text mixin
Mixin model TextTypeMixin
. Store text value in the text field.
Implements:
Attributes:
text
: str
Number mixin
Mixin model NumberTypeMixin
. Store number value in the number field.
Implements:
Attributes:
number
: Union[int, float, Decimal]
Location mixin
Mixin model LocationTypeMixin
. Store location value in the location field.
Implements:
Attributes:
location
: Location
Map layer mixin
Mixin model MapLayerTypeMixin
. Store map layer value in the map_layer field.
Implements:
Attributes:
map_layer
: MapLayer
Image mixin
Mixin model ImageTypeMixin
. Store image value in the image field.
Implements:
Attributes:
image
: Image
Area mixin
Mixin model AreaTypeMixin
. Store area value in the area field.
Implements:
Attributes:
area
:Area[#area]
Location
Store location value in the Location
model.
Attributes:
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).
Map layer
Store map_layer value in the MapLayer
model.
Attributes:
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
: Location
Image
Store image value in the Image
model.
Attributes:
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.
Polygon
Store polygon value in the Polygon
model.
Attributes:
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.
AreaType
Store area value in the Area
model.
Attributes:
polygon
: Polygon