Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

Generating a Python REST Client for Jira Cloud

You may have read my previous article about generating a Java library to call Jira’s REST APIs, but what about other languages?

Here I’ll cover doing the same with Python.

I will generate a library for Python, and then run through some sample code to create a project, find the “task” issue type in the project, and then create a issue of type “task”.

Why Generate?

There are 3rd party Python libraries around that can talk to Jira Cloud. If these work well for you, then that might be a good solution.

Atlassian publishes the Swagger/Open API spec for Jira’s API in real time though. If you need to call a new Jira Cloud API, or act on some feature that is being deprecated, then being able to generate an up-to-date library might be of value to your project.

Jira’s Open API spec

Just a quick recap: Swagger/Open API is a way of documenting APIs in a standard way. While you can always write your own code to call Jira’s APIs, the APIs change all the time in small ways. Generating a client library from the spec using a code generation tool is a quick way to get started (and easy to update in the future).

If you go to the documentation for the Jira Cloud REST API, you'll see the "…" in the top right. Click that, and you'll see the link for "Download OpenAPI Spec." This is a JSON file that describes the REST API for Jira Cloud.

I’m going to use swagger-codegen to generate my code. (Read more here)

The actual URL to this file is https://developer.atlassian.com/cloud/jira/platform/swagger-v3.v3.json . Although swagger-codegen can generate APIs directly from a URL, I recommend saving a local copy of this file. I am going to use a local copy in my examples.

In this post I will deal with APIs common to all Jira project types, but the process is similar for Jira Software's APIs, and Jira Service Desk's APIs.

Generating Code

Once you have downloaded the swagger-v3.v3.json file, the swagger-codegen command to generate a Python client under the current directory is:

swagger-codegen generate \
-i swagger-v3.v3.json \
-l python \
-o .

This will generate a usable client in the current directory, but it’s probably worth tweaking the configuration a little. I’m going to set the package name, and project name (which is used in setup.py).

Create a config.json file that describes your configuration overrides.

{
"packageName": "jira_client",
"projectName": "jira-cloud"
}

Now to generate code using the above config file use:

swagger-codegen generate \
-i swagger-v3.v3.json \
-c config.json \
-l python \
-o .

What to do with the library?

Run the following to install the library in your virtual environment:

python3 setup.py install

The output directory includes a README.md file that has more details on how you might install it. You may prefer to use pip3 install foldername.

You may wish to integrate the built code directly into your project, rather that install it as its own library.

Check into version control

While the client code is generated, my recommended best practice is to version control the generated client code.

Why? This helps you to know what changed since the last time you generated it. You can re-generate it from an updated spec file, and your version control system will show you what changed.

Using the code

For my code example I’m going to assume the library was installed using the package name “jira_client”, and I can just import it directly.

In this example I'm going to

  • Look up my user

  • Create a new project where I am the project lead

  • Find out the issue type ID of “Task” issue type in my project

  • Create a new issue of type Task in my project, and display the issue key

If you have used the Java client, you will notice that the API and model classes have similar names to the Java version, except with Python naming conventions.

Note: The generated code uses a class called Configuration to specify the configuration when creating the ApiClient. This will clash with a model class called Configuration, so I’m going to import it as ApiConfiguration.

from jira_client import ApiClient
# Configuration is ambiguous
from jira_client.configuration import Configuration as ApiConfiguration
from jira_client.rest import ApiException
from jira_client import ProjectsApi, MyselfApi, IssuesApi
from jira_client.models.create_project_details import CreateProjectDetails
from pprint import pprint

configuration = ApiConfiguration()
configuration.username = 'myemail@atlassian.com'
configuration.password = 'my_application_password'
configuration.host = 'https://myjirahost.atlassian.net/'
# Turn on debug output
configuration.debug = True

api_client = ApiClient(configuration)

# Get my account ID
myself_api = MyselfApi(api_client)
current_user = myself_api.get_current_user()

# Create a new project
projects_api = ProjectsApi(api_client)
details = CreateProjectDetails(
key='JPY',
name='Jira Python',
lead_account_id=current_user.account_id,
project_type_key='business')
project = projects_api.create_project(details)

# Now do a project search, expanding issue types
paged_projects = projects_api.search_projects(
start_at=0,
max_results=100,
query=project_key,
expand="issueTypes")
projects = paged_projects.values
project_result = projects[0]
task_issue_type_id = 0
for issue_type in project_result.issue_types:
if issue_type.name == 'Task':
task_issue_type_id = issue_type.id

print(f"Task issue type is {task_issue_type_id}")

# Now create an issue using the Task issue type

issues_api = IssuesApi(api_client)

project_field = {
"id": project_result.id
}
issue_type_field = {
"id": task_issue_type_id
}

issue_fields = {
"summary": "Learn Python",
"description": "Remember to study up on Python programming",
"project": project_field,
"issuetype": issue_type_field
}

issue_body = {
"fields": issue_fields
}

issue = issues_api.create_issue(issue_body)

print(f"Issue created. Key is {issue.key}")

Now if I log in to my site I should see that there is a project with the key “JPY”, and with a “Learn Python” task.

0 comments

Comment

Log in or Sign up to comment
TAGS

Community Events

Connect with like-minded Atlassian users at free events near you!

Find an event

Connect with like-minded Atlassian users at free events near you!

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you