Schema → Template → Config

A generic, plug‑and‑play tool for generating text configs — from a form, not a text editor.

Config Engineers fill in a guided form and get a validated, rendered config in one click. Template Engineers write the schema and Jinja2 template that define that form. Add a new config type by dropping in a file — no core code changes, no restart.

Desktop GUI + full CLI Windows exe, source, or Docker MIT licensed
router_base_config
schemas/router_base_config.yaml
id: router_base_config
template: router_base_config.j2
fields:
  - key: hostname
    pattern: '^[a-z0-9-]+$'
  - key: mgmt_ip
    type: ip_cidr
  - key: enable_ospf
    type: bool
rendered output
! Generated by ConfigGen | 2026-08-06
hostname rtr-core-01
interface GigabitEthernet0/0
 ip address 10.10.10.1 255.255.255.0
router ospf 1
 network 10.10.10.0 0.0.0.255 area 0
ntp server 192.0.2.123
snmp-server community public-ro RO
Adding a config

Three files, at most.

Nothing else changes. No core code, no registration step, no restart — the CLI and the GUI dashboard both re-scan schemas/ every time.

Required
schemas/<id>.yaml
The form itself: field types, validation, and which template renders it.
Required
templates/<id>.j2
Plain Jinja2, referencing the schema's field keys — the actual output shape.
Optional
hooks/<id>.py
A build() function for values a form field can't hold — database lookups, derived addresses.
configgen check schemas/my_thing.yaml — validates + warns on template/field mismatches, before you ever hit Generate.
Under the hood

Everything a config-generation tool needs, and nothing it doesn't.

It grew out of network configs — router and switch examples run through the docs — but there's nothing network-specific in the engine itself.

Engine

Two-tier generation

Tier 1 validates a schema's fields straight into the template. Tier 2 adds an optional hook — plain Python, with services.db and services.net — for values a form field alone can't express.

Desktop

Full GUI

Dashboard of template tiles, a guided form with live preview and diff-against-last, a Template Editor with Check / Test Render / version history, Bulk Generate, User Admin, and an in-app Help browser.

Headless

Every action, scriptable

Everything the GUI does has a CLI equivalent — check, generate, bulk, diff, history, export/import, and full user/group/API-key management.

Batch

Bulk generation

Generate many configs from one CSV/XLSX file, or a database query — every row validated independently, one bad row never blocks the rest.

Data

Multi-database service

A generic, read-only SQL layer backed by queries.yaml — one SQLite file or several, named and addressed per query.

Teams

Roles & groups

Admin, Template Engineer, and Config Engineer, with group-scoped template visibility — or skip it entirely and run solo, where none of it ever comes up.

Sharing

Config packs

Export a schema + template + hook + preflight check as one .zip; import it elsewhere with explicit overwrite/rename conflict handling.

Safety net

Preflight checks

Advisory syntax sanity checks after rendering — unclosed interface blocks, bad VLAN ranges, unbalanced braces — for IOS, JunOS, SR OS, VRP8, or your own.

Ship it

GUI exe, CLI exe, or Docker

One build produces a windowed ConfigGen.exe and a standalone console ConfigGen-CLI.exe — or run the CLI-only Docker image in CI, no Qt required either way.

Two ways to run it

Click through it, or script around it.

The GUI and the CLI call the exact same core — nothing the form does is unavailable to a script, and nothing the CLI does needs a window open.

GUI

Fill in a form, get a config

Pick a template from the dashboard, fill in the guided form, preview the rendered output, and save — with diff-against-last and a full generation log along the way.

# first run bootstraps admin/admin configgen-gui
CLI

Same pipeline, zero clicks

Validate, generate, and batch-process from a terminal or a CI job — every command returns exit code 0 or 1, scriptable without parsing output.

configgen check schemas/router_base_config.yaml OK: Generic Router Base Config (router_base_config) v1 configgen generate router_base_config --values values.json primary: out/tester/ungrouped/..._primary_....txt
Install

Python 3.10+, a Windows exe, or Docker.

Pick whichever matches how you'll actually run it.

From source

The desktop GUI, from a clone.

$ pip install -e ".[gui]" $ configgen-gui

CLI only

No PySide6/Qt pulled in at all.

$ pip install -e . $ configgen list --dir examples/schemas

Docker

CLI-only image, for CI or a server.

$ docker build -t configgen -f packaging/Dockerfile . $ docker run --rm configgen list
Get started

Your next config doesn't need a text editor.

Clone it, run it, and drop in your first schema — the example configs under examples/ are self-contained, try one immediately.