From c738d6ddfa21636a636128eb63581817bc905380 Mon Sep 17 00:00:00 2001 From: jsallay <31416796+jsallay@users.noreply.github.com> Date: Fri, 4 Mar 2022 06:46:39 -0500 Subject: [PATCH] grc: Add in json/yml config blocks with validation * Add in json and yaml config blocks Signed-off-by: John Sallay --- blocks/grc.tree.yml | 2 ++ blocks/json_config.block.yml | 58 ++++++++++++++++++++++++++++++++++++ blocks/yaml_config.block.yml | 58 ++++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 blocks/json_config.block.yml create mode 100644 blocks/yaml_config.block.yml diff --git a/blocks/grc.tree.yml b/blocks/grc.tree.yml index fc2fded..0d9560d 100644 --- a/blocks/grc.tree.yml +++ b/blocks/grc.tree.yml @@ -19,4 +19,6 @@ - variable_struct - variable_config - variable_function_probe + - json_config + - yaml_config - parameter diff --git a/blocks/json_config.block.yml b/blocks/json_config.block.yml new file mode 100644 index 0000000..07b9143 --- /dev/null +++ b/blocks/json_config.block.yml @@ -0,0 +1,58 @@ +id: json_config +label: JSON Config +flags: [ show_id, python ] + +parameters: +- id: config_file + label: Config File + dtype: file_open + default: "" +- id: schema_file + label: Config Schema + dtype: file_open + default: "" +# Not my favorite thing because it doesn't explicitly close the file, but +# it should be okay. The garbage collector will take care of it. +value: "${ json.load(open(config_file)) }" + +asserts: +- ${ schema_file == "" or validate(json.load(open(config_file)), json.load(open(schema_file))) is None } + +templates: + imports: |- + import json + from jsonschema import validate + # Note that yaml makes it really hard to insert spaces at the beginning of the line. + # The "\" char below is used to escape the space at the beginning of a line. + var_make: "with open(${config_file}) as fid:\n\ + \ self.${id} = ${id} = json.load(fid)\n\ + self.${id}_schema = ${id}_schema = ${schema_file}\n\ + if ${id}_schema:\n\ + \ with open(${id}_schema) as fid:\n\ + \ validate(${id}, json.load(fid))" + +documentation: |- + This block represents a json config file that is read in as a dictionary. + + The values can be used directly when instantiating blocks. For example, + Sample Rate: yaml_config["samp_rate"] + + Optionally, a json schema can be specified to validate the configuration. + + For example, you could have a json file that contains: + { + "samp_rate": 1e6, + } + And a schema that contains + { + "type": "object", + "properties": { + "samp_rate": {"type": "number", "exclusiveMinimum": 0} + } + } + + If the id of this block is json_config_0, then you can access the samp rate + in other blocks as json_config_0["samp_rate"] + + +file_format: 1 diff --git a/blocks/yaml_config.block.yml b/blocks/yaml_config.block.yml new file mode 100644 index 0000000..eda26b0 --- /dev/null +++ b/blocks/yaml_config.block.yml @@ -0,0 +1,58 @@ +id: yaml_config +label: YAML Config +flags: [ show_id, python ] + +parameters: +- id: config_file + label: Config File + dtype: file_open + default: "" +- id: schema_file + label: Config Schema + dtype: file_open + default: "" +# Not my favorite thing because it doesn't explicitly close the file, but +# it should be okay. The garbage collector will take care of it. +value: "${ yaml.safe_load(open(config_file)) }" + +asserts: +- ${ schema_file == "" or validate(yaml.safe_load(open(config_file)), json.load(open(schema_file))) is None } + +templates: + imports: |- + import json + import yaml + from jsonschema import validate + var_make: "with open(${config_file}) as fid:\n\ + \ self.${id} = ${id} = yaml.safe_load(fid)\n\ + self.${id}_schema = ${id}_schema = ${schema_file}\n\ + if ${id}_schema:\n\ + \ with open(${id}_schema) as fid:\n\ + \ validate(${id}, json.load(fid))" + +documentation: |- + This block represents a yaml config file that is read in as a dictionary. + + The values can be used directly when instantiating blocks. For example, + Sample Rate: yaml_config["samp_rate"] + + Optionally, a json schema can be specified to validate the configuration. + It may sound odd to use a json schema for a yaml file, but it works and + jsonschema is a rich specification. + + For example, you could have a yaml file that contains: + samp_rate: 1e6 + + And a schema that contains + { + "type": "object", + "properties": { + "samp_rate": {"type": "number", "exclusiveMinimum": 0} + } + } + + If the id of this block is yaml_config_0, then you can access the samp rate + in other blocks as yaml_config_0["samp_rate"] + + +file_format: 1