import AlteryxPythonSDK as Sdk import xml.etree.ElementTree as etree import os, time import sys class AyxPlugin: def __init__(self, n_tool_id: int, alteryx_engine: object, output_anchor_mgr: object): # Default properties self.n_tool_id = n_tool_id self.alteryx_engine = alteryx_engine self.output_anchor_mgr = output_anchor_mgr # Custom properties self.parent_field = None self.child_field = None self.is_initialized = True self.output_anchor = None self.single_input = None def pi_init(self, str_xml: str): self.output_anchor = self.output_anchor_mgr.get_output_anchor('Output') self.build_record_info() def pi_add_incoming_connection(self, str_type: str, str_name: str) -> object: self.single_input = IncomingInterface(self) return self.single_input def pi_add_outgoing_connection(self, str_name: str) -> bool: return True def pi_push_all_records(self, n_record_limit: int) -> bool: self.alteryx_engine.output_message(self.n_tool_id, Sdk.EngineMessageType.error, self.xmsg('Missing Incoming Connection')) return False def check_input_complete(self): if self.single_input.input_complete: self.process_output() def build_record_info(self): record_info_out = Sdk.RecordInfo(self.alteryx_engine) # A fresh record info object for outgoing records. fieldlength = 40 record_info_out.add_field('h1', Sdk.FieldType.v_wstring, fieldlength, 0, '','') record_info_out.add_field('h2', Sdk.FieldType.v_wstring, fieldlength, 0, '','') self.record_info_out = record_info_out self.output_anchor.init(record_info_out) def process_output(self): record_creator = self.record_info_out.construct_record_creator() # processing removed output = [('a','b'),('b','c')] self.output_anchor.update_progress(0.1) for o in output: self.record_info_out[0].set_from_string(record_creator, "%s" % o[0]) self.record_info_out[1].set_from_string(record_creator, "%s" % o[1]) out_record = record_creator.finalize_record() self.output_anchor.push_record(out_record, False) self.output_anchor.output_record_count(False) record_creator.reset() self.display_info_msg('Processing finished') self.output_anchor.output_record_count(True) self.output_anchor.close() def pi_close(self, b_has_errors: bool): self.output_anchor.assert_close() # Checks whether connections were properly closed. def process_update_input_progress(self): input_percent = (self.single_input.d_progress_percentage) self.alteryx_engine.output_tool_progress(self.n_tool_id, input_percent *0.5) def display_error_msg(self, msg_string: str): self.is_initialized = False self.alteryx_engine.output_message(self.n_tool_id, Sdk.EngineMessageType.error, self.xmsg(msg_string)) def display_info_msg(self, msg_string: str): self.is_initialized = False self.alteryx_engine.output_message(self.n_tool_id, Sdk.EngineMessageType.info, self.xmsg(msg_string)) def xmsg(self, msg_string: str): return msg_string class IncomingInterface: def __init__(self, parent: object): # Default properties self.parent = parent # Custom properties self.record_cnt = 0 self.record_info_out = None self.record_info_in = None self.data_in = [] self.input_complete = False self.d_progress_percentage = 0 def ii_init(self, record_info_in: object) -> bool: self.record_copier = Sdk.RecordCopier(record_info_in, record_info_in) for index in range(record_info_in.num_fields): self.record_copier.add(index, index) self.record_copier.done_adding() self.record_info_in = record_info_in self.parent_fielddef = self.record_info_in.get_field_by_name('parent', True) self.child_fielddef = self.record_info_in.get_field_by_name('child', True) return True def ii_push_record(self, in_record: object) -> bool: parent = self.parent_fielddef.get_as_string(in_record) child = self.child_fielddef.get_as_string(in_record) if parent != child: self.data_in.append([parent,child]) return True def ii_update_progress(self, d_percent: float): self.d_progress_percentage = d_percent self.parent.process_update_input_progress() def ii_close(self): self.input_complete = True self.parent.check_input_complete() return True