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, platform_security_token: str, app_name: str, stage: str, need_poll: bool = True): self.platform_security_token = platform_security_token self.app_name = app_name self.stage = stage self.endpoint = 'https://platform.sprinthub.ru/' self.configs_url = urllib.parse.urljoin(self.endpoint, 'configs/get') self.experiments_url = urllib.parse.urljoin(self.endpoint, 'experiments/get') self.staff_url = urllib.parse.urljoin(self.endpoint, 'is_staff') self.fetch_url = urllib.parse.urljoin(self.endpoint, '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, params, with_exception=False, retries_count=3): exception_to_throw = None for _ in range(retries_count): try: response = get( url, headers={'X-Security-Token': self.platform_security_token}, 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): return self.config_storage[name] def get_experiment(self, name): return self.experiment_storage[name] platform = PlatformClient( os.getenv('PLATFORM_SECURITY_TOKEN'), 'Ruletka', os.getenv('STAGE', 'local') )