from string import Template
import json
class ReplaceTepmlate(Template):
delimiter ="${}"
def test_example1():
a={"a":[{"c":1,'b':'${env}'},{"c":"${ip}"}]}
string_text=json.dumps(a)
# will replace like this {"a": [{"c": 1, "b": "litao"}, {"c": "10"}]}
print(Template(string_text).substitute({"env":"litao","ip":10}))
class TemplateUserDefine(Template):
delimiter = '$'
def test_example2():
""" test $$env replace escape,$$不替换"""
b={"test":11,'array':{"data":["hello",'$name'],"error":{"email":'$$env'}}}
s=json.dumps(b)
# will not replace $$env it keep self $env
#{"test": 11, "array": {"data": ["hello", "zhangsan"], "error": {"email": "$env"}}}
print(TemplateUserDefine(s).substitute({"name":'zhangsan',"env":111}))
class TemplateSpecial(Template):
delimiter = '#'
def test_example3():
# test # define variable replace
test='hello,#var,i test args replace instead of kwargs .'
ret=TemplateSpecial(test).substitute(var=111)
# hello,111,i test args replace instead of kwargs .
print(ret)
if __name__ == '__main__':
test_example2()
# 优雅的合并dict
foo=dict(a=1,b=2)
bar=dict(key="value")
# you will get {'a': 1, 'b': 2, 'key': 'value'}
print({**foo,**bar})
应用篇:django 替换请求头或者body 参数:
import os
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mall.settings')
django.setup()
from platformapp.models import UserVariable,JsonModels
import json
from jsonpath import jsonpath
import re
import operator
def demo():
user_var_object= UserVariable.objects.filter(id=7).first()
var=user_var_object.variables
json_model=JsonModels.objects.filter(id=7).first()
content=substitute_content(json_model.attrs,var) # dict
res=JsonModels.objects.filter(id=7).update(attrs=content)
print(res)
def substitute_content(content:dict,replace_kwargs:dict)->dict:
"""
@:param content of replace contains ${var_name}
@:param replace_kwargs is the replace kwargs
@:exception: use json string to serialize int,float,list
"""
# todo replace header'value or request body data ${variable}
dump_string = json.dumps(content)
for k,v in replace_kwargs.items():
if isinstance(v,(int,float,list)):
res = dump_string.replace('\"${' + str(k) + '}\"', json.dumps(v))
dump_string = res
else:
res=dump_string.replace('${' + str(k) + '}', str(v))
dump_string=res
contents=json.loads(dump_string)
return contents
def test_suite_replace():
res= substitute_content({"test": "${user}", "hex": "${pwd}","testlist":"${args}","at":{"a":{"k":"${user}"}}},
{"user": "hello", "pwd": 2.22,"args":[1,"22"]})
print(res)
def json_recur(data,key_rex=None,v_rex=None):
if isinstance(data,dict):
for key,value in data.items():
# print("key:",key,"value:",value,'===')
if isinstance(value,dict):
json_recur(value)
elif isinstance(value,list):
print(value,type(value),"@@@@@@@@")
for i in value:
json_recur(i)
else:
print(value,"--------???? ????? ",type(value))
elif isinstance(data,list):
for i in data:
json_recur(i)
else:
print(data,type(data),"!!!!!!!!")
def jsonpath_extractor(json_expr:str,body,index=0):
"""
@:param: json path expression $..data
@:param body the substitute body support [dict,str]
@index substitute value index default is 0 ,if -1 return all value
"""
if isinstance(body,str):
body=json.loads(body)
elif isinstance(body,dict):
pass
else:
raise ValueError("body type must be dict or string")
extract_value= jsonpath(body, json_expr)
if extract_value:
if index==-1:
return extract_value
else:
return extract_value[index] or None
else: return None
def regx_extractor(regx_expr,string:str,count=0):
"""
:param regx_expr:
:param string:
:param count:
:return: string
r=re.findall(regx_expr,string)
"""
results=re.findall(regx_expr,string)
if results:
return results[count]
return None
def assert_result(expect,actual,flag='eq'):
"""
:param expect:
:param actual:
:param flag: default is eq
:return:if True else False
"""
if flag == 'eq': # a==b
return operator.eq(expect,actual)
if flag == "ne": # a!=b
return operator.ne(expect,actual)
if flag == "lt": # a<b
return operator.lt(expect,actual)
if flag == "le": # a<=b | b contains a
return operator.le(expect,actual)
if flag == "gt": # a>b
return operator.gt(expect,actual)
if flag == "ge": # a>=b | a contains b
return operator.ge(expect,actual)
if __name__ == '__main__':
test_suite_replace()