"""This module contains the ZiplineApi class, which is the main class used to interact with the Zipline API.""" import logging from pyzipline.rest_adapter import RestAdapter from pyzipline.exceptions import PyZiplineError, FeatureDisabledError, Forbidden from pyzipline.models import * # pylint: disable=wildcard-import,unused-wildcard-import # pylint: disable=not-a-mapping class ZiplineApi: """Represents an instance of the Zipline API. All API requests should be made through this class. Args: hostname (str): The hostname of your Zipline instance, WITHOUT https or http. token (str = None): String used for authentication when making requests. ssl (bool = True): Normally set to True, but if your Zipline instance doesn't use SSL/TLS, set this to False. enforced_signing (bool = True): Normally set to True, but if having SSL/TLS cert validation issues, can turn off with False. logger (logging.Logger = None): If your app has a logger, pass it in here. """ def __init__( self, hostname: str, token: str = '', ssl: bool = True, enforced_signing: bool = True, logger: logging.Logger = None ): self._rest_adapter = RestAdapter(hostname=hostname, token=token, ssl=ssl, enforced_signing=enforced_signing, logger=logger) def get_user(self, user_id: int) -> User: """Get a user by ID /// admonition | Requires Administrator type: danger /// Args: user_id (int): Integer ID of the user to retrieve Returns: User: The user with the given ID """ result = self._rest_adapter.get(endpoint=f"user/{user_id}") return User(**result.data) def get_self(self) -> User: """Get the currently authenticated user /// admonition | Requires Authentication type: warning /// Returns: User: The currently authenticated user """ result = self._rest_adapter.get(endpoint=f"user") if result.status_code == 200: return User(**result.data) elif result.status_code == 401: raise ValueError(result.message) def check_user_exists(self, username: str, invite: str = None) -> bool: """Check if a user exists by username Args: username (str): Username to check invite (str = None): Invite code to use, only required if registration without invites is disabled Raises: FeatureDisabledError: Raised when registration or invites are disabled on the Zipline instance PyZiplineError: Raised if the API changes, causing a breaking change in this method ValueError: Raised when the username is not present, or the invite code is invalid/not present and invites are enabled Returns: bool: True if user exists, False if not """ data = {'username': username} if invite is None else {'username': username, 'code': invite} result: Result = self._rest_adapter.post(endpoint=f"user/check", data=data) if result.status_code == 200: return False if result.message == 'username already exists': return True if result.message == 'user registration is disabled': raise FeatureDisabledError('user registration or invites are disabled') if result.message == 'invalid invite code': raise ValueError(result.message + "(most likely doesn't exist)") if result.message == 'no code': raise ValueError('invite code not provided') if result.message == 'no username': raise ValueError('username not provided') raise PyZiplineError(f"{result.status_code}: {result.message}\n{result.data}") def get_self(self) -> User: """Get the currently authenticated user /// admonition | Requires Authentication type: warning /// Raises: PyZiplineError: Raised if the API changes, causing a breaking change in this method Returns: User: The currently authenticated user """ result = self._rest_adapter.get(endpoint="user") if result.status_code == 200: return User(**result.data) if result.status_code == 401: raise Forbidden(result.message) raise PyZiplineError(f"{result.status_code}: {result.message}\n{result.data}") def get_user(self, user_id: int) -> User: """Get a user by ID /// admonition | Requires Administrator type: danger /// Args: user_id (int): Integer ID of the user to retrieve Raises: Forbidden: Raised if the authenticated user is not an administrator PyZiplineError: Raised if the API changes, causing a breaking change in this method Returns: User: The user with the given ID """ result = self._rest_adapter.get(endpoint=f"user/{user_id}") if result.status_code == 200: return User(**result.data) if result.status_code == 403: raise Forbidden(result.message) raise PyZiplineError(f"{result.status_code}: {result.message}\n{result.data}")