Last active
March 21, 2017 16:09
-
-
Save Pentusha/97b0dd83e620597cfcb34781fcb7da8d to your computer and use it in GitHub Desktop.
pip3 install requests && python3 hh_api_curl_builder.py --resource hhdemo_2tables_2scalars_pg
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from argparse import ArgumentParser | |
from getpass import getpass | |
from json import dumps | |
from os.path import expanduser, join, exists | |
from sys import exit, stdout | |
from yaml import load, dump | |
from requests import Session, codes | |
def auth(config: dict, session: Session) -> Session: | |
url = '{c[base]}/api/v0.6/auth/?env={c[auth][env]}&proj={c[auth][proj]}&app={c[auth][app]}' | |
headers = {'X-Device-Id': config['auth']['device_id']} | |
auth_data = config['auth']['username'], config['auth']['password'] | |
response = session.get(url=url.format(c=config), headers=headers, auth=auth_data) | |
if response.status_code != codes.ok: | |
raise RuntimeError | |
return session | |
def get_resources_description(config: dict, session: Session) -> dict: | |
url = '{c[base]}/api/v0.6/resources_description/'.format(c=config) | |
response = session.get(url=url) | |
if response.status_code != codes.ok: | |
raise RuntimeError | |
return response.json() | |
def build_scalar(param_description: dict): | |
if param_description['DataSource'].get('Format'): | |
return param_description['DataSource']['Format'] | |
elif param_description['HyperHive'] == 'TEXT': | |
return '' | |
elif param_description['HyperHive'] == 'BIGINT': | |
return 0 | |
elif param_description['HyperHive'] == 'DOUBLE': | |
return 0.0 | |
elif param_description['HyperHive'] == 'BYTES': | |
return 'QQ==' | |
return None | |
def build_table(param_description: list): | |
return [[ | |
build_scalar(cell_description) | |
for column in param_description | |
for cell_description in column.values() | |
]] | |
def build_data(input_description: dict) -> str: | |
data = {} | |
for param_name, param_description in input_description.items(): | |
is_scalar = isinstance(param_description, dict) | |
is_table = isinstance(param_description, list) | |
if is_scalar: | |
data[param_name] = build_scalar(param_description) | |
elif is_table: | |
data[param_name] = build_table(param_description) | |
else: | |
raise RuntimeError | |
return dumps(data) | |
def build_curl_request(config: dict, session: Session, resource: str, data: str) -> str: | |
return ( | |
'curl \\\n' | |
' --silent \\\n' | |
' --request POST \\\n' | |
' --header "Content-Type: application/json" \\\n' | |
' --cookie "api_sessionid={session}" \\\n' | |
' --data \'{data}\' \\\n' | |
' {base}/api/v0.6/table/{resource}/' | |
).format( | |
session=session.cookies['api_sessionid'], | |
base=config['base'].rstrip('/'), | |
resource=resource, | |
data=data, | |
) | |
def query_yes_no(question, default='yes'): | |
valid = {'yes': True, 'y': True, 'no': False, 'n': False} | |
if default is None: | |
prompt = ' [y/n] ' | |
elif default == 'yes': | |
prompt = ' [Y/n] ' | |
elif default == "no": | |
prompt = ' [y/N] ' | |
else: | |
raise ValueError('invalid default answer: "{}"'.format(default)) | |
while True: | |
stdout.write(question + prompt) | |
choice = input().lower() | |
if default is not None and choice == '': | |
return valid[default] | |
elif choice in valid: | |
return valid[choice] | |
else: | |
stdout.write('Please respond with "yes" or "no" (or "y" or "n").\n') | |
def main(): | |
arg_parser = ArgumentParser() | |
arg_parser.add_argument('--configuration', nargs='?', default='default', type=str) | |
arg_parser.add_argument('--resource', type=str) | |
args = arg_parser.parse_args() | |
home = expanduser('~') | |
config_path = join(home, '.hhrc.yaml') | |
if not exists(config_path): | |
print('Config file ~/.hhrc.yaml not found') | |
if query_yes_no('Do you want to build default configuration?'): | |
base_url = input('Enter base URL (eg: http://127.0.0.1:8000):\n') | |
username = input('Enter username:\n') | |
password = getpass('Enter password (hidden):\n') | |
environment = input('Enter environment:\n') | |
project = input('Enter project:\n') | |
application = input('Enter application:\n') | |
device_id = input('Enter device_id:\n') | |
new_config = { | |
'default': { | |
'base': base_url, | |
'auth': { | |
'username': username, | |
'password': password, | |
'env': environment, | |
'proj': project, | |
'app': application, | |
'device_id': device_id, | |
}, | |
} | |
} | |
with open(config_path, 'w') as config_file: | |
dump(new_config, config_file) | |
print('Default configuration saved to ~/.hhrc.yaml. You could modify it manually.') | |
else: | |
return 1 | |
if not args.resource: | |
arg_parser.print_usage() | |
return 0 | |
with open(config_path) as config_file: | |
full_config = load(config_file) | |
if args.configuration not in full_config: | |
print('Configuration not found') | |
return 1 | |
config = full_config[args.configuration] | |
session = Session() | |
session = auth(config, session) | |
all_resources_description = get_resources_description(config, session) | |
if args.resource not in all_resources_description: | |
print('Resource not found') | |
return 1 | |
resource_description = all_resources_description[args.resource] | |
if resource_description['type'] != 'tabular': | |
print('Resource in not tabular') | |
return 1 | |
data = build_data(resource_description['input']) | |
curl_request = build_curl_request( | |
config=config, | |
session=session, | |
resource=args.resource, | |
data=data, | |
) | |
print(curl_request) | |
return 0 | |
if __name__ == '__main__': | |
exit_code = main() | |
exit(exit_code) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment