Package: jsonQM
jsonQMA simple tool to easily make your API endpoint json queries more versatile.pip install jsonQMQuick StartThe example model explains how to set up a model and query that model.tests/ExampleModel.pyfromjsonQMimport*# Make the model.# Declare a model serializerms=ModelSerializer()# Each model must have its own serializerclassMyModel(Model):def__init__(self)->None:# define the structure of the query model:self.model={# we have a single query scope/section called functions"functions":{},"msg":"test"# non functional attributes also need to be included in the json query if you wish for them to be present in the response (see Example query 3 below)}# sync/add the model attribute functions to the modelms.sync(self)# Define attributes of the model (argument 2) along with the scope/section they are found in (argument 1)@ms.add(["functions"],"repeater")# This attribute key is "repeater" and can be found in the "functions" dictdefrepeater(self,arg:int):# when the attribute is queried it will run this code and return the valuereturn["repeat"for_inrange(arg)]# You can use anything as the attribute key that is a valid python dictionary key.@ms.add(["functions"],7)# Keep in mind that if used with json, you are limited to what is a valid json key.defnumber_7(self):return"abc"@ms.token()# this marks this attribute as the model's token@ms.add([],"token")deftoken(self,tok:str):#insert some logic to compare token to tokens in databasereturntok=="token"# The token function must return true for the token to be valid.@ms.requires_token()# this marks this attribute as requiring the token attribute to return true@ms.add([],"secret")defsecret(self):return"My super secret message"# if the token is false this will return 'errot:token:invalid' if the token is missing from the query this will return 'error:token:missing'#LOGICif__name__=="__main__":# If you are experiencing bugs related to concurrency, you should reinstantiate your model per thread/concurrent task where it is being used.# note that instantiation may require many itterations depending on the ammount of attributes you've added and the length of their parent path.# (parent path is the first list argument in `ms.add(["some","dictionary","key","path"], "attribute name")`)model_instance=MyModel()# If you can avoid instantiating the model more than once for optimal performance.#Example query 1print(model_instance.get({"functions":{# programmed attribute values should be a list containing the function arguments."repeater":[5],7:[]}}))# prints:# {'functions': {'repeater': ['repeat', 'repeat', 'repeat', 'repeat', 'repeat'], 7: 'abc'}}#Example query 2print(model_instance.get({"functions":{# The model will only run/return attributes which have been specified"repeater":[5]}}))# prints:# {'functions': {'repeater': ['repeat', 'repeat', 'repeat', 'repeat', 'repeat']}}#Example query 3print(model_instance.get({"token":["token"],"secret":[]}))# prints:# {'token': True, 'secret': 'My super secret message'}#Example query 3print(model_instance.get({"token":["abc"],"secret":[]}))# prints:# {'token': False, 'secret': 'error:token:invalid'}#Example query 3print(model_instance.get({"secret":[]}))# prints:# {'secret': 'error:token:missing'}#Example query 3print(model_instance.get({"msg":1}))# prints:# {'msg': 'test'}