mrkeyoor.com_
Sat 08 Aug 21:00 UTC
PyPIUtilsupdated 08 Aug 2026

jira

jira is a community-maintained Python client for Jira's REST APIs. A JIRA session handles authentication and returns resource objects for issues, projects, users, comments, attachments, boards, sprints, service desks, and related entities, while convenience methods cover JQL searches, creates, updates, assignments, transitions, watchers, and worklogs. It aims to support Jira Cloud plus Server and Data Center, which is useful for shared automation but also exposes callers to product-version, authentication, field-schema, and permission differences.

Verdict

The practical general-purpose Python client for substantial Jira automation, especially when resource helpers save real code. For small Cloud-only integrations or brand-new endpoints, direct REST calls can be easier to reason about and quicker to update.

API stability4/5The JIRA session, dynamic Resource objects, issue, search_issues, create_issue, add_comment, transitions, transition_issue, assignment, and attachment methods have years of production use. Most instability comes from Atlassian rather than Python method names: Cloud authentication deprecations, account identifiers, rich-text formats, REST endpoint revisions, and self-hosted version differences change valid payloads. The broad compatibility goal therefore needs integration tests despite a familiar client surface.
Docs4/5Read the Docs includes authentication examples for Cloud API tokens, self-hosted PATs, OAuth 1.0a, Kerberos, headers, issue fields, create and update, JQL, comments, transitions, projects, watchers, and attachments, plus an API reference and advanced explanation of Resource objects. Some installation prose and examples are visibly old, including dated dependency statements and legacy authentication sections, so readers must distinguish historical support from current Jira Cloud rules.
Maintenance4/5PyPI 3.10.5 was uploaded in July 2025, while the repository was pushed in August 2026 and GitHub showed 236 combined open issues and pull requests on a repository with about 2,100 stars. The project supports current Python-only releases and continues active development, but the sizable queue and the README's explicit community-maintained warning mean fixes may not track Atlassian changes on an enterprise support timetable.
Ecosystem5/5The client covers Jira Core, Software, and Service Management concepts across Cloud and Server or Data Center, with helpers for issues, projects, boards, sprints, worklogs, attachments, users, watchers, and more. It integrates with requests, OAuth, Kerberos, JWT options, netrc, async request futures, keyring-backed CLI tools, and Python's normal testing stack. Its millions of weekly installations reflect a large base of automation and transitive consumers.

Use it if

  • You need broad Jira issue automation from Python and prefer resource objects over hand-written requests calls
  • Your code must work with Jira Cloud and self-hosted Server or Data Center through one client where their APIs overlap
  • You need JQL search, issue creation, comments, transitions, attachments, Agile boards, or service-desk operations
  • You can integration-test against the exact Jira edition, fields, workflows, and permissions used in production
Skip it if

Setup reality

Version 3.10.5 requires Python 3.10 and installs requests, requests-oauthlib, requests-toolbelt, defusedxml, packaging, and typing_extensions. Authentication is the first trap. Jira Cloud normally uses basic_auth=(email, api_token); username and password authentication and cookie auth are no longer supported there. Jira Server or Data Center 8.14+ can use token_auth with a personal access token. OAuth 1.0a needs an access token, token secret, consumer key, and matching private key configured through an application link. Kerberos, JWT-related helpers, the interactive CLI, asynchronous requests, and libmagic-based content detection are optional extras, not base behavior; filemagic also needs the native libmagic library and is awkward on Windows. Store credentials in environment variables, a secret manager, or netrc, never source. Set the server URL explicitly because JIRA() with no URL points at the local Atlassian SDK test address. Then test permissions and schema against the target tenant: assignment permission differs from edit permission, transitions are workflow-specific and only currently available transitions are returned, required create fields vary by project, custom field IDs differ, Cloud user identity often uses accountId, and rich descriptions or comments may require Atlassian Document Format. JQL searches return a limited first page unless maxResults is set, and asking for only required fields reduces large payloads. The client supports both Cloud and self-hosted products, so not every method or payload works identically. Configure timeouts and retries for automation, handle JIRAError status codes, avoid logging credentials or issue contents, and integration-test create, update, transition, pagination, and attachment flows after Jira or package upgrades.

Patterns

Authenticate to Jira Cloud with an API tokenconnect-jira-cloud

import os
from jira import JIRA

jira = JIRA(
    server=os.environ['JIRA_URL'],
    basic_auth=(os.environ['JIRA_EMAIL'], os.environ['JIRA_API_TOKEN']),
)

Cloud basic_auth is email plus API token, not an Atlassian account password; keep all three values out of source and logs.

Authenticate to self-hosted Jira with a PATconnect-data-center

jira = JIRA(
    server=os.environ['JIRA_URL'],
    token_auth=os.environ['JIRA_PAT'],
)

The docs identify token_auth for Jira Server or Data Center personal access tokens, available from Jira Core 8.14.

Fetch only the issue fields you needread-issue-fields

issue = jira.issue('PROJ-123', fields='summary,status,assignee')
print(issue.fields.summary)
print(issue.fields.status.name)
assignee = issue.fields.assignee

Requesting a narrow field list avoids large issue payloads; optional fields such as assignee can be None.

Search issues with an explicit page sizesearch-with-jql

issues = jira.search_issues(
    'project = PROJ AND statusCategory != Done ORDER BY priority DESC',
    startAt=0,
    maxResults=100,
    fields='key,summary,priority,status',
)
for issue in issues:
    print(issue.key, issue.fields.summary)

The examples say search returns only the first 50 by default; paginate when the result can exceed maxResults.

Create an issue with explicit fieldscreate-issue

issue = jira.create_issue(fields={
    'project': {'key': 'PROJ'},
    'summary': 'Printer reports low toner',
    'description': 'Observed on the third floor.',
    'issuetype': {'name': 'Task'},
})
print(issue.key)

Required fields and allowed issue types come from project configuration; custom fields use tenant-specific customfield IDs.

Update issue fields without notificationsupdate-issue

issue = jira.issue('PROJ-123')
issue.update(
    notify=False,
    fields={'summary': 'Updated summary'},
)

Permission to edit does not imply permission to assign or transition, and notify behavior can vary with server capabilities.

Add a plain-text commentadd-comment

comment = jira.add_comment(
    'PROJ-123',
    'Deployment finished successfully.',
)

Jira Cloud endpoints that expect Atlassian Document Format need a structured body rather than this plain string shape.

Find and perform an available transitiontransition-issue

issue = jira.issue('PROJ-123')
transitions = jira.transitions(issue)
done = next(t for t in transitions if t['name'].casefold() == 'done')
jira.transition_issue(issue, done['id'])

Transition IDs and names are workflow-specific, and the server returns only transitions available to the current user and state.

Upload an attachment with a closed file handleupload-attachment

with open('report.txt', 'rb') as attachment:
    jira.add_attachment(
        issue='PROJ-123',
        attachment=attachment,
        filename='report.txt',
    )

The optional filemagic integration needs native libmagic; supplying a filename and file object avoids depending on path-only convenience behavior.

Handle REST failures without hiding detailshandle-jira-error

from jira.exceptions import JIRAError

try:
    issue = jira.issue('PROJ-404')
except JIRAError as exc:
    if exc.status_code == 404:
        issue = None
    else:
        raise

A 404 can also hide a permission problem in Jira; log a safe request identifier, not tokens or full issue content.

Alternatives

PackageRegistryPick it when
atlassian-python-apiPyPIYour automation spans Confluence, Bitbucket, Bamboo, or other Atlassian products in addition to Jira
jiraonePyPIYou target Jira Cloud and want higher-level helpers for reports, fields, and bulk operations
requestsPyPIYou use only a few Jira endpoints and want exact control over the documented REST payloads and upgrade timing