How to use external Python packages
Using external Python package
Extension are standard Python scripts running in an embedded Python engine. Every standard Python package can be used in an extension. For example, you can use url.request for a simple import like this:
import urllib.requestfrom ruxit.api.base_plugin import RemoteBasePluginclass MyPlugin (RemoteBasePlugin):def query(self, **kwargs):response = urllib.request.urlopen('https://www.google.com/')response_data = response.read()
Sometimes you may find it necessary to use an external package, for example Python driver for Apache Cassandra.
The installation of such a package requires two steps:
- Development - prepare the environment for testing an extension in extension simulator.
- Deployment - prepare the extension package for an upload to Dynatrace Server, OneAgent-monitored host (OneAgent extensions) and the ActiveGate (ActiveGate extensions).
Development environment with external package
Let's create an extension using driver for Apache Cassandra:
from cassandra.cluster import Clusterfrom ruxit.api.base_plugin import RemoteBasePluginclass MyCassandraPlugin(RemoteBasePlugin):def query(self, **kwargs):cluster = Cluster(self.config['cluster'].split(','))session = cluster.connect(self.config['space'])
In the deployment stage, the extension should be tested with extension simulator. Add the plugin.json
definition for Python script:
{"name": "custom.remote.python.MyCassandraPlugin","version": "1.0","type": "python","entity": "CUSTOM_DEVICE","processTypeNames": ["PYTHON"],"technologies": ["CASSANDRA"],"source": {"package": "my_cassandra_plugin","className": "MyCassandraPlugin","activation": "Remote"},"configUI": {"displayName": "My Cassandra Active Plugin","properties": [{"key": "cluster","displayName": "Cluster IPs","displayHint": "list of IP addresses"},{"key": "space","displayName": "Cassandra space"}]},"properties": [{"key": "cluster","type": "String"},{"key": "space","type": "String"}]}
Install the Cassandra driver in your development environment.
Every package should contain its documentation with instructions on installation process. For example, to install the Python driver for Apache Cassandra, execute the following command:
pip3 install cassandra-driver
This is sufficient for extension simulator to run an extension using an external package.
Plugin deployment with external package
In the deployment stage, you upload the developed extension to Dynatrace Server, hosts with OneAgent-monoitored hosts (OneAgent extensions) and production Environment ActiveGate (ActiveGate extensions).
For the deployment to work, the plugin.json
has to refer to the Cassandra driver.
Update the plugin.json
definition with install_requires field in the source object. You may add version condition if necessary e.g. cassadra_driver>=1.0.0:
{"name": "custom.remote.python.MyCassandraPlugin","version": "1.0","type": "python","entity": "CUSTOM_DEVICE","processTypeNames": ["PYTHON"],"technologies": ["CASSANDRA"],"source": {"package": "my_cassandra_plugin","className": "MyCassandraPlugin","activation": "Remote","install_requires": ["cassandra-driver>=1.0.0"]},"configUI": {"displayName": "My Cassandra Active Plugin","properties": [{"key": "cluster","displayName": "Cluster IPs","displayHint": "list of IP addresses"},{"key": "space","displayName": "Cassandra space"}]},"properties": [{"key": "cluster","type": "String"},{"key": "space","type": "String"}]}
The command plugin_sdk build_plugin builds the extension zip archive and uploads it to Dynatrace Server.
The zip file is located in
/opt/dynatrace/remotepluginmodule/plugin_deployment/custom.remote.python.MyCassandraPlugin.zip
on Linux
or
c:\Program Files\dynatrace\remotepluginmodule\plugin_deployment\custom.remote.python.MyCassandraPlugin.zip
on Windows
The command plugin_sdk build_plugin uses pip package manager to download and prepare any package needed by an extension.
Building extensions with external packages
The command plugin_sdk build_plugin automatically prepares an extension with the external libraries that are defined in the install_requires field of plugin.json
. You don't need to place an external package in the source extension directory.
The extension zip file is located in
/opt/dynatrace/remotepluginmodule/plugin_deployment
on Linux
or
c:\Program Files\dynatrace\remotepluginmodule\plugin_deployment
on Windows
Built-in packages
There are a few external packages already used by the plugin module. These aren't included in plugin.json
:
You can find these libraries in the THIRDPARTYLICENSEREADME.txt
file located in
/opt/dynatrace/remotepluginmodule/agent
on Linux
or
c:\Program Files\dynatrace\remotepluginmodule\agent
on Windows
Native (C-compiled) components of Python packages
If the python package that you want to use contains any native dependencies these are resolved by pip automatically so there are are additional steps required during extension deployment phase.
Note the you must build a extension on the same system (Linux or Windows) and hardware platform (ActiveGate supports only 64-bit systems) as the destination production host. Native components of the Python package are not compatible between different systems and hardware platforms.
If you encounter any obstacles in installing a package using pip, copy the package folder together with the native libraries, but without the dist-info directory, to the extension directory.
Loading external libraries
Keep in mind the order in which the libraries are loaded:
- Engine libraries (Docker client, request, urllib3, etc.)
- Built-in extension libraries (in alphabetical order of directories)
- Custom extension libraries (in alphabetical order of directories)
Custom and built-in external packages may be of a different version. Loading of the newest version isn't guaranteed.