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

Uploaded Python 3

File details

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

File metadata

  • Download URL: badgeshield-0.2.1.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.1.tar.gz
Algorithm Hash digest
SHA256 a6adf39426a59ff7d99ab23c1fa9f40e3ecc528c9eb21eeae26f24ee1b14f3fa
MD5 be99a8555d43f265690734dbafdce7f2
BLAKE2b-256 c78a964929af15b296d7da427bc2b46f8fd5d42e8713087de92fc2fecfda1356

See more details on using hashes here.

File details

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

File metadata

  • Download URL: badgeshield-0.2.1-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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 c0844f03ec918728c213d3b6ccb0b360b54accfbda165bfe82d375209d625c9f
MD5 3075b7453436b52027c9b894a776658e
BLAKE2b-256 43e0d849f4ab45f3e5383d69e081346fb55f826acf885a69c162165884b18cc7

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