def __init__(self, reg, screen=None): self.reg = reg self.client = None self.loop = None self.screen = None self.stack = 0 self.tree_walker = None # create the template topnode = TuiParentNode(dummy_flow({'id': 'Loading...'})) self.listbox = urwid.TreeListBox(urwid.TreeWalker(topnode)) header = urwid.Text('\n') footer = urwid.AttrWrap( # urwid.Text(self.FOOTER_TEXT), urwid.Text(list_bindings()), 'foot') self.view = urwid.Frame(urwid.AttrWrap(self.listbox, 'body'), header=urwid.AttrWrap(header, 'head'), footer=footer) self.filter_states = {state: True for state in TASK_STATUSES_ORDERED} if isinstance(screen, html_fragment.HtmlGenerator): # the HtmlGenerator only captures one frame # so we need to pre-populate the GUI before # starting the event loop self.update()
def get_snapshot(self): """Contact the workflow, return a tree structure In the event of error contacting the workflow the message is written to this Widget's header. Returns: dict if successful, else False """ try: if not self.client: self.client = get_client(self.reg, timeout=self.CLIENT_TIMEOUT) data = self.client( 'graphql', { 'request_string': QUERY, 'variables': { # list of task states we want to see 'taskStates': [ state for state, is_on in self.filter_states.items() if is_on ] } } ) except WorkflowStopped: self.client = None return dummy_flow({ 'name': self.reg, 'id': self.reg, 'status': 'stopped', 'stateTotals': {} }) except (ClientError, ClientTimeout) as exc: # catch network / client errors self.set_header([('workflow_error', str(exc))]) return False if isinstance(data, list): # catch GraphQL errors try: message = data[0]['error']['message'] except (IndexError, KeyError): message = str(data) self.set_header([('workflow_error', message)]) return False if len(data['workflows']) != 1: # multiple workflows in returned data - shouldn't happen raise ValueError() return compute_tree(data['workflows'][0])