1

I have a class to parse data from some online dictionaries, it reads info about word from json and then executes methods as json tells to. An example of json:

{
"functions": [
    {
        "name": "find_translations",
        "properties": {
            "only_first": false
        }
    },
    {
        "name": "find_synonyms",
        "properties": {
             "number": 5
        }
],
"word": "to exuberate",
"language": "angielski",
"target_language": "polski",
"collection": "default"
}

So, I have a class with methods find_translations and find_synonyms. And __init __ is reading the json, and I want to execute functions with parameters as in json. I could do a bunch of ifs, but it isn't scalable, I guess. I could do eval(), but it is a vulnerability. What do I do? Can I create something like a dictionary with functions?

EDIT:

Here's my class (simplified):

class Parser:
  def __init__(self, path):
    ...
    # reads data from json
    ...

    # my problem: I need to launch methods from this class
    # that were mentioned in json. In case from example, I'd launch
    self.find_translations(self)
    self.find_synonyms(self)
    # it is an example, so without parameters


def find_translations(self):
    # do something

def find_synonyms(self):
    # do something

def find_usage(self):
    # do something
  • 2
    I'm not sure I understood the question, but maybe you are searching for `**kwargs`? Here a reference: https://stackoverflow.com/a/3394898/2319299 – Matteo Ragni Mar 13 '18 at 12:39
  • Thanks, I forgot about this. It is solving my problem with passing arguments from json, but I still need to execute functions mentioned in json – Jakub Cichalewski Mar 13 '18 at 12:42
  • 1
    Ah! that was not clear... No you need to use some eval-like function, and you need to bound it very well. Make a "white" list of allowed functions and check that you run only json functions that are on that list. I don't have a safer method in mind right now... hope in someone with a better idea... – Matteo Ragni Mar 13 '18 at 12:46
  • Thanks! I edited my question. Eval came to my mind also, but I wasn't sure if it is a good idea, if nobody will post an idea better than yours, I will use it – Jakub Cichalewski Mar 13 '18 at 12:54

2 Answers2

2

Use ast.literal_eval as a safer alternative to eval:

From documentation:

ast.literal_eval: Safely evaluate an expression node or a string containing a Python literal or container display. The string or node provided may only consist of the following Python literal structures: strings, bytes, numbers, tuples, lists, dicts, sets, booleans, and None.

This can be used for safely evaluating strings containing Python values from untrusted sources without the need to parse the values oneself. It is not capable of evaluating arbitrarily complex expressions, for example involving operators or indexing.

jpp
  • 159,742
  • 34
  • 281
  • 339
2

You can use the getattr function to call a particular method of class like this:-

getattr(Parser, function_name_here)(arguments_here)

I think This was what you were asking for? I hope it helps.

gautamaggarwal
  • 341
  • 2
  • 11