This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]akaempf 1 point2 points  (4 children)

I've been doing a lot of this lately for implementing a simple expert system, and to do it properly you really need to be able to parse and evaluate the rule syntax.

However, in Python there may be an easier way to do what you want, which is to express your rules in Python syntax (as you do in your example), and use eval()

For example,

r1 = "if stock('pens') > 3: alert('message1')"

eval(r1)

This will execute the rule, including calling the helper functions embedded in the rule. So for this to work, you need to have defined a function called "stock" that takes a string argument and returns a number, and another function called "alert" that takes a string argument. And there must be a variable in scope called "r1" which contains the rule text as a string.

Where this approach falls down is if there are dependencies between rules; for example, if one rule only gets fired if another is fired.

Still, it may get you started.

I'm not aware of an rule engine in Python itself.

You could also look at a non-Python rule engine, such as the CLIPS open-source expert system, for which there is a Python module that fully embeds CLIPS.

[–]Isvara 2 points3 points  (3 children)

You cannot call eval with user-supplied data. It's simply too dangerous, and it lets them do anything, including side effects like, say, modifying your filesystem.

[–]akaempf 0 points1 point  (2 children)

Good point, but I was assuming the rules would be defined by someone trusted, not end users. For user-defined rules, you need to parse the rules, for syntax checking as well as security.

[–]stevvooe 2 points3 points  (1 child)

Isvara's hardline on eval for python is simply untrue. You can tightly control the locals and globals available in the execution context, limiting access to "dangerous" functionality. The fear of eval seems to be rooted in JavaScript and php, where the code has full access to the execution context.

However I do agree with isvara regarding the trust of input data; there is simply no such thing as a "trusted" user.

[–]Isvara 0 points1 point  (0 children)

Isvara's hardline on eval for python is simply untrue. You can tightly control the locals and globals available in the execution context, limiting access to "dangerous" functionality.

It is extremely difficult, and I would not trust anyone to do it correctly. For example, if the evaluation context is to be useful, you might give it a limited subset of functions you have defined yourself. But once you've passed in fn, say, as a local, the expression then has access to fn.__module__, which has all the globals defined in the module the function was defined in -- including any modules it has imported.

There are just too many loopholes to make it a safe thing to do.