PYTHONJENKINS(1)
๐ PYTHONJENKINS ๐
okay bestie, sit down, we're talking about pythonjenkins โ aka Python Jenkins, the python wrapper for the Jenkins REST API ๐ซถ and literally its whole personality is giving Jenkins a conventionally pythonic glow-up so you can control a Jenkins server without wanting to scream. It hands you a higher-level API stuffed with convenience functions, no cap โจ
We (the devs) like to use python-jenkins to automate our Jenkins servers, fr fr. Here's a lil taste of the things you can use it for:
- Create new jobs
- Copy existing jobs
- Delete jobs
- Update jobs
- Get a job's build information
- Get Jenkins master version information
- Get Jenkins plugin information
- Start a build on a job
- Create nodes
- Enable/Disable nodes
- Get information on nodes
- Create/delete/reconfig views
- Put server in shutdown mode (quiet down)
- List running builds
- Delete builds
- Wipeout job workspace
- Create/delete/update folders [1]
- Set the next build number [2]
- Install plugins
- and many more..
To install:
$ sudo python setup.py install
Online documentation:
๐ DEVELOPERS ๐
Bug report:
Repository:
Cloning:
- git clone https://opendev.org/jjb/python-jenkins
Patches are submitted via Gerrit at:
Please do not submit GitHub pull requests, they will be automatically closed. ๐ like, do not do it, the bot will not hesitate.
The python-jenkins developers communicate in the #openstack-jjb channel on Freenode's IRC network.
More details on how you can contribute is available on our wiki at:
๐ WRITING A PATCH ๐
Be sure that you lint code before created an code review. The easiest way to do this is to install git pre-commit hooks. (yes bestie, lint first, we're not doing that other thing ๐)
๐ฆ INSTALLING WITHOUT SETUP.PY ๐ฆ
Then install the required python packages using pip:
$ sudo pip install python-jenkins
๐ธ FOOTNOTES ๐ธ
- [1] The free Cloudbees Folders Plugin provides support for a subset of the full folders functionality. For the complete capabilities you will need the paid for version of the plugin.
- [2] The Next Build Number Plugin provides support for setting the next build number.
โจ API REFERENCE โจ
See examples at Using Python-Jenkins
exception jenkins.JenkinsExceptionโ the general exception type for jenkins-API-related failures. your everyday "something went sideways" bestie.exception jenkins.NotFoundExceptionโ a special exception to call out the case of receiving a 404. iconic, honestly.exception jenkins.EmptyResponseExceptionโ a special exception to call out the case receiving an empty response.exception jenkins.BadHTTPExceptionโ a special exception to call out the case of a broken HTTP response.exception jenkins.TimeoutExceptionโ a special exception to call out in the case of a socket timeout.
๐ง class jenkins.WrappedSession ๐ง
A wrapper for requests.Session to override 'verify' property, ignoring REQUESTS_CA_BUNDLE environment variable.
This is a workaround for โ https://github.com/psf/requests/issues/3829 (will be fixed in requests 3.0.0)
merge_environment_settings(url, proxies, stream, verify, *args, **kwargs)
Check the environment and merge it with some settings.
Return type : dict
๐ class jenkins.Jenkins(url, username=None, password=None, timeout=_TYPE_DEFAULT.token, retries=0) ๐
Create handle to Jenkins instance.
All methods will raise JenkinsException on failure.
Parameters
- url -- URL of Jenkins server,
str - username -- Server username,
str - password -- Server password,
str - timeout -- Server connection timeout in secs (default: not set),
int
maybe_add_crumb(req)
(no extra deets, she just does her thing)
get_job_info(name, depth=0, fetch_all_builds=False)
Get job information dictionary.
Parameters
- name -- Job name,
str - depth -- JSON depth,
int - fetch_all_builds -- If true, all builds will be retrieved from Jenkins. Otherwise, Jenkins will only return the most recent 100 builds. This comes at the expense of an additional API call which may return significant amounts of data.
bool
Returns : dictionary of job information
get_job_info_regex(pattern, depth=0, folder_depth=0, folder_depth_per_request=10)
Get a list of jobs information that contain names which match the regex pattern.
Parameters
- pattern -- regex pattern,
str - depth -- JSON depth,
int - folder_depth -- folder level depth to search
int - folder_depth_per_request -- Number of levels to fetch at once,
int. Seeget_all_jobs().
Returns : List of jobs info, list
get_job_name(name)
Return the name of a job using the API.
That is roughly an identity method which can be used to quickly verify a job exists or is accessible without causing too much stress on the server side. (she's lowkey just vibing, not stressing the server ๐ )
Parameters : name -- Job name, str
Returns : Name of job or None
debug_job_info(job_name)
Print out job info in more readable format.
jenkins_open(req, add_crumb=True, resolve_auth=True)
Return the HTTP response body from a requests.Request.
Returns : str
jenkins_open_stream(req, add_crumb=True, resolve_auth=True)
Return the HTTP response body from a requests.Request.
Returns : stream
jenkins_request(req, add_crumb=True, resolve_auth=True, stream=None)
Utility routine for opening an HTTP request to a Jenkins server.
Parameters
- req -- A
requests.Requestto submit. - add_crumb -- If
True, try to add a crumb header to this req before submitting. Defaults toTrue. - resolve_auth -- If
True, maybe add authentication. Defaults toTrue. - stream -- If
True, return a stream
Returns : A requests.Response object.
get_queue_item(number, depth=0)
Get information about a queued item (to-be-created job).
The returned dict will have a "why" key if the queued item is still waiting for an executor.
The returned dict will have an "executable" key if the queued item is running on an executor, or has completed running. Use this to determine the job number / URL.
Parameters : name -- queue number, int
Returns : dictionary of queued information, dict
get_build_info(name, number, depth=0)
Get build information dictionary.
Parameters
- name -- Job name,
str - number -- Build number,
str(also acceptsint) - depth -- JSON depth,
int
Returns : dictionary of build information, dict
Example:
>>> next_build_number = server.get_job_info('build_name')['nextBuildNumber']
>>> output = server.build_job('build_name')
>>> from time import sleep; sleep(10)
>>> build_info = server.get_build_info('build_name', next_build_number)
>>> print(build_info)
{u'building': False, u'changeSet': {u'items': [{u'date': u'2011-12-19T18:01:52.540557Z', u'msg': u'test', u'revision': 66, u'user': u'unknown', u'paths': [{u'editType': u'edit', u'file': u'/branches/demo/index.html'}]}], u'kind': u'svn', u'revisions': [{u'module': u'http://eaas-svn01.i3.level3.com/eaas', u'revision': 66}]}, u'builtOn': u'', u'description': None, u'artifacts': [{u'relativePath': u'dist/eaas-87-2011-12-19_18-01-57.war', u'displayPath': u'eaas-87-2011-12-19_18-01-57.war', u'fileName': u'eaas-87-2011-12-19_18-01-57.war'}, {u'relativePath': u'dist/eaas-87-2011-12-19_18-01-57.war.zip', u'displayPath': u'eaas-87-2011-12-19_18-01-57.war.zip', u'fileName': u'eaas-87-2011-12-19_18-01-57.war.zip'}], u'timestamp': 1324317717000, u'number': 87, u'actions': [{u'parameters': [{u'name': u'SERVICE_NAME', u'value': u'eaas'}, {u'name': u'PROJECT_NAME', u'value': u'demo'}]}, {u'causes': [{u'userName': u'anonymous', u'shortDescription': u'Started by user anonymous'}]}, {}, {}, {}], u'id': u'2011-12-19_18-01-57', u'keepLog': False, u'url': u'http://eaas-jenkins01.i3.level3.com:9080/job/build_war/87/', u'culprits': [{u'absoluteUrl': u'http://eaas-jenkins01.i3.level3.com:9080/user/unknown', u'fullName': u'unknown'}], u'result': u'SUCCESS', u'duration': 8826, u'fullDisplayName': u'build_war #87'}
get_build_env_vars(name, number, depth=0)
Get build environment variables.
Parameters
- name -- Job name,
str - number -- Build number,
str(also acceptsint) - depth -- JSON depth,
int
Returns : dictionary of build env vars, dict or None for workflow jobs, or if InjectEnvVars plugin not installed
get_build_test_report(name, number, depth=0, tree=None)
Get test results report.
Parameters
- name -- Job name,
str - number -- Build number,
str(also acceptsint) - depth -- depth parameter for the
api/jsoncall, default0 - tree -- tree parameter for the
api/jsoncall used to limit returned fields
Returns : dictionary of test report results, dict or None if there is no Test Report
get_build_artifact(name, number, artifact)
Grab the artifacts from a job, bestie ๐
Parameters
nameโ job name,strnumberโ build number,str(it will also accept anint, we're not gatekeeping)artifactโ artifact relative path,str
Returns
artifact to download, dict
get_build_artifact_as_bytes(name, number, artifact)
Same vibe as above, but it hands you the artifact as raw bytes โจ
Parameters
nameโ job name,strnumberโ build number,str(also acceptsint, no drama)artifactโ artifact relative path,str
Returns
artifact to download, bytes
get_build_stages(name, number)
Get the stages info from a job, like a little behind-the-scenes tour ๐
Parameters
nameโ job name,strnumberโ build number,str(also acceptsint)- ... wait, nope, that's it, just those two ๐
Returns
dictionary of stages in the job, dict
get_queue_info()
No parameters, just vibes. It gives you the queue info ๐ฆ
Returns
list of job dictionaries, [dict]
Example
>>> queue_info = server.get_queue_info()
>>> print(queue_info[0])
{u'task': {u'url': u'http://your_url/job/my_job/', u'color': u'aborted_anime', u'name': u'my_job'}, u'stuck': False, u'actions': [{u'causes': [{u'shortDescription': u'Started by timer'}]}], u'buildable': False, u'params': u'', u'buildableStartMilliseconds': 1315087293316, u'why': u'Build #2,532 is already in progress (ETA:10 min)', u'blocked': True}
cancel_queue(id)
Cancel a queued build. Yeah, we're doing that ๐ซถ
Parameters
idโ Jenkins job id number for the build,int
get_info(item='', query=None)
Get information on this Master, or on a specific item on the Master ๐
This information includes job list and view information, and you can also use it to retrieve information on items such as job folders.
Parameters
itemโ item to get information about on this Masterqueryโ xpath to extract information about on this Master
Returns
dictionary of information about Master or item, dict
Example
>>> info = server.get_info()
>>> jobs = info['jobs']
>>> print(jobs[0])
{u'url': u'http://your_url_here/job/my_job/', u'color': u'blue',
u'name': u'my_job'}
get_whoami(depth=0)
Get information about the user account that authenticated to Jenkins. This is a simple way to verify that your credentials are correct โ a little vibe check for your login, iykyk ๐ญ
Returns
Information about the current user dict
Example
>>> me = server.get_whoami()
>>> print me['fullName']
>>> 'John'
get_version()
Get the version of this Master ๐
Returns
This master's version number str
Example
>>> info = server.get_version()
>>> print info
>>> 1.541
get_plugins_info(depth=2)
Get all installed plugins information on this Master ๐
This method retrieves information about each plugin that is installed on master, returning the raw plugin data in a JSON format.
Deprecated since version 0.4.9 โ use get_plugins() instead. She's iconic but she's retired, bestie ๐
Parameters
depthโ JSON depth,int
Returns
info on all plugins [dict]
Example
>>> info = server.get_plugins_info()
>>> print(info)
[{u'backupVersion': None, u'version': u'0.0.4', u'deleted': False,
u'supportsDynamicLoad': u'MAYBE', u'hasUpdate': True,
u'enabled': True, u'pinned': False, u'downgradable': False,
u'dependencies': [], u'url':
u'http://wiki.jenkins-ci.org/display/JENKINS/Gearman+Plugin',
u'longName': u'Gearman Plugin', u'active': True, u'shortName':
u'gearman-plugin', u'bundled': False}, ..]
get_plugin_info(name, depth=2)
Get an installed plugin's information on this Master ๐ง
This method retrieves information about a specific plugin and returns the raw plugin data in a JSON format. The passed-in plugin name (short or long) must be an exact match โ no fuzzy matching, she's strict ๐
NOTE: calling this method will query Jenkins fresh for the information for all plugins on each call. So if you need to retrieve information for multiple plugins, it's recommended to use get_plugins() instead, which will return a multi key dictionary that can be accessed via either the short or long name of the plugin. Save yourself the requests, bestie ๐
Parameters
nameโ name (short or long) of plugin,strdepthโ JSON depth,int
Returns
a specific plugin dict
Example
>>> info = server.get_plugin_info("Gearman Plugin")
>>> print(info)
{u'backupVersion': None, u'version': u'0.0.4', u'deleted': False,
u'supportsDynamicLoad': u'MAYBE', u'hasUpdate': True,
u'enabled': True, u'pinned': False, u'downgradable': False,
u'dependencies': [], u'url':
u'http://wiki.jenkins-ci.org/display/JENKINS/Gearman+Plugin',
u'longName': u'Gearman Plugin', u'active': True, u'shortName':
u'gearman-plugin', u'bundled': False}
get_plugins(depth=2)
Return plugins info using a helper class for version comparison โจ
This method retrieves information about all the installed plugins and uses a Plugin helper class to simplify version comparison. It also uses a multi key dict so you can retrieve stuff via either short or long names. Chef's kiss ๐
When printing/dumping the data, the version will transparently return a unicode string, which is exactly what was previously returned by the API.
Parameters
depthโ JSON depth,int
Returns
info on all plugins [dict]
Example
>>> j = Jenkins()
>>> info = j.get_plugins()
>>> print(info)
{('gearman-plugin', 'Gearman Plugin'):
{u'backupVersion': None, u'version': u'0.0.4',
u'deleted': False, u'supportsDynamicLoad': u'MAYBE',
u'hasUpdate': True, u'enabled': True, u'pinned': False,
u'downgradable': False, u'dependencies': [], u'url':
u'http://wiki.jenkins-ci.org/display/JENKINS/Gearman+Plugin',
u'longName': u'Gearman Plugin', u'active': True, u'shortName':
u'gearman-plugin', u'bundled': False}, ...}
get_jobs(folder_depth=0, folder_depth_per_request=10, view_name=None)
Get list of jobs ๐ฅ
Each job is a dictionary with 'name', 'url', 'color' and 'fullname' keys.
If the view_name parameter is present, the list of jobs will be limited to only those configured in the specified view. In this case, the job dictionary 'fullname' key would be equal to the job name.
Parameters
folder_depthโ number of levels to search,int. By default0, which will limit search to toplevel.Nonedisables the limit.folder_depth_per_requestโ number of levels to fetch at once,int. Seeget_all_jobs().view_nameโ name of a Jenkins view for which to retrieve jobs,str. By default, the job list is not limited to a specific view.
Returns
list of jobs, [{str: str, str: str, str: str, str: str}]
Example
>>> jobs = server.get_jobs()
>>> print(jobs)
[{
u'name': u'all_tests',
u'url': u'http://your_url.here/job/all_tests/',
u'color': u'blue',
u'fullname': u'all_tests'
}]
get_all_jobs(folder_depth=None, folder_depth_per_request=10)
Get list of all jobs recursively to the given folder depth ๐
Each job is a dictionary with 'name', 'url', 'color' and 'fullname' keys.
Parameters
folder_depthโ number of levels to search,int. By defaultNone, which will search all levels.0limits to toplevel.folder_depth_per_requestโ number of levels to fetch at once,int. By default10, which is usually enough to fetch all jobs using a single request and still easily fits into an HTTP request.
Returns
list of jobs, [ { str: str} ]
NOTE: on instances with many folders it would not be efficient to fetch each folder separately, hence folder_depth_per_request levels are fetched at once using the tree query parameter:
?tree=jobs[url,color,name,jobs[...,jobs[...,jobs[...,jobs]]]]
If there are more folder levels than the query asks for, Jenkins returns empty [1] objects at the deepest level:
{"name": "folder", "url": "...", "jobs": [{}, {}, ...]}
...and that's literally the whole point: this makes it possible to detect when additional requests are needed. Like, you get to know ahead of time whether you're gonna have to go back for more. ๐ฎ
[1] okay ngl, actually recent Jenkins includes a _class field everywhere, but it's missing the requested fields. ๐
copy_job(from_name, to_name)
Copies a Jenkins job. Duplicate it, bestie, go off. ๐
It will raise an exception whenever the source and destination folder for this jobs won't be the same. So like, same folder or it's drama.
Parameters
from_name-- Name of Jenkins job to copy from,strto_name-- Name of Jenkins job to copy to,str
Throws JenkinsException whenever the source and destination folder are not the same.
rename_job(from_name, to_name)
Renames an existing Jenkins job. Glow-up era. โจ
It will raise an exception whenever the source and destination folder for this jobs won't be the same.
Parameters
from_name-- Name of Jenkins job to rename,strto_name-- New Jenkins job name,str
Throws JenkinsException whenever the source and destination folder are not the same.
delete_job(name)
Deletes a Jenkins job. Permanently. Gone. No undo, no takebacks, it's giving final. ๐
Parameters
name-- Name of Jenkins job,str
enable_job(name)
Enables a Jenkins job. Wake up queen ๐
Parameters
name-- Name of Jenkins job,str
disable_job(name)
Disables a Jenkins job.
To re-enable, call Jenkins.enable_job().
Parameters
name-- Name of Jenkins job,str
set_next_build_number(name, number)
Sets a job's next build number. Very specific, very powerful, we love. ๐ฅ
The current next build number is contained within the job information retrieved using Jenkins.get_job_info(). And heads up: if the specified next build number is less than the last build number, Jenkins will ignore the request. Like, it's just not gonna happen, bestie. ๐
Note that the Next Build Number Plugin must be installed to enable this functionality. No plugin, no feature. Periodt.
Parameters
name-- Name of Jenkins job,strnumber-- Next build number to set,int
Example:
>>> next_bn = server.get_job_info('job_name')['nextBuildNumber']
>>> server.set_next_build_number('job_name', next_bn + 50)
job_exists(name)
Checks whether a job exists. Vibe check on the job itself. ๐ฆ
Parameters
name-- Name of Jenkins job,str
Returns True if Jenkins job exists
jobs_count()
Gets the number of jobs on the Jenkins server. Census time. ๐ง
Returns Total number of jobs, int
assert_job_exists(name, exception_message='job[%s] does not exist')
Raises an exception if a job does not exist. Like a bouncer at the door fr fr.
Parameters
name-- Name of Jenkins job,strexception_message-- Message to use for the exception. Formatted withname
Throws JenkinsException whenever the job does not exist.
create_folder(folder_name, ignore_failures=False)
Creates a new Jenkins folder. Organization? We love to see it. ๐
Parameters
folder_name-- Name of Jenkins Folder,strignore_failures-- ifTrue, don't raise if it was not possible to create the folder,bool
upsert_job(name, config_xml)
Creates a new Jenkins job, or reconfigures it if it already exists. Upsert is such a mood โ do it either way, no cap. โจ
Parameters
name-- Name of Jenkins job,strconfig_xml-- config file text,str
check_jenkinsfile_syntax(jenkinsfile)
Checks if a Pipeline Jenkinsfile has a valid syntax. Spelling test for your pipeline. ๐
Parameters
jenkinsfile-- Jenkinsfile text,str
Returns List of errors in the Jenkinsfile. Empty list if no errors. (An empty list is the slay outcome.)
create_job(name, config_xml)
Creates a new Jenkins job. Brand new baby job. ๐ธ
Parameters
name-- Name of Jenkins job,strconfig_xml-- config file text,str
get_job_config(name)
Gets configuration of existing Jenkins job. Show me your XML, bestie. ๐
Parameters
name-- Name of Jenkins job,str
Returns job configuration (XML format)
reconfig_job(name, config_xml)
Changes configuration of existing Jenkins job.
To create a new job, see Jenkins.create_job().
Parameters
name-- Name of Jenkins job,strconfig_xml-- New XML configuration,str
build_job_url(name, parameters=None, token=None)
Gets the URL to trigger a build job. No build yet, just the address, iykyk. ๐
Authenticated setups may require configuring a token on the server side.
Use list of two membered tuples to supply parameters with multi select options. (Yes, two-membered tuples specifically โ that's the rule. ๐ซถ)
Parameters
name-- Name of Jenkins job,strparameters-- parameters for job, orNone.,dictor list of two membered tuplestoken-- (optional) token for building job,str
Returns URL for building job
build_job(name, parameters=None, token=None)
Triggers a build job. GO GO GO ๐ฅ
This method returns a queue item number that you can pass to Jenkins.get_queue_item(). And listen โ that queue number is only valid for about five minutes after the job completes, so you should get/poll the queue information as soon as possible to determine the job's URL. Five minutes, bestie. Don't be late. โฐ
Parameters
name-- name of jobparameters-- parameters for job, orNone,dicttoken-- Jenkins API token
Returns int queue item
run_script(script, node=None)
Executes a groovy script on the jenkins master or on a node if specified.. (she said it with two dots, iconic)
Parameters
script-- The groovy script,stringnode-- Node to run the script on, defaults toNone(master).
Returns The result of the script run.
Example::
>>> info = server.run_script("println(Jenkins.instance.pluginManager.plugins)")
>>> print(info)
u'[Plugin:windows-slaves, Plugin:ssh-slaves, Plugin:translation,
Plugin:cvs, Plugin:nodelabelparameter, Plugin:external-monitor-job,
Plugin:mailer, Plugin:jquery, Plugin:antisamy-markup-formatter,
Plugin:maven-plugin, Plugin:pam-auth]'
install_plugin(name, include_dependencies=True)
Installs a plugin and its dependencies from the Jenkins public repository at http://repo.jenkins-ci.org/repo/org/jenkins-ci/plugins โ new plugin, who dis ๐
Parameters
name-- The plugin short name,stringinclude_dependencies-- Install the plugin's dependencies,bool
Returns Whether a Jenkins restart is required, bool
Example::
>>> info = server.install_plugin("jabber")
>>> print(info)
True
stop_build(name, number)
Stops a running Jenkins build. Enough. Sit down. โ
Parameters
name-- Name of Jenkins job,strnumber-- Jenkins build number for the job,int
delete_build(name, number)
Deletes a Jenkins build. Bye bye build ๐ฆ
Parameters
name-- Name of Jenkins job,strnumber-- Jenkins build number for the job,int
wipeout_job_workspace(name)
Wipes out the workspace for a given Jenkins job. Clean slate energy, very cathartic honestly. ๐
Parameters
name-- Name of Jenkins job,str
get_running_builds()
Returns a list of running builds. Who's active right now ๐
Each build is a dict with keys 'name', 'number', 'url', 'node', and 'executor'.
Returns List of builds, [ { str: str, str: int, str:str, str: str, str: int} ]
Example::
>>> builds = server.get_running_builds()
>>> print(builds)
[{'node': 'foo-slave', 'url': 'https://localhost/job/test/15/',
'executor': 0, 'name': 'test', 'number': 15}]
get_nodes_with_info(depth=0)
Gets a list of nodes connected to the Master. ๐ฅ๏ธโจ
Each node is a dictionary of node info.
Returns List of nodes
get_nodes(depth=0)
Gets a list of nodes connected to the Master.
Each node is a dict with keys 'name' and 'offline'.
Returns List of nodes, [ { str: str, str: bool} ]
get_node_info(name, depth=0)
Gets the node information dictionary. ๐
Parameters
name-- Node name,strdepth-- JSON depth,int
Returns Dictionary of node info, dict
node_exists(name)
Checks whether a node exists.
Parameters
name-- Name of Jenkins node,str
Returns True if Jenkins node exists
assert_node_exists(name, exception_message='node[%s] does not exist')
Raises an exception if a node does not exist.
Parameters
name-- Name of Jenkins node,strexception_messageโ the message the exception gets. Formatted withnameโจ
Throws JenkinsException whenever the node does not exist.
delete_node(name)
Deletes a Jenkins node permanently. Like, gone-gone. No undo button bestie ๐
Parameters:
nameโ Name of Jenkins node,str
disable_node(name, msg='')
Takes a node offline. It's not deleted, it's just โจrestingโจ
Parameters:
nameโ Jenkins node name,strmsgโ Offline message,str
enable_node(name)
Wakes that node back up. Welcome back to the group chat ๐ซถ
Parameters:
nameโ Jenkins node name,str
create_node(name, numExecutors=2, nodeDescription=None, remoteFS='/var/lib/jenkins', labels=None, exclusive=False, launcher='hudson.slaves.CommandLauncher', launcher_params={})
Builds you a brand new node from scratch, main character energy ๐
Parameters:
nameโ name of node to create,strnumExecutorsโ number of executors for node,intnodeDescriptionโ Description of node,strremoteFSโ Remote filesystem location to use,strlabelsโ Labels to associate with node,strexclusiveโ Use this node for tied jobs only,boollauncherโ The launch method for the slave,jenkins.LAUNCHER_COMMAND,jenkins.LAUNCHER_SSH,jenkins.LAUNCHER_JNLP,jenkins.LAUNCHER_WINDOWS_SERVICElauncher_paramsโ Additional parameters for the launcher,dict
get_node_config(name)
Hands you the configuration for a node. Receipts ๐
Parameters:
nameโ Jenkins node name,str
reconfig_node(name, config_xml)
Changes the configuration for a node that already exists. Glow-up time ๐
Parameters:
nameโ Jenkins node name,strconfig_xmlโ New XML configuration,str
get_build_console_output(name, number)
Gives you the build console text. All the drama, right there in the log ๐
Parameters:
nameโ Job name,strnumberโ Build number,str(also acceptsint)
Returns:
- Build console output,
str
get_view_name(name)
Returns the name of a view using the API.
It's basically an identity method, and you use it to quickly check that a view exists or that you can reach it, without putting too much stress on the server side. Be gentle with the server bestie, it's doing its best ๐ฅบ
Parameters:
nameโ View name,str
Returns:
- Name of view or
None
assert_view_exists(name, exception_message='view[%s] does not exist')
Raises an exception if a view does not exist. Vibe check: failed โ
Parameters:
nameโ Name of Jenkins view,strexception_messageโ Message to use for the exception. Formatted withname
Throws JenkinsException whenever the view does not exist.
view_exists(name)
Checks whether a view exists. Just a lil peek ๐
Parameters:
nameโ Name of Jenkins view,str
Returns:
Trueif Jenkins view exists
get_views()
Gets the list of views running.
Every view is a dictionary with 'name' and 'url' keys.
Returns:
- list of views,
[ { str: str} ]
delete_view(name)
Deletes a Jenkins view permanently. No take-backs ๐
Parameters:
nameโ Name of Jenkins view,str
create_view(name, config_xml)
Creates a new Jenkins view. Fresh start, new era ๐
Parameters:
nameโ Name of Jenkins view,strconfig_xmlโ config file text,str
reconfig_view(name, config_xml)
Changes the configuration of an existing Jenkins view.
If you wanna make a brand new view instead, go see Jenkins.create_view().
Parameters:
nameโ Name of Jenkins view,strconfig_xmlโ New XML configuration,str
get_view_config(name)
Gets the configuration of an existing Jenkins view.
Parameters:
nameโ Name of Jenkins view,str
Returns:
- view configuration (XML format)
get_promotion_name(name, job_name)
Returns the name of a promotion using the API.
Same deal as the view one โ it's roughly an identity method, and you use it to quickly verify that a promotion exists for a job or that you can reach it, without stressing the server side too hard. Lowkey considerate โจ
Parameters:
nameโ Promotion name,strjob_nameโ Job name,str
Returns:
- Name of promotion or
None
assert_promotion_exists(name, job_name, exception_message='promotion[%s] does not exist for job[%s]')
Raises an exception if a job lacks a promotion. It's giving "where is it though" ๐ญ
Parameters:
nameโ Name of Jenkins promotion,strjob_nameโ Job name,strexception_messageโ Message to use for the exception. Formatted withnameandjob_name
Throws JenkinsException whenever the promotion does not exist on a job.
promotion_exists(name, job_name)
Checks whether a job has a certain promotion.
Parameters:
nameโ Name of Jenkins promotion,strjob_nameโ Job name,str
Returns:
Trueif Jenkins promotion exists
get_promotions_info(job_name, depth=0)
Gets the promotion information dictionary of a job. Info dump, but make it useful ๐
Parameters:
job_nameโ job_name,strdepthโ JSON depth,int
Returns:
- Dictionary of promotion info,
dict
get_promotions(job_name)
Gets the list of promotions running.
Every promotion is a dictionary with 'name' and 'url' keys.
Parameters:
job_nameโ Job name,str
Returns:
- list of promotions,
[ { str: str} ]
delete_promotion(name, job_name)
Deletes a Jenkins promotion permanently. Say bye fr fr ๐
Parameters:
nameโ Name of Jenkins promotion,strjob_nameโ Job name,str
create_promotion(name, job_name, config_xml)
Creates a new Jenkins promotion. Iconic behaviour, honestly ๐
Parameters:
nameโ Name of Jenkins promotion,strjob_nameโ Job name,strconfig_xmlโ config file text,str
reconfig_promotion(name, job_name, config_xml)
Changes the configuration of an existing Jenkins promotion.
Wanna make a new one instead? Go see Jenkins.create_promotion().
Parameters:
nameโ Name of Jenkins promotion,strjob_nameโ Job name,strconfig_xmlโ New XML configuration,str
get_promotion_config(name, job_name)
Gets the configuration of an existing Jenkins promotion.
Parameters:
nameโ Name of Jenkins promotion,strjob_nameโ Job name,str
Returns:
- promotion configuration (XML format)
assert_folder(name, exception_message='job[%s] is not a folder')
Raises an exception if the job is not a Cloudbees Folder. Not everything can be a folder, bestie ๐๏ธ
Parameters:
nameโ Name of job,strexception_messageโ Message to use for the exception.
Throws JenkinsException whenever the job is not Cloudbees Folder.
is_folder(name)
Checks whether a job is a Cloudbees Folder.
Parameters:
nameโ Job name,str
Returns:
Trueif job is folder,Falseotherwise
assert_credential_exists(name, folder_name, domain_name='_', exception_message='credential[%s] does not exist in the domain[%s] of [%s]')
Raises an exception if a credential does not exist in the domain of a folder. Searching high and low and finding nothing ๐ญ
Parameters:
nameโ Name of credential,strfolder_nameโ Folder name,strdomain_nameโ Domain name, default is'_',strexception_messageโ Message to use for the exception. Formatted withname,domain_name, andfolder_name
Throws JenkinsException whenever the credential does not exist in domain of folder.
credential_exists(name, folder_name, domain_name='_')
Checks whether a credential exists in the domain of a folder.
Parameters:
nameโ Name of credential,strfolder_nameโ Folder name,strdomain_nameโ Domain name, default is'_',str
Returns:
Trueif credential exists,Falseotherwise
get_credential_info(name, folder_name, domain_name='_')
Gets the credential information dictionary in the domain of a folder. Receipts, but for creds ๐งพ
Parameters:
nameโ Name of credential,strfolder_nameโ folder_name,strdomain_nameโ Domain name, default is'_',str
Returns:
- Dictionary of credential info,
dict
get_credential_config(name, folder_name, domain_name='_')
Gets the configuration of a credential in the domain of a folder.
Parameters:
nameโ bestie, this is the credential's name, and it's astr๐folder_nameโ the folder's name, astrdomain_nameโ the domain name, defaults to'_', astrโจ
Returns โ the credential configuration, in XML format ๐
create_credential(folder_name, config_xml, domain_name='_')
Drop a brand new credential into the domain of a folder, no cap ๐
Parameters
folder_nameโ folder name, astrconfig_xmlโ the new XML configuration, astrdomain_nameโ domain name, defaults to'_', astr
delete_credential(name, folder_name, domain_name='_')
Yeet that credential out of the domain of the folder ๐๏ธ
Parameters
nameโ name of credential, astrfolder_nameโ folder name, astrdomain_nameโ domain name, defaults to'_', astr
reconfig_credential(folder_name, config_xml, domain_name='_')
Glow-up time โจ reconfig a credential with a fresh new config in the domain of the folder
Parameters
folder_nameโ folder name, astrconfig_xmlโ new XML configuration, astrdomain_nameโ domain name, defaults to'_', astr
list_credentials(folder_name, domain_name='_')
Show me the receipts โ list every credential in the domain of the folder ๐
Parameters
folder_nameโ folder name, astrdomain_nameโ domain name, defaults to'_', astr
Returns โ the credentials list, a list ๐ซถ
quiet_down()
Get Jenkins all prepped for shutdown ๐ค
No new builds will be started, which lets the running builds actually finish up before the server goes night-night. It's giving "we're closing the club but let everyone finish their drink" energy.
wait_for_normal_op(timeout)
Sit there and wait for Jenkins to come back into normal operation mode ๐ฆ
Parameters
timeoutโ number of seconds to wait, anint. Not me needing to explain this ๐ this is not the same as the connection timeout set via__init__, because that one controls the socket timeout. Instead, this is how long to wait until the status gets returned.
Returns โ True if Jenkins became ready in time, False otherwise.
Heads up bestie ๐ setting timeout to be less than the configured connection timeout may result in this waiting for at least the connection timeout length of time before returning. It is recommended that the timeout here should be at least as long as any set connection timeout. fr fr.
class jenkins.plugins.Plugin(*args, **kwargs)
A dictionary object holding plugin metadata ๐
It populates the dictionary using json object input.
It accepts the same arguments as the python dict class. periodt.
class jenkins.plugins.PluginVersion(version)
A class that brings the comparison capabilities for plugin versions ๐
It parses the plugin version and stores it, so you can compare away. Iconic, honestly.
๐ USING PYTHON-JENKINS ๐
okay so bestie, the python-jenkins library lets you run the whole Jenkins server situation through the Jenkins REST endpoints โ like, full remote-control main character energy โจ. Down below are examples to get you started using the library. If you need further help, take a look at the API reference docs for more details, iykyk ๐ซถ.
๐ธ Example 1: Get version of Jenkins
This one's the classic icebreaker: connect to a Jenkins instance and pull the Jenkins server version.
import jenkins
server = jenkins.Jenkins('http://localhost:8080', username='myuser', password='mypassword')
user = server.get_whoami()
version = server.get_version()
print('Hello %s from Jenkins %s' % (user['fullName'], version))
So the above code prints the fullName attribute of the user and the version of the Jenkins master running on 'localhost:8080'. For example, it may print "Hello John from Jenkins 2.0" ๐.
From Jenkins version 1.426 onward you can specify an API token instead of your real password while authenticating the user against the Jenkins instance. Refer to the Jenkins Authentication wiki for details about how you can generate an API token. Once you have an API token you can pass the API token instead of a real password while creating a Jenkins instance. no cap, way safer ๐ .
๐ฆ Example 2: Logging into Jenkins using kerberos
Kerberos support is only enabled if you have the "kerberos" python package installed. You can install the "kerberos" package from PyPI using the obvious pip command:
pip install kerberos
NOTE: This might require python header files as well as kerberos header files. ๐ญ
If you have the "kerberos" python package installed, python-jenkins tries to authenticate using kerberos automatically when the Jenkins server replies "401 Unauthorized" and indicates it supports kerberos. That is, kerberos authentication should work automagically โจ. For a quick test, just try the following:
import jenkins
server = jenkins.Jenkins('http://localhost:8080')
print server.jobs_count()
NOTE: Jenkins as such does not support kerberos, it needs to be supported by the Servlet container or a reverse proxy sitting in front of Jenkins. so like, don't come for Jenkins itself, she's not the one doing it ๐
๐ Example 3: Working with Jenkins Jobs
This is an example showing how to create, configure and delete Jenkins jobs โ the full job lifecycle glow-up ๐ฅ.
server.create_job('empty', jenkins.EMPTY_CONFIG_XML)
jobs = server.get_jobs()
print jobs
my_job = server.get_job_config('cool-job')
print(my_job) # prints XML configuration
server.build_job('empty')
server.disable_job('empty')
server.copy_job('empty', 'empty_copy')
server.enable_job('empty_copy')
server.reconfig_job('empty_copy', jenkins.RECONFIG_XML)
server.delete_job('empty')
server.delete_job('empty_copy')
# build a parameterized job
# requires creating and configuring the api-test job to accept 'param1' & 'param2'
server.build_job('api-test', {'param1': 'test value 1', 'param2': 'test value 2'})
last_build_number = server.get_job_info('api-test')['lastCompletedBuild']['number']
build_info = server.get_build_info('api-test', last_build_number)
print build_info
# get all jobs from the specific view
jobs = server.get_jobs(view_name='View Name')
print jobs
๐ Example 4: Working with Jenkins Views
This is an example showing how to create, configure and delete Jenkins views ๐ช.
server.create_view('EMPTY', jenkins.EMPTY_VIEW_CONFIG_XML)
view_config = server.get_view_config('EMPTY')
views = server.get_views()
server.delete_view('EMPTY')
print views
๐ Example 5: Working with Jenkins Plugins
This is an example showing how to retrieve Jenkins plugins information โ plug in, plug out, we love to see it ๐งฉ.
plugins = server.get_plugins_info()
print plugins
The above example will print a dictionary containing all the plugins that are installed on the Jenkins server. An example of what you can expect from the get_plugins_info method is documented in the API reference doc.
โญ Example 6: Working with Jenkins Nodes
This is an example showing how to add, configure, enable and delete Jenkins nodes โ nodes are literally the supporting cast and they deserve their flowers ๐ธ.
server.create_node('slave1')
nodes = get_nodes()
print nodes
node_config = server.get_node_info('slave1')
print node_config
server.disable_node('slave1')
server.enable_node('slave1')
# create node with parameters
params = {
'port': '22',
'username': 'juser',
'credentialsId': '10f3a3c8-be35-327e-b60b-a3e5edb0e45f',
'host': 'my.jenkins.slave1'
}
server.create_node(
'slave1',
nodeDescription='my test slave',
remoteFS='/home/juser',
labels='precise',
exclusive=True,
launcher=jenkins.LAUNCHER_SSH,
launcher_params=params)
๐ Example 7: Working with Jenkins Build Queue
This is an example showing how to retrieve information on the Jenkins queue โ the queue is giving "line outside the club" energy ngl ๐ .
server.build_job('foo')
queue_info = server.get_queue_info()
id = queue_info[0].get('id')
server.cancel_queue(id)
๐ง Example 8: Working with Jenkins Cloudbees Folders
Requires the Cloudbees Folders Plugin for Jenkins.
This is an example showing how to create, configure and delete Jenkins folders ๐.
server.create_job('folder', jenkins.EMPTY_FOLDER_XML)
server.create_job('folder/empty', jenkins.EMPTY_FOLDER_XML)
server.copy_job('folder/empty', 'folder/empty_copy')
server.delete_job('folder/empty_copy')
server.delete_job('folder')
๐ฅ Example 9: Updating Next Build Number
Requires the Next Build Number Plugin for Jenkins.
This is an example showing how to update the next build number for a Jenkins job ๐ข.
next_bn = server.get_job_info('job_name')['nextBuildNumber']
server.set_next_build_number('job_name', next_bn + 50)
๐ Example 9: Working with Build Promotions
Requires the Promoted Builds Plugin for Jenkins.
This is an example showing how to create, configure and delete a promotion process for an existing job.
bestie, yes, this one is also numbered 9 in the original โ not a typo of mine, it's just canon ๐
The job in this example is named prom_job and it needs to have this config xml snippet before creating the promotion:
<properties>
<hudson.plugins.promoted__builds.JobPropertyImpl>
<activeProcessNames>
<string>prom_name</string>
</activeProcessNames>
</hudson.plugins.promoted__builds.JobPropertyImpl>
</properties>
where prom_name is the name of the promotion that will get added to the job.
server.create_promotion('prom_name', 'prom_job', jenkins.EMPTY_PROMO_CONFIG_XML)
server.promotion_exists('prom_name', 'prom_job')
print server.get_promotions('prom_job')
server.reconfig_promotion('prom_name', 'prom_job', jenkins.PROMO_RECONFIG_XML)
print server.get_promotion_config('prom_name', 'prom_job')
server.delete_promotion('prom_name', 'prom_job')
๐ฆ Example 10: Waiting for Jenkins to be ready
It is possible to ask the API to wait for Jenkins to be ready with a given timeout. This can be used to aid launching of Jenkins and then waiting for the REST API to be responsive before continuing with subsequent configuration โณ.
# timeout here is the socket connection timeout, for each connection
# attempt it will wait at most 5 seconds before assuming there is
# nothing listening. Useful where firewalls may black hole connections.
server = jenkins.Jenkins('http://localhost:8080', timeout=5)
# wait for at least 30 seconds for Jenkins to be ready
if server.wait_for_normal_op(30):
# actions once running
...
else:
print("Jenkins failed to be ready in sufficient time")
exit 2
Note that the timeout arg to jenkins.Jenkins() is the socket connection timeout. If you set this to be more than the timeout value passed to wait_for_normal_op(), then in cases where the underlying connection is not rejected (firewall black-hole, or slow connection) then wait_for_normal_op() may wait at least the connection timeout, or a multiple of it where multiple connection attempts are made. A connection timeout of 5 seconds and a wait timeout of 8 will result in potentially waiting 10 seconds if both connections attempts do not get responses ๐ญ. fr fr, do the math before you set these.
โจ INSTALLING โจ
The module is known to pip and Debian-based distributions as python-jenkins.
pip:
pip install python-jenkins
easy_install:
easy_install python-jenkins
The module has been packaged since Ubuntu Oneiric (11.10):
apt-get install python-jenkins
And on Fedora 19 and later:
yum install python-jenkins
For development:
python setup.py develop
๐ Documentation
Documentation is included in the doc folder. To generate docs locally execute the command:
tox -e docs
The generated documentation is then available under doc/build/html/index.html ๐.
๐งช Unit Tests
Unit tests have been included and are in the tests folder. We recently started including unit tests as examples in our documentation so to keep the examples up to date it is very important that we include unit tests for every module ๐. To run the unit tests, execute the command:
tox -e py27
- Note: View
tox.inito run tests on other versions of Python.
Due to how the tests are split up into a dedicated class per API method, it is possible to execute tests against a single API at a time. To execute the tests for the Jenkins.get_version() API execute the command:
tox -e py27 -- tests.test_version.JenkinsVersionTest
For further details on how to list tests available and different ways to execute them, see <https://wiki.openstack.org/wiki/Testr>.
๐ Test Coverage
To measure test coverage, execute the command:
tox -e cover
- Index
- Module Index
- Search Page
๐ AUTHOR ๐
Ken Conley, James Page, Tully Foote, Matthew Gertner
๐ COPYRIGHT ๐
2010, Willow Garage
and that's a wrap bestie!! ๐ซถ this page was python-jenkins version 1.8.3, dated Sep 19, 2025, filed under PYTHONJENKINS(1) โ iconic, timeless, slay ๐
โจ go forth and automate ur Jenkins, u got this ๐ธ๐ </content> </invoke>
๐ฆ where this page comes from
- fedora 43: python-jenkins 1.8.3-2.fc43 ยท BSD-3-Clause
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms