import json import os import typing import urllib.parse from threading import Thread from time import sleep from requests import get class PlatformClient: def __init__(self, app_name: str, stage: str, need_poll: bool = True): self.app_name = app_name self.stage = stage self.endpoint = 'http://configurator/' self.fetch_url = urllib.parse.urljoin(self.endpoint, '/api/v1/fetch') self.config_storage = {} self.experiment_storage = {} self.staff_storage = {} self.poll_data() if need_poll: self.poll_data_in_thread() def poll_data_in_thread(self): def inner(): while True: sleep(30) self.fetch() Thread(target=inner, daemon=True).start() def poll_data(self): self.fetch(with_exception=True) def request_with_retries(self, url: str, params: dict, with_exception=False, retries_count=3): exception_to_throw = None for _ in range(retries_count): try: response = get( url, params=params ) if response.status_code == 200: return response.json() print(f'Failed to request {url}, status_code={response.status_code}') exception_to_throw = Exception('Not 200 status') except Exception as exc: print(exc) exception_to_throw = exc sleep(1) print(f'Failed fetching with retries: {url}, {params}') if with_exception: raise exception_to_throw def fetch(self, with_exception=False): if self.stage == 'local': local_platform = json.loads(open('local_platform.json', 'r').read()) self.config_storage = local_platform['configs'] self.experiment_storage = local_platform['experiments'] self.staff_storage = { key: set(value) for key, value in local_platform['platform_staff'].items() } return response_data = self.request_with_retries(self.fetch_url, { 'project': self.app_name, 'stage': self.stage, }, with_exception) self.config_storage = response_data['configs'] self.experiment_storage = response_data['experiments'] self.staff_storage = { key: set(value) for key, value in response_data['platform_staff'].items() } def is_staff(self, **kwargs): for key, value in kwargs.items(): if value in self.staff_storage[key]: return True return False def get_config(self, name: str) -> dict: return self.config_storage[name] def get_experiment(self, name: str) -> dict: return self.experiment_storage[name] platform_client = PlatformClient( 'Botalka', os.getenv('STAGE', 'local'), need_poll=True, )