Export Plugins

With the Export custom plugin, you can add your own export format to Ango Hub with only a few clicks.

The Export custom plugin provides a way for you to obtain the normal Ango JSON Export, manipulate it from within a Python script, and present its manipulated version to users for download.

Creating an Export Plugin

Following the steps outlined in this section, create a new plugin from the UI, choosing "Export" as the plugin type.

Then, create and run a Python script using the ExportPlugin class you can find in our ango Python package under ango.plugins.

In this script, you will get the 'regular' Ango export as input, and you will need to provide a .zip file as well as its name as output. An example is provided below.

You will need to add the ango package to your Python environment by running

pip install ango

Here is the class's documentation, and an example:

ExportPlugin

Parameters:

  • id: str

    • The plugin's ID. You may obtain this ID from the plugin's information box in the Development section of the Plugin page.

  • secret: str

    • The plugin's secret. You can think of this as a private key you'll need to be able to connect your script to the plugin. You may obtain this secret from the plugin's information box in the Development section of the Plugin page.

  • callback: Callable[[str, dict], Tuple[str, BytesIO]]

    • The callback function. This function will be run whenever a user asks for the export using this plugin. More on the callback function below.

  • host: str, default="https://api.ango.ai"

    • You do not need to change the host unless you are creating plugins in environments other than our main Cloud instance at hub.ango.ai.

Callback Function

Parameters:

  • **data: dict

    • projectId: str

      • The ID of the project for which the export was wanted.

    • jsonExport: dict

      • The normal JSON export in Ango Hub Annotation Format. This is the export you would get if you manually requested the export in the "JSON" format.

    • logger: PluginLogger

      • [TODO]

    • apiKey: str

      • The API key of the user running the plugin.

    • orgId: str

      • The organization ID of the organization where the plugin is run.

    • runBy: str

      • User ID of the user running the plugin.

    • session: str

      • ID of the session opened when the plugin is run.

    • configJSON: str

      • The config JSON your users will pass to you through the Config JSON text field when running the plugin. Warning: the JSON will be passed as a string so you will have to destringify it. Example code to obtain the original JSON as a Python object named config:

def sample_callback(**data):
    config_str = data.get('configJSON')
    config = json.loads(config_str)

Returns:

  • zip_file_name: str

    • When closing your callback, you'll need to return the name of the export .zip file as a string here.

  • zip_data: BytesIO

    • The final .zip you will provide users with, containing the export.

Sample Python Script

import json
import zipfile
from tqdm import tqdm
from io import BytesIO
from ango.plugins import ExportPlugin, run

HOST = '<YOUR HOST>'
PLUGIN_ID = '<YOUR PLUGIN ID>'
PLUGIN_SECRET = '<YOUR PLUGIN SECRET>'


def sample_callback(**data):
    # Extract input parameters
    project_id = data.get('projectId')
    json_export = data.get('jsonExport')
    logger = data.get('logger')
    config_str = data.get('configJSON')
    config = json.loads(config_str)

    logger.info("Plugin session is started!")

    # Check config input
    separator_char = '-'
    if 'separator-character' in config:
        if isinstance(config['separator-character'], str):
            separator_char = config['separator-character']

    # Convert annotation data to intended format
    file_list = []
    for image_index, asset in enumerate(tqdm(json_export)):
        external_id = asset['externalId']
        data_url = asset['asset']
        objects = asset['tasks'][0]['objects']

        object_list = []
        for obj in objects:
            if "bounding-box" in obj:
                class_name = obj['title']
                x, y = int(round(obj["bounding-box"]['x'])), int(round(obj["bounding-box"]['y']))
                w, h = int(round(obj["bounding-box"]['width'])), int(round(obj["bounding-box"]['height']))

                single_object_string = ' '.join([class_name, str(x), str(y), str(w), str(h)])
                object_list.append(single_object_string)
        object_string = separator_char.join(object_list)
        file_list.append({'externalId': external_id, 'URL': data_url, 'Annotations': object_string})

    # Create zip file
    zip_file_name = project_id + '.zip'
    zip_data = BytesIO()
    with zipfile.ZipFile(zip_data, mode="w") as zf:
        zf.writestr(project_id + '.json', json.dumps(file_list, indent=4))

    logger.info("Plugin session is ended!")
    return zip_file_name, zip_data


if __name__ == "__main__":
    plugin = ExportPlugin(id=PLUGIN_ID,
                          secret=PLUGIN_SECRET,
                          callback=sample_callback,
                          host=HOST)

    run(plugin, host=HOST)

Find an always up-to-date version of this sample code at:

For this example, we use the following default Config JSON:

{
  "separator-character": "-"
}

Getting an Export using the Plugin

Your Python script needs to be running for users to be able to download exports using your format.

Navigate to the project you'd like to get the export of. From the Settings tab, enter the Plugins section. Click Open on the Export plugin of interest.

From the dialog that pops up, click on Run. You will get a notification when your export is ready.

Last updated