How to get projects from Jira using Python

Jira, a leading ticketing and project management solution, boasts an expansive API that lets developers engage with its data programmatically, paving the way for effortless integration with other tools and systems.

In many cases, your team may want to extract projects from the Jira API; doing so can provide  invaluable insights on a project to other applications, such as a project’s status, description, or its assignee.

To help you get projects from Jira, we’ll break down how you can set up authentication for the Jira API and execute 'get' requests to pull projects via Python.

Note: If you'd prefer to use Javascript to fetch projects in Jira, you can read this guide.

Authenticating with Jira

Before making any requests to the Jira API, you need to provide authentication. 

This is done using basic authentication, where your email address and the API key are combined and encoded in Base64 format. This Base64 encoded string is then included in the headers of your HTTP requests to the API. 

The header should be in the format: <code class='blog_inline-code'>Authorization: Basic {Email Address}:{API-KEY}</code>. 

Related: A guide to getting attachments from Jira via Python

Pulling projects from Jira

The following script will print the name of every project in Jira:


import requests
import base64
import json
# Define the base url and endpoint
base_url = "https://{DOMAIN}.atlassian.net"
endpoint = "/rest/api/3/project/search"
# Define the headers for the request
email = "{Email Address}"
api_key = "{API-KEY}"
base_64_auth = base64.b64encode(bytes(f'{email}:{api_key}', 'utf-8')).decode('ascii')
headers = {
    'Authorization': f'Basic {base_64_auth}',
    'Accept': 'application/json'
}
# Define the query parameters
query_params = {
    'expand': 'description',
    'maxResults': 50,
    'startAt': 0
}
# Make the initial request
response = requests.get(base_url + endpoint, headers=headers, params=query_params)
# Check if the request was successful
if response.status_code == 200:
    # Parse the JSON response
    data = json.loads(response.text)
    
    # Loop through the pages
    while data['values']:
        # Process the data
        for project in data['values']:
            print(project['name'])
        
        # Update the startAt parameter for the next page
        query_params['startAt'] += query_params['maxResults']
        
        # Make the request for the next page
        response = requests.get(base_url + endpoint, headers=headers, params=query_params)
        
        # Parse the JSON response
        data = json.loads(response.text)
else:
    print(f"Request failed with status code {response.status_code}")

If you want to do something different with the project data, replace the <code class='blog_inline-code'>print(project['name'])</code> line with whatever processing you need to do. Also, remember to replace <code class='blog_inline-code'>"{DOMAIN}"</code>, <code class='blog_inline-code'>"{Email Address}"</code>, and <code class='blog_inline-code'>"{API-KEY}"</code> with your actual Jira domain, email address, and API key, respectively.

An example of an individual item returned by this API Endpoint is:

{
    "expand": "field",
    "self": "http://www.example.com/jira/rest/api/2/project/EX",
    "id": "10000",
    "key": "EX",
    "description": "Example Project",
    "name": "Example",
    "avatarUrls": {
        "48x48": "http://www.example.com/jira/secure/projectavatar?pid=10000&avatarId=10011",
        "24x24": "http://www.example.com/jira/secure/projectavatar?size=small&pid=10000&avatarId=10011",
        "16x16": "http://www.example.com/jira/secure/projectavatar?size=xsmall&pid=10000&avatarId=10011",
        "32x32": "http://www.example.com/jira/secure/projectavatar?size=medium&pid=10000&avatarId=10011"
    },
    "projectTypeKey": "business",
    "simplified": false,
    "style": "classic",
    "isPrivate": false,
    "properties": {}
}

Related: A guide to fetching comments from the Jira API

Tips for testing your Jira integration

To prevent any issues once you push the integration to production, you should adopt a comprehensive approach to testing. To that end, here are some measures you can take:

  • Define clear test objectives: It's crucial to know exactly what you're testing for. By setting specific goals, like verifying seamless data exchange or ensuring user interface consistency, you'll have a clear focus during testing.
  • Create a test plan: A well-structured test plan is your roadmap to a successful integration. Think about including a variety of cases, such as how the system behaves under heavy load or how it recovers from a network interruption, so that you're covering a range of scenarios.
  • Use the right tools: Selecting appropriate tools is key to effective testing. Explore options like Postman for API testing or Selenium for automated browser testing to find what best suits your needs.
  • Test for different HTTP methods: It's important to check how the integration handles various HTTP methods like GET, POST, or PUT. You can do this by simulating requests and examining the responses to ensure they're as expected.
  • Test under different conditions: Finally, don't forget to test in different environments and conditions. This includes varying network speeds, different user loads, and cross-platform compatibility to ensure robust performance in real-world scenarios.

Final thoughts

In this guide, we've walked you through how to harness the power of Python to interface with Jira and fetch projects. However, it's worth noting that Jira is just one of many ticketing systems your clients might be using.

You can easily expand your integration to reach other popular ticketing applications, such as Asana and ClickUp, by building to a single API—namely, Merge's Ticketing Unified API.

You can learn more about Merge's Ticketing Unified API, and Merge more broadly, by scheduling a demo with one of our integration experts.