"""Zephir Client library """ from os.path import isfile from requests import get, post from json import dumps, loads from typing import Dict # import warnings # from urllib3.exceptions import InsecureRequestWarning from tiramisu_cmdline_parser import TiramisuCmdlineParser from argparse import RawDescriptionHelpFormatter from tiramisu_api import Config from .config import config, TO_JSON # warnings.simplefilter('ignore', InsecureRequestWarning) class CucchiaiataParser(TiramisuCmdlineParser): def print_help(self, *args, **kwargs): if not self.config.option('message').value.get(): self.remove_empty_od = False return super().print_help(*args, **kwargs) class Parser: def __init__(self): # retrieve config's option self.cucchiaiata_config = config self.remote_url = self.cucchiaiata_config.remote_url self.remote_config = self.remote_json_to_config() # build a tiramisu parser and parse argument parser = CucchiaiataParser(self.remote_config, fullpath=False, remove_empty_od=True, display_modified_value=False, formatter_class=RawDescriptionHelpFormatter) parser.parse_args() def get(self): # get current message message = self.remote_config.option('message').value.get() payload = self.get_payload(message) # send message result = self.send_data(message, payload) # convert some results (file) to json if message in TO_JSON: if isinstance(result, list): for res in result: _to_json(res) else: _to_json(result) return dumps(result, indent=config.indent) def remote_json_to_config(self, headers=None, config_type=Config): "retrieves the remote config from the distant api description" req = get(self.remote_url, headers=headers, verify=False) code = req.status_code if code != 200: err = get_error_from_http(req) raise Exception('unable to load url ({}): {} ({})'.format(self.remote_url, err, code)) json = req.json() return config_type(json) def send_data(self, message: str, payload: Dict): # get stored token if available if isfile(self.cucchiaiata_config.token_file): token = open(self.cucchiaiata_config.token_file).read() else: token = '' final_url = '{}/{}'.format(self.remote_url, message) headers = {'Authorization':'Bearer {}'.format(token)} ret = post(final_url, data=dumps(payload), headers=headers, # FIXME verify=False) if ret.status_code != 200: raise Exception(ret.text) response = ret.json() if 'error' in response: if 'reason' in response['error']['kwargs']: raise Exception("{}".format(response['error']['kwargs']['reason'])) raise Exception('erreur inconnue') else: return(response['response']) def _to_json(self, res): for key, value in res.items(): if key in TO_JSON[message]: res[key] = loads(value) def get_payload(self, message: str): # remove symlinkoption and default value from payload payload = {} for option in self.remote_config.option(message).list(): if not option.owner.isdefault() and not option.option.issymlinkoption(): payload[option.option.name()] = option.value.get() return payload def get_error_from_http(self, req): try: json = req.json() err = json['error']['kwargs']['reason'] except: err = req.text return err def configure_server(server, session_id, version, message, reporter=None): url = 'https://{}/config/{}/api'.format(server, session_id) token = open(config.token_file).read() headers = {'Authorization':'Bearer {}'.format(token)} tconfig = remote_json_to_config(url, headers, ConfigConfigurationAPI) tconfig.version = version tconfig.message = message tconfig.url = server tconfig.session_id = session_id tconfig.reporter = reporter return tconfig def configuration(config, session_id, configure): parameters = sys.argv.copy() # get sessionid index session_id try: index = parameters.index('-s') except ValueError: try: index = parameters.index('--sessionid') except ValueError: remote_config = remote_json_to_config(config.remote_url) parser = cmdline_factory(remote_config) parser.print_help() sys.exit(1) parameters.pop(index) session_id = parameters.pop(index) # remove config.session.server.configure parameters.pop(1) # remove commandline prog = parameters.pop(0) try: conf = configure_server(config.url, session_id, config.version, configure) parser = TiramisuCmdlineParser(conf, prog, unrestraint=True, fullpath=True) parser.parse_args(parameters, valid_mandatory=False) config.send() except Exception as err: if config.debug: print_exc() print(_("Error: {}").format(err)) sys.exit(1)