def parse(template_text, metadata): processed_variables = {} variables = metadata.get(VARS_KEY, []) for var in variables: if not isinstance(var, dict): value = input(f" - {var} : ") processed_variables[var] = value else: processed_variables.update(var) template_text = search_and_replace_file_include_token(template_text) template_text = search_and_replace_samwise_variables(template_text, processed_variables) final_template_obj = YAML().load(template_text) # explicitly set the code uri for each function in preparation of packaging for k, v in final_template_obj['Resources'].items(): if v.get('Type') == 'AWS::Serverless::Function': final_template_obj['Resources'][k]['Properties']['CodeUri'] = 'samwise-pkg.zip' # Force Version elements to be strings, there are parts of the aws cli that wants to turn them into datetime objs nested_alter(final_template_obj, key='Version', callback_function=lambda x: f"{x}", in_place=True) # placeholder for future layers analysis work layers = final_template_obj['Globals']['Function'].get('Layers') or [] if layers: print(' - Layers detected') for layer in layers: print(layer) return final_template_obj
def process_line(stat, obfuscator_dict): """ obfuscator_dict - dict with structure {key: callback_function} """ new_stat = deepcopy(stat) for k in obfuscator_dict: nl.nested_alter(new_stat, k, callback_function=obfuscator_dict[k], conversion_function=str, in_place=True) return new_stat
def test_nested_alter_work_with_right_order(self): document = {"taco": 42, "salsa": [{"burrito":{"key":20}}], "key":50} def callback(data): return data + 100 altered_document = nested_alter(document, "key", callback, in_place=True) self.assertEqual(altered_document["salsa"][0]["burrito"]["key"], 120) self.assertEqual(altered_document["key"], 150)
def test_sample_data4(self): result = { "modelversion": "1.1.0", "vorgangsID": "1", "versorgungsvorschlagDatum": 1510558834978, "eingangsdatum": 1510558834978, "plz": 82270, "vertragsteile": [ { "typ": "1", "beitragsDaten": { "endalter": 85, "brutto": 58.76, "netto": 58.76, "zahlungsrhythmus": "MONATLICH", "plz": 86900, }, "beginn": 1512082800000, "lebenslang": "True", "ueberschussverwendung": { "ueberschussverwendung": "2", "indexoption": "3", }, "deckung": [ { "typ": "2", "art": "1", "leistung": {"value": 7500242424.0, "einheit": "2"}, "leistungsRhythmus": "1", } ], "zuschlagNachlass": [], }, { "typ": "1", "beitragsDaten": { "endalter": 85, "brutto": 0.6, "netto": 0.6, "zahlungsrhythmus": "1", }, "zuschlagNachlass": [], }, ], } # add +1 to all plz def callback(data): return data + 1 self.maxDiff = None self.assertEqual(result, nested_alter(self.sample_data4, "plz", callback))
def test_nested_alter_in_place_true(self): # callback functions def callback(data): return str(data) + "###" doc_updated = nested_alter( self.sample_data4, "vorgangsID", callback, in_place=True ) vorgangsid = doc_updated["vorgangsID"] self.assertEqual(vorgangsid, "1###")
def _get_open_api_schema(self, schema: Mapping[str, Any]) -> Mapping[str, Any]: """ Convert a Pydantic model into an OpenAPI compliant schema object. """ result = {} for key, value in schema.items(): if key == "properties": result[key] = self._validate_property(value) else: result[key] = value return cast(Mapping[str, Any], nested_alter(result, "$ref", _move_schema_reference))
def _get_model_definitions(self): """ handle nested models """ definitions = {} for model, schema in self.models.items(): if model not in definitions.keys(): definitions[model] = schema if "definitions" in schema: for key, value in schema["definitions"].items(): definitions[key] = self._get_open_api_schema(value) del schema["definitions"] return nested_alter(definitions, "$ref", _move_schema_reference)
def test_nested_alter_in_place_false(self): # callback functions def callback(data): return str(data) + "###" doc_updated = nested_alter( self.sample_data4, "vorgangsID", callback, in_place=False ) vorgangsid = doc_updated["vorgangsID"] # should not work without specifying # "treat_list_as_element = True" in nested_update self.assertEqual(vorgangsid, "1###")
def test_nested_alter_recursive(self): document = {"key": {"rename me": {"key": {"rename me": 1}}}} def callback(data): try: data["renamed"] = data.pop("rename me") except KeyError: pass return data altered_document = nested_alter(document, "key", callback, in_place=True) self.assertIn("renamed", altered_document["key"].keys()) self.assertIn("renamed", altered_document["key"]["renamed"]["key"].keys())
def test_nested_alter_list_input_in_place_false(self): # callback functions def callback(data): return str(data) + "###" doc_updated = nested_alter(self.sample_data4, ["plz", "vorgangsID"], callback, in_place=False) plz1 = doc_updated["plz"] plz2 = doc_updated["vertragsteile"][0]["beitragsDaten"]["plz"] vorgangsid = doc_updated["vorgangsID"] # should not work without specifying # "treat_list_as_element = True" in nested_update self.assertEqual(plz1, "82269###") self.assertEqual(plz2, "86899###") self.assertEqual(vorgangsid, "1###")
def test_nested_alter_list_input_with_args_in_place_false(self): # callback functions def callback(data, str1, str2): return str(data) + str1 + str2 doc_updated = nested_alter( self.sample_data4, ["plz", "vorgangsID"], callback, function_parameters=["abc", "def"], in_place=False, ) plz1 = doc_updated["plz"] plz2 = doc_updated["vertragsteile"][0]["beitragsDaten"]["plz"] vorgangsid = doc_updated["vorgangsID"] # should not work without specifying # "treat_list_as_element = True" in nested_update self.assertEqual(plz1, "82269abcdef") self.assertEqual(plz2, "86899abcdef") self.assertEqual(vorgangsid, "1abcdef")
def test_nested_alter_taco_for_example(self): documents = [{"taco": 42}, {"salsa": [{"burrito": {"taco": 69}}]}] # write a callback function which processes a scalar value. # Be aware about the possible types which can be passed to # the callback functions. # In this example we can be sure that only int will be passed, # in production you should check the type because it could be # anything. def callback(data): return data + 10 # (data/100*10) # The alter-version only works for scalar input (one dict), # if you need to adress a list of dicts, you have to # manually iterate over those and pass them to # nested_update one by one out = [] for elem in documents: altered_document = nested_alter(elem, "taco", callback) out.append(altered_document) self.maxDiff = None self.assertEqual(out[0]["taco"], 52) self.assertEqual(out[1]["salsa"][0]["burrito"]["taco"], 79)