Library / SDK
pycontribs/jenkinsapi avatar
pycontribs/jenkinsapi

jenkinsapi wraps the Jenkins REST API in Python objects

A Python API for accessing resources and configuring Hudson & Jenkins continuous-integration servers

883 stars488 forksPythonMIT

At a glance

What is it?
jenkinsapi is a Python library that turns the Jenkins REST API into ordinary Python objects, covering jobs, builds, artifacts, nodes, views and credentials. It suits a team scripting a continuous integration server from Python, and it is a client for the remote API rather than a server of its own.
Who is it for?
jenkinsapi suits a team that drives a Jenkins instance from Python, whether to query build history, pull artifacts, toggle jobs or manage nodes, and who want an object model rather than raw HTTP calls. It is the wrong tool for anything that needs to run the server itself, and the wrong tool for a Java shop, since the library exists precisely to bridge a Python codebase to a Java-centric system.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 4 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A bridge to a Java-centric system

jenkinsapi is described as a Python API for accessing resources and configuring Hudson and Jenkins continuous-integration servers, and the README explains the motivation in a paragraph that is more honest than most.

Jenkins is called the market leading continuous integration system, and Jenkins and its predecessor Hudson are described as useful projects for automating common development tasks such as unit testing and production batches, but they are somewhat Java-centric. Jenkinsapi then makes scripting Jenkins tasks a breeze by wrapping the REST API into familiar Python objects.

That framing tells you exactly what the library is for. It is not a Jenkins distribution, a plugin, or a way to run jobs. It is a client, and its job is to make an HTTP API feel like an object graph, so that a Python script can ask for a job and get back something with methods rather than a dictionary of JSON keys.

The library is classified as production and stable, is intended for developers and system administrators, and is operating system independent. The declared Python support is 3.10 through 3.14, and the project is tested against both stable LTS and latest Jenkins versions.

One small inconsistency is worth noting because it is the kind of thing that wastes an afternoon. The package manifest records the version as 0.3.20 while the published releases in the list are 0.3.22 and 0.3.23, with an alpha of 0.3.23 in between. The manifest is not the authority on what is published, so the release history on PyPI is the place to check which version you actually get.

The capability list, grouped by what you want to do

The README lists the commonly used functionality, and the grouping is the useful part, because it shows the library is organised around tasks rather than around REST endpoints.

Jobs come first: add, remove and query Jenkins jobs. Then control of pipeline execution, which covers querying the results of a completed build, blocking until jobs are complete or running them asynchronously, and getting objects that represent the latest builds of a job.

Artifact management covers searching for artifacts by simple criteria and installing artifacts to custom-specified directory structures. Then searching for builds by source code revision, which is the operation most CI scripts actually want and the one that is awkward over raw HTTP, because it is a server-side query rather than a lookup of a known build number.

The create, destroy and monitor group is the broadest. It covers build nodes, with the parenthetical noting Webstart and SSH slaves, views, including nested views using the NestedViews Jenkins plugin, and credentials, specifically username and password and ssh key.

The last two items are about the server itself: authentication support for username and password, and managing Jenkins and plugin installation.

The plugin support is what makes the library practical against a real instance, since a working server usually has plugins installed that change the API surface. A client that only understood the core endpoints would fall over on the first server with the Folders plugin in it.

Folders, and the naming rules that bite

One example in the README is worth isolating, because it shows the object model reaching into a plugin's namespace and because the two accepted forms look like a typo until you know the rule.

When using the Folders plugin, you can pass folder paths directly:

python
jenkins.create_job("folder1/folder2/job-name", config_xml)
jenkins.create_job("/job/folder1/job/folder2/job-name", config_xml)

Both forms are valid and they mean the same thing. The second is the fully qualified Jenkins REST path, with a job segment in front of each folder level, and the first is the friendlier form the library normalises into it. A developer who mixes the two, or who assumes the short form works on a server without the Folders plugin, gets a failure that reads like a permissions problem rather than a naming problem.

The configuration is passed as XML, which is the other thing this example teaches. Job definitions in Jenkins are XML, and a create operation takes that document, so the examples directory in the repository carries an addjob.xml file that shows the shape of the configuration a job needs. A Python script that creates a job therefore has to produce XML, which is the one part of the workflow that is not a Python object, and it is why the library hands you a config_xml parameter rather than a builder.

The examples directory also has a how_to folder and a low_level folder. The second is the interesting one for anyone who needs behaviour the object model does not cover, because it exists to let you drop down to the underlying HTTP calls without leaving the library.

Job deletion needs cross-site scripting protection turned off

The Known issues section contains a single line, and it is the kind of line that should stop an adopter before they deploy rather than after they hit it.

Job deletion operations fail unless Cross-Site scripting protection is disabled.

That is a security setting on the Jenkins side, and the library needs it off in order to delete a job. Any team reading this has to decide what they are prepared to change on a server that runs their builds. Disabling cross-site scripting protection on a production Jenkins instance is not a small decision, because that protection is one of the defences against a web request triggering an administrative action.

The library does not say which Jenkins versions are affected, does not say whether there is a way around it on newer releases, and does not say whether a future version of the library will work without the setting. It states the known issue and points to the support tracker for anything else. A reader should assume that the workaround still applies and that the tracking issue is the place to check for a change.

The honest way to put this in an evaluation is that jenkinsapi can create, modify and query jobs, and that deleting them through the library may require weakening a security control on the server. If your automation needs to delete jobs, or if your security policy forbids disabling the protection, this library is a poor fit for that part of the job and you need a different approach for it. If your automation only reads and triggers, the issue may never apply to you.

Development, tests and a Docker-based Jenkins

The development section is where the project's own working practices are visible, and they are more modern than the version number suggests.

For contributors the requirement is Java, because Jenkins will be automatically downloaded and started during the tests. The environment is created with uv, and the tests are run with uv as well:

bash
uv sync
bash
uv run pytest -sv

The Makefile shows the full set of targets and a level of care that is unusual for a client library. The default test target excludes the docker-marked tests, so the fast suite does not need a container, and there is a separate coverage target that runs the same suite with coverage reporting. There is a lint target that runs ruff check and ruff format in check mode over the jenkinsapi package, and a dist target that runs uv build.

The Docker story is the part worth reading twice. The Makefile has docker-build, docker-run, docker-clean and docker-logs targets, and the image is built from the docker/ directory in the repository:

dockerfile
docker build -t $(DOCKER_IMAGE) docker/

The container is a Jenkins instance on port 8080, and the run target maps it to the host and reports where to find it. There are separate targets for the Docker integration test, for the system tests, and for running everything at once, and the system tests run in parallel with pytest-xdist using all available CPUs by default, with the worker count overridable.

The practical point is that this project tests against a real Jenkins rather than against a mock, which is the only way to know whether the library still matches the server. The cost is that the test suite needs Java and a container, so the fast path is the non-docker subset and the thorough path is much heavier.

The licence, the maintainers and the two entry points

The licence is MIT, recorded in the package manifest as MIT license and in the repository as a LICENSE file. For a client library that talks to a server you already run, that is the straightforward case, and the one thing it does not cover is the licensing of the Jenkins plugins you may end up installing through it.

Two console entry points are declared in the manifest. jenkins_invoke maps to a main function in the jenkinsapi.command_line package, and jenkinsapi_version is the second. The first is the one that matters: a command line way to talk to a server, which is what makes the library usable from a shell script or a CI job without writing Python.

The dependency surface is deliberately minimal. The manifest declares exactly two runtime dependencies, pytz at 2014.4 or later and requests at 2.33.0 or later, and the build backend is hatchling. Two dependencies for a REST client is a good sign, since it means the library is not dragging a framework or an ORM into your environment, and that pytz is there for timezone handling on the build timestamps that Jenkins reports.

On maintenance, the facts are that the repository is not archived, the last push was on 2026-10-19, and the recent releases are 0.3.23 on 2026-04-21, an alpha of 0.3.23 on 2026-04-14 and 0.3.22 on 2026-03-27. That is an active project with a low version number, and the README closes with a request that support questions go to the GitHub tracker rather than to the individual contributors, with twelve names listed and an explicit instruction not to contact them directly. A library with that many contributors and that instruction is one where the tracker, not a person, is the support channel, and a team should plan its questions accordingly.

Editorial conclusion

jenkinsapi suits a team that drives a Jenkins instance from Python, whether to query build history, pull artifacts, toggle jobs or manage nodes, and who want an object model rather than raw HTTP calls. It is the wrong tool for anything that needs to run the server itself, and the wrong tool for a Java shop, since the library exists precisely to bridge a Python codebase to a Java-centric system. Before you adopt it, read the known issues section, because job deletion fails unless cross-site scripting protection is disabled on the server, and check the credential handling, since the library supports username and password and SSH key credentials and that is where an operator has to be careful.

Frequently asked questions

How do I install jenkinsapi?

The installation section of the README gives a single command, pip install jenkinsapi. The package is on PyPI under the name jenkinsapi, and the release history is linked from the README.

What can jenkinsapi do with Jenkins jobs and builds?

It can add, remove and query jobs, control pipeline execution by querying completed build results, blocking until jobs finish or running them asynchronously, and return objects for the latest builds of a job. It also searches for builds by source code revision and manages artifacts, nodes, views and credentials.

Why does deleting a job through jenkinsapi fail?

The README lists this as the known issue: job deletion operations fail unless Cross-Site scripting protection is disabled on the Jenkins server. Other issues are tracked in the GitHub support tracker.

How do I turn on request and response logging in jenkinsapi?

JenkinsAPI emits request and response debug logs when enabled. You can opt in with the environment variable JENKINSAPI_LOG_LEVEL set to DEBUG, or by calling the helper configure_logging from jenkinsapi.utils.logging with a level such as INFO.

Official sources

  1. License: MIT
  2. Project website
  3. pycontribs/jenkinsapi on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/pycontribs-jenkinsapi.svg)](https://hysenlabs.com/projects/pycontribs-jenkinsapi)

Was this useful?