Skip to main content

SimpleEval with Examples

ยท 5 min read
Serhii Hrekov
software engineer, creator, artist, programmer, projects founder

While simpleeval is great for basic calculators, its true power shines in production environments where you need to let users define their own logic-like setting up custom alerts, dynamic pricing discounts, or conditional triggers-without exposing your server to malicious code execution.


๐Ÿ—๏ธ 1. The Core Concept: Why a Rules Engine?โ€‹

Imagine you are building an e-commerce platform. You want shop owners to create custom discount rules, such as: "If the user's cart is over $100 and they are a VIP, give them a 20% discount."

Hardcoding every possible rule combination into your Python backend is impossible. Instead, you let the user save the logic as a string in the database, and you evaluate it on the fly using simpleeval.


๐Ÿ’ป 2. Example: The Dynamic Pricing Engineโ€‹

Here is how you can use simpleeval to safely process user-defined business rules.

from simpleeval import simple_eval
from simpleeval import NameNotDefined

# 1. The data coming from your application (e.g., current checkout state)
checkout_context = {
"cart_total": 150.00,
"user_role": "VIP",
"item_count": 5,
"coupon_code": "SUMMER26"
}

# 2. Custom functions we want to allow inside the rules
def calculate_tax(amount):
return amount * 0.08

safe_functions = {
"tax": calculate_tax,
"max": max,
"min": min
}

# 3. The rules defined by the shop owner (stored as text in a database)
rules = [
{"name": "VIP Discount", "condition": "user_role == 'VIP' and cart_total > 100", "discount": 20},
{"name": "Bulk Buyer", "condition": "item_count >= 10", "discount": 15},
{"name": "Tax Calculation", "condition": "True", "result": "cart_total + tax(cart_total)"}
]

# 4. Processing the rules safely
print("๐Ÿ›’ Processing Checkout Rules...\n")

for rule in rules:
try:
# Evaluate the condition string safely
is_match = simple_eval(
rule["condition"],
names=checkout_context,
functions=safe_functions
)

if is_match and "discount" in rule:
print(f"โœ… Rule Applied: {rule['name']} - ${rule['discount']} off!")
elif is_match and "result" in rule:
final_price = simple_eval(
rule["result"],
names=checkout_context,
functions=safe_functions
)
print(f"๐Ÿ’ฐ Final Price (with {rule['name']}): ${final_price:.2f}")

except NameNotDefined as e:
# Catches if a user writes a rule using a variable that doesn't exist
print(f"โš ๏ธ Error in rule '{rule['name']}': {e}")
except Exception as e:
print(f"โŒ Invalid rule syntax in '{rule['name']}': {e}")


๐Ÿ›ก๏ธ 3. Handling Complex Types (EvalWithCompoundTypes)โ€‹

By default, simpleeval restricts access to objects and methods to prevent users from escaping the sandbox (e.g., trying to run "".__class__.__mro__... to execute system commands).

If you need users to access dictionaries, lists, or object attributes within their expressions, you can use EvalWithCompoundTypes.

from simpleeval import EvalWithCompoundTypes

# A complex nested dictionary
user_data = {
"profile": {
"age": 28,
"tags": ["developer", "early_adopter"]
}
}

evaluator = EvalWithCompoundTypes(names={"user": user_data})

# Now the string can safely navigate the dictionary and lists!
expression = "user['profile']['age'] >= 18 and 'developer' in user['profile']['tags']"

result = evaluator.eval(expression)
print(f"Is target audience? {result}") # Output: True


๐Ÿ“Š 4. The Python Evaluation Landscapeโ€‹

How does simpleeval compare to other string-evaluation methods in Python?

MethodSafetyCapabilitiesBest Used For
eval()โŒ DangerousRuns any Python code.Strictly internal, trusted scripts.
ast.literal_eval()โœ… SafeOnly parses data structures (dicts, lists, ints).Converting JSON/strings to Python objects safely.
simpleevalโœ… SafeMath, logic, variables, and custom functions.User-defined formulas, business rules, calculators.

๐Ÿ“š 5. Further Readingโ€‹

  • [1.1] simpleeval GitHub: Advanced Usage and Security - Read the specific limitations on recursion and execution time limits.
  • [2.1] Python AST Module: Abstract Syntax Trees - If you want to understand how simpleeval breaks down user strings into safe, readable nodes.
  • [3.1] Building a Rules Engine: Design Patterns for Business Rules - Explore how to structure your application to support dynamic rules effectively.