mirror of
https://github.com/jongracecox/anybadge.git
synced 2025-07-21 04:11:05 +02:00
Fix label and value escaping by defaulting to html escaping them. Provide Python and CLI args to allow reverting to old behavior of not escaping. Fixes #91
472 lines
29 KiB
Markdown
472 lines
29 KiB
Markdown
# anybadge
|
|
|
|
Python project for generating badges for your projects
|
|
|
|
[](https://pypi.org/project/anybadge)
|
|
[](https://app.travis-ci.com/github/jongracecox/anybadge)
|
|
[](https://pypistats.org/packages/anybadge)
|
|
[](https://github.com/jongracecox/anybadge/commits/master)
|
|
[](https://github.com/jongracecox/anybadge/blob/master/LICENSE)
|
|
[](https://github.com/jongracecox/anybadge/stargazers)
|
|
[](https://snyk.io/advisor/python/anybadge)
|
|
[](https://pepy.tech/project/anybadge)
|
|
|
|
[](https://www.buymeacoffee.com/jongracecox)
|
|
|
|
Supports: Python 3.7-3.13 (2.7-3.6 support has been dropped)
|
|
|
|
## Overview
|
|
|
|
`anybadge` can be used to add badge generation to your Python projects,
|
|
and also provides a command line interface.
|
|
|
|
This utility can be used to generate .svg badge images, using configurable
|
|
thresholds for coloring the badges based on the badge value. Many badge
|
|
generation tools just provide the ability to specify the color of badge.
|
|
`anybadge` allows you to specify the label, badge value, and color, but
|
|
it also allows you to specify a set of thresholds that can be used to
|
|
select a color based on the badge value.
|
|
|
|
`anybadge` may be useful for companies developing internally, or any time
|
|
making calls to external badge services is not possible, or undesirable.
|
|
In this situation using `anybadge` will be easier than running your own
|
|
internal badge service.
|
|
|
|
The package can be imported into your python code, or run direct from the
|
|
command line.
|
|
|
|
## Demo
|
|
|
|
You can find a [repl.it demo here](https://repl.it/@JonGrace_Cox/anybadge-demo).
|
|
This will allow you to see what the package can do and play with it to test outputs.
|
|
|
|
## Basic usage
|
|
|
|
### Command line
|
|
|
|
As an example, if you want to produce a pylint badge, you may run `anybadge`
|
|
from the command line like this:
|
|
|
|
```bash
|
|
anybadge -l pylint -v 2.22 -f pylint.svg 2=red 4=orange 8=yellow 10=green
|
|
```
|
|
|
|
This would result in a badge like this:
|
|
|
|

|
|
|
|
In this example the label is set to "pylint", the value "2.22", and an
|
|
output file called "pylint.svg". The thresholds are provided in pairs
|
|
of `<value>=color` Values can be integer or floats for ranges, and
|
|
string values are also supported.
|
|
|
|
### Python
|
|
|
|
Here is the same example implemented in Python code:
|
|
|
|
```python
|
|
import anybadge
|
|
|
|
# Define thresholds: <2=red, <4=orange <8=yellow <10=green
|
|
thresholds = {2: 'red',
|
|
4: 'orange',
|
|
6: 'yellow',
|
|
10: 'green'}
|
|
|
|
badge = anybadge.Badge('pylint', 2.22, thresholds=thresholds)
|
|
|
|
badge.write_badge('pylint.svg')
|
|
```
|
|
|
|
## Installation
|
|
|
|
`anybadge` is available in PyPi at https://pypi.python.org/pypi/anybadge
|
|
|
|
You can install the latest release of `anybadge` using `pip`:
|
|
|
|
```bash
|
|
pip install anybadge
|
|
```
|
|
|
|
This will install the Python package, and also make `anybadge` available
|
|
as a command line utility.
|
|
|
|
## Getting help
|
|
|
|
To get help from the command line utility, just run:
|
|
|
|
```bash
|
|
anybadge --help
|
|
```
|
|
|
|
## Command line usage
|
|
|
|
### Output
|
|
|
|
Running the utility with the `--file` option will result in the .svg image being
|
|
written to file. Without the `--file` option the `.svg` file content will be
|
|
written to stdout, so can be redirected to a file.
|
|
|
|
### Thresholds
|
|
|
|
Some thresholds have been built in to save time. To use these thresholds you
|
|
can simply specify the template name instead of threshold value/color pairs.
|
|
|
|
```bash
|
|
anybadge --value=<VALUE> --file=<FILE> <TEMPLATE-NAME>
|
|
```
|
|
|
|
For example:
|
|
|
|
```bash
|
|
anybadge --value=2.22 --file=pylint.svg pylint
|
|
```
|
|
|
|
### Colors
|
|
|
|
Anybadge comes with some pre-defined colors, which can be referred to by name. It also
|
|
supports the use of custom colors by using the hex representation of the color. Both color
|
|
types can be used in the `default_color`, `text_color` and `thresholds` attributes. Color names are
|
|
taken from the [Mozilla color keywords list](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/color_keywords).
|
|
|
|
Here is a Python example showing use of a named color and a custom color.
|
|
|
|
```python
|
|
import anybadge
|
|
|
|
badge = anybadge.Badge(label='custom color', value='teal', default_color='teal', num_padding_chars=1)
|
|
badge = anybadge.Badge(label='custom color', value='teal', default_color='#008080', num_padding_chars=1)
|
|
```
|
|
|
|
Available named colors are:
|
|
|
|
| Color Name | Hex | Example |
|
|
| ------------- | ------- | ------- |
|
|
| aliceblue | #F0F8FF |  |
|
|
| antiquewhite | #FAEBD7 |  |
|
|
| aqua | #00FFFF |  |
|
|
| aquamarine | #7FFFD4 |  |
|
|
| azure | #F0FFFF |  |
|
|
| beige | #F5F5DC |  |
|
|
| bisque | #FFE4C4 |  |
|
|
| black | #000000 |  |
|
|
| blanchedalmond | #FFEBCD | |
|
|
| blue | #0000FF |  |
|
|
| blueviolet | #8A2BE2 |  |
|
|
| bright_red | #FF0000 |  |
|
|
| bright_yellow | #FFFF00 | |
|
|
| brown | #A52A2A |  |
|
|
| burlywood | #DEB887 |  |
|
|
| cadetblue | #5F9EA0 |  |
|
|
| chartreuse | #7FFF00 |  |
|
|
| chocolate | #D2691E |  |
|
|
| coral | #FF7F50 |  |
|
|
| cornflowerblue | #6495ED | |
|
|
| cornsilk | #FFF8DC |  |
|
|
| crimson | #DC143C |  |
|
|
| darkblue | #00008B |  |
|
|
| darkcyan | #008B8B |  |
|
|
| darkgoldenrod | #B8860B | |
|
|
| darkgray | #A9A9A9 |  |
|
|
| darkgreen | #006400 |  |
|
|
| darkkhaki | #BDB76B |  |
|
|
| darkmagenta | #8B008B |  |
|
|
| darkolivegreen | #556B2F | |
|
|
| darkorange | #FF8C00 |  |
|
|
| darkorchid | #9932CC |  |
|
|
| darkred | #8B0000 |  |
|
|
| darksalmon | #E9967A |  |
|
|
| darkseagreen | #8FBC8F |  |
|
|
| darkslateblue | #483D8B | |
|
|
| darkslategray | #2F4F4F | |
|
|
| darkturquoise | #00CED1 | |
|
|
| darkviolet | #9400D3 |  |
|
|
| deeppink | #FF1493 |  |
|
|
| deepskyblue | #00BFFF |  |
|
|
| dimgray | #696969 |  |
|
|
| dodgerblue | #1E90FF |  |
|
|
| firebrick | #B22222 |  |
|
|
| floralwhite | #FFFAF0 |  |
|
|
| forestgreen | #228B22 |  |
|
|
| fuchsia | #FF00FF |  |
|
|
| gainsboro | #DCDCDC |  |
|
|
| ghostwhite | #F8F8FF |  |
|
|
| gold | #FFD700 |  |
|
|
| goldenrod | #DAA520 |  |
|
|
| gray | #808080 |  |
|
|
| green | #4C1 |  |
|
|
| greenyellow | #ADFF2F |  |
|
|
| green_2 | #008000 |  |
|
|
| honeydew | #F0FFF0 |  |
|
|
| hotpink | #FF69B4 |  |
|
|
| indianred | #CD5C5C |  |
|
|
| indigo | #4B0082 |  |
|
|
| ivory | #FFFFF0 |  |
|
|
| khaki | #F0E68C |  |
|
|
| lavender | #E6E6FA |  |
|
|
| lavenderblush | #FFF0F5 | |
|
|
| lawngreen | #7CFC00 |  |
|
|
| lemonchiffon | #FFFACD |  |
|
|
| lightblue | #ADD8E6 |  |
|
|
| lightcoral | #F08080 |  |
|
|
| lightcyan | #E0FFFF |  |
|
|
| lightgoldenrodyellow | #FAFAD2 | |
|
|
| lightgray | #D3D3D3 |  |
|
|
| lightgreen | #90EE90 |  |
|
|
| lightpink | #FFB6C1 |  |
|
|
| lightsalmon | #FFA07A |  |
|
|
| lightseagreen | #20B2AA | |
|
|
| lightskyblue | #87CEFA |  |
|
|
| lightslategray | #778899 | |
|
|
| lightsteelblue | #B0C4DE | |
|
|
| lightyellow | #FFFFE0 |  |
|
|
| light_grey | #9F9F9F |  |
|
|
| lime | #00FF00 |  |
|
|
| limegreen | #32CD32 |  |
|
|
| linen | #FAF0E6 |  |
|
|
| maroon | #800000 |  |
|
|
| mediumaquamarine | #66CDAA | |
|
|
| mediumblue | #0000CD |  |
|
|
| mediumorchid | #BA55D3 |  |
|
|
| mediumpurple | #9370DB |  |
|
|
| mediumseagreen | #3CB371 | |
|
|
| mediumslateblue | #7B68EE | |
|
|
| mediumspringgreen | #00FA9A | |
|
|
| mediumturquoise | #48D1CC | |
|
|
| mediumvioletred | #C71585 | |
|
|
| midnightblue | #191970 |  |
|
|
| mintcream | #F5FFFA |  |
|
|
| mistyrose | #FFE4E1 |  |
|
|
| moccasin | #FFE4B5 |  |
|
|
| navajowhite | #FFDEAD |  |
|
|
| navy | #000080 |  |
|
|
| oldlace | #FDF5E6 |  |
|
|
| olive | #808000 |  |
|
|
| olivedrab | #6B8E23 |  |
|
|
| orange | #FE7D37 |  |
|
|
| orangered | #FF4500 |  |
|
|
| orange_2 | #FFA500 |  |
|
|
| orchid | #DA70D6 |  |
|
|
| palegoldenrod | #EEE8AA | |
|
|
| palegreen | #98FB98 |  |
|
|
| paleturquoise | #AFEEEE | |
|
|
| palevioletred | #DB7093 | |
|
|
| papayawhip | #FFEFD5 |  |
|
|
| peachpuff | #FFDAB9 |  |
|
|
| peru | #CD853F |  |
|
|
| pink | #FFC0CB |  |
|
|
| plum | #DDA0DD |  |
|
|
| powderblue | #B0E0E6 |  |
|
|
| purple | #800080 |  |
|
|
| rebeccapurple | #663399 | |
|
|
| red | #E05D44 |  |
|
|
| rosybrown | #BC8F8F |  |
|
|
| royalblue | #4169E1 |  |
|
|
| saddlebrown | #8B4513 |  |
|
|
| salmon | #FA8072 |  |
|
|
| sandybrown | #F4A460 |  |
|
|
| seagreen | #2E8B57 |  |
|
|
| seashell | #FFF5EE |  |
|
|
| sienna | #A0522D |  |
|
|
| silver | #C0C0C0 |  |
|
|
| skyblue | #87CEEB |  |
|
|
| slateblue | #6A5ACD |  |
|
|
| slategray | #708090 |  |
|
|
| snow | #FFFAFA |  |
|
|
| springgreen | #00FF7F |  |
|
|
| steelblue | #4682B4 |  |
|
|
| tan | #D2B48C |  |
|
|
| teal | #008080 |  |
|
|
| thistle | #D8BFD8 |  |
|
|
| tomato | #FF6347 |  |
|
|
| turquoise | #40E0D0 |  |
|
|
| violet | #EE82EE |  |
|
|
| wheat | #F5DEB3 |  |
|
|
| white | #FFFFFF |  |
|
|
| whitesmoke | #F5F5F5 |  |
|
|
| yellow | #DFB317 |  |
|
|
| yellowgreen | #9ACD32 |  |
|
|
| yellow_green | #A4A61D |  |
|
|
|
|
### Emojis
|
|
|
|
It is possible to use emoji characters in badge labels and values. Here are some examples:
|
|
|
|

|
|

|
|

|
|

|
|
|
|
These files were created by using the **actual** emoji character in the label/value text. For example:
|
|
|
|
```python
|
|
badge = anybadge.Badge(label="Pipeline status", value="😄")
|
|
```
|
|
|
|
There are some caveats worth mentioning:
|
|
- The "look" of the emoji is determined by the client (Emoji characters are placed as-is into the SVG file, and are
|
|
rendered client-side)
|
|
- Rendering may fail in some viewers and developer IDEs (for example, PyCharm does not render emojis in the svg viewer)
|
|
- Emojis can have different widths, so the layout may be affected. You can use `num_label_padding_chars` and
|
|
`num_value_padding_chars` to fix (see below)
|
|
|
|
Here are some examples to show how to use padding to fix layout:
|
|
|
|
| Badge | Code |
|
|
| ----- |----------------------------------------------------------------------|
|
|
|  | `anybadge.Badge("Pipeline status", "😄")` |
|
|
|  | `anybadge.Badge("Pipeline status", "😄", num_value_padding_chars=1)` |
|
|
|
|
### Value or label only
|
|
|
|
It is possible to create badges with only a label or only a value. This can be done by passing
|
|
an empty string to the appropriate field. Note that either a label or value must be provided.
|
|
|
|
| Badge | Code |
|
|
|---------------------------------------------------------------------------------|--------------------------------------|
|
|
|  | `anybadge.Badge(label="Label only")` |
|
|
|  | `anybadge.Badge(value="Value only")` |
|
|
|
|
### Semantic version support
|
|
|
|
Anybadge supports semantic versions for value and threshold keys. This supports color-coded
|
|
badges based on version numbering. Here are some examples:
|
|
|
|
```python
|
|
badge = Badge(
|
|
label='Version',
|
|
value='3.0.0',
|
|
thresholds={'3.0.0': 'red', '3.2.0': 'orange', '999.0.0': 'green'},
|
|
semver=True
|
|
)
|
|
```
|
|
|
|
In the above example the thresholds equate to the following:
|
|
|
|
* If value is < 3.0.0 then badge will be red.
|
|
* If value is < 3.2.0 then badge will be orange.
|
|
* If value is < 999.0.0 then badge will be green.
|
|
|
|
Each threshold entry is used to define the upper bounds of the threshold. If you don't know the
|
|
upper bound for your version number threshold you will need to provide an extreme upper bound -
|
|
in this example it is `999.0.0`.
|
|
|
|
### Escaping
|
|
|
|
Badges are generated as .svg files, which utilize an XML-based markup language. Consequently,
|
|
any HTML characters present in badge labels or values must be escaped to ensure proper
|
|
representation. If you need to disable escaping, the following options are available:
|
|
|
|
- Python API
|
|
- `escape_label=False`
|
|
- `escape_value=False`
|
|
- CLI
|
|
- `--no-escape-label`
|
|
- `--no-escape-value`
|
|
|
|
### Examples
|
|
|
|
#### Pylint using template
|
|
```bash
|
|
anybadge --value=2.22 --file=pylint.svg pylint
|
|
```
|
|

|
|
|
|
#### Pylint using arguments
|
|
```bash
|
|
anybadge -l pylint -v 2.22 -f pylint.svg 2=red 4=orange 8=yellow 10=green
|
|
```
|
|

|
|
|
|
#### Coverage using template
|
|
```bash
|
|
anybadge --value=65 --file=coverage.svg coverage
|
|
```
|
|

|
|
|
|
#### Pipeline, using labeled colors
|
|
```bash
|
|
anybadge --label=pipeline --value=passing --file=pipeline.svg passing=green failing=red
|
|
```
|
|

|
|
|
|
#### Badge with fixed color
|
|
```bash
|
|
anybadge --label=awesomeness --value="110%" --file=awesomeness.svg --color='#97CA00'
|
|
```
|
|

|
|
|
|
#### GitLab Scoped style badge
|
|
```bash
|
|
anybadge --style=gitlab-scoped --label=Project --value=Archimedes --file=gitlab_scoped.svg --color='#c1115d'
|
|
```
|
|

|
|
|
|
#### Thresholds based on semantic versions
|
|
```bash
|
|
anybadge --label=Version --value=2.4.5 --file=version.svg 1.0.0=red 2.4.6=orange 2.9.1=yellow 999.0.0=green
|
|
```
|
|
|
|
#### Importing in your own app
|
|
```python
|
|
from anybadge import Badge
|
|
|
|
test1 = Badge(
|
|
label,
|
|
value,
|
|
font_name='DejaVu Sans,Verdana,Geneva,sans-serif',
|
|
font_size=11,
|
|
num_padding_chars=0.5,
|
|
template='<?xml version="1.0" encoding="UTF-8"?>\n<svg xmlns="http://www.w3.org/2000/svg" width="{{ badge width }}" height="20">\n <linearGradient id="b" x2="0" y2="100%">\n <stop offset="0" stop-color="#bbb" stop-opacity=".1"/>\n <stop offset="1" stop-opacity=".1"/>\n </linearGradient>\n <mask id="a">\n <rect width="{{ badge width }}" height="20" rx="3" fill="#fff"/>\n </mask>\n <g mask="url(#a)">\n <path fill="#555" d="M0 0h{{ color split x }}v20H0z"/>\n <path fill="{{ color }}" d="M{{ color split x }} 0h{{ value width }}v20H{{ color split x }}z"/>\n <path fill="url(#b)" d="M0 0h{{ badge width }}v20H0z"/>\n </g>\n <g fill="{{ label text color }}" text-anchor="middle" font-family="{{ font name }}" font-size="{{ font size }}">\n <text x="{{ label anchor shadow }}" y="15" fill="#010101" fill-opacity=".3">{{ label }}</text>\n <text x="{{ label anchor }}" y="14">{{ label }}</text>\n </g>\n <g fill="{{ value text color }}" text-anchor="middle" font-family="{{ font name }}" font-size="{{ font size }}">\n <text x="{{ value anchor shadow }}" y="15" fill="#010101" fill-opacity=".3">{{ value }}</text>\n <text x="{{ value anchor }}" y="14">{{ value }}</text>\n </g>\n</svg>',
|
|
value_prefix='',
|
|
value_suffix='',
|
|
thresholds=None,
|
|
default_color='#4c1',
|
|
use_max_when_value_exceeds=True,
|
|
value_format=None,
|
|
text_color='#fff'
|
|
)
|
|
|
|
test1.write_badge('test1.svg')
|
|
```
|
|
|
|
### Command-line options
|
|
|
|
The command line options can be viewed using `anybadge --help`.
|
|
|
|
Examples
|
|
--------
|
|
|
|
Here are some usage specific command line examples that may save time on defining
|
|
thresholds.
|
|
|
|
Pylint::
|
|
|
|
```
|
|
anybadge.py --value=2.22 --file=pylint.svg pylint
|
|
anybadge.py --label=pylint --value=2.22 --file=pylint.svg 2=red 4=orange 8=yellow 10=green
|
|
```
|
|
|
|
Coverage::
|
|
|
|
```
|
|
anybadge.py --value=65 --file=coverage.svg coverage
|
|
anybadge.py --label=coverage --value=65 --suffix='%%' --file=coverage.svg 50=red 60=orange 80=yellow 100=green
|
|
```
|
|
|
|
CI Pipeline::
|
|
|
|
```
|
|
anybadge.py --label=pipeline --value=passing --file=pipeline.svg passing=green failing=red
|
|
```
|
|
|
|
Python usage
|
|
============
|
|
|
|
For Python API details you can use the inbuilt documentation:
|
|
|
|
```python
|
|
from anybadge import badge
|
|
help(badge)
|
|
```
|