Class: SignalWire::Utils::SchemaUtils
- Inherits:
-
Object
- Object
- SignalWire::Utils::SchemaUtils
- Defined in:
- lib/signalwire/utils/schema_utils.rb
Overview
SchemaUtils — Ruby port of signalwire.utils.schema_utils.SchemaUtils.
Loads the SWML JSON Schema, extracts verb metadata, and validates either a single verb config or a complete SWML document.
Construction rules mirror Python:
- Pass schema_path: nil to use the bundled schema.json.
- schema_validation: false disables validation (validate_verb returns
true for every call).
- The env var SWML_SKIP_SCHEMA_VALIDATION=1/true/yes also disables
validation regardless of the constructor argument.
The Ruby port currently ships only the lightweight validator (verb existence + required-property check). Full JSON Schema validation can be wired in via the ‘json_schemer` gem by extending init_full_validator. The lightweight contract matches Python’s _validate_verb_lightweight() exactly.
Instance Attribute Summary collapse
-
#schema ⇒ Hash{String=>Object}
readonly
Parsed JSON Schema document.
-
#schema_path ⇒ String?
readonly
Resolved schema path (nil = embedded default).
Instance Method Summary collapse
-
#full_validation_available? ⇒ Boolean
Whether full JSON Schema validation is wired up.
-
#generate_method_body(verb_name) ⇒ Object
Generate a Python-style method body string for a verb.
-
#generate_method_signature(verb_name) ⇒ Object
Generate a Python-style method signature string for a verb.
-
#get_all_verb_names ⇒ Object
Sorted list of all known verb names.
-
#get_verb_parameters(verb_name) ⇒ Object
Parameter-definition block used by code-gen tooling.
-
#get_verb_properties(verb_name) ⇒ Object
The properties block for a verb, or {} when unknown.
-
#get_verb_required_properties(verb_name) ⇒ Object
The required list for a verb, or [] when unknown / no required.
-
#initialize(schema_path = nil, schema_validation = true) ⇒ SchemaUtils
constructor
Construct a SchemaUtils.
-
#load_schema ⇒ Object
Read and parse the JSON Schema.
-
#validate_document(document) ⇒ Object
Validate a complete SWML document.
-
#validate_verb(verb_name, verb_config) ⇒ Array(Boolean, Array<String>)
Validate a verb config against the schema.
Constructor Details
#initialize(schema_path = nil, schema_validation = true) ⇒ SchemaUtils
Construct a SchemaUtils.
58 59 60 61 62 63 64 65 66 |
# File 'lib/signalwire/utils/schema_utils.rb', line 58 def initialize(schema_path = nil, schema_validation = true) env_skip = env_boolish(ENV.fetch('SWML_SKIP_SCHEMA_VALIDATION', '')) @schema_path = schema_path @validation_enabled = schema_validation && !env_skip @schema = load_schema @verbs = {} extract_verbs init_full_validator if @validation_enabled && !@schema.empty? end |
Instance Attribute Details
#schema ⇒ Hash{String=>Object} (readonly)
Returns parsed JSON Schema document.
48 49 50 |
# File 'lib/signalwire/utils/schema_utils.rb', line 48 def schema @schema end |
#schema_path ⇒ String? (readonly)
Returns resolved schema path (nil = embedded default).
51 52 53 |
# File 'lib/signalwire/utils/schema_utils.rb', line 51 def schema_path @schema_path end |
Instance Method Details
#full_validation_available? ⇒ Boolean
Whether full JSON Schema validation is wired up. Mirrors Python’s full_validation_available property.
70 71 72 |
# File 'lib/signalwire/utils/schema_utils.rb', line 70 def full_validation_available? !@full_validator.nil? end |
#generate_method_body(verb_name) ⇒ Object
Generate a Python-style method body string for a verb. Mirrors Python’s generate_method_body(verb_name).
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/signalwire/utils/schema_utils.rb', line 188 def generate_method_body(verb_name) params = get_verb_parameters(verb_name) keys = params.keys.sort lines = [ ' # Prepare the configuration', ' config = {}' ] keys.each do |name| lines << " if #{name} is not None:" lines << " config['#{name}'] = #{name}" end lines << ' # Add any additional parameters from kwargs' lines << ' for key, value in kwargs.items():' lines << ' if value is not None:' lines << ' config[key] = value' lines << '' lines << " # Add the #{verb_name} verb" lines << " return self.add_verb('#{verb_name}', config)" lines.join("\n") end |
#generate_method_signature(verb_name) ⇒ Object
Generate a Python-style method signature string for a verb. Mirrors Python’s generate_method_signature(verb_name).
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/signalwire/utils/schema_utils.rb', line 159 def generate_method_signature(verb_name) params = get_verb_parameters(verb_name) required = get_verb_required_properties(verb_name).to_set parts = ['self'] keys = params.keys.sort keys.each do |name| t = python_type_annotation(params[name]) parts << if required.include?(name) "#{name}: #{t}" else "#{name}: Optional[#{t}] = None" end end parts << '**kwargs' doc = +"\"\"\"\n Add the #{verb_name} verb to the current document\n \n" keys.each do |name| desc = '' d = params[name] if d.is_a?(Hash) && d['description'] desc = d['description'].to_s.gsub("\n", ' ').strip end doc << " Args:\n #{name}: #{desc}\n" end doc << " \n Returns:\n True if the verb was added successfully, False otherwise\n \"\"\"\n" "def #{verb_name}(#{parts.join(', ')}) -> bool:\n#{doc}" end |
#get_all_verb_names ⇒ Object
Sorted list of all known verb names. Mirrors Python’s get_all_verb_names().
87 88 89 |
# File 'lib/signalwire/utils/schema_utils.rb', line 87 def get_all_verb_names @verbs.keys.sort end |
#get_verb_parameters(verb_name) ⇒ Object
Parameter-definition block used by code-gen tooling. Mirrors Python’s get_verb_parameters(verb_name).
118 119 120 121 122 123 124 |
# File 'lib/signalwire/utils/schema_utils.rb', line 118 def get_verb_parameters(verb_name) inner = get_verb_properties(verb_name) props = inner['properties'] return {} unless props.is_a?(Hash) props end |
#get_verb_properties(verb_name) ⇒ Object
The properties block for a verb, or {} when unknown. Mirrors Python’s get_verb_properties(verb_name).
93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/signalwire/utils/schema_utils.rb', line 93 def get_verb_properties(verb_name) v = @verbs[verb_name] return {} if v.nil? outer_props = v['definition']['properties'] rescue nil return {} unless outer_props.is_a?(Hash) inner = outer_props[verb_name] return {} unless inner.is_a?(Hash) inner end |
#get_verb_required_properties(verb_name) ⇒ Object
The required list for a verb, or [] when unknown / no required. Mirrors Python’s get_verb_required_properties(verb_name).
108 109 110 111 112 113 114 |
# File 'lib/signalwire/utils/schema_utils.rb', line 108 def get_verb_required_properties(verb_name) inner = get_verb_properties(verb_name) req = inner['required'] return [] unless req.is_a?(Array) req.select { |x| x.is_a?(String) } end |
#load_schema ⇒ Object
Read and parse the JSON Schema. Mirrors Python’s load_schema().
75 76 77 78 79 80 81 82 83 |
# File 'lib/signalwire/utils/schema_utils.rb', line 75 def load_schema path = @schema_path || default_schema_path return {} if path.nil? || !File.exist?(path) raw = File.read(path, encoding: 'UTF-8') JSON.parse(raw) rescue JSON::ParserError, Errno::ENOENT {} end |
#validate_document(document) ⇒ Object
Validate a complete SWML document. Mirrors Python’s validate_document(document). Returns (false, [‘Schema validator not initialized’]) when no full validator is wired in.
148 149 150 151 152 153 154 155 |
# File 'lib/signalwire/utils/schema_utils.rb', line 148 def validate_document(document) if @full_validator.nil? return [false, ['Schema validator not initialized']] end # Reserved for full-validator wiring. [true, []] end |
#validate_verb(verb_name, verb_config) ⇒ Array(Boolean, Array<String>)
Validate a verb config against the schema. Mirrors Python’s validate_verb(verb_name, verb_config).
130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/signalwire/utils/schema_utils.rb', line 130 def validate_verb(verb_name, verb_config) return [true, []] unless @validation_enabled unless @verbs.key?(verb_name) return [false, ["Unknown verb: #{verb_name}"]] end if @full_validator validate_verb_full(verb_name, verb_config) else validate_verb_lightweight(verb_name, verb_config) end end |