Forums

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

How can I authenticate to Jira Cloud Rest API from flask webapp?

Levi Reynolds December 30, 2020

I can successfully create an issue in jira using jira cloud rest api via my standalone python script below:

from jira import JIRA
import os

options = {"server": "https://mysite.atlassian.net"}
username = os.environ.get("jira_username")
token = os.environ.get("api_token")
jira = JIRA(options, basic_auth=(username, token))

workRequest = {
        'project' : {'key' : 'myprojectkey'},
        'summary' : 'Are you working?',
        'description' : 'Testing, Testing',
        'issuetype' : {'name' : 'Task'}
    }
new_issue = jira.create_issue(fields=workRequest)

print(new_issue)

I am trying to build a basic flask webapp which consists of a generic webform that when submitted generates a jira ticket. The problem I am having is I am getting a 401 unauthorized error when I 'POST' from the form. I am confused as I am using the same code as above(See below for flask .py). I am new to the web development/python world and trying to get my feet wet. Any help would be greatly appreciated. (yes, I know there are issue collectors; I am trying to learn to create my own form webapp.)

from flask import Flask, render_template, request
import os
from jira import JIRA

app = Flask(__name__)

def createRequest(testemail, freetext, jira):
    workRequest = {
        'project': {'key': 'myprojectkey'},
        'summary': 'Request from Flask Webform',
        'description': 'My email is: {} /nI would like {}'.format(testemail, freetext),
        'issuetype': {'name': 'Task'}
    }
    new_issue = jira.create_issue(fields=workRequest)

@app.route('/form', methods=["GET", "POST"])
def form():
    if request.method == "POST":
        testemail = request.form.get("testemail")
        freetext = request.form.get("freetext")
        options = {"server": "https://mysite.atlassian.net"}
        username = os.environ.get("jira_username")
        token = os.environ.get("api_token")
        jira = JIRA(options, basic_auth=(username, token)),
        createRequest(testemail, freetext, jira)
    return render_template("form.html")

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.
January 1, 2021

Hi @Levi Reynolds 

Welcome to Community! Learning how things works is far more interesting as it helps you develop a mindset that is logical.

From your short code it seems you're using the pyjira framework, if creating a webapp with flask, I will suggest writing your own API login implementation. A simple one is given below

import requests
from requests.auth import HTTPBasicAuth
from flask import Flask, render_template, request

email = "email"
token = "apitoken"
url = "link"
headers = {"Content-type": "application/json"}
auth = HTTPBasicAuth(email, token)

app = Flask(__name__)

@app.route("/", methods=["GET","POST"])
def submit():
web = "link"
if request.method == "POST":
data = your_data_here
return render_template("index.html")

So in your html document, you should design your form where a user can fill based on the fields needed and you can create an action that will be another route that will process the form and user input. if you need more guidance just let me know.

Levi Reynolds January 1, 2021

Hey, @Prince Nyeche ! Thanks for your help! I will be doing some more tinkering with this tomorrow evening and will let you know if this is something that resolves the issue. Thanks!

Levi Reynolds January 1, 2021

@Prince Nyeche I just realized that I only provided all the code on the stack overflow post I made. I have updated this post with all of my code and details of what I currently have. Looks like I already have most of what you mentioned besides headers variable? 

Levi Reynolds January 2, 2021

@Prince Nyeche I tried what you mentioned above still with no luck. Can you see any other issues in my code I have above?

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.
January 2, 2021

Hi @Levi Reynolds 

I think the issue is on this line

jira = JIRA(options, basic_auth=(username, token)),

the return value of jira should return the JIRA class and not a Tuple[JIRA]  class. This could the reason for the 401 you're receiving. So remove the comma after the closing bracket and try again,

Levi Reynolds January 2, 2021

Good evening, @Prince Nyeche . I appreciate the help; however, that was not it either, My Friend.. 

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.
January 4, 2021

Hi @Levi Reynolds 

Thanks for letting me know. I only changed the project key to use id

'project': {'id': 10016},

And instead of getting the values from a set os.environ, I added my email and token as string directly and the code seems to be working fine for me. probably you should check your permission level on the project itself.

This is the full script I used and folder structure. "templates" is a folder

test_folder

        |----- test.py

        |-----templates

               |------- form.html

          

python-test.py

from flask import Flask, render_template, request
from jira import JIRA

app = Flask(__name__)


def create_request(testemail, freetext, jira):
work_request = {
"project": {"id": 10016},
"summary": "Request from Flask Webform",
"description": "My email is: {} I would like {}".format(testemail, freetext),
"issuetype": {"name": "Bug"}
}
jira.create_issue(fields=work_request)


@app.route("/form", methods=["GET", "POST"])
def form():
if request.method == "POST":
testemail = request.form["testemail"]
freetext = request.form["freetext"]
options = {"server": "https://yourinstance.atlassian.net"}
username = "email"
token = "token"
jira = JIRA(options, basic_auth=(username, token))
create_request(testemail, freetext, jira)
return render_template("form.html")


if __name__ == "__main__":
app.run()

HTML-form.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>

</head>
<body>
<form method="post">
<input type="text" name="testemail" value="">
<input type="text" name="freetext" value="">
<input type="submit" value="submit">
</form>
</body>
</html>

with the above, it should just work. 

Levi Reynolds January 4, 2021

@Prince Nyeche I am off to the races! You'll never guess what it was.. 

For starters, even though your code was practically identical to mine, I created a separate venv and just copy/pasted your code and changed the necessary values, then tested... STILL wasn't working. I am the admin of the project so I knew permissions wasn't the issue.

Since this was the case I figured the only other thing I hadn't tried was revoking and generating a new API token...

 

THIS RESOLVED MY ISSUE. 

 

I am SO confused why this resolved it because it was working in my stand alone script but not my flask app. I even compared and they were definitely the same.

Thank you so much for the troubleshooting assistance.

I wish you a Happy New Year, Health, Wealth, and Love.

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.
January 4, 2021

It's a mystery with the API token but I guess that could happen. Glad to help out. Have a nice day ahead.

Suggest an answer

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

Atlassian Community Events