In this post, we'll explore a step-by-step guide on how to extract all Jira tickets with their comment history using Python. This can be a crucial task for analysis, reporting or backup.
Prerequisites
Jira Account
Ensure you have access to a Jira account with the necessary permissions to view and extract ticket data.
Python Environment
Install Python on your machine if it's not already installed. This code is tested against Python 3.10
Required Libraries
Install the necessary Python libraries using the following commands:
pip install jira
pip install pandas
1. Get API token
First step is to get an API token with the right permissions. You can find more here:
In my case steps were:
- Log in to https://id.atlassian.com/manage-profile/security/api-tokens.
- Click Create API token
- Enter a label for your token
- Create.
- Copy to clipboard
P.S. You can copy the key only once - so store it somewhere in case of a need.
2. Python Extract Ticket and Changelog
Below you can find the code which is extracting full Jira history of tickets with comments:
import pandas as pd
from jira import JIRA
jira = JIRA({"server": "https://xxx.atlassian.net/"}, basic_auth=("[email protected]", "xxx"))
issues = jira.search_issues('comment ~ "keyword" and project = "XXX" ORDER BY created DESC', maxResults=None)
ls_status = []
for issue in issues:
issue_num = issue.key
issue = jira.issue(issue_num, expand="changelog,issuelinks")
changelog = issue.changelog
for history in changelog.histories:
for item in history.items:
if item.field == 'status':
statuses = {'issue_num': issue_num, 'history.created': history.created,
'item.fromString': item.fromString, 'item.toString': item.toString}
ls_status.append(statuses)
df = pd.DataFrame(ls_status)
2.1 Explain the code
Below you can find detailed explanation of this code:
-
Libraries Imported:
pandas
is used for data manipulation and analysis.jira
is used for interacting with the Jira API.
-
Jira Connection:
- Use your Jira server URL and user credentials (email and API token).
-
Issue Search:
- The JQL (Jira Query Language) query searches for issues with a specific keyword in comments. Extraction of issues belonging to a particular project and orders the results by creation date in descending order.
- The
maxResults=None
parameter ensures that all matching issues are retrieved.
-
Changelog Processing:
- The code iterates through the changelog histories of each issue.
- For each history entry, it further iterates through the items in the history.
-
Status Change Detection:
- If an item in the changelog corresponds to a change in the 'status' field, relevant information is extracted.
- We extract information such as:
- issue number (
issue_num
) - the timestamp of the status change (
history.created
) - the previous status (
item.fromString
) - and the new status (
item.toString
)
- issue number (
-
Data Storage:
- The extracted status change information is stored in the
df_status
list.
- The extracted status change information is stored in the
2.2 Data processing
In this section we will see how to calculate how much time a ticket spend in a given status.
First we will convert Jira dates and time to Pandas:
- date
- week number
- time
df['history.created'] = pd.to_datetime(df['history.created'], utc=True)
df['history.created.prev'] = df['history.created'].shift(-1)
df['date'] = df['history.created'].dt.date
df['week'] = df['history.created'].dt.isocalendar().week
df['time'] = df['history.created'].dt.time
Next we will calculate how much hours a ticket stayed in a given status by:
df['time_in_status'] = 0
df['time_in_status_days'] = 0
df['time_in_status_hours'] = 0
n = 0
for row in df.iterrows():
row = row[1]
if row.name > 0 and row['issue_num'] != df.loc[row.name - 1, :]['issue_num']:
n = 0
if row['item.fromString'] == 'To Do':
time_feed = row['history.created'] - row['history.created.prev']
df.loc[row.name, 'time_in_status_days'] = time_feed.days
df.loc[row.name, 'time_in_status_hours'] = (time_feed.days) * 24 + (time_feed.seconds)/3600
df.loc[row.name, 'time_in_status'] = time_feed
df.loc[row.name, 'iteration'] = n
n = n + 1
3. Extract All ticket Comments in Jira
To extract ticket comments from Jira using Python, we can use the jira library:
from jira import JIRA
JIRA_SERVER = "xxx"
USERNAME = "xxx"
API_TOKEN = 'xxx'
jira = JIRA(server=JIRA_SERVER, basic_auth=(USERNAME, API_TOKEN))
issue_key = 'xxx'
issue = jira.issue(issue_key, expand='comments')
comments = []
for comment in issue.fields.comment.comments:
comments.append({
'author': comment.author.displayName,
'created': comment.created,
'body': comment.body
})
for comment in comments:
print(f"Author: {comment['author']}\nCreated: {comment['created']}\nComment: {comment['body']}\n---\n")
P.S. Replace the placeholder values for:
- JIRA_SERVER
- USERNAME
- API_TOKEN
- issue_key
This script above connects to Jira, retrieves the specified issue, and extracts the comments along with:
- the author's name
- creation timestamp
- comment body
4. Resources
Below you can find additional resources. For example you can learn how to use request library to access Jira API endpoint:
- REST API v3 (beta) - Issue attachments
- Manage API tokens for your Atlassian account
- How to request JIRA API with Python examples
- How to export issue history from Jira?
- Extracting complete issue history via API
- https://pypi.org/project/jira/
Summary
In summary, this code fetches Jira issues based on a specified JQL query, then iterates through each issue's changelog to identify and record status changes.
The collected status change data is stored in a list (df_status) for further analysis or storage.
By following these steps, you can effortlessly extract Jira ticket data along with comment history using Python, facilitating more comprehensive insights and reporting for your project management needs.