def format_commands(self, ctx, formatter): """Custom formatter to control whether a command is displayed Note: This is only called when formatting the help message. """ ctx.obj = ContextObject() try: ctx.obj.api = Connection.from_file('~/.transcriptic') except (FileNotFoundError, OSError): # This defaults to feature_groups = [] ctx.obj.api = Connection() rows = [] for subcommand in self.list_commands(ctx): cmd = self.get_command(ctx, subcommand) if cmd is None: continue try: if cmd.feature is not None and \ cmd.feature in ctx.obj.api.feature_groups: help = cmd.short_help or '' rows.append((subcommand, help)) else: continue except AttributeError: help = cmd.short_help or '' rows.append((subcommand, help)) if rows: with formatter.section('Commands'): formatter.write_dl(rows)
def summarize_cmd(ctx, file, html, tree, lookup, runtime): """Summarize Autoprotocol as a list of plain English steps, as well as a visualized Job Tree contingent upon desired runtime allowance (in seconds). A Job Tree refers to a structure of protocol based on container dependency, where each node, and its corresponding number, represents an instruction of the protocol. More specifically, the tree structure contains process branches, in which the x-axis refers to the dependency depth in a given branch, while the y-axis refers to the traversal of branches themselves. Example usage is as follows: python my_script.py | transcriptic summarize --tree python my_script.py | transcriptic summarize --tree --runtime 20 python my_script.py | transcriptic summarize --html """ if lookup or html: try: config = '~/.transcriptic' ctx.obj = ContextObject() ctx.obj.api = Connection.from_file(config) except: click.echo("Connection with Transcriptic failed. " "Summarizing without lookup.", err=True) api = ctx.obj.api commands.summarize(api, file, html, tree, lookup, runtime)
def cli(ctx, apiroot, config, organization): """A command line tool for working with Transcriptic.""" if ctx.invoked_subcommand in ['login', 'compile', 'preview', 'summarize', 'init']: # For login/local commands, initialize empty connection ctx.obj = ContextObject() ctx.obj.api = Connection(use_environ=False) else: try: ctx.obj = ContextObject() ctx.obj.api = Connection.from_file(config) if organization is not None: ctx.obj.api.organization_id = organization if apiroot is not None: ctx.obj.api.api_root = apiroot except: click.echo("Welcome to TxPy! It seems like your `.transcriptic` config file is missing or out of date") analytics = click.confirm("Send TxPy CLI usage information to improve the CLI user " "experience?", default=True) ctx.obj.api = Connection(use_environ=False) # Initialize empty connection ctx.invoke(login, analytics=analytics) if ctx.obj.api.analytics: try: ctx.obj.api._post_analytics(event_action=ctx.invoked_subcommand, event_category="cli") except: pass
def summarize(ctx, file, tree, lookup, runtime): """Summarize Autoprotocol as a list of plain English steps, as well as a visualized Job Tree contingent upon desired runtime allowance (in seconds). A Job Tree refers to a structure of protocol based on container dependency, where each node, and its corresponding number, represents an instruction of the protocol. More specifically, the tree structure contains process branches, in which the x-axis refers to the dependency depth in a given branch, while the y-axis refers to the traversal of branches themselves. Example usage is as follows: python my_script.py | transcriptic summarize --tree python my_script.py | transcriptic summarize --tree --runtime 20 """ with click.open_file(file, 'r') as f: try: protocol = json.loads(f.read()) except ValueError: click.echo( "The autoprotocol you're trying to summarize is invalid.") return if lookup: try: config = '~/.transcriptic' ctx.obj = ContextObject() ctx.obj.api = Connection.from_file(config) parser = AutoprotocolParser(protocol, ctx=ctx) except: click.echo( "Connection with Transcriptic failed. " "Summarizing without lookup.", err=True) parser = AutoprotocolParser(protocol) else: parser = AutoprotocolParser(protocol) if tree: import multiprocessing print("\nGenerating Job Tree...") p = multiprocessing.Process(target=parser.job_tree) p.start() # Wait for <runtime_allowance> seconds or until process finishes p.join(runtime) # If thread is still active if p.is_alive(): print("Still running... Aborting tree construction.") print( "Please allow for more runtime allowance, or opt for no tree construction.\n" ) # Terminate p.terminate() p.join() else: print("\nYour Job Tree is complete!\n")
def cli(ctx, apiroot, config, organization): """A command line tool for working with Transcriptic.""" if ctx.invoked_subcommand in [ 'login', 'compile', 'preview', 'summarize', 'init' ]: # For login/local commands, initialize empty connection ctx.obj = ContextObject() ctx.obj.api = Connection(use_environ=False) else: try: ctx.obj = ContextObject() ctx.obj.api = Connection.from_file(config) if organization is not None: ctx.obj.api.organization_id = organization if apiroot is not None: ctx.obj.api.api_root = apiroot except: click.echo( "Welcome to TxPy! It seems like your `.transcriptic` config file is missing or out of date" ) analytics = click.confirm( "Send TxPy CLI usage information to improve the CLI user " "experience?", default=True) ctx.obj.api = Connection( use_environ=False) # Initialize empty connection ctx.invoke(login, analytics=analytics) if ctx.obj.api.analytics: try: ctx.obj.api._post_analytics(event_action=ctx.invoked_subcommand, event_category="cli") except: pass
def connect(transcriptic_path="~/.transcriptic"): #TODO: Mirror login code from CLI try: api = Connection.from_file(transcriptic_path) except: print( "Unable to find .transcriptic file, please ensure the right path is provided" )
def summarize(ctx, file, tree, lookup, runtime): """Summarize Autoprotocol as a list of plain English steps, as well as a visualized Job Tree contingent upon desired runtime allowance (in seconds). A Job Tree refers to a structure of protocol based on container dependency, where each node, and its corresponding number, represents an instruction of the protocol. More specifically, the tree structure contains process branches, in which the x-axis refers to the dependency depth in a given branch, while the y-axis refers to the traversal of branches themselves. Example usage is as follows: python my_script.py | transcriptic summarize --tree python my_script.py | transcriptic summarize --tree --runtime 20 """ with click.open_file(file, 'r') as f: try: protocol = json.loads(f.read()) except ValueError: click.echo( "The autoprotocol you're trying to summarize is invalid.") return if lookup: try: config = '~/.transcriptic' ctx.obj = ContextObject() ctx.obj.api = Connection.from_file(config) parser = AutoprotocolParser(protocol, ctx=ctx) except: click.echo("Connection with Transcriptic failed. " "Summarizing without lookup.", err=True) parser = AutoprotocolParser(protocol) else: parser = AutoprotocolParser(protocol) if tree: import multiprocessing print("\nGenerating Job Tree...") p = multiprocessing.Process(target=parser.job_tree) p.start() # Wait for <runtime_allowance> seconds or until process finishes p.join(runtime) # If thread is still active if p.is_alive(): print("Still running... Aborting tree construction.") print( "Please allow for more runtime allowance, or opt for no tree construction.\n") # Terminate p.terminate() p.join() else: print("\nYour Job Tree is complete!\n")
def cli(ctx, apiroot, config, organization): '''A command line tool for working with Transcriptic.''' if ctx.invoked_subcommand not in ['login', 'preview', 'run']: try: ctx.obj = Connection.from_file(config) if organization is not None: ctx.obj.organization_id = organization if apiroot is not None: ctx.obj.api_root = apiroot except IOError: click.echo("Error reading config file, running " "`transcriptic login` ...") ctx.invoke(login)
def protocol_response(method, protocol_path=None, response_path=None, **kwargs): """ Helper function for getting protocol response and dumping json to response path Caveat Emptor: Does not do any additional checks on the response object, just dumps to json if possible """ from transcriptic import api if not api: from transcriptic.config import Connection api = Connection.from_file("~/.transcriptic") protocol = json.loads(open(protocol_path).read()) response = requests.post(api.get_route(method), headers=api.headers, data=json.dumps({'protocol': protocol})) with open(response_path, 'w') as out_file: json.dump(response.json(), out_file, indent=2)
def protocol_response(method, protocol_path=None, response_path=None, **kwargs): """ Helper function for getting protocol response and dumping json to response path Caveat Emptor: Does not do any additional checks on the response object, just dumps to json if possible """ from transcriptic import api if not api: from transcriptic.config import Connection api = Connection.from_file("~/.transcriptic") protocol = json.loads(open(protocol_path).read()) response = requests.post(api.get_route(method), headers=api.session.headers, data=json.dumps({'protocol': protocol})) with open(response_path, 'w') as out_file: json.dump(response.json(), out_file, indent=2)
def cli(ctx, api_root, email, token, organization, config): """A command line tool for working with Transcriptic. Note: This is the main entry point of the CLI. If specifying credentials, note that the order of preference is: --flag, environment then config file. Example: `transcriptic --organization "my_org" projects` >> `export USER_ORGANIZATION="my_org"` >> `"organization_id": "my_org" in ~/.transcriptic """ # Initialize ContextObject to be used for storing api object ctx.obj = ContextObject() if ctx.invoked_subcommand in ['compile', 'preview', 'summarize', 'init']: # For local commands, initialize empty connection ctx.obj.api = Connection() elif ctx.invoked_subcommand == 'login': # Load analytics option from existing dotfile if present, else prompt try: api = Connection.from_file(config) api.api_root = ( api_root or os.environ.get('BASE_URL', None) or api.api_root ) ctx.obj.api = api except (OSError, IOError): ctx.obj.api = Connection() # Echo a warning if other options are defined for login if organization or email or token: click.echo("Only the `--api-root` option is applicable for the " "`login` command. All other options are ignored.") else: try: api = Connection.from_file(config) api.api_root = ( api_root or os.environ.get('BASE_URL', None) or api.api_root ) api.organization_id = ( organization or os.environ.get('USER_ORGANIZATION', None) or api.organization_id ) api.email = ( email or os.environ.get('USER_EMAIL', None) or api.email ) api.token = ( token or os.environ.get('USER_TOKEN', None) or api.token ) ctx.obj.api = api except (OSError, IOError): click.echo("Welcome to TxPy! It seems like your `.transcriptic` " "config file is missing or out of date") analytics = click.confirm("Send TxPy CLI usage information to " "improve the CLI user " "experience?", default=True) ctx.obj.api = Connection() # Initialize empty connection ctx.invoke(login_cmd, api_root=api_root, analytics=analytics) if ctx.obj.api.analytics: try: ctx.obj.api._post_analytics(event_action=ctx.invoked_subcommand, event_category="cli") except requests.exceptions.RequestException: pass
def connect(transcriptic_path="~/.transcriptic"): #TODO: Mirror login code from CLI try: api = Connection.from_file(transcriptic_path) except: print ("Unable to find .transcriptic file, please ensure the right path is provided")