Python 3rd-party Dependencies¶
Adding 3rd-party Packages¶
In many cases, it is useful to add 3rd-party Python packages that can be used in your plugin. To do this, add dependencies to the requirements-thirdparty.txt file in the tool workspace directory.
There are 2 options:
Manually add dependencies. If you use this approach, make sure to include all dependencies (including any sub-dependencies).
2. Use pip freeze > requirements.txt
to generate a new requirements.txt file in the workspace. You will need to prune this
file to remove any dependencies that aren’t explicitly imported or required by your plugin. Do this before you
copy or overwrite the contents to the requirements-thirdparty.txt
file
Using 3rd-party Packages in Code¶
When you use 3rd-party packages in Python, you typically import these packages at the top of a file. However, if the packages that you use are large (like numpy, pandas, scikit-learn, etc.), then these imports can take a long time.
Since the update-only mode of Alteryx Designer should be as fast as possible, these import statements
can be a bottleneck. Because of this, instead of putting import statements at the top of a file, you should include these
inline so that they only occur just before they are needed. See the example below for an Input-type tool that
uses pandas to generate its data (note that pandas is imported in the on_complete
method):
class ExampleInput(Plugin):
"""Concrete implementation of an AyxPlugin."""
def __init__(self, provider: ProviderBase) -> None:
"""Construct a plugin."""
self.provider = provider
self.tool_config = provider.tool_config
self.config_value = self.tool_config["Value"]
self.output_anchor = self.provider.get_output_anchor("Output")
self.output_metadata = Metadata()
self.output_metadata.add_field("x", FieldType.float)
self.output_metadata.add_field("y", FieldType.v_wstring, size=100)
self.output_metadata.add_field("z", FieldType.float)
self.output_anchor.open(self.output_metadata)
if float(self.config_value) > 0.5:
raise WorkflowRuntimeError("Values greater than 0.5 are not allowed.")
self.provider.io.info("Plugin initialized.")
def on_incoming_connection_complete(self, anchor: "Anchor") -> None:
"""Initialize the Input Connections of this plugin."""
raise NotImplementedError("Input tools don't have input connections.")
def on_record_batch(self, "pa.Table", anchor: "Anchor") -> None:
"""Handle the record batch received through the input connection."""
raise NotImplementedError("Input tools don't receive batches.")
def on_complete(self) -> None:
"""Create all records."""
import pandas as pd
import pyarrows as pa
df = pd.DataFrame(
{
"x": [1, 2, 3],
"y": ["hello", "world", "from ayx_plugin_sdk!"],
"z": [self.config_value, self.config_value, self.config_value],
}
)
table = pa.Table.from_pandas(df)
self.provider.write_to_anchor(table)
self.provider.io.info("Completed processing records.")