Python Endpoint Client Examples

This is a quick tutorial on how to use R4J's web services using python scripts. The following examples will allow a faster start for users to use the R4J web services. 

Requirements

  1. Python 2.7.x https://www.python.org/downloads/
  2. Requests http://docs.python-requests.org/en/master/user/install/

Imports

The import code block used in the examples

# Import the request HTTP library for python 
# Documentation http://docs.python-requests.org/en/master/user/quickstart/ 
import requests 


# Import HTTPBasicAuth to handle the required authentication for the web services 
from requests.auth import HTTPBasicAuth 


# Import json library to process encoding and decoding of JSON responses 
import json

Constant variables

The constant variables used in all the examples. Refer to the comments for the contents and use of this variables.

# the host URL of the JIRA instance, e.g. 'http://localhost:8080' or 'http://example.com' HOST_URL = 'http://example.com' 
HOST_URL = 'http://example.com'

# valid username and password with rights to configure Requirements USERNAME = 'myUsername' PASSWORD = 'myPassword'
USERNAME = 'myUsername'
PASSWORD = 'myPassword'

Requirements endpoint library

The python script file with the collection of all methods used in the examples.

Endpoint library
# Import the request HTTP library for python
# Documentation http://docs.python-requests.org/en/master/user/quickstart/
import requests

# Import HTTPBasicAuth to handle the required authentication for the web services
from requests.auth import HTTPBasicAuth

# Import json library to process encoding and decoding of JSON
import json

'''
The following section are methods to use the Requirements General REST API
'''


def get_requirements_version(host_url, username, password):
    """
    This method is used to get R4J version
    """

    # The REST API path to get R4J version
    path_uri = '/rest/com.easesolutions.jira.plugins.requirements/1.0/version'

    # Send a GET request to get R4J version
    # Return the result of the GET request
    try:
        return requests.get(host_url + path_uri, auth=HTTPBasicAuth(username, password))
    except requests.exceptions.RequestException as e:
        print e


'''
The following section are methods to use the Requirements Baselines REST API
'''


def get_all_baselines(host_url, username, password):
    """
    This method is used to get all baselines
    """

    # The REST API path to search for tree elements
    path_uri = '/rest/com.easesolutions.jira.plugins.requirements/1.0/baselines'

    # Send a GET request to get all baselines
    # Return the result of the GET request
    try:
        return requests.get(host_url + path_uri, auth=HTTPBasicAuth(username, password))
    except requests.exceptions.RequestException as e:
        print e


def get_baseline_by_id(host_url, username, password, baseline_id):
    """
    This method is used to get detailed information for a given baseline
    Template parameters:
    [baseline_id] the ID of the baseline
    """

    # The REST API path to get detailed information for a given baseline
    path_uri = '/rest/com.easesolutions.jira.plugins.requirements/1.0/baseline/' + baseline_id

    # Send a GET request to get detailed information for a given baseline
    # Return the result of the GET request
    try:
        return requests.get(host_url + path_uri, auth=HTTPBasicAuth(username, password))
    except requests.exceptions.RequestException as e:
        print e


def get_baseline_by_project(host_url, username, password, project_key):
    """
    This method is used to get all baselines for a given project
    Template parameters:
    [project_key] the project key
    """

    # The REST API path to get all baselines for a given project
    path_uri = '/rest/com.easesolutions.jira.plugins.requirements/1.0/baselines/project/' + project_key

    # Send a GET request to get all baselines
    # Return the result of the GET request
    try:
        return requests.get(host_url + path_uri, auth=HTTPBasicAuth(username, password))
    except requests.exceptions.RequestException as e:
        print e


def create_baseline_root_folder(host_url, username, password, project_key, baseline_name, baseline_description):
    """
    This method is used to create a new baseline on the project's root folder
    Template parameters:
    [project_key] the project key
    Query parameters:
    [baseline_name] the name of the new baseline
    [baseline_description] description of the new baseline
    """

    # The REST API path to create a new baseline on the project's root folder
    path_uri = '/rest/com.easesolutions.jira.plugins.requirements/1.0/tree/' + project_key + '/baseline?'

    # The field-value pair/s that will be added to the query string
    baseline_name_field_value = 'name=' + baseline_name
    baseline_description_field_value = '&description=' + baseline_description

    # The query string to be added to the URI
    query_string = baseline_name_field_value + baseline_description_field_value

    # Send a POST request to create a new baseline on the project's root folder
    # Return the result of the POST request
    try:
        return requests.post(host_url + path_uri + query_string, auth=HTTPBasicAuth(username, password))
    except requests.exceptions.RequestException as e:
        print e


def create_baseline_specific_folder(host_url, username, password, project_key,
                                    folder_id, baseline_name, baseline_description):
    """
    This method is used to create a new baseline on a given folder
    Template parameters:
    [project_key] the project key
    [folder_id] the ID of the folder to create the baseline on
    Query parameters:
    [baseline_name] the name of the new baseline
    [baseline_description] description of the new baseline
    """

    # The REST API path to create a new baseline on a given folder
    path_uri = '/rest/com.easesolutions.jira.plugins.requirements/1.0/tree/' + \
               project_key + '/baseline/' + folder_id + '?'

    # The field-value pair/s that will be added to the query string
    baseline_name_field_value = 'name=' + baseline_name
    baseline_description_field_value = '&description=' + baseline_description

    # The query string to be added to the URI
    query_string = baseline_name_field_value + baseline_description_field_value

    # Send a POST request to create a new baseline on the project's root folder
    # Return the result of the POST request
    try:
        return requests.post(host_url + path_uri + query_string, auth=HTTPBasicAuth(username, password))
    except requests.exceptions.RequestException as e:
        print e


'''
The following section are methods to use the Requirements Project Tree REST API
'''


def search_tree_element(host_url, username, password, project_key, element_path):
    """
    This method is used to search for tree elements
    Template parameters:
    [project_key] the project key
    Query parameters:
    [element_path] the path to search in
    """

    # The REST API path to search for tree elements
    path_uri = '/rest/com.easesolutions.jira.plugins.requirements/1.0/search/' + project_key + '?'

    # The field-value pair/s that will be added to the query string
    element_path_field_value = 'path=' + element_path

    # The query string to be added to the URI
    query_string = element_path_field_value

    # Send a GET request to search for tree elements
    # Return result of the GET request
    try:
        return requests.get(host_url + path_uri + query_string, auth=HTTPBasicAuth(username, password))
    except requests.exceptions.RequestException as e:
        print e


def get_tree_structure(host_url, username, password, project_key):
    """
    This method is used to get complete tree structure for an existing project
    Template parameters:
    [project_key] the project key
    """

    # The REST API path to get complete tree structure for an existing project
    path_uri = '/rest/com.easesolutions.jira.plugins.requirements/1.0/tree/' + project_key

    # Send a GET request to get complete tree structure for an existing project
    # Return the result of the GET request is saved in response variable
    try:
        return requests.get(host_url + path_uri, auth=HTTPBasicAuth(username, password))
    except requests.exceptions.RequestException as e:
        print e


def create_folder_on_project_root(host_url, username, password, project_key, folder_name, folder_description):
    """
    This method is used to create a new folder on project root
    Template parameters:
    [project_key] the project key
    Query parameters:
    [folder_name] the name of the new folder
    [folder_description] optional description of the new folder
    """

    # The REST API path to create a folder on project root
    path_uri = '/rest/com.easesolutions.jira.plugins.requirements/1.0/tree/' + project_key + '/folder?'

    # The field-value pair/s that will be added to the query string
    project_name_field_value = 'name=' + folder_name
    project_description_field_value = '&description=' + folder_description

    # The query string to be added to the URI
    query_string = project_name_field_value + project_description_field_value

    # Send a POST request to create a folder in root in the Requirements
    # Return result of the POST request
    try:
        return requests.post(host_url + path_uri + query_string, auth=HTTPBasicAuth(username, password))
    except requests.exceptions.RequestException as e:
        print e


def create_folder_on_specified_folder(host_url, username, password, project_key, folder_id,
                                      folder_name, folder_description):
    """
    This method is used to create a new folder under a specified folder
    Template parameters:
    [project_key] the project key
    [folder_id] the ID of the parent folder
    Query parameters:
    [folder_name] the name of the new folder
    [folder_description] optional description of the new folder
    """

    # The REST API path to create a folder on a specified folder
    path_uri = '/rest/com.easesolutions.jira.plugins.requirements/1.0/tree/' + \
               project_key + '/folder/' + str(folder_id) + '?'

    # The field-value pair/s that will be added to the query string
    project_name_field_value = 'name=' + folder_name
    project_description_field_value = '&description=' + folder_description

    # The query string to be added to the URI
    query_string = project_name_field_value + project_description_field_value

    # Send a POST request to create a folder under a specified folder
    # Return the result of the POST request
    try:
        return requests.post(host_url + path_uri + query_string, auth=HTTPBasicAuth(username, password))
    except requests.exceptions.RequestException as e:
        print e


def delete_folder(host_url, username, password, project_key, folder_id):
    """
    This method is used to delete specified folder in Requirements
    Template parameters:
    [project_key] the project key
    [folder_id] the ID of the parent folder
    """

    # The REST API path to delete a folder on project root
    path_uri = '/rest/com.easesolutions.jira.plugins.requirements/1.0/tree/' + project_key + '/folder/' + folder_id

    # Send a DELETE request to delete a folder in the Requirements
    # Return the result of the DELETE request
    try:
        return requests.delete(host_url + path_uri, auth=HTTPBasicAuth(username, password))
    except requests.exceptions.RequestException as e:
        print e


def add_issue_to_root(host_url, username, password, project_key, issue_key):
    """
    This method is used to add an existing issue to root folder
    Template parameters:
    [project_key] the project key
    Query parameter
    [issue_key] the key of the issue to be added
    """

    # The REST API path to add an issue on the root folder
    path_uri = '/rest/com.easesolutions.jira.plugins.requirements/1.0/tree/' + project_key + '/rootissue?'

    # The field-value pair/s that will be added to the query string
    issue_key_field_value = 'issuekey=' + issue_key

    # The query string to be added to the URI
    query_string = issue_key_field_value

    # Send a POST request to add an issue on the root folder of Requirements
    # Return the result of the POST request
    try:
        return requests.post(host_url + path_uri + query_string, auth=HTTPBasicAuth(username, password))
    except requests.exceptions.RequestException as e:
        print e


def add_issue_to_folder(host_url, username, password, project_key, folder_id, issue_key):
    """
    This method is used to add an existing issue to a given folder
    Template parameters:
    [project_key] the project key
    [folder_id] the folder ID
    Query parameter
    [issue_key] the key of the issue to be associated
    """

    # The REST API path to add an issue on the specified folder
    path_uri = '/rest/com.easesolutions.jira.plugins.requirements/1.0/tree/' + \
               project_key + '/folderissue/' + folder_id + '?'

    # The field-value pair/s that will be added to the query string
    issue_key_field_value = 'issuekey=' + issue_key

    # The query string to be added to the URI
    query_string = issue_key_field_value

    # Send a POST request to add  an existing issue to a given folder
    # Return the result of the POST request
    try:
        return requests.post(host_url + path_uri + query_string, auth=HTTPBasicAuth(username, password))
    except requests.exceptions.RequestException as e:
        print e


def remove_issue_from_root(host_url, username, password, project_key, issue_key):
    """
    This method is used to delete an existing issue from the root folder
    Template parameters:
    [project_key] the project key
    Query parameter
    [issue_key] the key of the issue to be deleted
    """

    # The REST API path to delete an issue on project root
    path_uri = '/rest/com.easesolutions.jira.plugins.requirements/1.0/tree/' + project_key + '/rootissue?'

    # The field-value pair/s that will be added to the query string
    issue_key_field_value = 'issuekey=' + issue_key

    # The query string to be added to the URI
    query_string = issue_key_field_value

    # Send a DELETE request to delete an issue in the Requirements
    # Return the result of the DELETE request
    try:
        return requests.delete(host_url + path_uri + query_string, auth=HTTPBasicAuth(username, password))
    except requests.exceptions.RequestException as e:
        print e


def remove_issue_from_folder(host_url, username, password, project_key, folder_id, issue_key):
    """
    This method is used to remove an issue association from a given folder
    Template parameters:
    [project_key] the project key
    [folder_id] the folder ID
    Query parameter
    [issue_key] the key of the issue whose association should be removed
    """

    # The REST API path to remove an issue association from a given folder
    path_uri = '/rest/com.easesolutions.jira.plugins.requirements/1.0/tree/' + \
               project_key + '/folderissue/' + folder_id + '?'

    # The field-value pair/s for the query string of the URI
    issue_key_field_value = 'issuekey=' + issue_key

    # The query string to be added to the URI
    query_string = issue_key_field_value

    # Send a DELETE request to remove an issue association from a given folder
    # The full DELETE URL is host_url + path_uri + query_string
    # The result of the DELETE request is saved in response variable
    response = requests.delete(host_url + path_uri + query_string, auth=HTTPBasicAuth(username, password))

    # Check response if issue was added on the given folder of Requirements
    if response.status_code == 200:
        print "Issue association removed from folder"
    else:
        print 'Error code: ', response.status_code
        print response.text


def move_issue(host_url, username, password, project_key, issue_key, source_folder, target_folder):
    """
    This method is used to move an existing issue association to a new folder
    Template parameters:
    [project_key] the project key
    Query parameter
    [issue_key] the key of the issue to be moved
    [source_folder] the ID of the source folder
    [target_folder] the ID of the destination folder
    """

    # The REST API path to move an existing issue association to a new folder
    path_uri = '/rest/com.easesolutions.jira.plugins.requirements/1.0/tree/' + project_key + '/moveissue?'

    # The field-value pair/s for the query string of the URI
    source_folder_field_value = 'from=' + source_folder
    target_folder_field_value = '&to=' + target_folder
    issue_key_field_value = '&issuekey=' + issue_key

    # The query string to be added to the URI
    query_string = source_folder_field_value + target_folder_field_value + issue_key_field_value

    # Send a POST request to move an existing issue association to the target folder
    # Return the result of the POST request
    try:
        return requests.post(host_url + path_uri + query_string, auth=HTTPBasicAuth(username, password))
    except requests.exceptions.RequestException as e:
        print e


def get_all_child_requirements(host_url, username, password, project_key, parent_key):
    """
    This method is used to get all child requirements for a given issuekey in a specific project.
    Template parameters:
    [project_key] the project key
    [parent_key] the key of the parent issue
    """

    # The REST API path to add an issue on the root folder
    path_uri = '/rest/com.easesolutions.jira.plugins.requirements/1.0/child-req/' + project_key + '/' + parent_key

    # Send a GET request to add an issue on the root folder of Requirements
    # Return the result of the GET request
    try:
        return requests.get(host_url + path_uri, auth=HTTPBasicAuth(username, password))
    except requests.exceptions.RequestException as e:
        print e


def add_child_requirement_relation(host_url, username, password, project_key, parent_key, child_key):
    """
    This method is used to creates a child requirement relation for a given issuekey in a specific project
    Template parameters:
    [project_key] the project key
    [parent_key] the key of the parent issue
    Query parameters:
    [child_key] key of the child issue
    """

    # The REST API path to add an issue on the root folder
    path_uri = '/rest/com.easesolutions.jira.plugins.requirements/1.0/child-req/' + project_key + '/' + parent_key + '?'

    # The field-value pair/s for the query string of the URI
    child_key_field_value = 'childKey=' + child_key

    # The query string to be added to the URI
    query_string = child_key_field_value

    # Send a POST request to creates a child requirement relation for a given issuekey
    # Return the result of the POST request
    try:
        return requests.post(host_url + path_uri + query_string, auth=HTTPBasicAuth(username, password))
    except requests.exceptions.RequestException as e:
        print e


def remove_child_requirement_relation(host_url, username, password, project_key, parent_key, child_key):
    """
    This method is used to removed a child requirement relation for a given issuekey in a specific project
    Template parameters:
    [project_key] the project key
    [parent_key] the key of the parent issue
    Query parameters:
    [child_key] key of the child issue
    """

    # The REST API path to add an issue on the root folder
    path_uri = '/rest/com.easesolutions.jira.plugins.requirements/1.0/child-req/' + project_key + '/' + parent_key + '?'

    # The field-value pair/s for the query string of the URI
    child_key_field_value = 'childKey=' + child_key

    # The query string to be added to the URI
    query_string = child_key_field_value

    # Send a DELETE request to creates a child requirement relation for a given issuekey
    # Return the result of the DELETE request
    try:
        return requests.delete(host_url + path_uri + query_string, auth=HTTPBasicAuth(username, password))
    except requests.exceptions.RequestException as e:
        print e


'''
The following section are methods to use the Requirements Issues REST API
'''


def get_requirements_path_for_issues(host_url, username, password, jql):
    """
    This method is used to get all requirements path for all issues returned by a jql
    Template parameters:
    [jql] the JQL statement
    """

    # The REST API path to search for tree elements
    path_uri = '/rest/com.easesolutions.jira.plugins.requirements/1.0/issue/req-path/' + jql

    # Send a GET request to get all requirements path for all issues returned by a jql
    # Return the result of the GET request is saved in response variable
    try:
        return requests.get(host_url + path_uri, auth=HTTPBasicAuth(username, password))
    except requests.exceptions.RequestException as e:
        print e


'''
The following section are methods to use the REST API that are not yet defined in the documentation
'''


def enable_project(host_url, username, password, project_key):
    """
    This method is used to enable a project in Requirements.
    Template parameters:
    [project_key] is the project that will be enabled in Requirements
    """

    # The REST API path to enable a project in Requirements
    path_uri = '/rest/com.easesolutions.jira.plugins.requirements/1.0/projects/enable/' + project_key

    # Send a POST request to enable a project in the Requirements
    # The result of the POST request is saved in response variable
    try:
        return requests.post(host_url + path_uri, auth=HTTPBasicAuth(username, password))
    except requests.exceptions.RequestException as e:
        print e


def disable_project(host_url, username, password, project_key):
    """
    This method is used to disable a project in Requirements.
    Template parameters:
    [project_key] is the project that will be disabled in Requirements
    """

    # The REST API path to disable a project in Requirements
    path_uri = '/rest/com.easesolutions.jira.plugins.requirements/1.0/projects/disable/' + project_key

    # Send a POST request to disable a project in the Requirements
    # Return the result of the post request
    try:
        return requests.post(host_url + path_uri, auth=HTTPBasicAuth(username, password))
    except requests.exceptions.RequestException as e:
        print e


def reuse(host_url, username, password, source_folder, target_folder, rule_name):
    """
    This method trigger a requirements reuse. Source and target may be in different projects.
    Query parameters:
    [source_folder] is the the source folder for reuse (e.g. Requirements Plugin/Implementation)
    [target_folder] is the the target folder for the reuse (e.g. Requirements Plugin/Features/Baseline/Permissions)
    [rule_name] is the the name of a reuse rule (e.g. "rule 27")
    """

    # The REST API path to reuse a requirement
    path_uri = '/rest/com.easesolutions.jira.plugins.requirements/1.0/tree/reuse?'

    # The field-value pair/s for the query string of the URI
    source_folder_field_value = 'sourceFolder=' + source_folder
    target_folder_field_value = '&targetFolder=' + target_folder
    rule_name_field_value = '&ruleName=' + rule_name

    # The query string to be added to the URI
    query_string = source_folder_field_value + target_folder_field_value + rule_name_field_value

    # Send a POST request to reuse Requirements
    # Return the result of the POST request
    try:
        return requests.post(host_url + path_uri + query_string, auth=HTTPBasicAuth(username, password))
    except requests.exceptions.RequestException as e:
        print e


def configure_suspect(host_url, username, password, project_key, fields_list, link_type_id, scope, notify_assignee,
                      notify_reporter, notify_project_lead, notify_user_list):
    """
    This method is used to configure the Requirements Suspect Configuration
    Query parameters:
    [project_key] the project key
    Query parameters:
    [fields_list] fields that trigger a suspect
    [link_type_id] link types that should be affected if a field change
    [scope] define if a change in an issue will trigger suspect. Accepts 'both' or 'downstream'
    [notify_assignee] notify assignee if set to true
    [notify_reporter] notify reporter if set to true
    [notify_project_lead] notify project lead if set to true
    [notify_user_list] the jira users to be notified
    """

    # The REST API path to configure the Requirements Suspect Configuration
    path_uri = '/rest/com.easesolutions.jira.plugins.requirements/1.0/' + project_key + '/suspectconfiguration?'

    # The query string to be added to the URI
    query_string = ""

    # The field-value pair/s for the query string of the URI
    if not fields_list:
        query_string = 'fieldList=' + fields_list
    if not link_type_id:
        if not query_string:
            query_string = '&linkTypeIds=' + link_type_id
        else:
            query_string = 'linkTypeIds=' + link_type_id
    if not scope:
        if not query_string:
            query_string = '&scope=' + scope
        else:
            query_string = 'scope=' + scope
    if not notify_assignee:
        if not query_string:
            query_string = '&notifyAssignee=' + notify_assignee
        else:
            query_string = 'notifyAssignee=' + notify_assignee
    if not notify_reporter:
        if not query_string:
            query_string = '&notifyReporter=' + notify_reporter
        else:
            query_string = 'notifyReporter=' + notify_reporter
    if not notify_project_lead:
        if not query_string:
            query_string = '&notifyProjectLead=' + notify_project_lead
        else:
            query_string = 'notifyProjectLead=' + notify_project_lead
    if not notify_user_list:
        if not query_string:
            query_string = '&notifyUserList=' + notify_user_list
        else:
            query_string = 'notifyUserList=' + notify_user_list

    # Send a PUT request to configure the Requirements Suspect Configuration
    # Return the result of the PUT request
    response = requests.put(host_url + path_uri + query_string,
                            auth=HTTPBasicAuth(username, password))

    # Check response if Suspect is configured
    if response.status_code == 200:
        print response.text
    else:
        print 'Error code: ', response.status_code
        print response.text


def create_scheduled_job(host_url, username, password, project_key, job_name, folder_id, jql_or_filter, interval):
    """
    This method allows the creation of jobs for the scheduled adding of existing issues
    Query parameters:
    [project_key] the project key
    Query parameters:
    [job_name] the name of the scheduled job
    [folder_id] the folder id of the tree folder
    [filter] the JQL or JIRA filter
    [interval] the time interval in minutes
    """

    # The REST API path to allow the creation of jobs for the scheduled adding of existing issues
    path_uri = '/rest/com.easesolutions.jira.plugins.requirements/1.0/tree/' + project_key + '/createscheduledjob?'

    # The field-value pair/s for the query string of the URI
    job_name_field_value = 'name=' + job_name
    folder_id_field_value = '&&folderId=' + folder_id
    filter_field_value = '&filter=' + jql_or_filter
    interval_field_value = '&interval=' + interval

    # The query string to be added to the URI
    query_string = job_name_field_value + folder_id_field_value + filter_field_value + interval_field_value

    # Send a POST request to allow the creation of jobs for the scheduled adding of existing issues
    # The full POST URL is host_url + path_uri + query_string
    # The result of the POST request is saved in response variable
    response = requests.post(host_url + path_uri + query_string,
                             auth=HTTPBasicAuth(username, password))

    # Check response if scheduled job is created
    if response.status_code == 201:
        print response.text
    else:
        print 'Error code: ', response.status_code
        print response.text


def print_folder_structure(folders):
    # If folder has values then print the information of the folder
    if folders:
        for folder in folders:
            print '\n%s %s' % ('Display name: ', folder['name_display'])
            print '%s %s' % ('Folder ID: ', folder['id'])
            print '%s %s' % ('Parent folder ID: ', folder['parent'])

            # Perform recursion if there is a folder under this folder
            sub_folders = folder['folders']
            print_folder_structure(sub_folders)