Source code for terminusgps.wialon.session

import os
import typing

import wialon.api


[docs] class WialonAPIError(Exception): """Raised when a Wialon API call fails.""" def __init__(self, message, *args, **kwargs) -> None: self.message = message self._code = int(message._code) super().__init__(message, *args, **kwargs) @property def code(self) -> int: """Wialon API error code.""" return self._code
class Wialon(wialon.api.Wialon): def call(self, *argc, **kwargs) -> dict[str, typing.Any]: try: return super().call(*argc, **kwargs) except wialon.api.WialonError as e: raise WialonAPIError(e)
[docs] class WialonSession: def __init__( self, token: str | None = None, sid: str | None = None, scheme: str = "https", host: str = "hst-api.wialon.com", port: int = 443, ) -> None: """ Starts or continues a Wialon API session. :param token: A Wialon API token. If not provided, the environment variable ``"WIALON_TOKEN"`` is used. :type token: str | None :param sid: An optional Wialon API session id. If provided, the session is continued. :type sid: str | None :param scheme: HTTP request scheme to use. Default is ``"https"``. :type scheme: str :param host: Wialon API host url. Default is ``"hst-api.wialon.com"``. :type host: str :param port: Wialon API port. Default is ``443``. :type port: int :returns: Nothing. :rtype: None """ self._token = token if token else os.getenv("WIALON_TOKEN") self._username = None self._uid = None self._wialon_api = Wialon( scheme=scheme, host=host, port=port, sid=sid, token=self.token ) def __str__(self) -> str: return f"Session #{self.id}" def __repr__(self) -> str: return f"{self.__class__}(sid={self.id})" def __enter__(self) -> "WialonSession": """ Logs into the Wialon API using :py:meth:`login`. :raises AssertionError: If the session's Wialon API :py:attr:`token` wasn't set. :returns: A valid Wialon API session. :rtype: ~terminusgps.wialon.session.WialonSession """ assert self.token, "Wialon API token wasn't set." self.login(self.token) return self def __exit__(self, exc_type, exc_value, exc_traceback) -> None: """ Logs out of the session by calling :py:meth:`logout`. :returns: Nothing. :rtype: None """ self.logout() @property def wialon_api(self) -> Wialon: return self._wialon_api @property def uid(self) -> str | None: """ User id of the session's authenticated Wialon user. :type: str | None :value: None """ return self._uid @property def username(self) -> str | None: """ Username of the session's authenticated Wialon user. :type: str | None :value: None """ return self._username @property def id(self) -> str | None: """ Wialon API session id. Shortcut property for :py:attr:`WialonSession.wialon_api.sid`. Returns :py:obj:`None` if the session wasn't logged in. :type: str | None :value: None """ return self.wialon_api.sid @property def token(self) -> str: """ Wialon API token set during :py:meth:`WialonSession.__init__`. :type: str """ return str(self._token)
[docs] def login(self, token: str, flags: int | None = None) -> str: """ Logs into the Wialon API, starts a new session then returns its id. :param token: An active Wialon API token. :type token: str :param flags: A login response flag integer. :type flags: int :raises WialonError: If the login fails. :raises AssertionError: If the login token was not set. :returns: The new session id. :rtype: str """ try: response = self.wialon_api.token_login( **{"token": token, "fl": flags if flags else 0x2} ) self._set_login_response(response) return response.get("eid", "") except (wialon.api.WialonError, ValueError): print("Failed to login to the Wialon API.") raise
[docs] def logout(self) -> None: """ Logs out of the Wialon API session. :returns: Nothing. :rtype: None """ sid = self.wialon_api.sid response = self.wialon_api.core_logout({}) if response.get("error") != 0: print( f"Failed to properly logout of session #{sid}: '{response.get('message')}'" ) self.wialon_api.sid = None
def _set_login_response(self, login_response: dict | None = None) -> None: """ Sets the Wialon API session's attributes based on a login response. :param login_response: A dictionary returned from :py:meth:`login`. :type login_response: dict :raises ValueError: If ``login_response`` wasn't provided. :returns: Nothing. :rtype: None """ if login_response is None: raise ValueError( f"Login response is required, got '{login_response}'" ) self.wialon_api.sid = login_response.get("eid") self._uid = login_response.get("user", {}).get("id") self._username = login_response.get("au")