https://github.com/ihassan8/badgeshield
Python package for generating customizable SVG badges. It supports rectangular, circle, and framed-circle templates with 51 predefined colors, logo embedding, batch processing, and both a programmatic API and CLI.
https://github.com/ihassan8/badgeshield
badges desgin gitlab svg
Last synced: 2 days ago
JSON representation
Python package for generating customizable SVG badges. It supports rectangular, circle, and framed-circle templates with 51 predefined colors, logo embedding, batch processing, and both a programmatic API and CLI.
- Host: GitHub
- URL: https://github.com/ihassan8/badgeshield
- Owner: ihassan8
- License: mit
- Created: 2026-03-15T07:19:46.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2026-05-30T04:07:07.000Z (about 1 month ago)
- Last Synced: 2026-06-18T13:13:44.638Z (13 days ago)
- Topics: badges, desgin, gitlab, svg
- Language: Python
- Homepage: https://ihassan8.github.io/badgeshield/
- Size: 3.03 MB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
[](https://pypi.org/project/badgeshield/)
[](https://pypi.org/project/badgeshield/)
[](https://github.com/ihassan8/badgeshield/blob/main/LICENSE.txt)
[](https://pypi.org/project/badgeshield/)
[](https://github.com/ihassan8/badgeshield/actions/workflows/ci.yml)
[](https://ihassan8.github.io/badgeshield)
---
## 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
```bash
# 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
- [Why badgeshield?](#why-badgeshield-instead-of-shieldsio)
- [Overview](#-overview)
- [Features](#-features)
- [Badge Showcase](#-badge-showcase)
- [Installation](#-installation)
- [Quick Start](#-quick-start)
- [Coverage Badge](#-coverage-badge)
- [CLI Usage](#%EF%B8%8F-cli-usage)
- [Batch Generation](#-batch-generation)
- [Contributing](#-contributing)
---
## ๐ฃ 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 templates** โ `DEFAULT` (two-part rectangular), `PILL` (fully rounded), `CIRCLE`, `CIRCLE_FRAME` with 11 PNG overlay frames, and `BANNER` (icon-zone + text).
- **4 visual styles** โ `FLAT`, `ROUNDED`, `GRADIENT`, and `SHADOWED` via `BadgeStyle` enum or `--style` CLI flag.
- **51 built-in colors** โ `BadgeColor` 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.
---
## ๐
Badge Showcase
These badges are generated by badgeshield itself โ no shields.io, no network calls.
### Project badges
| Badge | Preset |
|---|---|
|  | `badgeshield preset version` |
|  | `badgeshield preset python` |
|  | `badgeshield preset branch` |
|  | `badgeshield preset ruff` |
|  | `badgeshield preset mypy` |
|  | `badgeshield preset maintained` |
|  | `badgeshield preset library` |
|  | `badgeshield preset cross-platform` |
### Templates
| Template | Preview |
|---|---|
| `DEFAULT` |  |
| `PILL` |  |
| `CIRCLE` |  |
| `BANNER` |  |
### Styles (DEFAULT template)
| Style | Preview |
|---|---|
| `FLAT` |  |
| `ROUNDED` |  |
| `GRADIENT` |  |
| `SHADOWED` |  |
---
## ๐ Installation
```bash
pip install badgeshield
```
With logo tinting support (requires Pillow):
```bash
pip install "badgeshield[image]"
```
Upgrade:
```bash
pip install --upgrade badgeshield
```
---
## ๐ Quick Start
### Python API โ DEFAULT template
```python
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
```python
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
```python
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
```python
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
```python
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
```bash
badgeshield coverage coverage.xml \
--badge-name coverage.svg \
--output-path ./badges
```
The color is chosen automatically based on these thresholds:
| Coverage | Color |
|----------|-------|
| โฅ 90% |  green |
| โฅ 80% |  yellow-green |
| โฅ 70% |  yellow |
| โฅ 60% |  orange |
| < 60% |  red |
Use `--metric branch` to badge on branch coverage instead of line coverage.
### Python API
```python
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
```bash
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
```bash
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:
```bash
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:
```bash
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:
```bash
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
```bash
badgeshield batch badges.json --output-path ./badges --max-workers 8
```
### JSON config (`badges.json`)
```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
```python
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}")
```
---
## CI Pipeline
Every push to `main` and every pull request runs automatically via [shared-workflows](https://github.com/ihassan8/shared-workflows):
| Job | What it checks |
|-----|----------------|
| **Test** | pytest on Python 3.9โ3.12 x Ubuntu + Windows |
| **Lint** | `ruff check` + `ruff format --check` |
| **Type Check** | `mypy src/` |
| **Audit** | `pip-audit` โ all dependencies scanned for known CVEs |
| **Coverage** | `pytest-cov` โ report posted to the Actions job summary |
## ๐ช 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](https://github.com/ihassan8/badgeshield/graphs/contributors)
---
๐ [Full Docs](https://ihassan8.github.io/badgeshield) ย ยทย ๐ง [Report a Bug](https://github.com/ihassan8/badgeshield/issues/new)