# jira, a Python client for the Jira REST API

> The jira package wraps Atlassian's REST endpoints in a Python object model for scripts, CI jobs and ticket automation. It covers Cloud and Server, but the extras that install cleanly differ from what the README tells you to ask for.

**pycontribs/jira** — Python Jira library. Development chat available on https://matrix.to/#/#pycontribs:matrix.org

- Repository: https://github.com/pycontribs/jira
- Website: https://jira.readthedocs.io
- Stars: 2,138 · Forks: 887
- Language: Python
- License: BSD-2-Clause
- Published: 2026-10-14 · Updated: 2026-10-14 · Language: en
- Canonical page: https://hysenlabs.com/projects/pycontribs-jira

## Wrapping the Jira REST API in Python 3.10 and up

pycontribs/jira exists so Python code can talk to a Jira instance without hand-rolling HTTP requests. pyproject.toml describes it as "Python library for interacting with JIRA via REST APIs." and the README says it eases use of the Jira REST API from Python. The distribution on PyPI is called jira, not pycontribs-jira, so the import is short:

```python
from jira import JIRA

jira = JIRA('https://jira.atlassian.com')

issue = jira.issue('JRA-9')
print(issue.fields.project.key)            # 'JRA'
```

The client takes a site URL, authenticates, then returns an issue whose fields are reachable as attributes. That shape suits CI jobs, note builders, triage scripts and anything that reads or writes issues from a Python process.

The supported floor is Python 3.10 and it is stated twice. requires-python reads ">=3.10" and the classifiers list 3.10, 3.11 and 3.12, with a Programming Language :: Python :: 3 :: Only marker. There is no path for older interpreters, which lines up with the repository topics jira, python and python3-only. The package is community maintained, and the README says outright that bugs and features may not be implemented quickly.

## The base install is six dependencies and no cli tool

A plain install pulls a small dependency set and nothing else:

```bash
pip install jira
```

```toml
dependencies = [
  "defusedxml",
  "packaging",
  "requests-oauthlib>=1.1.0",
  "requests>=2.10.0",
  "requests_toolbelt",
  "typing_extensions>=3.7.4.2"
]
```

Six packages, all of them familiar. requests carries a floor of 2.10.0, which any current build of it clears, and typing_extensions asks for 3.7.4.2 or newer. defusedxml is there because Jira search payloads can contain XML, and requests_toolbelt supplies multipart helpers used when attaching files.

What that base set does not contain is the command line tool. The README states that by default only basic library dependencies are installed, and that the cli tool and other optional dependencies require a full installation:

```bash
pip install jira[opt,cli,test]
```

A second form, pip install --user --upgrade jira, installs into the user directory, which the README offers for people who are not using a virtualenv. The README also mentions easy_install jira, a setuptools-era installer that does not fit a package declaring requires-python >= 3.10.

## The test extra named in the README has no entry in the extras table

Here is the discrepancy worth catching before you run the documented full install. The README asks for pip install jira[opt,cli,test], but the optional-dependencies table in pyproject.toml opens with async, then cli, then docs, then opt. No extra named test appears in that section.

```toml
[project.optional-dependencies]
async = ["requests-futures>=0.9.7"]
cli = [
  "ipython>=4.0.0",
  "keyring"
]
docs = [
  "sphinx>=5.0.0",
  "sphinx-copybutton",
  "furo"
]
```

The dependency groups themselves are coherent. async adds requests-futures for callback style work, cli adds ipython and keyring, and docs adds Sphinx with the furo theme for building the documentation at jira.readthedocs.io. The opt group starts with filemagic>=1.6, PyJWT and requests_jwt.

Whether the test extra is defined further down the file is not something the repository listing settles, since pyproject.toml as given is truncated. What is visible is that the four groups a new user looks for first are all named and versioned, and that the README points at a fifth name that the visible table does not carry.

## Windows installs skip the gssapi dependency deliberately

The opt group carries an inline comment explaining what was left out and why. As written, the group starts:

```toml
opt = [
  "filemagic>=1.6",
  "PyJWT",
  "requests_jwt",
```

The file as given is truncated before the group closes, so this is the opening of the list, not its full contents.

The comment attached to the kerberos entry explains that gssapi, pulled in transitively, needs external header libraries at install time and ships no wheels for that platform. Because the kerberos authentication path is opt-in at runtime, skipping it on Windows costs nothing for the default user and keeps pip install jira[opt] working there.

That is a packaging decision written as prose, and it has a clear consequence. On Windows you get file type detection through filemagic plus the JWT libraries for token based authentication, but you do not get kerberos from the install. Anyone whose corporate Jira runs behind single sign-on through kerberos on Windows has to satisfy the system headers and build the dependency outside the normal install. On Linux and macOS the same entry installs normally.

## The test suite points at a self-hosted Jira Server, not Cloud

Testing needs a real Jira, and the project builds one. Manual setup instructions start from a Docker image built out of the docker/jira-test-image directory and pinned to Jira 8.17.1:

```bash
docker build -t pycontribs/jira-test-image:8.17.1 docker/jira-test-image
docker run -dit -p 2990:2990 --name jira pycontribs/jira-test-image:8.17.1
```

Port 2990 is where that container listens. The tox envs run linting and the test suite through two commands:

```bash
tox -e lint
```

A bare tox run executes the tests, and tox -e publish builds and publishes with TWINE. The README says development happens on GitHub on the default repository branch, and it points at a contributing guide that describes a dev container as the automatic path on VS Code. The manual path asks for pyenv first, to install a suitable Python version.

Worth noting for anyone judging coverage: the pinned test instance is Jira Server 8.17.1, a self-hosted build from the Data Center line. The README also credits Atlassian for a free on-demand instance at pycontribs.atlassian.net used for continuous integration testing, so both deployment shapes have a place in the loop.

## One package name covers two unrelated REST surfaces

A Jira Cloud account and a self-hosted Jira Server do not share an API. The README says the project aims to support both Jira Cloud and Jira Server / Data Center, then lists six separate Atlassian references to consult when changing interactions: Jira Cloud and Jira Server as the main REST API references, Jira Software Cloud and Jira Software Server under their former names of Jira Agile and Greenhopper, and Jira Service Desk Cloud and Jira Service Desk Server.

For a developer this is the practical cost of the client. There is one import, JIRA, but the payloads behind it differ, so code written against one deployment can fail on the other without any version change. The examples directory carries a separate agile.py file for the software and agile endpoints, which is a plain acknowledgement that the Agile surface is not the issue surface.

The client also takes the site URL as its first argument, which is how the same code is pointed at different instances. The README gives https://jira.atlassian.com as the example target and JRA-9 as the issue key to read.

## Version strings are computed from tags, and the code moved past them

Version numbers are not written into the source. pyproject.toml sets dynamic = ["version"] and the build backend is setuptools with setuptools_scm[toml] >= 7.0.0, so the version string comes from the tag that is checked out at build time. Anything that builds from an untagged checkout has to handle that.

The repository layout backs up the packaging story. There is an AUTHORS.rst next to MANIFEST.in, an uv.lock for dependency pinning, a .pyup.yml file for automated upgrade pulls, and lint and format configuration in .yamllint, .taplo.toml and .pre-commit-config.yaml. bindep.txt records system level dependencies, and a top-level script named make_local_jira_user.py sits beside the package directory.

Two facts set the outer boundary. The distribution is licensed BSD-2-Clause, with the classifier "License :: OSI Approved :: BSD License" matching the LICENSE file at the root, and the last push was on 2026-09-28 while the newest listed tag, 3.10.5, is dated 2025-07-28, so unreleased commits sit between the code you can read and the version you can install.

## Four example scripts mark the kinds of work people script

The repository ships four runnable examples rather than a single hello world: `examples/agile.py`, `examples/auth.py`, `examples/basic_use.py` and `examples/maintenance.py`. Each one marks a distinct job.

basic_use.py covers the read path shown in the quickstart, auth.py covers the authentication modes a site can require, agile.py reaches into the software and agile endpoints that the main reference lists separately, and maintenance.py handles bulk or administrative operations. The existence of maintenance.py is the hint that recurring housekeeping work is a real use case rather than an afterthought.

The README is deliberately thin on all four. It says only to see the documentation for full details and links jira.readthedocs.io, so the details of each script, including which authentication flows are demonstrated, have to be read in the files themselves or in the hosted docs. Nothing in the repository listing indicates which Jira deployment each example targets.

## Conclusion

Adopt jira when your automation already speaks Python and you need to read or write issues from Cloud or Server without writing HTTP calls by hand. Skip it if you need Jira administration screens, an async-first design, or a client Atlassian maintains itself. Before installing the cli tool, check the extras table in pyproject.toml, because the test extra named in the README has no entry there, then pin the version your scripts were written against. On Windows, confirm that filemagic and the JWT libraries are all your authentication path needs.

## FAQ

### How do I install the jira library with the command line tool?

The README says to use pip install jira[opt,cli,test] for a full installation, since a plain pip install jira pulls only the basic dependencies and no cli tool. Note that the optional-dependencies table in pyproject.toml names async, cli, docs and opt, and carries no entry for the test extra named in the README.

### Which Python versions does pycontribs/jira support?

Python 3.10 and newer. pyproject.toml sets requires-python to >=3.10 and its classifiers list 3.10, 3.11 and 3.12 alongside a Python 3 only marker.

### Does the jira library work with both Jira Cloud and Jira Server?

The README says the project aims to support both Jira Cloud and Jira Server / Data Center, and lists separate Atlassian reference documentation for each product line, including Jira Software and Jira Service Desk. The client takes the site URL as its constructor argument, so the same code targets either deployment.

### Why does pip install jira[opt] behave differently on Windows?

The comment in pyproject.toml explains that gssapi, pulled in transitively by the kerberos dependency, needs MIT or Heimdal headers at install time and ships no Windows wheels, so it is left out on Windows. The kerberos path is opt-in at runtime anyway, and the install keeps working there without it.

### How do I run the test suite for the jira library against a real Jira?

The README asks you to build a Docker image from docker/jira-test-image tagged 8.17.1 and run it with port 2990 mapped, then run tox for the suite and tox -e lint for linting. It also offers a VS Code dev container as the automatic path, with pyenv used for the manual Python setup.

### Where does the jira package get its version number at install time?

pyproject.toml lists version under dynamic and builds with setuptools_scm[toml] >= 7.0.0, so the version string comes from the checked out tag rather than a hardcoded value. The README notes that each version is tagged on the default repository branch.

## Sources

- [License: BSD-2-Clause](https://github.com/pycontribs/jira/blob/main/LICENSE)
- [Project website](https://jira.readthedocs.io)
- [pycontribs/jira on GitHub](https://github.com/pycontribs/jira)
- [README](https://github.com/pycontribs/jira/blob/main/README.md)
- [Releases](https://github.com/pycontribs/jira/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/pycontribs-jira
