Skip to content

BIAN Integration

Overview

In this example we will fill a workspace with components representing the Business Areas and Business Domains defined by BIAN (Banking Industry Architecture Network). We will use the example client to interact with the Batch API in order simplify the process.

Creating the Workspace

We create a new workspace using the Blank Workspace template. We create two component types Business Area and Business Domain. We set the Business Area type to be the parent of the Business Domain type.

Model

Once the workspace has been created, we take note of the Ardoq identifier in the url. In our case the workspace id is 95a2a80b31ec6ce5c06d629e.

https://app.ardoq.com/app/.../workspace/95a2a80b31ec6ce5c06d629e?...

Writing the Script

The following Python code does not require any external dependencies, however you should have downloaded the example client. We will create a new file called bian_example.py in the same directory as the downloaded example_ardoq_client.py file. You can download thea copy of the bian_example.py script here.

Setup

The initial setup ensures that we can fetch the BIAN data. While this is not strictly needed, using the argparse library makes the script more maintainable.

import example_ardoq_client
import argparse
import json
import urllib.request
import urllib.parse

def get_BIAN(what):
    req = urllib.request.Request(
        "https://bian-modelapisandbox.azurewebsites.net/" + what
    )
    with urllib.request.urlopen(req) as resp:
        return json.loads(resp.read().decode("utf-8"))

parser = argparse.ArgumentParser()

parser.add_argument(
    "--host",
    metavar="ARDOQ_API_HOST",
    type=str,
    help="Required if you are using a custom domain",
)
parser.add_argument(
    "--org",
    metavar="ARDOQ_ORG_LABEL",
    type=str,
    help="The label associated with your org",
)
parser.add_argument(
    "--token", metavar="ARDOQ_API_TOKEN", type=str, help="Your secret API token"
)
parser.add_argument(
    "workspace",
    metavar="Ardoq Identifier",
    type=str,
    help="Ardoq identifier of your workspace",
)

args = parser.parse_args()

print("Using workspace {}".format(args.workspace))

Firstly, we need some data to upload to Ardoq. We can make requests against the BIAN Model API Sandbox. In this example we are interested in BusinessAreas and BusinessDomains. We fetch the data and store then as two lists; business_areas and business_domains.

business_areas = get_BIAN("BusinessAreas")
business_domains = get_BIAN("BusinessDomains")
We create an instance of the (example) Ardoq API client. We pass in the configuration info provided by the caller of the script.
api = example_ardoq_client.API(
    ardoq_api_host=args.host, ardoq_org_label=args.org, ardoq_api_token=args.token
)
When we created the Workspace we used "Business Area" and "Business Domain" as the component type names. Internally, these types have immutable ids. When working with the API it is (often) required to use these internal ids. Luckily, we can use the workspace context to lookup the ids for the component type names.

workspace_context = api.read_workspace_context(args.workspace)

typeId_for_name = {}
for componentType in workspace_context["componentTypes"]:
    typeId_for_name[componentType["name"]] = componentType["typeId"]

business_area_typeId = typeId_for_name["Business Area"]
business_domain_typeId = typeId_for_name["Business Domain"]

Inserting (Batch) Data

We are now ready to start computing the batch request. To ensure that we do not try to set the parent of a component to something that does not exist, we will track the batchId usage.

batch = example_ardoq_client.Batch()
batch_ids = set()
For each Business Area defined by BIAN, we will create a component in Ardoq. We assume that each name is unique and use it as the batch identifier.
for business_area in business_areas:
    business_area_name = business_area.get("name")
    assert business_area_name not in batch_ids, "A Batch Id must be unique"
    batch_ids.add(business_area_name)
    batch.create_component(
        {
            "rootWorkspace": args.workspace,
            "typeId": business_area_typeId,
            "name": business_area_name,
            "description": business_area.get("description"),
        },
        batchId=business_area_name,
    )

In our workspace hierarchy we have modelled a Business Area as having zero or more children of type Business Domain. This means that when creating a Business Domain component, we want the parent field to reference the correct Business Area component. If we were performing sequential requests we would first have to create the parent component and use the returned Ardoq identifier as the value for the parent field. This is where the batchId comes into play. In a Batch request we can set the parent field of one component to be the same value as a temporary batchId associated with some other component. When the Batch is uploaded, these Batch ids are resolved and replaced by Ardoq ids.

Info

Using a batchId lets us create both a parent and child component in the same request. You may also include both the source and target of a reference in the list of components being created.

Every Business domain has an object under the key businessArea. We expect the value of businessArea.name to belong to the set of batch_ids. However, to ensure that we can handle the case where a Business Domain object belongs to a Business Area that we do not know about, we will add an extra check before setting the parent field.

for business_domain in business_domains:
    business_area_name = business_domain.get("businessArea", {}).get("name")

    if business_area_name not in batch_ids:
        batch.create_component(
            {
                "rootWorkspace": args.workspace,
                "typeId": business_area_typeId,
                "name": business_area_name,
                "description": "Business Area used by Business Domain, but does not exist.",
            },
            batchId=business_area_name,
        )
        batch_ids.add(business_area_name)

    batch.create_component(
        {
            "rootWorkspace": args.workspace,
            "typeId": business_domain_typeId,
            "parent": business_area_name,
            "name": business_domain.get("name"),
            "description": business_domain.get("description"),
        }
    )
Finally we perform the Batch request.
print("Sending batch request")

response = api.batch(batch.body)
components_created = response.get("components", {}).get("created", [])

print("Created: {} components".format(len(components_created))) 

Running the script

Assuming that you have an API token XXX that grants you access to myorg hosted on a custom domain myorg.ardoq.com:

python3 bian_example.py --host https://myorg.ardoq.com --token XXX 95a2a80b31ec6ce5c06d629e

Should display something similar.

Using workspace: 95a2a80b31ec6ce5c06d629e      
----------------------------------------------------
Using Ardoq host: https://myorg.ardoq.com
Using API token ending: ...XXX
Using Org Label: <NOT PROVIDED>
----------------------------------------------------
Sending batch request...
Created: 50 components

If you are not using a custom domain (ie your Ardoq instance is hosted on app.ardoq.com) then you could use the following

python3 bian_example.py --org myorg --token XXX 95a2a80b31ec6ce5c06d629e
Which would display
Using workspace: 95a2a80b31ec6ce5c06d629e      
----------------------------------------------------
Using Ardoq host: https://myorg.ardoq.com
Using API token ending: ...XXX
Using Org Label: myorg
----------------------------------------------------
Sending batch request...
Created: 50 components

If you have the Workspace open in Ardoq, then you will see your components appear!

Result