diff --git a/src/tailscale/__init__.py b/src/tailscale/__init__.py index a048aa7..7e619d7 100644 --- a/src/tailscale/__init__.py +++ b/src/tailscale/__init__.py @@ -1,5 +1,5 @@ """Asynchronous client for the Tailscale API.""" -from .models import ClientConnectivity, ClientSupports, Device +from .models import ClientConnectivity, ClientSupports, Device, Devices from .tailscale import ( Tailscale, TailscaleAuthenticationError, @@ -11,6 +11,7 @@ "ClientConnectivity", "ClientSupports", "Device", + "Devices", "Tailscale", "TailscaleAuthenticationError", "TailscaleConnectionError", diff --git a/src/tailscale/models.py b/src/tailscale/models.py index f9f834e..67d8805 100644 --- a/src/tailscale/models.py +++ b/src/tailscale/models.py @@ -1,8 +1,10 @@ """Asynchronous client for the Tailscale API.""" +from __future__ import annotations + from datetime import datetime -from typing import Any, List, Optional +from typing import Any, Dict, List, Optional -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, validator class ClientSupports(BaseModel): @@ -56,4 +58,17 @@ class Device(BaseModel): class Devices(BaseModel): """Object holding Tailscale device information.""" - devices: List[Device] + devices: Dict[str, Device] + + @validator("devices", pre=True) + @classmethod + def convert_to_dict(cls, data: list[dict]) -> dict[Any, dict]: # noqa: F841 + """Convert list into dict, keyed by device id. + + Args: + data: List of dicts to convert. + + Returns: + dict: Converted list of dicts. + """ + return {device["id"]: device for device in data} diff --git a/src/tailscale/tailscale.py b/src/tailscale/tailscale.py index c6313e0..9c903b6 100644 --- a/src/tailscale/tailscale.py +++ b/src/tailscale/tailscale.py @@ -105,11 +105,11 @@ async def _request( return await response.json(content_type=None) - async def devices(self) -> list[Device]: + async def devices(self) -> dict[str, Device]: """Get devices information from the Tailscale API. Returns: - Returns a list of Tailscale devices. + Returns a dictionary of Tailscale devices. """ data = await self._request(f"tailnet/{self.tailnet}/devices") return Devices.parse_obj(data).devices