Skip to content

genbadge

Generate badges for tools that do not provide one.

Python versions Build Status Tests Status Coverage Status Flake8 Status

Documentation PyPI Downloads Downloads per week GitHub stars codecov

genbadge provides a set of commandline utilities to generate badges for tools that do not provide one. It currently can create:

  • tests badges such as Tests Badge from pytest or other junit.xml-generating framework,
  • coverage badges such as Coverage Badge from python coverage or other coverage.xml-generating framework,
  • flake8 badges such as Flake8 Status from flake8 --statistics.

Badges are either generated using the shields.io HTTP REST API, or with an equivalent local SVG template included in genbadge.

Installing

Full

In order for all commandline features to work, you should install genbadge with the extra dependencies:

> pip install genbadge[all]

This is equivalent to pip install genbadge[tests,coverage,flake8]. Alternatively you can install dependencies for only a subset of commands for example pip install genbadge[tests,flake8].

Minimal

genbadge core only requires click (the CLI framework), pillow (for SVG file templating) and requests (to call the shields.io API). You can install it using

> pip install genbadge

This will only allow you to use the low-level API.

Usage

Once installed, genbadge is available as a commandline utility. You can get some help with:

> genbadge

Usage: genbadge [OPTIONS] COMMAND [ARGS]...

  Commandline utility to generate badges. To get help on each command use:

      genbadge <cmd> --help

Options:
  --help  Show this message and exit.

Commands:
  coverage  Generate a badge for the coverage results (e.g. from a
            coverage.xml).
  flake8    Generate a badge for the flake8 results (e.g. from a flake8stats.txt
            file).
  tests     Generate a badge for the test results (e.g. from a junit.xml).

1. Tests badge

Prerequisite: a test report

a. pytest

If you use pytest, you can use some options to generate test reports:

  • with --junitxml=path/to/junit.xml a junit-format report is generated. This is the file that we'll need to generate the badge.

  • with --html=path/to/report.html a detailed HTML report is generated. This is not required to generate the badge, but you might wish to use it so that users navigate to it when they will click on your badge.

Security concerns

Test reports might contain secrets (keys, env variables, OS user names containing employee numbers, etc.), so always review them carefully before publishing them !

Let's run this in your project:

> pytest --junitxml=reports/junit/junit.xml --html=reports/junit/report.html

You can check that the two files are correctly generated before moving forward.

b. Other frameworks

Any junit.xml input file would be accepted so other language users (e.g. java) can get this working for them as well.

Generating the badge

Now you can generate a badge similar to this one Tests Status with the following command:

> genbadge tests

By default it assumes that

  • the input file can be found at ./reports/junit/junit.xml. You can change this with the -i/--input-file flag.

    • - can be used to denote <stdin>: e.g. genbadge tests -i - < junit.xml.
  • the output file will be at ./tests-badge.svg. You can change it with the -o/--output-file flag

    • - can be used to denote <stdout>: e.g. genbadge tests -o - > badge.svg.
  • the badge name (left-hand side text) is tests. You can change it with the -n/--name flag or clear it with -n "" (but keep the empty space). Alternatively if you want to completely remove the left-hand side of the badge you can use --noname.

  • the badge should be generated using shields.io (requires an internet connection). If you prefer you can use -l/--local to use the included SVG file template (less mature but seems to work)

In addition to generating the badge, executing the command will also display some details about the parsed file is you use the verbose -v flag:

Test statistics parsed successfully from '(...)/reports/junit/junit.xml'
 - Nb tests: Total (6) = Success (2) + Skipped (1) + Failed (2) + Errors (1)
 - Success percentage: 40.00% (2 / 5) (Skipped tests are excluded)

SUCCESS - Tests badge created: '(...)/tests-badge.svg'

Note that without the verbose flag, only the last line of this message is displayed. You can disable it entirely using the silent flag -s.

The resulting badge will by default look like this: [tests | 2/5] where 2 is the number of tests that have run successfully, and 5 is the total number of tests minus the number of skipped tests. When all tests pass with success, the badge simply shows the number of tests: [tests | 5]. The success percentage, defined as this ratio multiplied by 100, is displayed and can be further used to fail on threshold, see below.

Finally, the color of the badge depends on the success percentage.

  • Less than 50%: red
  • less than 75%: orange
  • less than 90%: green
  • higher: bright green

Using the badge

To include the resulting badge in your documentation and make it point to the generated report.html, you can for example use the following markdown:

[![Tests Status](./reports/junit/junit-badge.svg?dummy=8484744)](./reports/junit/report.html)

It will render as follows: Tests Status

Note that the query part of the image url ?dummy=8484744 is a trick so that the github pages web server does not try to add an extra cache layer to the badge. Maybe this is not useful anymore with new versions of github, if you know the answer let me know !

Security concerns

Test reports might contain secrets (keys, env variables, OS user names containing employee numbers, etc.), so always review them carefully before publishing them !

Failing on threshold

You might wish the command to fail if the success percentage is not high enough.

This may be done using the -t/--threshold flag:

> genbadge tests -t 90

will fail and return an exit code of 1 if the success percentage is strictly lower than 90%.

The success percentage is defined as the number of tests that have run successfully, divided by the total number of tests minus the number of skipped tests, times 100. So for 6 tests run, if 2 tests ran successfully and 1 was skipped then the success percentage is 2 / (6 - 1) * 100 which gives 40%.

2. Coverage badge

Prerequisite: a cov report

a. coverage

If you use coverage, you can use some options to generate reports:

  • with coverage report the coverage statistics are displayed in the console. This is not required but might be useful to debug if the xml generation fails.

  • with coverage xml an XML-format report is generated. This is the file that we'll need to generate the badge.

  • with coverage html a detailed HTML report (a folder) is generated. This is not required to generate the badge, but you might wish to use it so that users navigate to it when they will click on your badge.

Let's run this in your project:

> coverage report
> coverage xml
> coverage html

You can check that the coverage file and html report folder are correctly generated before moving forward.

b. Other frameworks

Any coverage.xml input file would be accepted so other language users (e.g. java) can get this working for them as well.

Generating the badge

Now you can generate a badge similar to this one Coverage Status with the following command:

> genbadge coverage

By default it assumes that

  • the input file can be found at ./reports/coverage/coverage.xml. You can change this with the -i/--input-file flag.

    • - can be used to denote <stdin>: e.g. genbadge coverage -i - < coverage.xml.
  • the output file will be at ./coverage-badge.svg. You can change it with the -o/--output-file flag

    • - can be used to denote <stdout>: e.g. genbadge coverage -o - > badge.svg.
  • the badge name (left-hand side text) is coverage. You can change it with the -n/--name flag or clear it with -n "" (but keep the empty space). Alternatively if you want to completely remove the left-hand side of the badge you can use --noname.

  • the badge should be generated using shields.io (requires an internet connection). If you prefer you can use -l/--local to use the included SVG file template (less mature but seems to work)

In addition to generating the badge, executing the command will also display some details about the parsed file is you use the verbose -v flag:

Coverage results parsed successfully from '(...)/reports/coverage/coverage.xml'
 - Branch coverage: 5.56% (1/18)
 - Line coverage: 17.81% (13/73)
 - Total coverage: 15.38% ((1+13)/(18+73))

SUCCESS - Coverage badge created: '(...)/coverage-badge.svg'

Note that without the verbose flag, only the last line of this message is displayed. You can disable it entirely using the silent flag -s.

The resulting badge will by default look like this: [coverage | 98.1%] where 98.1 is the total coverage, obtained from the branch and line coverages using the formula (nb_lines_covered + nb_branches_covered) / (nb_lines / nb_branches) and multiplying this by 100.

Finally, the color of the badge depends on the success percentage.

  • Less than 50%: red
  • less than 75%: orange
  • less than 90%: green
  • higher: bright green

Using the badge

To include the resulting badge in your documentation and make it point to the generated HTML report, you can for example use the following markdown:

[![Coverage Status](./reports/coverage/coverage-badge.svg?dummy=8484744)](./reports/coverage/index.html)

It will render as follows: Coverage Status

Note that the query part of the image url ?dummy=8484744 is a trick so that the github pages web server does not try to add an extra cache layer to the badge. Maybe this is not useful anymore with new versions of github, if you know the answer let me know !

3. Flake8 badge

Prerequisite: a flake8 report

If you use flake8, you can use some options to generate reports:

  • with --statistics, the number of issues grouped by code (e.g. E201) is consolidated and printed to std out. You can redirect this to a file named flake8stats.txt using --tee --output-file flake8stats.txt. This is the file that we'll need to generate the badge. Note that --tee is to continue to see the report on the console, this is optional.

  • with --format=html --htmldir a detailed HTML report (a folder) is generated. This is not required to generate the badge, but you might wish to use it so that users navigate to it when they will click on your badge.

Let's run this in your project. We use --exit-zero so that the commands always returns with exit code 0 even if problems are found.

> flake8 <src_folder> --exit-zero --format=html --htmldir ./reports/flake8 --statistics --tee --output-file flake8stats.txt
1     B014 Redundant exception types in `except (IOError, OSError):`.  Write `except OSError:`, which catches exactly the same exceptions.
7     C801 Copyright notice not present.
1     E122 continuation line missing indentation or outdented
1     E303 too many blank lines (3)
...

You can check that the statistics file and html report folder are correctly generated before moving forward.

Generating the badge

Now you can generate a badge similar to this one Flake8 Status with the following command:

> genbadge flake8

By default it assumes that

  • the input file can be found at ./reports/flake8/flake8stats.txt. You can change this with the -i/--input-file flag.

    • - can be used to denote <stdin>: e.g. genbadge flake8 -i - < flake8stats.txt.
  • the output file will be at ./flake8-badge.svg. You can change it with the -o/--output-file flag

    • - can be used to denote <stdout>: e.g. genbadge flake8 -o - > badge.svg.
  • the badge name (left-hand side text) is flake8. You can change it with the -n/--name flag or clear it with -n "" (but keep the empty space). Alternatively if you want to completely remove the left-hand side of the badge you can use --noname.

  • the badge should be generated using shields.io (requires an internet connection). If you prefer you can use -l/--local to use the included SVG file template (less mature but seems to work)

In addition to generating the badge, executing the command will also display some details about the parsed file is you use the verbose -v flag:

Flake8 statistics parsed successfully from '(...)/reports/flake8/flake8stats.txt'
 - Total (20) = Critical (6) + Warning (9) + Info (5)

SUCCESS - Flake8 badge created: '(...)/flake8-badge.svg'

Note that without the verbose flag, only the last line of this message is displayed. You can disable it entirely using the silent flag -s.

The resulting badge will by default look like this: [flake8 | 6 C, 0 W, 5 I] where 6, 0, 5 denote the number of critical issues, warnings, and information messages respectively. These severity levels are determined by the flake8-html plugin so as to match the colors in the HTML report.

Finally, the color of the badge depends on the number of issues at each severity level.

  • at least a critical issue (severity 1): red
  • at least a warning (severity 2): orange
  • at least an info (severity 3): green
  • no issue at all: bright green

Using the badge

To include the resulting badge in your documentation and make it point to the generated HTML report, you can for example use the following markdown:

[![Flake8 Status](./reports/flake8/flake8-badge.svg?dummy=8484744)](./reports/flake8/index.html)

It will render as follows: Flake8 Status

Note that the query part of the image url ?dummy=8484744 is a trick so that the github pages web server does not try to add an extra cache layer to the badge. Maybe this is not useful anymore with new versions of github, if you know the answer let me know !

4. Low-level API

You can create a badge with the Badge class.

from genbadge import Badge

b = Badge(left_txt="foo", right_txt="bar", color="green")
print(b)

yields

[ foo | bar ]  color: green

By default no svg is generated: this is a purely abstract badge. You can make it a real badge with the following code:

b.write_to("tmp_badge.svg", use_shields=False)

Note the optional use_shields boolean flag that is used to switch between querying shields.io (True, default) or using a local SVG file template (False, but maybe less bullet-proof).

See Also

Other badge generation projects exist:

Others

Do you like this library ? You might also like my other python libraries

Want to contribute ?

Details on the github page: https://github.com/smarie/python-genbadge