Skip to main content

A package to generate custom badges for GitLab

Project description


Why badgeshield instead of shields.io?

shields.io is great — but it makes an HTTP call to an external server on every CI run.

badgeshield generates badges entirely offline:

  • No network calls — works in air-gapped CI, behind corporate proxies, and offline laptops
  • No rate limits — generate thousands of badges in a single run
  • No data sent externally — your version numbers, branch names, and repo stats stay local
  • Reproducible — same inputs always produce the same SVG, no caching surprises
# Generate every standard badge for your Python project in one command
badgeshield preset --all --output_path ./badges/ --format markdown

Drop the output straight into your README. No account needed, no tokens, no network.


📋 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.2.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.2.0-py3-none-any.whl (2.6 MB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: badgeshield-0.2.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.2.0.tar.gz
Algorithm Hash digest
SHA256 e51da8bcb52bd8c0849312281af1d07d67867e1464c35f1813647a105f2c6d95
MD5 351b18be7630a5da7c2cd9c9b4a90154
BLAKE2b-256 23e5fd701375e07171104efbadd0f3b857a7479a71da5b94facea35dc525fcc2

See more details on using hashes here.

File details

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

File metadata

  • Download URL: badgeshield-0.2.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.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f9621a29371006343072618279571f4c77b3655a85c8ae32c176b7f17e149828
MD5 6dd861ef8161308c965a27fd9110c63f
BLAKE2b-256 a8f8ae378b9b03826c19bdb27a9326cfe6905c2cd532a00826bd67c24f5eb17f

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