# 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](/plugins/plugin-developer-documentation.md#creating-a-new-plugin), 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 `imerit-ango` Python package under `imerit_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 `imerit-ango` package to your Python environment by running

```
pip install imerit-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*:

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

Returns:

* export\_response\_obj = `ExportResponse(file=zip_data, file_name=zip_file_name, storage_id="", bucket="")`
  * **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

{% code lineNumbers="true" fullWidth="false" %}

```python
import json
import zipfile
from tqdm import tqdm
from io import BytesIO
from imerit_ango.plugins import ExportPlugin, ExportResponse, 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')
    num_assets = data.get('numTasks')
    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 asset_index, asset in enumerate(tqdm(json_export)):
        external_id = asset['externalId']
        data_url = asset['asset']
        objects = asset['task']['tools']

        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!")

    export_response_obj = ExportResponse(file=zip_data, file_name=zip_file_name, storage_id="" ,bucket="")
    return export_response_obj


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

    run(plugin, host=HOST)
```

{% endcode %}

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

```json
{
  "separator-character": "-"
}
```

## Getting an Export using the Plugin

{% hint style="info" %}
Your Python script needs to be running for users to be able to download exports using your format.
{% endhint %}

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.

<figure><img src="/files/y7iqxRPSEVEiN6i605WY" alt=""><figcaption></figcaption></figure>

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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.imerit.net/plugins/plugin-developer-documentation/export-plugins.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
