feature: support JSON config as well as YAML#1490
Conversation
Signed-off-by: Patricia Pampanelli <ppampanelli@nvidia.com>
Signed-off-by: Patricia Pampanelli <ppampanelli@nvidia.com>
Signed-off-by: Patricia Pampanelli <ppampanelli@nvidia.com>
…anelli/garak into support-json-config
Signed-off-by: Patricia Pampanelli <ppampanelli@nvidia.com>
jmartin-tech
left a comment
There was a problem hiding this comment.
Thanks you, some thoughts for consideration.
garak/_config.py
Outdated
| if settings_filename.endswith(".json"): | ||
| settings = json.load(settings_file) | ||
| else: | ||
| settings = yaml.safe_load(settings_file) |
There was a problem hiding this comment.
this seems inverted based on the assumptions and resolutions in the description:
| if settings_filename.endswith(".json"): | |
| settings = json.load(settings_file) | |
| else: | |
| settings = yaml.safe_load(settings_file) | |
| if settings_filename.endswith(".yaml"): | |
| settings = yaml.safe_load(settings_file) | |
| else: | |
| settings = json.load(settings_file) |
Consider expanding this to have a try block that can be used to retry load with the other format for cases where the filename does not contain a supported extension.
This would account for user provided cli arguments like:
--config my_config--config my_config.file--config my_config.yml--config my_config.yaml--config my_config.json
There was a problem hiding this comment.
Would recommend accepting yaml, yml, json extensions in both upper & lower case
-- or we could even have --config_json and --config_yaml options, ignoring extension, and default to --config_yaml
There was a problem hiding this comment.
I like both of these ideas, and we should consider just adding error handling here.
leondz
left a comment
There was a problem hiding this comment.
This looks pretty thorough. Maybe we can re-think how we do switching, and put the burden onto the user to specify their intent explicitly wrt. extension, rather than having to guess it.
Would also like deeper testing of edge cases & loading behaviour from YAML and JSON loading, so we know how to write garak configs in both these formats, and so we know we're treating them both evenly and not e.g. misapplying fixes on YAML loading to results from JSON loading
garak/_config.py
Outdated
| if settings_filename.endswith(".json"): | ||
| settings = json.load(settings_file) | ||
| else: | ||
| settings = yaml.safe_load(settings_file) |
There was a problem hiding this comment.
Would recommend accepting yaml, yml, json extensions in both upper & lower case
-- or we could even have --config_json and --config_yaml options, ignoring extension, and default to --config_yaml
| fq_site_config_filename = str(transient.config_dir / site_config_filename) | ||
| if os.path.isfile(fq_site_config_filename): | ||
| settings_files.append(fq_site_config_filename) | ||
| if site_config_filename == "garak.site.yaml": |
There was a problem hiding this comment.
what does this if intent to test for? the literal of a .yaml makes me think it could be re-thought
There was a problem hiding this comment.
Would appreciate a more detailed test of YAML and JSON loading - perhaps a test version of garak.core.yaml in JSON, for example - to be sure that we're getting the same results out of both YAML and JSON loaders. YAML->Python has pecularities around Nones, for example, and it's not impossible JSON->Python has its own idiosyncracies.
There was a problem hiding this comment.
garak.core.yaml is not standard user controlled as it should only source from the distributed install location. The core config should not support a json version being found. For other files further more complex examples of each format would be reasonable though I think the current tests cover the required set of expectations.
Signed-off-by: Patricia Pampanelli <ppampanelli@nvidia.com>
Signed-off-by: Patricia Pampanelli <ppampanelli@nvidia.com>
jmartin-tech
left a comment
There was a problem hiding this comment.
Testing shows the new exception raise here needs to be handled in cli.py to get the error trace into the logs and output a clear indicator to the user:
python -m garak -t test --config broad_.yaml --fix
garak LLM vulnerability scanner v0.13.4.pre1 ( https://github.com/NVIDIA/garak ) at 2026-01-06T10:53:41.806014
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "/Users/jemartin/Projects/nvidia/garak/garak/__main__.py", line 14, in <module>
main()
File "/Users/jemartin/Projects/nvidia/garak/garak/__main__.py", line 9, in main
cli.main(sys.argv[1:])
File "/Users/jemartin/Projects/nvidia/garak/garak/cli.py", line 301, in main
_config.load_config(run_config_filename=args.config)
File "/Users/jemartin/Projects/nvidia/garak/garak/_config.py", line 350, in load_config
raise FileNotFoundError(message)
FileNotFoundError: run config not found: broad_.yaml
Suggested change:
diff --git a/garak/cli.py b/garak/cli.py
index dbc03432..30445daa 100644
--- a/garak/cli.py
+++ b/garak/cli.py
@@ -298,7 +298,12 @@ def main(arguments=None) -> None:
# load site config before loading CLI config
_cli_config_supplied = args.config is not None
prior_user_agents = _config.get_http_lib_agents()
- _config.load_config(run_config_filename=args.config)
+ try:
+ _config.load_config(run_config_filename=args.config)
+ except FileNotFoundError as e:
+ logging.exception(e)
+ print(f"❌{e}")
+ exit(1)
# extract what was actually passed on CLI; use a masking argparser
aux_parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)
Signed-off-by: Jeffrey Martin <jemartin@nvidia.com>
Adds JSON config file support alongside YAML, enabling users to use either format for garak configuration files. Extension-less config lookups (
--config fast) now work JSON-only, while YAML configs require explicit.yamlextension.issue #913
Extension-less Lookup: JSON-Only
--config fast) only work for JSON files.yamlextensionBehavior
.jsonexists.yamlexists--config fastfast.json--config fast--config fast.json--config fast.yamlfast.yaml(explicit)--config fast.jsonfast.json(explicit)Site Config
garak.site.jsonandgarak.site.yamlsupported