Skip to main content

A package to generate custom badges for GitLab

Project description


📋 Table of Contents


📣 Overview

BadgeShield generates customizable SVG badges for GitLab, GitHub, and anywhere you can embed SVG. Five badge templates, four visual styles, 51 built-in colors, Pillow-powered font metrics, logo embedding with color tinting, automatic coverage badges from coverage.xml, and a Typer CLI with Rich progress bars and an SVG audit subcommand.


💡 Features

  • 5 templatesDEFAULT (two-part rectangular), PILL (fully rounded), CIRCLE, CIRCLE_FRAME with 11 PNG overlay frames, and BANNER (icon-zone + text).
  • 4 visual stylesFLAT, ROUNDED, GRADIENT, and SHADOWED via BadgeStyle enum or --style CLI flag.
  • 51 built-in colorsBadgeColor enum or any #RRGGBB hex string.
  • Accurate text sizing — font widths measured via Pillow (DejaVuSans) with a fallback estimator when Pillow is absent.
  • Logo support — embed PNG/JPEG logos with optional color tinting.
  • Coverage badge — read coverage.xml and auto-generate a correctly-colored badge in one command.
  • Concurrent batch — generate hundreds of badges in parallel from a JSON config; per-entry style overrides the CLI flag.
  • Modern CLI — Typer + Rich: progress bar, error panels, summary table, and audit subcommand.
  • Python API — import and generate from any script or CI job.

📌 Installation

pip install badgeshield

With logo tinting support (requires Pillow):

pip install "badgeshield[image]"

Upgrade:

pip install --upgrade badgeshield

🚀 Quick Start

Python API — DEFAULT template

from badgeshield import BadgeGenerator, BadgeStyle, BadgeTemplate

generator = BadgeGenerator(template=BadgeTemplate.DEFAULT, style=BadgeStyle.GRADIENT)
generator.generate_badge(
    left_text="build",
    left_color="#555555",
    right_text="passing",
    right_color="#44cc11",
    badge_name="build.svg",
    output_path="./badges",
)

style is set at generator construction time and applies to all badges that instance generates. Options: FLAT (default), ROUNDED, GRADIENT, SHADOWED.

PILL template

from badgeshield import BadgeGenerator, BadgeTemplate

generator = BadgeGenerator(template=BadgeTemplate.PILL)
generator.generate_badge(
    left_text="build",
    left_color="#555555",
    right_text="passing",
    right_color="#44cc11",
    badge_name="build-pill.svg",
)

CIRCLE template

from badgeshield import BadgeGenerator, BadgeTemplate

generator = BadgeGenerator(template=BadgeTemplate.CIRCLE)
generator.generate_badge(
    left_text="v2.1",
    left_color="#673ab7",
    badge_name="version.svg",
)

CIRCLE_FRAME template

from badgeshield import BadgeGenerator, BadgeTemplate, FrameType

generator = BadgeGenerator(template=BadgeTemplate.CIRCLE_FRAME)
generator.generate_badge(
    left_text="MH",
    left_color="#FF0000",
    badge_name="initials.svg",
    frame=FrameType.FRAME1,
    logo="path/to/avatar.png",
    logo_tint="#ffffff",
)

BANNER template

from badgeshield import BadgeGenerator, BadgeTemplate

generator = BadgeGenerator(template=BadgeTemplate.BANNER)
generator.generate_badge(
    left_text="badgeshield",
    left_color="#1a1a2e",
    right_text="v1.0",
    right_color="#16213e",
    badge_name="banner.svg",
)

📊 Coverage Badge

Generate a correctly-colored badge directly from a coverage.xml report — no manual color selection needed.

CLI

badgeshield coverage coverage.xml \
  --badge-name coverage.svg \
  --output-path ./badges

The color is chosen automatically based on these thresholds:

Coverage Color
≥ 90% #44cc11 green
≥ 80% #97ca00 yellow-green
≥ 70% #a4a61d yellow
≥ 60% #dfb317 orange
< 60% #e05d44 red

Use --metric branch to badge on branch coverage instead of line coverage.

Python API

from badgeshield import parse_coverage_xml, coverage_color
from badgeshield import BadgeGenerator, BadgeTemplate

pct = parse_coverage_xml("coverage.xml")          # e.g. 94.3
color = coverage_color(pct)                        # "#44cc11"

gen = BadgeGenerator(template=BadgeTemplate.DEFAULT)
gen.generate_badge(
    left_text="coverage",
    left_color="#555555",
    right_text=f"{pct:.0f}%",
    right_color=color,
    badge_name="coverage.svg",
    output_path="./badges",
)

🖥️ CLI Usage

Coverage badge

badgeshield coverage coverage.xml --badge-name coverage.svg --output-path ./badges

Use --metric branch for branch coverage, --left-text to change the label.

Single badge

badgeshield single \
  --left-text "coverage" \
  --left-color "#555555" \
  --right-text "94%" \
  --right-color "#44cc11" \
  --style gradient \
  --badge-name coverage.svg \
  --output-path ./badges

--style accepts flat (default), rounded, gradient, or shadowed (case-insensitive).

With a logo and links:

badgeshield single \
  --left-text "build" \
  --left-color "DARK_GREEN" \
  --right-text "passing" \
  --right-color "#44cc11" \
  --logo path/to/logo.png \
  --logo-tint "#ffffff" \
  --left-link "https://example.com/pipeline" \
  --badge-name build.svg

Framed circle:

badgeshield single \
  --left-text "MH" \
  --left-color "#673ab7" \
  --template CIRCLE_FRAME \
  --frame FRAME1 \
  --badge-name initials.svg

SVG audit

Verify that a generated SVG contains no external resource references:

badgeshield audit badges/build.svg          # exits 0 if clean, 1 if violations found
badgeshield audit badges/build.svg --json   # machine-readable JSON output

⚡ Batch Generation

CLI

badgeshield batch badges.json --output-path ./badges --max-workers 8

JSON config (badges.json)

[
  {
    "badge_name": "build.svg",
    "left_text": "build",
    "left_color": "GREEN"
  },
  {
    "badge_name": "coverage.svg",
    "left_text": "coverage",
    "left_color": "#555555",
    "right_text": "94%",
    "right_color": "#44cc11",
    "style": "gradient"
  },
  {
    "badge_name": "version.svg",
    "left_text": "v2.1.0",
    "left_color": "#673ab7"
  }
]

A per-entry "style" key overrides the CLI --style flag for that badge.

After the run, a Rich summary table shows which badges succeeded or failed.

Python API

from badgeshield import BadgeBatchGenerator, BadgeStyle, BadgeTemplate

batch = BadgeBatchGenerator(max_workers=4)
badges = [
    {"badge_name": "build.svg",    "left_text": "build",    "left_color": "GREEN", "output_path": "./out", "template": BadgeTemplate.DEFAULT, "style": BadgeStyle.FLAT},
    {"badge_name": "coverage.svg", "left_text": "coverage", "left_color": "#555",  "right_text": "94%", "right_color": "#44cc11", "output_path": "./out", "template": BadgeTemplate.DEFAULT, "style": BadgeStyle.GRADIENT},
]

try:
    batch.generate_batch(badges, progress_callback=lambda name: print(f"✓ {name}"))
except RuntimeError:
    for badge_name, error in batch._failures:
        print(f"✗ {badge_name}: {error}")

👪 Contributing

All contributions are welcome. Fork the repo, make your changes, and open a pull request. You can also open an issue with the label enhancement.

Don't forget to ⭐ star the project!

🔶 View all contributors


📃 Full Docs  ·  🔧 Report a Bug  ·  ⛪ Vertex AI Automations

(back to top)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

badgeshield-0.1.0.tar.gz (2.9 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

badgeshield-0.1.0-py3-none-any.whl (2.6 MB view details)

Uploaded Python 3

File details

Details for the file badgeshield-0.1.0.tar.gz.

File metadata

  • Download URL: badgeshield-0.1.0.tar.gz
  • Upload date:
  • Size: 2.9 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for badgeshield-0.1.0.tar.gz
Algorithm Hash digest
SHA256 8e5d7ed15523d3f0b2be6224830e64c8003a08a7c51362297b25962fdb8c675c
MD5 738c5a991f148e499d1b4f7c59c2c69d
BLAKE2b-256 f4aae5edeaf06d60030b88eb075c1ed4c734fe97d6309c7035b5ee049c4d81e7

See more details on using hashes here.

File details

Details for the file badgeshield-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: badgeshield-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 2.6 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for badgeshield-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bb50fdeb24736604d7681bc198d87b316d5385148afd1a49d696e76b52aa0ec2
MD5 e56603fd09eab6ba6c17aafdacaa41d0
BLAKE2b-256 2f7614f60362ddfbbc0fbcdc119c267a54749fe25cb43d6f4d1eab39d121cc95

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page