Mike Driscoll: How to Extract Build Info from Jenkins with Python

I work with continuous integration software as a part of my job. I use both Hudson and Jenkins in my role and occasionally need to interact with them programmatically. There are two Python packages you can use for this task:

The Python Jenkins package will work with both Hudson and Jenkins which JenkinsAPI only works with Jenkins. I usually use Python Jenkins because of this, although I have recently started looking to see which one works better with artifacts and I discovered that JenkinsAPI is actually better for that sort of thing. So you will need to evaluate both of these packages depending on what you need to do.


Install Python Jenkins

To follow along with the code examples in this article, you will need to install Python Jenkins. You can use pip for that:

pip install python-jenkins

Now that it’s installed, let’s give Python Jenkins a whirl!


Getting All the Jobs from Jenkins

One common task is needing to get a listing of all the jobs that are configured in your build system.

To get started, you need to login to your Jenkins server:

import jenkins   server = jenkins.Jenkins('http://server:port/', username='user',                           password='secret')

Now you have a Jenkins object that you can use to execute REST requests against your Jenkins CI server. The results that are returned are usually a Python dictionary or dictionary of dictionaries.

Here’s an example getting all the jobs that are configured on your CI system:

import jenkins   server = jenkins.Jenkins('http://server:port/', username='user',                          password='secret')   # Get all builds jobs = server.get_all_jobs(folder_depth=None) for job in jobs:     print(job['fullname'])

This will loop through all the jobs that are configured in Jenkins and print out their job names.


Getting Job Information

Now that you know the names of the jobs on your Jenkins box, you can get more detailed information about each job.

Here’s how:

import jenkins   server = jenkins.Jenkins('http://server:port/', username='user',                          password='secret')   # Get information on specific build job # This returns all the builds that are currently shown in  # hudson for this job info = server.get_job_info('job-name')   # Passed print(info['lastCompletedBuild'])   # Unstable print(info['lastUnstableBuild'])   # Failed print(info['lastFailedBuild'])

The get_job_info() will give you a lot of information about the job, including all the currently saved builds. It is nice to be able to extract which builds have passed, failed or are unstable.


Getting Build Information

If you want to know how long a job takes to run, then you need to get down to the build level.

Let’s find out how:

import jenkins   server = jenkins.Jenkins('http://server:port/', username='user',                          password='secret')   info = server.get_job_info('job-name')   # Loop over builds builds = info['builds'] for build in builds:     for build in builds:         print(server.get_build_info('job-name',                                      build['number']))

To get build metadata, you need to call get_build_info(). This method takes in the job name and the build number and returns the metadata as a dictionary.


Wrapping Up

You can do a lot more with the Python Jenkins package. For example, you can use it to start a build job, create a new job or delete an old one as well as quite a few other things. Unfortunately, the documentation is pretty bare-bones, so you’ll have to do a fair bit of experimentation to get it working the way you want.


Additional Reading

Planet Python

Mike Driscoll: PyDev of the Week: Tania Allard

This week we welcome Tania Allard (@ixek) as our PyDev of the Week! Tania is a developer advocate at Microsoft. She is also a speaker at multiple conferences. If you’d like to learn more about her, you should check out her blog. She also has some of her projects up on Github for you to peruse. Let’s take a few moments to get to know Tania!

Can you tell us a little about yourself (hobbies, education, etc):

I am originally from Mexico but have lived in the USA and in the UK for the last 8 years.

I have a bachelor’s in Mechatronic engineering and have also always been fascinated by technology and I can class myself as a lifelong learner. As such I got a PhD from the University of Manchester in Data science applied to Materials science, during which I discovered and fell in love with Python. Since completing my PhD I have worked as a research software engineer, research engineer, data engineer, and more recently could advocate.

Apart from tech I love Olympic weightlifting, so I spend quite a good amount of time in the gym every week and I am already looking forward for this year’s competition season!

I also love craft beer and recently joined the women in beer scene in Manchester, UK where I live.

Why did you start using Python?

As I said before I did a PhD in Materials Science, but instead of focusing on the experimental side of things my work was focused on modelling materials for tissue replacement. Most of the people in my discipline were using MATLAB for such purposes (as did I at the beginning) but eventually I realized I needed something more flexible. I was also soon driven into the ‘open science’ movement and decided I should create not only all my analyses but also my thesis plots and research papers outputs using an open source programming language to encourage reproducibility and accessibility.
It was until I starts using Python that I discovered the open source community and never looked back.

What other programming languages do you know and which is your favorite?

Coming from a scientific computing background I know MATLAB, FORTRAN (spoiler alert I do think modern FORTRAN is really good), C/C++, R, Julia, and Assembly. More recently I have been diving into functional programming via Scala and also into Go.

What projects are you working on now?

I recently joined the developer advocate team at Microsoft, so I am focusing on understanding the community barriers and needs when it comes to cloud computing.
In the Python ecosystem I am trying to work more closely with the Jupyter community to help drive better accessibility and community initiatives.

Something I am really excited about is the organisation of the mentored sprints for underrepresented folks in the Python community during PyCon.

Finally, I am working on a project focused on understanding the relationship between corruption and gender inequality in Latin American countries such as Mexico and Colombia. I truly believe that we can make a positive societal impact through technology, so this project is something I really care about.

What non-Python open source projects do you enjoy using?

As an R user I really like the Drake project as it has provided important tools towards reproducible scientific workflows (which is also a thing I deeply care about). I also have been enjoying working with projects like Docker, Kubernetes and Terraform over the last couple of years.

How did you get into speaking at Python events?

Since I come from a research background, I was already familiar with talks, poster presentations, conferences and the such, but I never thought I could speak at Python events. Then I joined a local scientific Python group and was eventually asked to speak about my PhD work. I was terrified back then, but after giving my talk and realising that people actually cared about the topic and were super supportive I decided I would like to share my knowledge with others.

Do you have any advice for others who would like to start giving talks?

If you are wondering whether you have something interesting to say I can guarantee you do!

Local user groups/meetups are great places to get started at within a relaxed environment. Folks are usually very supportive and eager to see what is going on in the community.

Is there anything else you’d like to say?

Thanks for the interview Mike. Hope to see loads of folks around in PyCon and if you’re there come say hi!

Thanks for doing the interview, Tania!

Planet Python

Mike Driscoll: An Intro to StaticBox and StaticBoxSizers

There are many widgets that are included with the wxPython GUI toolkit. One of them is a fairly handy widget called wx.StaticBox. This widget accepts a string and then will draw a box with the string in the upper left-hand corned of the box. However this only works when you use it in conjunction with wx.StaticBoxSizer.

Here is an example of what one might look like:

Simple wx.StaticBox

Now let’s go ahead and write the code you would use to create the example above:

import wx   class MyPanel(wx.Panel):       def __init__(self, parent):         super().__init__(parent)         box = wx.StaticBox(self, -1, "This is a wx.StaticBox")         bsizer = wx.StaticBoxSizer(box, wx.VERTICAL)           t = wx.StaticText(self, -1, "Controls placed \"inside\" the box are really its siblings")         bsizer.Add(t, 0, wx.TOP|wx.LEFT, 10)           border = wx.BoxSizer()         border.Add(bsizer, 1, wx.EXPAND|wx.ALL, 25)         self.SetSizer(border)     class MyFrame(wx.Frame):       def __init__(self):         super().__init__(None, title='Test')         panel = MyPanel(self)         self.Show()   if __name__ == '__main__':     app = wx.App(False)     frame = MyFrame()     app.MainLoop()

This code is based on the wx.StaticBox demo code from wxPython’s demo application. Basically you create the wx.StaticBox, add it to an instance of wx.StaticBoxSizer and then add that to a wx.BoxSizer and you’re done.

But what if you wanted a more complicated layout within the box?

Let’s take a look at that use-case next!


Nesting Sizers in wx.StaticBoxSizer

More often then not, you will want more than a single widget inside of your box widget. When that happens, you will need to use sizers inside of your wx.StaticBoxSizer.

Here is an example:

StaticBoxSizer with nested sizers

Let’s go ahead and take a look at the code for this example:

import wx   class MyPanel(wx.Panel):       def __init__(self, parent):         super().__init__(parent)           box = wx.StaticBox(self, -1, "Group Name")         bsizer = wx.StaticBoxSizer(box, wx.VERTICAL)           hsizer = wx.BoxSizer()           vsizer = wx.BoxSizer(wx.VERTICAL)         lbl = wx.StaticText(self, label='label 1')         vsizer.Add(lbl)         cbo = wx.ComboBox(self, value='Python', choices=['Python', 'Ruby'],                           size=(75, -1))         vsizer.Add(cbo)         hsizer.Add(vsizer)           hsizer.AddSpacer(80)           vsizer = wx.BoxSizer(wx.VERTICAL)         lbl = wx.StaticText(self, label='label 2')         vsizer.Add(lbl)         cbo = wx.ComboBox(self, value='Ford', choices=['Ford', 'Chevrolet'],                           size=(75, -1))         vsizer.Add(cbo)         hsizer.Add(vsizer)           bsizer.Add(hsizer, 0, wx.CENTER)             main_sizer = wx.BoxSizer()         main_sizer.Add(bsizer, 1, wx.EXPAND | wx.ALL, 10)         self.SetSizer(main_sizer)   class MyFrame(wx.Frame):       def __init__(self):         super().__init__(None, title='Test')         panel = MyPanel(self)         self.Show()   if __name__ == '__main__':     app = wx.App(False)     frame = MyFrame()     app.MainLoop()

In this case, you need to create two vertically oriented wx.BoxSizers to hold the four widgets in two columns. You add those sizers to a horizontally oriented wx.BoxSizer as well. If you wanted to simplify this a bit, you could use a wx.GridSizer instead of these BoxSizers.

Regardless of the approach, you end up with a nicely laid out application.


Wrapping Up

Using the wx.StaticBox widget is pretty straight-forward overall. I think it could be simpler if the widget and the sizer were combined into one class though. Anyway, if you’d like to learn more about this widget, you should see the documentation. Have fun and happy coding!

Planet Python

Mike Driscoll: Books on Sale for PyCon 2019

In honor of PyCon 2019 that is starting this week, I am putting three of my books on sale. You can get any of the following books for $ 9.99 through May 6th by clicking on the links:

Python 201 is a fun book for those of you who would be interested in learning intermediate and advanced topics in Python.

My ReportLab book covers how to create PDFs using Python and ReportLab. It also covers many other topics related to PDFs, such as splitting, merging and overlaying PDFs to name a few.

Finally my Jupyter Notebook 101 book is a good way for you to learn about the Jupyter Notebook and many of its capabilities.

Planet Python

Mike Driscoll: PyDev of the Week: Neil Muller

This week we welcome Neil Muller as our PyDev of the Week! Neil is an organizer for Cape Town Python User Group and PyCon ZA. He also speaks at conferences! You can learn more about his open source projects over on Github. Let’s take a few moments to get to know Neil better!

Can you tell us a little about yourself (hobbies, education, etc):

I’m an Applied Mathematician with interests in image processing and numerical computation, currently living and working in the Cape Town area, South Africa. I followed an interest in facial recognition into a PhD from the University of Stellenbosch, and that led to working on a variety of image processing and numerical modelling problems at iThemba LABS.

These days I split my working time between iThemba LABS and Praelexis, a machine learning company (mainly using Python) in Stellenbosch.

In my spare time, I am obsessed with board and card games, especially Vampire: The Eternal Struggle.

Why did you start using Python?

I first used Python in 1997 to solve a simple text processing problem while working on my Masters thesis. I liked the language, but I was still mainly a Matlab user at the time and so I didn’t really touch Python again until around 2004, when several of my friends and colleagues started getting really interested in the language and encouraged me to revisit it. I rapidly fell in love with the large standard library and the developing scientific computing stack. By 2005, it had replaced Matlab as my go-to tool for experimenting with problems.

What other programming languages do you know and which is your favorite?

Other than Python, I do a fair amount of work with C and C++, and also do a bit of JavaScript and shell scripting. In the past, I’ve worked extensively with Matlab, done some PHP and a bit of Fortran.

Python is my favourite language. The saying “Python Fits Your Brain” is true for me – I like the syntax and expressiveness of the language, and find it a very powerful tool for modelling and understanding whatever problem I’m trying to solve. While it’s not always part of the final solution to a given problem, it’s almost always part of getting there.

What projects are you working on now?

Currently, OSS projects I’m working on:

  • wafer, a Django web app for managing conferences, used by PyCon ZA and Debconf.
  • Sutekh, a card inventory management program for Vampire: the Eternal Struggle based on Python and PyGtk.

I’m also one of the main organisers of the Cape Town Python User Group, am involved with organising PyCon ZA and help maintain a few python packages in Debian.

Which Python libraries are your favorite (core or 3rd party)?

NumPy has been tremendously useful to me.

I have a considerable fondness for SQLObject.

I’m also a huge fan of Sphinx and the readthedocs infrastructure that grown up around that.

How did you get into giving talks at Python conferences?

I started speaking about Python as part of helping the Cape Town Python User Group develop. One of the great things about Python, because to the wide variety of projects people are doing in Python, there’s always something new to talk about. As PyCon ZA got going, it was a natural transition to start offering talks there.

Do you have any advice for prospective speakers?

Mostly my advice is don’t be afraid to submit that talk idea. Almost everyone I speak to undervalues how interesting the stuff they know well is. You’ll be amazed at how many people haven’t heard of the thing you think everyone already knows. Even if you don’t feel up to speaking at a conference, give talks to your local user group or other relevant meetups. Speaking about stuff is cool, and more people should do it.

Is there anything else you’d like to say?

I encourage everyone working with Python to take part in PyWeek at least once. I’ve learnt a great deal about Python from the entries I’ve participated in, it’s a great community and it’s incredible to see what talented and determined people can produce in a week.

Thanks for doing the interview, Neil!

Planet Python