How to assign Jira issues automatically using textblob classifier in Python ?

Photo by rawpixel.com on Unsplash
Abstract: I’ve used Python’s textblob classifier to simply classify issues according to assignees from their description and headers. Classified issues used to classify newly created issues and results are recorded to a database. 2019 issues used as training set and %82 assignment accuracy have been achieved. As the training set grows bigger accuracy could be better.

Atlassian Jira is a product for corporate firms to track both internal and external issues related with their business. This product can be summarized with an example as; If a company sells technical support, customers want to make sure that their problems are resolved in a pre-determined period of time or corporates may want to measure their technical supports’ performance. Jira provides high performant and easy to use solutions for the companies. You can find more information about Jira here.

My experience with Atlassian Jira started five months ago. My employer have decided to use Jira for the scenarios I’ve mentoined above, actually those scenarios were real experiences of mine. I was responsible for the Jira management in my section.

My responsibility was; reading the description and assign the issue to the related person everytime a customer created an issue. This may sound simple but there are two major problems here;

1. Fast response

If you had only one job; assigning issues, then it is very simple but things don’t work this way. On a busy day it is very normal to forget assigning a few issues. Assigning issues doesn’t mean they are solved but at least technical support knows about issues and they can adjust their priorities.

2. Personal disputes

I’m the youngest person in the office and assigning issues to your elders might become problematic. People may question your decisions and it can be exhausting to explaining people why you think they are suitable for that specific issue.

No more talking, If you want to check the whole script you can go to bottom from here;

Or you can follow the script that I’ve used to assign the issues step by step with explanations;

Step 1: Jira Authentication in Python
user_name = ‘user.name’
password = ‘secret’
#PostgreSQL database connection
conn = psycopg2.connect(“dbname=Jiradb user=postgres password=111 port=5433”)
cur = conn.cursor()
options = {‘server’: ‘http://your.domain.com'}
# Authentication
try:
jira = JIRA(options, basic_auth=(f’{user_name}’, f’{password}’))
except BaseException as Be:
print(Be)
props = jira.application_properties()
Step 2: Querying all closed issues using JQL and training textblob classifier
all_closed_issues = jira.search_issues(
‘resolution in (Resolved, Cancelled, Repeated ,”Not Repeatable”) and assignee is not EMPTY order by createdDate asc’, maxResults=False)
i = 0
for i in range(0, len(all_closed_issues)):
train.append((str(all_closed_issues[i].key.split(‘-’)[0]) + ‘ ‘ + str(
all_closed_issues[i].fields.summary), all_closed_issues[i].fields.assignee.name))
#Train classifier with issues key value and summary with assignee
cl = NaiveBayesClassifier(train)

JQL stands for Jira Query Language. In Jira, issues can be queried with this SQL-like language. In this step you will probably have to write your own JQL to query your closed issues. Another important thing is maxResults value. If not specified maximum quantity of results return from Jira API is limited with fifty. We want all issues so we set max results value to false.

Step 3: Assigning the issues according to classification and write results to database for classification assessment.
while True:
#Gathering key and summary values of all open issues without an #assignee
all_open_issues = jira.search_issues(‘assignee = EMPTY AND (category = IG-Ankara OR category = YY-Ankara)’, maxResults=False)
if len(all_open_issues) > 0:
for i in range(0, len(all_open_issues)):
#Only key value and summary of issue are enough for classification
issue = str(all_open_issues[i].key.split(‘-’)[0]) + \
‘   ‘ + str(all_open_issues[i].fields.summary)
assignee_ = cl.classify(issue)
print(all_open_issues[i].key,
‘ is assigned to: ‘, assignee_)
jira.assign_issue(all_open_issues[i].key, assignee_)
ts = d.datetime.now().strftime(‘%Y/%m/%d’)
#Inserting classification result to database for later assessment
cur.execute(“INSERT INTO auto_assigned (i_key ,assignee,timestamp_) VALUES (“+f”’{all_open_issues[i].key}’”+ “,”+ f”’{assignee_}’”+”,”+f”’{ts}’”+”)”)
conn.commit()
#Add a comment to issue which indicates this issue has been assigned #automatically.
comment = jira.add_comment(all_open_issues[i], ‘This issue was assigned automatically.’, visibility={‘type’: ‘role’, ‘value’: ‘Administrators’}) 
total_time_lapse = time.time() — start_time
cur_date = d.datetime.now().strftime(‘%Y-%m-%d %H:%M:%S’)
print(f” — — Total Time: {total_time_lapse} seconds — -”)
try:
sendemail(from_addr=’huseyin.capan@netcad.com.tr’,
to_addr_list=[‘capanh@gmail.com’],
cc_addr_list=’’,
subject=str(all_open_issues[i].key) +
“is  assigned to ; “ + str(cl.classify(issue)),
body=f” Total time lapse: {total_time_lapse} seconds— -”,
login=”huseyin.capan@netcad.com.tr”,
password=f’{mail_password}’)
except BaseException as Be:
print(Be)
else:
cur_date = d.datetime.now().strftime(‘%Y-%m-%d %H:%M:%S’)
#If there are no issues to be assigned, wait one minute and try again.
print(“There aren’t ant issues for now. It will be retried after one minute !( “ + cur_date + “ )”)
time.sleep(60)

Full script can be found here.

PS: I’m not an expert on Python or machine learning. If you see anything wrong or if you know an easier way, please feel free to share it with me.