A simple feature managment tool library
Project description
pyconfix
A single‑file, curses‑powered, menuconfig‑style configuration editor for any project.
Why?
Do you need an interactive config menu like Linux menuconfig, but without C or a build step? pyconfix is forty kilobytes of pure Python you can drop into any repo—no external deps, no compilation. It also spits out JSON or Kconfig‑style header files, so it plugs straight into C/C++, CMake, Conan, Makefiles—anything that can consume a generated file.
Features
- 🗂 Hierarchical options –
bool,int,string,multiple_choice, recursive groups. - 🔀 Boolean & arithmetic dependencies with logical operators
&&,||,!(keyword formsand,or,xor), comparison/relational operators (==,!=,>,>=,<,<=), arithmetic expressions (+,-,*,/,%), and bitwise operators (&,|,^,<<,>>). - 📦 Composable schemas –
"include": [ ... ]lets you split large configs. - 🔍 Instant search (
/). - ⏹ Abort key – Ctrl+A exits search, input boxes etc.
- 🎚 Live validation – options auto‑hide when dependencies fail.
- 💾 Pluggable save hook – write JSON, YAML, C headers, env‑files – whatever.
- 💻 100 % standard library (Windows users:
pip install windows‑curses).
Installation
pip install pyconfix
Quick start
Create a tiny launcher script first:
# menu.py
import pyconfix
pyconfix.pyconfix(schem_file=["schem.json"]).run()
Then run it:
python menu.py
Press / to search, Enter to toggle, s to save, q to quit.
Headless / CI mode
Run the schema parser non‑interactively to dump a JSON config – handy for scripts and pipelines:
python - <<'PY'
import pyconfix, json
cfg = pyconfix.pyconfix(
schem_file=["schem.json"],
output_file="cfg.json",
config_file="prev.json"
)
cfg.run(graphical=False)
PY
Python API
If you’d rather drive everything from code, import the class:
from pyconfix import pyconfix
cfg = pyconfix(
schem_file=["main.json", "extras.json"],
config_file="prev.json", # load an existing config (optional)
output_file="final.json", # where to write when you press "s"
expanded=True, # expand all groups initially
show_disabled=True # show options that currently fail deps
)
cfg.run() # interactive TUI
print(cfg.get("HOST")) # access a value programmatically
Constructor signature for reference:
pyconfix(
schem_file: list[str],
config_file: str | None = None,
output_file: str = "output_config.json",
save_func: Callable[[dict, list], None] | None = None,
expanded: bool = False,
show_disabled: bool = False,
)
Key bindings
| Action | Key |
|---|---|
| Navigate | ↑ / ↓ |
| Toggle / edit option | Enter |
| Collapse / expand group | c |
| Search | / |
| Save | s |
| Show option description | Ctrl+D |
| Help | h |
| Abort search / input | Ctrl+A |
| Quit | q |
Schema format
{
"name": "Main Config",
"options": [
{ "name": "ENABLE_FEATURE_A", "type": "bool", "default": true },
{ "name": "LogLevel",
"type": "multiple_choice",
"default": "INFO",
"choices": ["DEBUG", "INFO", "WARN", "ERROR"],
"dependencies": "ENABLE_FEATURE_A" },
{ "name": "TIMEOUT",
"type": "int",
"default": 10,
"dependencies": "ENABLE_FEATURE_A && LogLevel==DEBUG" },
{ "name": "Network", "type": "group", "options": [
{ "name": "HOST", "type": "string", "default": "localhost" }
]}
],
"include": ["extra_schem.json"]
}
Supported option types
| Type | Notes |
|---|---|
bool |
true / false |
int |
any integer |
string |
unicode string |
multiple_choice |
one value from choices |
group |
nests other options |
Dependency syntax – cheatsheet
!ENABLE_FEATURE_A # logical NOT
ENABLE_FEATURE_A && HOST=="dev" # logical AND + comparison
TIMEOUT>5 || HOST=="localhost" # logical OR + relational
COUNT+5 > MAX_VALUE # addition + relational
SIZE-1 >= MIN_SIZE # subtraction + comparison
VALUE*2 == LIMIT # multiplication + equality
RATIO/3 < 1 # division + relational
SIZE%4==0 # modulus check
POWER**2 <= LIMIT # exponentiation + relational
BITS & 0xFF == 0xAA # bitwise AND + equality
FLAGS | FLAG_VERBOSE # bitwise OR
MASK ^ 0b1010 # bitwise XOR
VALUE<<2 > 1024 # left shift + relational
VALUE>>1 == 0 # right shift + equality
Advanced usage
import json, pyconfix
def save_as_header(cfg, _):
with open("config.h", "w") as f:
for k, v in cfg.items():
f.write(f"#define {k} {v}\n")
pyconfix.pyconfix(
schem_file=["schem.json", "extras.json"],
output_file="settings.json",
save_func=save_as_header
).run()
Conan integration example
After you have saved a JSON config with pyconfix (e.g. settings.json), a Conan recipe can read that file to enable/disable features and tweak package options at build time.
# conanfile.py
from conan import ConanFile
import os, json
# Load the JSON produced by pyconfix at *import* time so we can
# populate default_options immediately (Conan expects a plain dict).
_cfg = {}
try:
with open(os.getenv("CFG", "settings.json")) as f:
_cfg = json.load(f)
except FileNotFoundError:
# Fall back to built‑ins if the file isn't around yet (first run).
pass
class MyProject(ConanFile):
name = "myproject"
version = "1.0"
# Declare the build‑time options your project cares about
options = {
"feature_a": [True, False],
"log_level": ["DEBUG", "INFO", "WARN", "ERROR"],
}
# Pull the defaults straight from the JSON file
default_options = {
"feature_a": bool(_cfg.get("ENABLE_FEATURE_A", False)),
"log_level": _cfg.get("LogLevel", "INFO"),
}
Call it with:
python pyconfix.py # produce settings.json
CFG=settings.json conan install .
Roadmap
- Add unit tests + GitHub Actions CI
- Cache dependency evaluation for massive configs
Contributions are welcome – fork, hack, send PRs! :rocket:
© 2025 Nemesis – MIT License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyconfix-0.4.6.tar.gz.
File metadata
- Download URL: pyconfix-0.4.6.tar.gz
- Upload date:
- Size: 14.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d6318dd1a3a415c59468ab7625f848ff2a59df2897271396136ffcd7f8217942
|
|
| MD5 |
11290c919b2378e5cdaea73d02bcb494
|
|
| BLAKE2b-256 |
fe45bf99a22f6afa7bc4e32758ca8087a18411a846f052a2f46f0680d97045ae
|
File details
Details for the file pyconfix-0.4.6-py3-none-any.whl.
File metadata
- Download URL: pyconfix-0.4.6-py3-none-any.whl
- Upload date:
- Size: 14.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a95943c4ca5dcbe23531113559a7a5a4191e218faf1a8e2cf02c6c98b143a53b
|
|
| MD5 |
30a1df9dd528a4fff7cf5587d76058a7
|
|
| BLAKE2b-256 |
6b4431968f0ffa374a33fa1e38abdd5c44f859bca15c9821f140df077a620047
|