Thanks to visit codestin.com
Credit goes to github.com

Skip to content

A mini language that looks and works like python for LLMs

License

montaguegabe/tiny-python

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

37 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tiny-python

WARNING: This library is under development and still needs some security testing. Use at your own risk.

LLMs are very good at writing python code!

tiny-python allows you to take advantage of this without your web app getting hacked.

It is very simple: use tiny_exec(unsafe_llm_code) on code generated by an LLM, and a python-like language will be run instead of dangerously running real python.

Why?

More powerful structured outputs: OpenAI supports structured outputs, but you must define the schema rigorously beforehand, and it is really only designed to handle small numbers of classes. What if you are having the AI create a complicated nested and polymorphic structure like a video game level? What if you want the AI to be able to use mathematical functions to lay out positions of where things are? What if you are trying to represent a graph structure with cycles instead of a tree structure?

Solution: Have the LLM generate python and evaluate it safely using tiny-python. You can control the number of iterations of execution the code is allowed.

Does tiny-python guarantee security?

No:

tiny-python allows you to pass your own functions and dataclasses into the execution environment! You must use this feature responsibly. If you want to see a toy example of insecure usage of tiny-python:

# BAD: Suppose we define an insecure dataclass
@dataclass
class MyInsecureClass:
  code: str
  def __post_init__(self):
    exec(self.code)  # exec is bad.

# BAD: Then we run on an LLM output
tiny_exec(llm_output, allowed_classes=[MyInsecureClass])

To use this library properly, you should avoid providing it access to dataclasses with insecure side effects, or that are used in an insecure way. Care must be taken when you pass any of the following extra arguments to the tiny_exec function (see more docs on these below): allowed_classes, allowed_functions, or global_vars.

Features

  • Safe execution without using Python's exec or eval
  • Support for math operations, string operations, and dataclass instantiation
  • Control flow structures (if, for, while)
  • Configurable execution limits (iterations, recursion depth)

Installation

pip install tiny-python

Quick Start

from tiny_python import tiny_exec, tiny_eval_last
from dataclasses import dataclass
from typing import List, Optional

# Define dataclasses that model an organization
# Note: These can have circular references to each other
@dataclass
class Person:
    name: str
    role: str
    team: Optional['Team'] = None

@dataclass
class Team:
    name: str
    description: str
    leader: Optional[Person] = None
    members: List[Person] = None

    def __post_init__(self):
        if self.members is None:
            self.members = []

@dataclass
class Project:
    title: str
    team: Team
    budget: float
    priority: int

# Use tiny_exec to safely execute LLM-generated code that builds complex structures
code = """
# Create team members
alice = Person("Alice", "Engineer")
bob = Person("Bob", "Designer")
charlie = Person("Charlie", "Manager")

# Create a team with a leader
dev_team = Team("Development Team", "Builds awesome products", charlie)
dev_team.members = [alice, bob, charlie]

# Set team references (creating cycles)
alice.team = dev_team
bob.team = dev_team
charlie.team = dev_team

# Create a project for this team
project = Project("New Website", dev_team, 50000.0, 1)

# Calculate some metrics
team_size = len(dev_team.members)
budget_per_person = project.budget / team_size
high_priority = project.priority == 1

# Store results in a summary
summary = {
    "project_name": project.title,
    "team_leader": dev_team.leader.name,
    "team_size": team_size,
    "budget_per_person": budget_per_person,
    "is_high_priority": high_priority
}
"""

# Execute the code safely with the allowed dataclasses
result = tiny_exec(code, allowed_classes=[Person, Team, Project])

# Access the created objects and computed values from the returned locals
print(result["summary"])
# {'project_name': 'New Website', 'team_leader': 'Charlie', 'team_size': 3,
#  'budget_per_person': 16666.666666666668, 'is_high_priority': True}

print(f"Team leader: {result['dev_team'].leader.name}")  # Charlie
print(f"First team member's team: {result['alice'].team.name}")  # Development Team

# Or use tiny_eval_last to get just the last expression value
last_value = tiny_eval_last("2 + 3 * 4")
print(last_value)  # 14

You can imagine that the code given in the string above is generated by an LLM that was given a description of the team and its members and projects.

API

tiny_exec(code, **kwargs)

Execute tiny-python code safely and return the local variables.

Parameters:

  • code: String containing the code to execute
  • max_iterations: Maximum number of total operations allowed (default: 1000)
  • max_iterations_per_loop: Maximum iterations for any single loop (default: 100)
  • allowed_classes: List of classes that can be instantiated (must be dataclasses)
  • global_vars: Dictionary of global variables to make available
  • allowed_functions: List of functions that may be called

Returns a dictionary containing all local variables created during execution.

Supported Operations

  • Arithmetic: +, -, *, /, //, %, **
  • Comparison: ==, !=, <, <=, >, >=, in, not in, is, is not
  • Boolean: and, or, not
  • Built-in functions: len, range, int, float, str, bool, list, dict, tuple, set, abs, min, max, sum, round, sorted, reversed, enumerate, zip, all, any, isinstance, type
  • String methods: upper, lower, strip, lstrip, rstrip, split, join, replace, startswith, endswith, find, rfind, format, capitalize, title, isdigit, isalpha, isalnum, isspace, and many more string methods
  • Control flow: if, elif, else, for, while, break, continue, return, pass
  • Variable assignment: =, +=, -=, *=, /=, //=, %=, **=
  • Tuple unpacking in assignments and for loops
  • Dataclass instantiation and attribute access (with allowed_classes)
  • Custom functions (with allowed_functions)
  • Dictionary and list indexing/slicing

Security

This package is designed to provide a safe execution environment by:

  • Using AST parsing and a custom executor function instead of exec or eval
  • Whitelisting allowed operations
  • Limiting iteration
  • No module imports or file operations
  • No access to dangerous python built-ins
  • At this early stage, feel free to open an issue if you find a security vulnerability

About

A mini language that looks and works like python for LLMs

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages