Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

Retrieving projects component data from Jira Cloud with Python

Hi Atlassian Community!

I'm now sharing another simple but helpful Python script designed to retrieve project components and export them to a CSV file. This script can be incredibly useful for auditing project configurations, understanding component assignments, and generating reports.

The solution

This script leverages the Jira Cloud REST API (this endpoint specifically) to fetch component data for specified Jira project(s). It then processes this data and saves it into a CSV file with the following columns:

  • Project: The key of the Jira project the component belongs to
  • Component ID: The unique ID of the component
  • Component Name: The name of the component
  • Component Lead (ID): The account ID of the user who is the component lead (if any)
  • Component Lead Name: The display name of the component lead (if any)

The script will prompt you to enter the Jira Cloud URL, your email, API token, and the project key(s) you want to retrieve component data from.

Key features

  • Retrieves components from one or multiple projects in a single run
  • Organizes the data by project in the CSV output
  • Includes handling for components without a designated lead
  • Provides informative feedback on the retrieval process, including the number of components found per project and the total number of components retrieved
  • Saves the retrieved data into a well-structured CSV file
  • Prompts you for your Jira Cloud domain, email, and API token for secure authentication

Preparation

1) Make sure that the user acting on this script has the necessary project permissions to "Browse Projects"
2) Install the necessary Python libraries by running:

pip install requests

3) Prepare your Jira Cloud site URL (your-domain.atlassian.net), email address, and API token

The script

import requests
from requests.auth import HTTPBasicAuth
from getpass import getpass
import logging
import os
import csv
import json

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

def get_jira_auth():
    jira_domain = input("Enter your Jira Cloud domain (e.g., your-domain.atlassian.net): ")
    email = input("Enter your Jira email: ")
    api_token = getpass("Enter your Jira API token: ")
    return jira_domain, HTTPBasicAuth(email, api_token)

def get_project_components(jira_domain, auth, project_key):
    """Retrieves all components for a given Jira project."""
    base_url = f"https://{jira_domain}/rest/api/3/project/{project_key}/components"
    headers = {"Accept": "application/json"}

    try:
        response = requests.get(base_url, headers=headers, auth=auth)
        response.raise_for_status()
        components_data = response.json()
        logging.info(f"Retrieving component information for project {project_key} has been completed and {len(components_data)} components were found.")
        return components_data
    except requests.exceptions.RequestException as e:
        logging.error(f"Error retrieving components for project {project_key}: {e}")
        if response is not None and response.status_code == 401:
            logging.error("Authentication failed. Please verify your email and API token.")
        elif response is not None and response.status_code == 404:
            logging.error(f"Project with key '{project_key}' not found.")
        return None

def process_components_data(components_data, project_key):
    """Processes the component data to extract relevant information."""
    processed_components = []
    if components_data:
        for component in components_data:
            component_id = component.get('id')
            component_name = component.get('name')
            lead_account_id = component.get('lead', {}).get('accountId')
            lead_display_name = component.get('lead', {}).get('displayName')

            processed_components.append({
                'Project': project_key,
                'Component ID': component_id,
                'Component Name': component_name,
                'Component Lead (ID)': lead_account_id if lead_account_id else '',
                'Component Lead Name': lead_display_name if lead_display_name else ''
            })
    return processed_components

def save_to_csv(data, filename="jira_components.csv"):
    """Saves the processed component data to a CSV file."""
    if not data:
        logging.warning("No component data to save to CSV.")
        return

    fieldnames = data[0].keys()
    try:
        with open(filename, 'w', newline='', encoding='utf-8') as csvfile:
            writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
            writer.writeheader()
            writer.writerows(data)
        logging.info(f"Crafting CSV file with the retrieved data")
        logging.info(f"Operation completed, CSV file saved in {os.path.abspath(filename)}")
    except Exception as e:
        logging.error(f"Error saving data to CSV file: {e}")

def main():
    jira_domain, auth = get_jira_auth()

    project_keys_input = input("Enter the Jira project key(s) separated by comma (e.g., PROJ1,PROJ2): ").strip()
    project_keys = [key.strip() for key in project_keys_input.split(',')]

    all_components_data = []
    total_components = 0
    retrieved_projects = 0

    for project_key in project_keys:
        logging.info(f"Retrieving component information for {project_key} project")
        components = get_project_components(jira_domain, auth, project_key)
        if components is not None:
            processed_data = process_components_data(components, project_key)
            all_components_data.extend(processed_data)
            total_components += len(processed_data)
            retrieved_projects += 1

    logging.info(f"Data for a total of {total_components} components were retrieved from {retrieved_projects} projects")

    if all_components_data:
        save_to_csv(all_components_data)
    else:
        logging.info("No component data retrieved. CSV file will not be created.")

if __name__ == "__main__":
    main()

This is how it looks:
Zight 2025-05-16 at 1.15.07 PM.jpgimage (7).png

Disclaimer:

While this script is designed to facilitate certain interactions with JIRA Software Cloud as a convenience, it is essential to understand that its functionality is subject to change due to updates to JIRA Software Cloud’s API or other conditions that could affect its operation.

Please note that this script is provided on an "as is" and "as available" basis without any warranties of any kind. This script is not officially supported or endorsed by Atlassian, and its use is at your own discretion and risk.

Cheers!

2 comments

Matt Doar _Adaptavist_
Community Champion
May 16, 2025

Handy, thanks. I'd probably use the jira python library myself rather than requests, which always seems a bit more low-level than I need. But the end result is the same

Like Delfino Rosales likes this
James Rickards _Spark-Nel_
Contributor
May 18, 2025

Or in PowerShell you can use something close the following...

Disclaimer... this is un-tested, so it might need a few tweaks to get working, and add iteration through several projects.

function Invoke-JiraRestAPIGet {
param(
[string]$URI, [string]$UserName, [string]$APIToken
)

$pair = "$($UserName):$($APIToken)"
$encodedCreds = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($pair))
$basicAuthValue = "Basic $encodedCreds"

$Headers = @{
Authorization = $basicAuthValue;
'Accept' = 'application/json';
'Content-Type' = 'application/json'
}
$ProgressPreference = 'SilentlyContinue'
Invoke-WebRequest -Uri $URI -Headers $Headers -Method "get"
$ProgressPreference = 'Continue'
}

$Site = Read-Host -Prompt "Enter the site name"
$Username = Read-Host -Prompt "Enter a your jira username (email)"
# See: https://id.atlassian.com/manage-profile/security/api-tokens
$APIToken = Read-Host -Prompt "Enter a Jira Personal API Token"
$FilePath = Read-Host -Prompt "Enter a file path for the CSV File"
$ProjectKey = Read-Host -Prompt "Enter a project key"

$URI = "https://${Site}.atlassian.net/rest/api/3/project/${ProjectKey}/components"

Invoke-JiraRestAPIGet -Uri $URI -UserName $UserName -APIToken $APIToken `
| Select-Object -Property 'contents' | ConvertFrom-Json | Export-Csv -path $FilePath

 

Like Delfino Rosales likes this

Comment

Log in or Sign up to comment
TAGS
AUG Leaders

Atlassian Community Events