Skip to content
Merged
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
60 changes: 52 additions & 8 deletions disruptive/resources/device.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
from __future__ import annotations

from typing import Optional, Any
import warnings
from typing import Any, Optional

import disruptive.logging as dtlog
import disruptive.outputs as dtoutputs
import disruptive.requests as dtrequests
from disruptive.errors import LabelUpdateError, TransferDeviceError
from disruptive.events import events
import disruptive.outputs as dtoutputs
from disruptive.errors import TransferDeviceError, LabelUpdateError


class Device(dtoutputs.OutputBase):
Expand Down Expand Up @@ -151,16 +152,21 @@ def list_devices(cls,
device_types: Optional[list[str]] = None,
label_filters: Optional[dict[str, str]] = None,
order_by: Optional[str] = None,
organization_id: Optional[str] = None,
project_ids: Optional[list[str]] = None,
**kwargs: Any,
) -> list[Device]:
"""
Gets a list of the current state of all devices in a
project, including emulated devices.
Gets a list of devices from either a project or
projects in an organization.

Parameters
----------
project_id : str
Unique ID of the target project.
Either a unique ID of the target project, or
wildcard `"-"` to list devices from all projects
in an organization. If `"-"` is provided, the
parameter `organization_id` must be set.
query : str, optional
Keyword-based device search device type, labels, and identifiers.
Does not provide additional capabilities over setting explicit
Expand All @@ -177,6 +183,14 @@ def list_devices(cls,
The field name you want to order the response by.
Referred to using dot notation (i.e. "reported.temperature.value").
Default order is ascending, but can be flipped by prefixing "-".
organization_id : str, optional
Unique ID of the target organization.
Required if `project_id` is wildcard `"-"`.
Ignored if `project_id` is unique project ID.
project_ids : list[str], optional
Filter by a list of project IDs.
Optional if `project_id` is wildcard `"-"`.
Ignored if `project_id` is unique project ID.
**kwargs
Arbitrary keyword arguments.
See the :ref:`Configuration <configuration>` page.
Expand All @@ -193,6 +207,12 @@ def list_devices(cls,
... project_id='<PROJECT_ID>',
... )

>>> # List all devices in an organization.
>>> devices = dt.Device.list_devices(
... project_id='-',
... organization_id='<ORGANIZATION_ID>',
... )

>>> # List all touch, temperature, and proximity sensors
>>> # in a project that has both the labels "room-number"
>>> # and "external-id" set to spesific values, then
Expand All @@ -213,7 +233,27 @@ def list_devices(cls,

"""

# Construct parameters dictionary.
# Enforce organization_id if project_id is wildcard.
if project_id == '-' and organization_id is None:
raise ValueError(
'Parameter `organization_id` is required when '
'`project_id` is wildcard `"-"`.'
)

# Warn about unsupported combination of parameters.
if project_id != '-' and organization_id is not None:
warnings.warn(
'Parameter `organization_id` is ignored when '
'`project_id` is not wildcard "-".',
UserWarning,
)
if project_id != '-' and project_ids is not None:
warnings.warn(
'Parameter `project_ids` is ignored when '
'`project_id` is not wildcard "-".',
UserWarning,
)

params: dict = dict()
if query is not None:
params['query'] = query
Expand All @@ -223,6 +263,10 @@ def list_devices(cls,
params['device_types'] = device_types
if order_by is not None:
params['order_by'] = order_by
if organization_id is not None:
params['organization'] = 'organizations/' + organization_id
if project_ids is not None:
params['projects'] = ['projects/' + xid for xid in project_ids]

# Convert label_filters dictionary to list of strings.
if label_filters is not None:
Expand All @@ -233,7 +277,7 @@ def list_devices(cls,

# Return list of Device objects of paginated GET response.
devices = dtrequests.DTRequest.paginated_get(
url='/projects/{}/devices'.format(project_id),
url=f'/projects/{project_id}/devices',
pagination_key='devices',
params=params,
**kwargs,
Expand Down
6 changes: 3 additions & 3 deletions tests/test_device.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from unittest.mock import patch

import disruptive
import disruptive.errors as dterrors
import disruptive.events.events as dtevents
import tests.api_responses as dtapiresponses
import disruptive.errors as dterrors


class TestDevice():
Expand Down Expand Up @@ -88,7 +88,7 @@ def test_list_devices(self, request_mock):
request_mock.assert_request_count(1)

# output should be list.
assert type(devices) == list
assert isinstance(devices, list)

# Assert output is list of Device.
for d in devices:
Expand Down Expand Up @@ -126,7 +126,7 @@ def test_list_devices_optionals(self, request_mock):
request_mock.assert_request_count(1)

# output should be list.
assert type(devices) == list
assert isinstance(devices, list)

# Assert output is list of Device.
for d in devices:
Expand Down