import os from datetime import datetime, timedelta import requests from .exceptions import AuthError class AtlasClient: """ Atlas API client. Provides base generic interface to Atlas API and maintains auth tokens freshness. """ def __init__( self, host: str = "", client_id: str = "", client_secret: str = "", audience: str = "", schema: str = "https", ): self._host = host or os.environ.get("ATLAS_HOST") self._schema = schema self._api_root = f"{self._schema}://{self._host}/api/v1" self._client_id = client_id or os.environ.get("ATLAS_CLIENT_ID") self._client_secret = client_secret or os.environ.get("ATLAS_CLIENT_SECRET") self._audience = audience or os.environ.get("ATLAS_AUDIENCE") self._token = "" self._token_expires_at = None def request(self, url: str, method: str = "GET", **kwargs): url = url[1:] if url.startswith("/") else url headers = kwargs.get("headers") or dict() headers.update({f"Authorization": f"Bearer {self.get_token()}"}) return requests.request( url=f"{self._api_root}/{url}", method=method, headers=headers, **kwargs ) def get_token(self): if ( self._token and self._token_expires_at - timedelta(seconds=60) > datetime.now() ): return self._token url = f"{self._schema}://{self._host}/oauth/token" resp = requests.post( url, data={ "audience": self._audience, "grant_type": "client_credentials", "client_id": self._client_id, "client_secret": self._client_secret, }, ) if not resp.ok: raise AuthError("Unable to get access token") data = resp.json() self._token = data.get("access_token") self._token_expires_at = datetime.now() + timedelta( seconds=data.get("expires_in") ) return self._token