Skip to main content
Skip table of contents

Example Creating OSLC Links with Python

We have noticed some OSLC Connect users with IBM ELM want to bulk import some OSLC Links. If you are using Global Configuration, the Links are only stored in Jira, and you can rapidly import links using the Jira API.

Note that when using this technique, OSLC Connect does not validate your links, targets, or GC context. The validity of the links created will be up to the script creator and executor.

We are starting with a simple Excel spreadsheet. This has a Jira Key, a Link Type, and Target Resource(s). The target resources are the URIs for the DNG Requirements.

Example.xlsx

We are then using a basic Python script that will read the Excel file (using Pandas), Use REST APIs with Jira (using requests), and then inspecting and creating Json content for the body of our requests.

We have documented the script so users can learn and update it.

PY
# Simple demonstration of reading an excel file to create some OSLC links in Jira
#
# Format of the XLS file is
#
# Jira Key, Relationship Type, Target URL (in this case DNG)
#
# Basic flow is to 
#  1) Read XLS
#  2) Iterate across Rows (do any parsing)
#  3) Check to see if a link already exists
#  5) Add remote link if needed
#
# Note, we are not checking the validity of the end-points or the proper formating of 
#  the relationship type, or extracting the remote title.
#
# Note, optimizations can be done, but this is a demonstrator not intended for performance optimizations

# imports
import pandas as pd
import os
from dotenv import load_dotenv
import requests
from requests.auth import HTTPBasicAuth
import json


def checkForLinkExisting (
        JiraKey : str,
        LinkType : str,
        LinkTarget : str,
        ) -> bool :
    # Check to see if a link exists already
    # Get the remote links on the artifact 
    # Inspect if the link already exists    
    url = f"{jiraRoot}/rest/api/latest/issue/{JiraKey}/remotelink"
    existingLinks = requests.get(url, auth=basic, verify=False)
  
    if existingLinks.status_code == 200 :
        linksObj = existingLinks.json()
        for link in linksObj :
            if link['application']['type'] == 'com.sodius.oslc.app.jira' :
                if link['relationship'] == LinkType :
                    if link['object']['url'] == LinkTarget :
                        # link already exists, return true
                        return True
    # no link found, return false
    return False
    
def addLink (        
        JiraKey : str,
        LinkType : str,
        LinkTarget : str,
        LinkTitle : str = "Generated Title",
        ) -> bool :
    
        url = f"{jiraRoot}/rest/api/latest/issue/{JiraKey}/remotelink"
        headers = {'Content-Type': 'application/json'}  
        
        # Now build the Json structure https://developer.atlassian.com/server/jira/platform/jira-rest-api-for-remote-issue-links/
        # With OSLC specific configuration https://docs.sodiuswillert.com/oslc-connect/latest/understanding-oslc-connect-for-jira-link-storage
        #	{
        #    "application": {
        #        "type": "com.sodius.oslc.app.jira",
        #        "name": "Collaboration Link"
        #    },
        #    "relationship": LinkType,
        #    "object": {
        #        "url": LinkTarget,
        #        "title": "Generated Link",
        #    }
        #    }
        
        body = json.dumps( {'application': { 'type' : 'com.sodius.oslc.app.jira' , 'name' : 'Collaboration Link' },
                            'relationship' : LinkType ,
                            "object" : { 'url' : LinkTarget, 'title' : LinkTitle} } )
            
        addLink = requests.post(url, auth=basic, headers=headers, verify=False, data=body)
               
        if addLink.status_code==201 :
            return True
        else :
            return False
        
# Load our user password information from file
load_dotenv()
basic = HTTPBasicAuth(os.getenv('JIRA_USER_ID'), os.getenv('JIRA_USER_PASSWORD') )

jiraRoot = 'https://phoenix-jira.sodiuswillert.cloud'

links_df = pd.read_excel('example.xlsx')

# Interate across our rows in our Excel file (now in a data frame)
for i in range(0, len(links_df)):
    # Need to split the link Target
    row = links_df.iloc[i]
    jiraKey = row['Jira Key']
    linkType = row['Link Type']
    # Getting the targets of the links.  Assuming multiple and removing the Query parameters
    targets = [text.strip().split('?')[0] for text in row['Target Resource'].split(",")]

    for target in targets:
        linkExists = checkForLinkExisting( jiraKey, linkType, target )
        if not linkExists:
            print(f'Creating Link on {jiraKey} to {str(target)}')
            addLink( jiraKey, linkType, target )
        else:
            print(f'Skipping Link (already there) on {jiraKey} to {str(target)}')
    

All scripts are provided as is. Users are responsible for testing and validating the behavior. The purpose is an example of what is possible. Enhancements or customizations can be requested and performed under a Statement of Work.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.