Setting the "Epic Status" using python and JIRA API

ken October 13, 2020

I want to programmatically change the value of Epic Status on a bunch of tickets.  However I an not figure out what the right dictionary/JSON object structure is in order to get the API to accept an update to this field.  I have done quite a few searches for an answer to this one - and have yet to find something that provide a recommendation.

 

I have created a code snippet to show what I am doing and I have provided the output from two different runs.  Deeply appreciated if someone could point me in the right direction here.

CODE:

import pprint
pp = pprint.PrettyPrinter(indent=4)

from atlassian import Jira

url= 'your-url',
username= 'your-account'
token='your-token-or-password'
ticket='NCCWEB-7919'


def jira_find_field( jira, fld, dumpall=False ):
results = jira.get_all_fields()
if dumpall:
pp.pprint(results)
return

for result in results:
if fld == result['name']:
pp.pprint(result)


jira = Jira(
url=url,
username=username,
password=token)

print('Field information in our instance')
jirafld = 'Epic Status'
jira_find_field( jira, jirafld )
# try different structures
jira_epic_done_field_formats = [
{ "customfield_10010" : [{"value" : "Done",}],},
{ "customfield_10010" : {"value" : "Done",},},
{ "customfield_10010" : "Done" },
]
print('-'*80)
print('Current value for this field')
result = jira.issue_field_value( ticket, "customfield_10010" )
print(result)
for jira_epic_done_fields in jira_epic_done_field_formats:
print('-'*80)
print(jira_epic_done_fields)
try:
result = jira.update_issue_field( ticket, jira_epic_done_fields )
print('epic status updated')
except Exception as e:
print(e)

 

 

RESULTS:

Field information in our instance
{ 'clauseNames': ['cf[10010]', 'Epic Status'],
'custom': True,
'id': 'customfield_10010',
'key': 'customfield_10010',
'name': 'Epic Status',
'navigable': True,
'orderable': True,
'schema': { 'custom': 'com.pyxis.greenhopper.jira:gh-epic-status',
'customId': 10010,
'type': 'option'},
'searchable': True,
'untranslatedName': 'Epic Status'}
--------------------------------------------------------------------------------
Current value for this field
{'self': 'https://<your-instance>atlassian.net/rest/api/2/customFieldOption/10003', 'value': 'Done', 'id': '10003'}
--------------------------------------------------------------------------------
{'customfield_10010': [{'value': 'Done'}]}
400 Client Error: for url: https://<your-instance>atlassian.net/rest/api/2/issue/NCCWEB-7899
--------------------------------------------------------------------------------
{'customfield_10010': {'value': 'Done'}}
400 Client Error: for url: https://<your-instance>atlassian.net/rest/api/2/issue/NCCWEB-7899
--------------------------------------------------------------------------------
{'customfield_10010': 'Done'}
400 Client Error: for url: https://<your-instance>atlassian.net/rest/api/2/issue/NCCWEB-7899

================================================================================
Field information in our instance
{ 'clauseNames': ['cf[10010]', 'Epic Status'],
'custom': True,
'id': 'customfield_10010',
'key': 'customfield_10010',
'name': 'Epic Status',
'navigable': True,
'orderable': True,
'schema': { 'custom': 'com.pyxis.greenhopper.jira:gh-epic-status',
'customId': 10010,
'type': 'option'},
'searchable': True,
'untranslatedName': 'Epic Status'}
--------------------------------------------------------------------------------
Current value for this field
{'self': 'https://<your-instance>atlassian.net/rest/api/2/customFieldOption/10001', 'value': 'To Do', 'id': '10001'}
--------------------------------------------------------------------------------
{'customfield_10010': [{'value': 'Done'}]}
400 Client Error: for url: https://<your-instance>atlassian.net/rest/api/2/issue/NCCWEB-7919
--------------------------------------------------------------------------------
{'customfield_10010': {'value': 'Done'}}
400 Client Error: for url: https://<your-instance>atlassian.net/rest/api/2/issue/NCCWEB-7919
--------------------------------------------------------------------------------
{'customfield_10010': 'Done'}
400 Client Error: for url: https://<your-instance>atlassian.net/rest/api/2/issue/NCCWEB-7919

1 answer

1 accepted

0 votes
Answer accepted
Prince Nyeche
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 13, 2020

Hi @ken 

Welcome to community, the reason for 400 error is because the json is wrong!  Since you're updating a single select list, you shouldn't wrap your value in a list. you should pass your payload as below:

{
"fields":
{
"customfield_10006": # customfield id of the Epic Status field
{

"value": "Done"
}

}
}

with the above , you should be able to update the field.

ken October 14, 2020

@Prince N - thanks for the suggestion.  The array that i have put in this example is just to allow me to try different json payloads in an effort to find the one that works.  Given your suggestion above, I have added two more payloads to the array in order to test them out in hopes that one would work.   The array is now:

# try different structures
jira_epic_done_field_formats = [
{ "customfield_10010" : [{"value" : "Done",}],},
{ "customfield_10010" : {"value" : "Done",},},
{ "customfield_10010" : "Done" },
{ "fields" : { "customfield_10010" : {"value" : "Done",},},},
{ "fields" : { "customfield_10006" : {"value" : "Done",},},},

 

the bottom two are new payloads - but neither worked for me :-(

after adding these to the array and running it again - these are the results for the last two / new calls:

 

update json payload:
{'fields': {'customfield_10010': {'value': 'Done'}}}
400 Client Error: for url: https://<your instance>/rest/api/2/issue/NCCWEB-7919
--------------------------------------------------------------------------------
update json payload:
{'fields': {'customfield_10006': {'value': 'Done'}}}
400 Client Error: for url: https://<your instance>/rest/api/2/issue/NCCWEB-7919

 

clearly - my code lost its indenting when I posted it here - I can create a github project and share the link  if people want access to the code in order to run it and see what is going on.

 

as you can see above - i ran the new structure with two different customfield values - in case that was the cause of the issue.

Prince Nyeche
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 16, 2020

Hi @ken 

You can put the code you're using on github and share the link, for further test and for proper formatting. That payload should work, except there's something else wrong in the code!

ken October 16, 2020

@Prince N - here is a link to my jira repository


https://github.com/kenvenner/jiraepicstatus

thanks for taking a look at this - excited to figure out where the bug.

Prince Nyeche
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 18, 2020

Hi @ken 

When I tried to execute the code, I was running into this error

lib/python3.7/site-packages/atlassian/rest_client.py", line 128, in <genexpr>

url_link = '/'.join(s.strip('/') for s in [url, path])
AttributeError: 'tuple' object has no attribute 'strip'

the generator expression is suppose to return the request, however the output tells me otherwise. did you run to similar problems?

ken October 19, 2020

jira>python -V
Python 3.6.8

jira>pip freeze | grep atlassian
WARNING: pip is being invoked by an old script wrapper. This will fail in a future version of pip.
Please see https://github.com/pypa/pip/issues/5599 for advice on fixing the underlying issue.
To avoid this problem you can invoke Python with '-m pip' instead of running pip directly.
atlassian-python-api==1.17.6

 

and I am not getting any errors when running this script?

 

--------------

Field information in our instance
{ 'clauseNames': ['cf[10010]', 'Epic Status'],
'custom': True,
'id': 'customfield_10010',
'key': 'customfield_10010',
'name': 'Epic Status',
'navigable': True,
'orderable': True,
'schema': { 'custom': 'com.pyxis.greenhopper.jira:gh-epic-status',
'customId': 10010,
'type': 'option'},
'searchable': True,
'untranslatedName': 'Epic Status'}

Prince Nyeche
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 19, 2020

Hi @ken 

I found out what caused that error in my previous comment. In the url variable, you added a comma which changed the string into a tuple, I didn't notice that at first.

url = 'your-url', 

However, after evaluation, i looked at the library's method for the update_issue_field and the field key of the json has been defined, all you need to do is call the other keys and then the value. Here's a working version

import pprint
from atlassian import Jira

pp = pprint.PrettyPrinter(indent=4)

url = 'url'
username = 'email'
token = 'token'
ticket = 'ABC-123'


def jira_find_field(jira, fld, dumpall=False):
results = jira.get_all_fields()
if dumpall:
pp.pprint(results)
return

for result in results:
if fld == result['name']:
pp.pprint(result)


jira = Jira(
url=url,
username=username,
password=token)

print('Field information in our instance')
jirafld = 'Epic Status'
jira_find_field(jira, jirafld)
# try different structures
jira_epic_done_field_formats = [
{"customfield_10010":
{"value": "In Progress"
}
}
]
print('-' * 80)
print('Current value for this field')
result = jira.issue_field_value(ticket, "customfield_10010")
print(result)
for jira_epic_done_fields in jira_epic_done_field_formats:
print('-' * 80)
print('update json payload:')
pp.pprint(jira_epic_done_fields)
try:
result = jira.update_issue_field(ticket, jira_epic_done_fields)
print('epic status updated')
except Exception as e:
print(str(e)) 

 Hopefully the above helps you.

ken October 20, 2020

thank you for continuing to work this with me - i really appreciate it.

Sorry about the bug - i fixed the code and put your suggestion in as the first option to execute and checked it into github.  I also made it that the "value" can be changed as to what epicstatus we are moving to. 

It sounds like this code worked in your instance of jira.... mine continues to not work and I am unsure why.

in order to see the format of the output from my run - i have checked that into the github repository so you can see it (result.txt).  Open to any other debugging steps I can take to figure out why this code is not working in my instance.

Prince Nyeche
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 21, 2020

Hi @ken 

Yes, the code worked, you might want to check if you can actually update the issue manually or have the right permission to the issue for editing before running the script again. I don't particularly see any issue with the script at this point.

ken October 21, 2020

@Prince N  - thanks - i am able to make the change manually - which is what I am doing now - i do it from the backlog screen for epics and set it to done.  That is why I am stumped that this automation is not working.  I am open to suggestions for how to debug this to figure out what is going on if you have any suggestions - or - if getting on a screen sharing/video meeting to trouble shoot together makes sense - i could get that scheduled. 

 

if you have suggestoins on additional troubleshooting code that I could put in the tooling i have to get more feedback - please feel free to change the .py file and I will just run it and provide back the results.

Prince Nyeche
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 22, 2020

Hi @ken 

Let's take a step back here. These are the steps I took on my own instance

  1. I went to the issue https://<your-instance>.atlassian.net/browse/AT2-210
  2. I switched to the old issue view (this is because the Epic status doesn't show on the new view)
  3. I went to Project Settings > Screens and confirmed on the issue type i'm using has the Epic Status added
  4. I used the script to change the Epic Status from "In Progress" to "Done"
  5. Result

 

Field information in our instance
{ 'clauseNames': ['cf[10006]', 'Epic Status'],
'custom': True,
'id': 'customfield_10006',
'key': 'customfield_10006',
'name': 'Epic Status',
'navigable': True,
'orderable': True,
'schema': { 'custom': 'com.pyxis.greenhopper.jira:gh-epic-status',
'customId': 10006,
'type': 'option'},
'searchable': True,
'untranslatedName': 'Epic Status'}
--------------------------------------------------------------------------------
Current value for this field
{'self': 'https://<instance>.atlassian.net/rest/api/2/customFieldOption/10001', 'value': 'In Progress', 'id': '10001'}
--------------------------------------------------------------------------------
update json payload:
{'customfield_10006': {'value': 'Done'}}
epic status updated

Process finished with exit code 0

so try to follow the same steps. 

epic.png

ken October 22, 2020

@Prince N  - the script is now working.  your step 3, the field was not visible on the page, and i made it visible.  and the script worked.  I am going to validate this logic by removing the field from the page again.  I did and the script failed, and when I added it back in the script worked.  I only add the field to the "view" not the "edit" but i guess the API requires the field to be seen in the page in order to be updateable.

 

Thanks for hanging in there with me - that was extremely helpful.  And if my conclusion is right - you might want to make this clear in the API docs - that the field has to be part of the page definition in order to be updated through the API.  I would have not looked at this without your suggestion.

Prince Nyeche
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 23, 2020

Hi @ken 

 Actually from how I understood the API docs, the field has to be visible else 400 error.

  • the request includes one or more fields that are not found or are not associated with the issue's edit screen.

but glad to hear that it's working now. Have a nice day ahead

Suggest an answer

Log in or Sign up to answer
DEPLOYMENT TYPE
CLOUD
PRODUCT PLAN
STANDARD
TAGS
AUG Leaders

Atlassian Community Events