Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Pine queries examples and tips #341

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DOCUMENTATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -2314,7 +2314,7 @@ Get the overriden value of a service variable on a device
#### Examples:
```python
>>> balena.models.device.service_var.get('8deb12a', 'myservice', 'VAR')
>>> balena.models.device.service_var.get('8deb12a', 1234', 'VAR')
>>> balena.models.device.service_var.get('8deb12a', 1234, 'VAR')
```

<a name="deviceserviceenvvariable.get_all_by_application"></a>
Expand Down
53 changes: 53 additions & 0 deletions EXAMPLES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Pine Query Examples

This file presents a few tricks and tips regarding how to use the Pine queries more effectively, putting together some knowledge acquired while developing several applications using it. For an introduction to the Pine client, please check https://blog.balena.io/balena-python-sdk-v13/.


### Getting devices from a list of devices IDs/UUIDs

When we have a list of device UUIDs without any particular common grouping (all devices in a given application or all devices in a given organization) and want to get information about all these devices, we might be tempted to do something like:

```python
for device_uuid in list_of_device_uuids:
device = sdk.models.device.get(device_uuid)
do_something(device)
...
```
This works, but it can be rather slow as it has to get each device one by one. Instead, we can use:

```python
devices = sdk.models.device.get_all({
"$filter": {
"uuid": {
"$in": list_of_device_uuids
}
}
})

for device in devices:
do_something(device)
...
```

This second version, instead of requiring multiple round trips to the API, requires only one, which makes it faster and uses always 1 request instead of `len(list_of_device_uuids)`.

It is also interesting to mention that this pattern does not only work for `device` but for all resources in the balena API.


### Foreign key references

If we look at the typing for Foreign Key (FK) references, for example: a Device has an FK for a DeviceType on `is_of__device_type`. If we just query the device, for example:

```python
device = sdk.models.device.get(123)
print(device["is_of__device_type"])
```

The result will be a dictoinary containing only one key `__id`. Notice that if we add an `$expand`

```python
device = sdk.models.device.get(123, {"$expand": "is_of__device_type"})
print(device["is_of__device_type"])
```

The result is now a List of device types. The detail here is to notice that because in the underlying model this is a FK the List is guaranteed to have maximum size of 1. Notice that in the JS SDK we use Typescript to express this typing [here](https://github.com/balena-io/balena-sdk/blob/master/typings/pinejs-client-core.d.ts#L24) which means a either a PineDeferred (object with `__id`) or a list of maximum size 1 (and generic type T), whereas in Python type hint we just use a generic list [here](https://github.com/balena-io/balena-sdk-python/blob/master/balena/types/models.py#L10) of any size altough it is guaranteed that in runtime it will have maximum size of 1.
2 changes: 1 addition & 1 deletion balena/models/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -2253,7 +2253,7 @@ def get(self, uuid_or_id: Union[str, int], service_name_or_id: Union[str, int],

Examples:
>>> balena.models.device.service_var.get('8deb12a', 'myservice', 'VAR')
>>> balena.models.device.service_var.get('8deb12a', 1234', 'VAR')
>>> balena.models.device.service_var.get('8deb12a', 1234, 'VAR')
"""
device_id = self.__device.get(uuid_or_id, {"$select": "id"})["id"]

Expand Down