### Configuration File Example Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/quick-start.md Example of a `safepyrun` configuration file (`config.py`) to enable pandas, matplotlib, register functions, and set default write destinations. ```python # Enable pandas allow_pandas() # Enable matplotlib allow_matplotlib() # Register custom functions allow('my_module.my_function') # Set default write destinations default_ok_dests = ('/tmp', '/home/user/data') ``` -------------------------------- ### Mixed Registration Example Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/api-reference-allow.md Shows a comprehensive example of using allow() with various registration methods simultaneously, including direct references, string names, dictionaries for class methods, and wildcard module access. ```python import numpy as np allow( 'my_func', # String for locally-defined function 'json.loads', # String for module function np.array, # Direct reference to numpy function {np.ndarray: ['sum', 'mean']}, # Dict for class methods {'pandas.*': ...} # Full module access (use cautiously) ) ``` -------------------------------- ### Example Global Configuration File Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/configuration.md This example demonstrates how to configure pandas, numpy, and custom libraries globally. It enables support for pandas and matplotlib, registers specific methods for pandas DataFrame and Series, and allows specific numpy functions and custom library components. The file path depends on the operating system. ```python # ~/.config/safepyrun/config.py (Linux) # or ~/Library/Application Support/safepyrun/config.py (macOS) import pandas as pd import numpy as np # Enable pandas support allow_pandas() # Enable matplotlib support allow_matplotlib() # Register additional pandas methods allow({pd.DataFrame: ['mean', 'std', 'min', 'max']}) allow({pd.Series: ['mean', 'std', 'quantile']}) # Register numpy array operations allow({np.ndarray: ['sum', 'mean', 'reshape', 'T', 'dtype']}) allow('numpy.linspace') allow('numpy.arange') # Register custom library functions allow('my_library.safe_function') allow({MyClass: ['method1', 'method2']}) # Override default write destinations # default_ok_dests = ('/tmp', '/var/tmp', '/home/user/data') ``` -------------------------------- ### Example Config File Error Warning Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/configuration.md This example shows the format of a UserWarning emitted when the global configuration file contains errors. The warning includes the file path and the specific error encountered, such as a NameError. ```text UserWarning: Failed to load /home/user/.config/safepyrun/config.py: NameError: name 'unknown_var' is not defined ``` -------------------------------- ### Funtools Partial Application Example Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/stdlib-allowlist.md Shows how to use `functools.partial` to create a new function with some arguments pre-filled. ```python from functools import partial add_five = partial(int.__add__, 5) result = add_five(3) # 8 ``` -------------------------------- ### Safepyrun CLI Configuration Example Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/api-reference-cli.md Illustrates how to extend the safepyrun sandbox configuration by creating a custom config.py file. This example allows the use of the pandas library. ```python # ~/.config/safepyrun/config.py import pandas as pd allow_pandas() allow({pd.DataFrame: ['head', 'describe', 'info', 'shape']}) ``` -------------------------------- ### Install Safepyrun Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/quick-start.md Install the safepyrun package using pip. ```bash pip install safepyrun ``` -------------------------------- ### User Configuration Loading Example Source: https://github.com/answerdotai/safepyrun/blob/main/nbs/00_core.ipynb Illustrates how safepyrun loads an optional user configuration file to extend sandbox allowlists. ```python # Add pandas tools allow({pandas.DataFrame: ['head', 'describe', 'info', 'shape']}) ``` ```python #| export _cfg_py = xdg_config_home() / 'safepyrun' / 'config.py' if _cfg_py.exists(): try: _cfg_ns = {k:v for k,v in globals().items() if not k.startswith('_')} exec(_cfg_py.read_text(), _cfg_ns) # TODO: Need to update this for the new set-data/allow API if 'default_ok_dests' in _cfg_ns: globals()['default_ok_dests'] = _cfg_ns['default_ok_dests'] except Exception as e: warnings.warn(f"Failed to load {_cfg_py}: {e}") ``` -------------------------------- ### Itertools Combinations and Product Example Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/stdlib-allowlist.md Demonstrates the use of `itertools.combinations` to generate unique pairs and `itertools.product` for Cartesian products. ```python from itertools import combinations, product pairs = list(combinations([1, 2, 3], 2)) # [(1, 2), (1, 3), (2, 3)] cartesian = list(product([1, 2], ['a', 'b'])) # [(1, 'a'), (1, 'b'), ...] ``` -------------------------------- ### Pathlib Path Operations Example Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/stdlib-allowlist.md Illustrates reading file content and finding files using `pathlib.Path` methods like `exists`, `read_text`, and `glob`. ```python from pathlib import Path p = Path('/tmp/data.txt') if p.exists(): content = p.read_text() files = list(Path('.').glob('*.py')) ``` -------------------------------- ### Fnmatch Filter Example Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/stdlib-allowlist.md Shows how to use `fnmatch.filter` to find files matching a Unix-style pattern. ```python import fnmatch matches = fnmatch.filter(['file1.py', 'file2.txt', 'test.py'], '*.py') ``` -------------------------------- ### Example Usage of find_var Source: https://github.com/answerdotai/safepyrun/blob/main/nbs/00_core.ipynb Demonstrates how to use the find_var function to retrieve a variable from the call stack. ```python find_var('_test_sentinel') ``` -------------------------------- ### Run a Python script file Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/api-reference-cli.md Example of creating a Python script file and executing it using the safepyrun CLI. The output of the last expression is printed to stdout. ```bash $ cat > script.py << 'EOF' import json data = {'x': 1, 'y': 2} json.dumps(data) EOF $ safepyrun script.py {"x": 1, "y": 2} ``` -------------------------------- ### Python Time Formatting Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/stdlib-allowlist.md Shows how to get the current time, convert it to a time structure, and format it as a string. ```python import time current = time.time() struct = time.localtime(current) formatted = time.strftime('%Y-%m-%d %H:%M:%S', struct) ``` -------------------------------- ### OS Path Basename and Isdir Example Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/stdlib-allowlist.md Demonstrates legacy path operations using `os.path.basename` to extract a filename and `os.path.isdir` to check if a path is a directory. ```python import os.path filename = os.path.basename('/path/to/file.txt') # 'file.txt' is_dir = os.path.isdir('/tmp') ``` -------------------------------- ### Write to Allowed Directory Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/quick-start.md Configure `RunPython` to allow writes to specific directories using `ok_dests`. This example writes to `/tmp`. ```python from safepyrun import RunPython # Allow writes to /tmp python = RunPython(ok_dests=['/tmp']) await python(''' from pathlib import Path Path("/tmp/output.txt").write_text("Hello, World!") ''') ``` -------------------------------- ### Example Usage of Custom Extension Write Policy Source: https://github.com/answerdotai/safepyrun/blob/main/README.md Demonstrates the usage of a custom ExtWritePolicy to allow or block writes based on file extensions. Shows successful writes and correctly blocked attempts. ```python ep = ExtWritePolicy(['.csv', '.json']) ep(Path('/tmp/data.csv'), [], {}, ['/tmp']) try: ep(Path('/tmp/script.sh'), [], {}, ['/tmp']) except PermissionError: print("ExtWritePolicy correctly blocked .sh") ``` -------------------------------- ### Pseudo-Random Number Generation in Python Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/stdlib-allowlist.md Provides examples of generating random integers and sampling items from a list using the `random` module. Ensure the `random` module is imported. ```python import random num = random.randint(1, 100) items = random.sample([1, 2, 3, 4, 5], 3) ``` -------------------------------- ### Custom Pre-Deny Hook for File Operations Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/errors.md This example shows how to implement custom authorization logic using a `pre_deny` hook, specifically allowing file operations only for .csv files. ```python def custom_pre_deny(info): # Allow file operations only for .csv files if info.event == 'open': if info.find('pathlib.Path.write_text'): if str(info.args[0]).endswith('.csv'): return True return None python = RunPython(pre_deny=custom_pre_deny) ``` -------------------------------- ### Disallowed Class and Function Creation Source: https://github.com/answerdotai/safepyrun/blob/main/nbs/index.ipynb These examples demonstrate that creating new classes and functions is explicitly disallowed by `RunPython` and will raise a `PermissionError`. This is a key security feature of the sandbox. ```python with expect_fail(PermissionError): await python('class A: def __init__(self): print("hi")') with expect_fail(PermissionError): await python('def f(): print("hi")') ``` -------------------------------- ### Allowing Specific Write Operations Source: https://github.com/answerdotai/safepyrun/blob/main/nbs/index.ipynb Demonstrates the `allow_write_types` configuration, showing how to permit specific write operations on objects like namespaces or dictionaries within the sandbox. This example attempts to modify an object and access its properties. ```python o = SimpleNamespace(x=1) await python(''' d = {} d["x"] = 1 o.x = 2 d["x"],o.x''') ``` -------------------------------- ### Custom Permission Logic with pre_deny Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/quick-start.md Implement custom permission logic by providing a `pre_deny` function to `RunPython`. This example allows JSON operations everywhere while applying default behavior to others. ```python def pre_deny(info): # Allow json operations everywhere if info.find('json.loads') or info.find('json.dumps'): return True # Default behavior for everything else return None python = RunPython(pre_deny=pre_deny) ``` -------------------------------- ### Configure Default Write Destinations Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/configuration.md Override the default allowed write destinations in the configuration file. This example allows writes to /tmp, /var/tmp, and a custom data directory. ```python # ~/.config/safepyrun/config.py # Allow writes to /tmp, /var/tmp, and a specific data directory default_ok_dests = ('/tmp', '/var/tmp', '/home/user/data') ``` -------------------------------- ### DenyInfo.find() Example Usage Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/api-reference-deny-info.md Demonstrates how to use the find method within a before_deny function to check if specific functions like 'pathlib.Path.write_text' or 'json.loads' were involved in a denied operation. This allows for custom logic or conditional allowance based on the function called. ```python def before_deny(info): # Check if the operation involves a specific function if info.find('pathlib.Path.write_text'): # Allow Path.write_text in certain contexts return True if info.find('json.loads'): # Custom logic for JSON parsing return None # Use default sandbox logic return False # Deny by default ``` -------------------------------- ### Get Safepyrun Version Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/module-overview.md Access the installed version of the safepyrun package. ```python from safepyrun import __version__ ``` -------------------------------- ### Get Current Version Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/module-overview.md Retrieves the current installed version of the safepyrun library using the __version__ attribute. ```python from safepyrun import __version__ # '0.2.1' ``` -------------------------------- ### Custom Pre-Deny Logic for Safepyrun Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/api-reference-deny-info.md Implement custom pre-deny logic to conditionally allow or deny operations. This example shows how to allow specific file operations based on path and permit JSON operations. ```python def custom_pre_deny(info: DenyInfo) -> bool | None: """ Called when sandbox would deny an operation. Return: True: Allow the operation False: Deny the operation None: Use default sandbox logic """ # Example: Allow Path.write_text only for CSV files if info.event == 'open' and info.find('pathlib.Path.write_text'): path = str(info.args[0]) if info.args else '' if path.endswith('.csv'): return True # Allow json operations anywhere if info.find('json.loads') or info.find('json.dumps'): return True return None # Use default logic for other operations python = RunPython(pre_deny=custom_pre_deny) ``` -------------------------------- ### Python HTTP GET Request Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/stdlib-allowlist.md Demonstrates making a read-only HTTP GET request and parsing the JSON response. ```python import httpx response = httpx.get('https://api.example.com/data') data = response.json() ``` -------------------------------- ### Python unicodedata: Get Unicode character information Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/stdlib-allowlist.md Use `unicodedata.name` to get the official name of a Unicode character and `unicodedata.normalize` to normalize its representation. ```python import unicodedata name = unicodedata.name('π') # 'GREEK SMALL LETTER PI' normalized = unicodedata.normalize('NFC', 'café') ``` -------------------------------- ### Allow Network Request with httpx Source: https://github.com/answerdotai/safepyrun/blob/main/nbs/00_core.ipynb Defines a function 'getexample' that uses 'httpx.get' and allows it for execution. This demonstrates how to permit specific network operations. ```python @allow def getexample(): return httpx.get('http://example.org') ``` -------------------------------- ### Get Object Size in Bytes Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/stdlib-allowlist.md Use the sys module to get the size of a Python object in bytes. Note that certain sys functions like exit and path are not available. ```python import sys size = sys.getsizeof([1, 2, 3]) ``` -------------------------------- ### Execute Python Code and Capture Output Source: https://github.com/answerdotai/safepyrun/blob/main/nbs/00_core.ipynb Demonstrates basic execution of Python code and capturing its standard output. Includes a function that emits a warning. ```python def f(): warnings.warn('a warning') ``` ```python %%py print("asdf") f() 1+1 ``` -------------------------------- ### Instantiate and Execute Code with RunPython Source: https://github.com/answerdotai/safepyrun/blob/main/nbs/index.ipynb Demonstrates how to instantiate the `RunPython` class and execute a simple string of Python code. This is the basic usage pattern for the `RunPython` API. ```python python = RunPython() ``` ```python await python('[]') ``` -------------------------------- ### Get sys.monitoring Module Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/internals.md Access the sys.monitoring module, available in Python 3.12+ for efficient instrumentation. ```python mon = sys.monitoring # Imported in core.py:64 ``` -------------------------------- ### Path Joining Source: https://github.com/answerdotai/safepyrun/blob/main/nbs/00_core.ipynb Demonstrates joining multiple path components into a single path string using `os.path.join`. ```python %%py os.path.join('/foo', 'bar', 'baz.py') ``` -------------------------------- ### Creating a Pandas DataFrame Source: https://github.com/answerdotai/safepyrun/blob/main/nbs/00_core.ipynb Initializes a pandas DataFrame with sample data for demonstration purposes. ```python df = pd.DataFrame(data={'col1':[1,1,1,2,2],'col2':['George','Tim','Anna','Bob','Jon']}) ``` -------------------------------- ### Get Source Code of a Function Source: https://github.com/answerdotai/safepyrun/blob/main/nbs/00_core.ipynb Retrieves the source code of a defined function `g` using `inspect.getsource`. ```python def g(): ... ``` ```python %%py inspect.getsource(g) ``` -------------------------------- ### Python SHA256 Hashing Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/stdlib-allowlist.md Shows how to compute the SHA256 hash of a byte string and get its hexadecimal representation. ```python import hashlib hash_obj = hashlib.sha256(b'hello') hex_digest = hash_obj.hexdigest() ``` -------------------------------- ### Heap Operations with heapq Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/stdlib-allowlist.md Illustrates how to use the heapq module for min-heap queue operations, including heapifying a list and popping the smallest element. ```python import heapq heap = [3, 1, 4, 1, 5, 9, 2, 6] heapq.heapify(heap) smallest = heapq.heappop(heap) ``` -------------------------------- ### Using Counter and defaultdict from collections Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/stdlib-allowlist.md Demonstrates the usage of Counter for frequency counting and defaultdict for automatically initializing dictionary values. ```python from collections import Counter, defaultdict counts = Counter(['a', 'b', 'a', 'c', 'a']) # Counter({'a': 3, 'b': 1, 'c': 1}) d = defaultdict(list) d['key'].append(1) # No KeyError ``` -------------------------------- ### Execute Allowed Network Request Source: https://github.com/answerdotai/safepyrun/blob/main/nbs/00_core.ipynb Executes the previously allowed 'getexample()' function, demonstrating a successful network request within the Safepyrun environment. ```python await python('getexample()') ``` -------------------------------- ### Custom Safepyrun Sandbox Configuration Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/configuration.md Demonstrates how to create a custom RunPython sandbox with specific configurations for global namespace, allowed write destinations, banned imports, function definitions, and pre-deny logic. Also shows how to use factory defaults with a single modification. ```python from safepyrun import RunPython, PosAllowPolicy from pathlib import Path # Create a custom sandbox python = RunPython( # Use a specific namespace g=my_globals, # Restrict writes to /tmp and current directory ok_dests=('/tmp', '.'), # Allow importing specific safe modules ban_imports=frozenset({'socket', 'importlib', 'subprocess'}), # Allow function definitions ban_defs=False, # Custom pre-deny logic pre_deny=my_permission_callback ) # Or use factory defaults with just one change python = RunPython(ok_dests=['/tmp']) ``` -------------------------------- ### Accessing exported variables Source: https://github.com/answerdotai/safepyrun/blob/main/README.md Exported symbols are real objects in your namespace. This example shows exporting and then accessing a dictionary. ```python await python('counts_ = {"a": 1, "b": 2}') counts_ ``` -------------------------------- ### Registering with Write Policies Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/api-reference-allow.md Demonstrates how to register a method that performs write operations, applying a specific write policy to control where and how it can be used. This is crucial for security when allowing file system modifications. ```python from pathlib import Path # Allow Path.write_text() only for files in /tmp policy = PosAllowPolicy(0, 'data') # Check position 0 (or keyword 'data') allow({Path: [('write_text', policy)]}) python = RunPython(ok_dests=('/tmp',)) await python("Path('/tmp/test.txt').write_text('data')") # OK ``` -------------------------------- ### Basic Mathematical Functions in Python Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/stdlib-allowlist.md Demonstrates the usage of common mathematical functions like square root and factorial from the `math` module. Ensure the `math` module is imported. ```python import math result = math.sqrt(16) # 4.0 factorial = math.factorial(5) # 120 ``` -------------------------------- ### Built-in Type Operations Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/stdlib-allowlist.md Provides examples of common operations on built-in Python types like lists, strings, and dictionaries. ```python nums = [3, 1, 4, 1, 5] sorted_nums = sorted(nums) text = "hello world" words = text.split() ``` -------------------------------- ### RunPython with Minimal Banned Imports Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/configuration.md Instantiate RunPython with a minimal set of banned imports. This example only bans the 'socket' module. ```python # Minimal bans python = RunPython(ban_imports=frozenset({'socket'})) ``` -------------------------------- ### Inspect Function Signature and Parameters Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/stdlib-allowlist.md Use the inspect module to get the signature of a Python function and print parameter names and their default values. ```python import inspect def my_func(a, b=5): pass sig = inspect.signature(my_func) for param_name, param in sig.parameters.items(): print(f"{param_name}: {param.default}") ``` -------------------------------- ### Background Job Example Source: https://github.com/answerdotai/safepyrun/blob/main/nbs/index.ipynb Defines an asynchronous background job that simulates work by sleeping for a short duration and then appending a status message to a results list. ```python res = [] async def bg_job(): await asyncio.sleep(0.1) res.append('finished') ``` -------------------------------- ### Python IP Address and Network Utilities Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/stdlib-allowlist.md Shows how to create IP address and network objects from strings. ```python from ipaddress import ip_address, ip_network addr = ip_address('192.168.1.1') network = ip_network('10.0.0.0/24') ``` -------------------------------- ### Safepyrun CLI Implementation (cli.py) Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/api-reference-cli.md Alternative CLI entry point, functionally equivalent to the one in core.py, also using the fastcore.script decorator. ```python @call_parse def main(path: Param("Path to script, or '-' for stdin", str, opt=False, nargs='?', default='-')) ``` -------------------------------- ### RunPython with Restricted Write Permissions Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/configuration.md Instantiate RunPython with explicit restrictions on write destinations. This example restricts writes to only the /tmp directory or the current directory. ```python # Restrict to /tmp only python2 = RunPython(ok_dests=('/tmp',)) # Restrict to current directory only python3 = RunPython(ok_dests=('.')) ``` -------------------------------- ### Enable and Use Pandas Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/quick-start.md Enable pandas support using `allow_pandas()` and then use pandas DataFrames within the sandbox for operations like saving to CSV. ```python from safepyrun import allow_pandas, RunPython allow_pandas() python = RunPython(ok_dests=['/tmp']) await python(''' import pandas as pd df = pd.DataFrame({ 'A': [1, 2, 3], 'B': [4, 5, 6] }) df.to_csv('/tmp/data.csv') ''') ``` -------------------------------- ### Run Python code from stdin Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/api-reference-cli.md Example of piping Python code to the safepyrun CLI via standard input. The result of the expression is printed to stdout. ```bash $ echo "sum([1, 2, 3, 4, 5])" | safepyrun 15 ``` -------------------------------- ### Enable and Use Matplotlib Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/quick-start.md Enable matplotlib support using `allow_matplotlib()` and then use it within the sandbox to create and save plots to files. ```python from safepyrun import allow_matplotlib, RunPython allow_matplotlib() python = RunPython(ok_dests=['/tmp']) await python(''' import matplotlib.pyplot as plt plt.plot([1, 2, 3], [1, 4, 9]) plt.savefig('/tmp/plot.png') ''') ``` -------------------------------- ### Define Auditable HTTP GET Function Source: https://github.com/answerdotai/safepyrun/blob/main/nbs/00_core.ipynb Creates an auditable function 'httpget' that calls '_httpget' and emits a 'myapp.httpget' audit event. This allows tracking of HTTP requests. ```python def httpget(url): sys.audit('myapp.httpget', url) return _httpget(url) ``` -------------------------------- ### Import Configuration Functions Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/module-overview.md Imports common configuration functions like allow, allow_pandas, and allow_matplotlib. Use these to configure the execution environment. ```python from safepyrun import allow, allow_pandas, allow_matplotlib ``` -------------------------------- ### Registering Class Methods with a Dictionary Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/api-reference-allow.md Illustrates registering multiple methods for one or more classes using a dictionary. This allows for concise registration of several related functionalities. ```python import numpy as np # Register multiple methods at once allow({ np.ndarray: ['sum', 'mean', 'reshape', 'tolist'], np.linalg: ['norm', 'det'] }) python = RunPython() result = await python('np.array([1,2,3,4]).reshape(2,2).mean()') # 2.5 ``` -------------------------------- ### Call srcfn with empty strings Source: https://github.com/answerdotai/safepyrun/blob/main/nbs/00_core.ipynb This example demonstrates calling the srcfn function twice with empty strings to show how it generates sequential filenames and manages its internal counter. ```python srcfn(''),srcfn('') ``` -------------------------------- ### Define Main CLI Function Source: https://github.com/answerdotai/safepyrun/blob/main/nbs/01_cli.ipynb Defines the main entry point for the CLI tool. It accepts a script path or reads from stdin, executes the code in a sandbox, and prints the result or any errors. ```python #| export @call_parse def main(path: Param("Path to script, or '-' for stdin", str, opt=False, nargs='?', default='-')): """Run a python script file in the safepyrun sandbox""" try: code = sys.stdin.read() if path == '-' else Path(path).read_text() if (r := asyncio.run(RunPython()(code))) is not None: print(r) return 0 except Exception as e: print(f"Error: {e}", file=sys.stderr) return 1 ``` -------------------------------- ### RunPython with Custom Banned Imports Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/configuration.md Configure RunPython to ban additional modules beyond the defaults. This example bans 'subprocess' and 'os.system' in addition to the standard banned modules. ```python # Ban additional modules python = RunPython( ban_imports=frozenset({ 'socket', 'importlib', 'safepyrun', 'fastaudit', 'subprocess', # Also ban subprocess 'os.system' # More fine-grained (though 'os' itself isn't banned) }) ) ``` -------------------------------- ### Execute code with print output and return value Source: https://github.com/answerdotai/safepyrun/blob/main/README.md Demonstrates capturing both standard output and the final expression's result. ```python await python('print("hello"); 1+1') ``` -------------------------------- ### Python Struct Packing and Unpacking Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/stdlib-allowlist.md Shows how to pack two unsigned short integers into bytes and unpack them. ```python import struct packed = struct.pack('HH', 1000, 2000) unpacked = struct.unpack('HH', packed) ``` -------------------------------- ### Execute Python Code with RunPython Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/api-reference-runpython.md Executes a string of Python code within the sandboxed environment. The result of the execution is returned. This example demonstrates a simple arithmetic operation. ```python result = await python('1 + 1') ``` -------------------------------- ### Python Datetime Operations Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/stdlib-allowlist.md Demonstrates creating datetime objects, calculating future dates using timedelta, and formatting dates. ```python from datetime import datetime, timedelta now = datetime.now() tomorrow = now + timedelta(days=1) formatted = now.strftime('%Y-%m-%d') ``` -------------------------------- ### Safepyrun CLI Error Handling (Division by Zero) Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/api-reference-cli.md Example showing how safepyrun handles runtime errors like division by zero. Error messages are printed to stderr. ```bash $ echo "1 / 0" | safepyrun 2>&1 Error: division by zero ``` -------------------------------- ### Registering a Function with allow() Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/api-reference-allow.md Demonstrates how to register a function for use in the sandbox, either as a decorator or by direct call. The registered function can then be invoked within the sandboxed Python environment. ```python def my_function(x): return x * 2 # As a decorator @allow def double(x): return x * 2 # Or called directly allow(my_function) python = RunPython() await python('my_function(21)') # 42 ``` -------------------------------- ### Define HTTP GET Helper Function Source: https://github.com/answerdotai/safepyrun/blob/main/nbs/00_core.ipynb Defines a helper function '_httpget' that wraps 'httpx.get'. This function is intended to be used with Safepyrun's auditing and access control mechanisms. ```python @allow def _httpget(url): return httpx.get(url) ``` -------------------------------- ### Configure Safepyrun with Python Source: https://github.com/answerdotai/safepyrun/blob/main/README.md Extend safepyrun's sandbox allowlists by creating a Python configuration file. This file is executed at import time and has access to safepyrun.core globals. ```python import pandas # Add pandas tools allow({pandas.DataFrame: ['head', 'describe', 'info', 'shape']}) # Allow pandas to write CSV to ~/data allow({pandas.DataFrame: [('to_csv', PosAllowPolicy(0, 'path_or_buf'))]}) ``` -------------------------------- ### Block Network Request with httpx Source: https://github.com/answerdotai/safepyrun/blob/main/nbs/00_core.ipynb Attempts to make an HTTP GET request using 'httpx' within Safepyrun, which is expected to fail with a PermissionError if network access is not explicitly allowed. ```python with expect_fail(PermissionError): await python('httpx.get("http://example.org")') ``` -------------------------------- ### Setting up IPython Extension for Safepyrun Source: https://github.com/answerdotai/safepyrun/blob/main/nbs/00_core.ipynb Configures the IPython environment to use safepyrun. It makes the `python` executor and `allow` function available in the user's namespace and creates a custom IPython magic command. ```python #| export def load_ipython_extension(ip): ns = ip.user_ns ns['python'] = python = RunPython(g=ns) ns['allow'] = allow create_python_magic(ip, python) ``` -------------------------------- ### Get Live Policy Snapshot Source: https://github.com/answerdotai/safepyrun/blob/main/nbs/00_core.ipynb Captures a frozen snapshot of the mutable host policy, including allowed imports and monitoring settings. This is used to detect policy changes during execution. ```python #| export def _live_policy(): """Frozen fingerprint of mutable host policy that AI code must not change mid-call.""" return (frozenset(allow_imports), freeze_mon_policy(mon_disable_policy)) ``` -------------------------------- ### Python Zlib Compression and Decompression Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/stdlib-allowlist.md Illustrates compressing a byte string and decompressing it using zlib. ```python import zlib compressed = zlib.compress(b'hello' * 100) decompressed = zlib.decompress(compressed) ``` -------------------------------- ### Async support in SafePyRun Source: https://github.com/answerdotai/safepyrun/blob/main/README.md SafePyRun supports async operations like await, async for, and async with. This example demonstrates running an async function and gathering results using asyncio. ```python await python(''' import asyncio async def fetch(n): return n * 10 await asyncio.gather(fetch(1), fetch(2), fetch(3)) ''') ``` -------------------------------- ### Execute Python Code via Command Line Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/module-overview.md Shows how to execute Python code from the command line, either by passing a script file or piping code directly to the safepyrun command. ```bash safepyrun script.py ``` ```bash echo "1 + 1" | safepyrun ``` -------------------------------- ### Using Third-Party Libraries (Pandas) Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/README.md Integrate and use third-party libraries like Pandas within the sandbox. Ensure the library is allowed using functions like `allow_pandas()` and configure file operation permissions. ```python from safepyrun import allow_pandas, RunPython import asyncio allow_pandas() python = RunPython(ok_dests=['/tmp']) asyncio.run(python(''' import pandas as pd df = pd.DataFrame({'A': [1, 2, 3]}) df.to_csv('/tmp/data.csv') ''')) ``` -------------------------------- ### Safepyrun Python API Customization Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/api-reference-cli.md Example of using the safepyrun Python API for advanced customization, including setting allowed destinations, disabling definition bans, and unbanning imports. ```python from safepyrun import RunPython, allow import asyncio # Customize the sandbox python = RunPython( ok_dests=['/tmp'], ban_defs=False, ban_imports=frozenset() ) # Register custom functions allow('my_module.my_function') # Execute code result = asyncio.run(python(code_string)) ``` -------------------------------- ### Registering Functions with Allowlist Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/internals.md Demonstrates the structure of the `__pytools__` dictionary used for registering functions and modules. This structure allows for granular control over access. ```python __pytools__ = { 'module.name': {...}, # Full module access 'module.ClassName': {...}, # Class methods 'module.ClassName.method': {...}, # Specific method ... } ``` -------------------------------- ### Checking Instance Type within Sandbox Source: https://github.com/answerdotai/safepyrun/blob/main/nbs/index.ipynb These examples verify that `isinstance` checks work correctly within the '%%py' cell magic, even for custom classes defined outside the sandbox. ```python class C: ... c = C() ``` ```python %%py isinstance(C, type) ``` ```python %%py isinstance(c, type) ``` -------------------------------- ### Convert RGB to HLS Color Space Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/stdlib-allowlist.md Perform color space conversions using the `colorsys` module. This example shows converting an RGB color (red) to the HLS color space. ```python import colorsys h, l, s = colorsys.rgb_to_hls(1.0, 0.0, 0.0) # Convert red ``` -------------------------------- ### Defining a Command-Line Interface Script Source: https://github.com/answerdotai/safepyrun/blob/main/nbs/00_core.ipynb Creates a command-line interface (CLI) tool using `fastcore.script`. It accepts a file path as an argument, reads the script content from stdin or a file, and executes it within the safepyrun sandbox, printing any output or errors. ```python #| export import sys import asyncio from pathlib import Path from safepyrun import RunPython @call_parse def cli(path: Param("Path to script, or '-' for stdin", str, opt=False, nargs='?', default='-')): """Run a python script file in the safepyrun sandbox""" try: code = sys.stdin.read() if path == '-' else Path(path).read_text() if (r := asyncio.run(RunPython()(code))) is not None: print(r) except Exception as e: return not print(f"Error: {e}", file=sys.stderr) ``` -------------------------------- ### Run Python Code with Globals and Await Source: https://github.com/answerdotai/safepyrun/blob/main/nbs/00_core.ipynb Demonstrates executing Python code that includes variable assignments and a generator expression, ensuring that variables defined in earlier statements are accessible within the generator. ```python await __run_python( "rnd_var_name_123 = 10\n" "sum(x + rnd_var_name_123 for x in [1, 2])", g={} ) ``` -------------------------------- ### Execute Simple Python Expression Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/api-reference-runpython.md Demonstrates executing a simple mathematical expression using the `RunPython` instance. The result of the expression is returned. ```python python = RunPython() # Simple expressions result = await python('2 ** 10') # 1024 ``` -------------------------------- ### Safepyrun CLI Error Handling (Disallowed Import) Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/api-reference-cli.md Example demonstrating safepyrun's security feature of blocking disallowed imports, such as the 'socket' module. Error messages are printed to stderr. ```bash $ echo "import socket" | safepyrun 2>&1 Error: import 'socket' not allowed ``` -------------------------------- ### Define and allow a custom function Source: https://github.com/answerdotai/safepyrun/blob/main/README.md Registers a user-defined function 'greet' to be callable within the sandbox. ```python def greet(name): return f"Hello, {name}!" allow(greet) await python('greet("World")') ``` -------------------------------- ### PosAllowPolicy: Allow write to specific positional argument Source: https://github.com/answerdotai/safepyrun/blob/main/nbs/index.ipynb Demonstrates the `PosAllowPolicy` which checks a specific positional or keyword argument against allowed destinations. This example allows writing to '/tmp' (position 1) but blocks '/root/bad'. ```python pp = PosAllowPolicy(1, 'dst') pp(None, ['src', '/tmp/ok'], {}, dict(ok_dests=['/tmp'])) try: pp(None, ['src', '/root/bad'], {}, dict(ok_dests=['/tmp'])) except PermissionError: print("PosAllowPolicy correctly blocked /root/bad") ``` -------------------------------- ### Instantiate Default RunPython Sandbox Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/api-reference-runpython.md Creates a RunPython instance with default security settings. This is suitable for general-purpose sandboxing where standard restrictions are sufficient. ```python python = RunPython() ``` -------------------------------- ### Executing Python code with a custom global namespace Source: https://github.com/answerdotai/safepyrun/blob/main/nbs/00_core.ipynb Shows how to execute Python code within a provided global namespace (`g`). The example verifies that a variable `keep` is correctly set in the namespace, while other variables are not. ```python g = {} await _run_python("python = 'trojan'\nallow = 'trojan'\nkeep = 42", g=g) test_eq(g['keep'], 42) assert 'python' not in g and 'allow' not in g ``` -------------------------------- ### Class Definition and Instantiation Check Source: https://github.com/answerdotai/safepyrun/blob/main/nbs/00_core.ipynb Shows the definition of a simple class `C` and checks its type and instance type using `isinstance`. ```python class C: ... ``` ```python %%py isinstance(C, type) ``` ```python %%py isinstance(c, type) ``` -------------------------------- ### Allow a mix of functions and module methods Source: https://github.com/answerdotai/safepyrun/blob/main/README.md Demonstrates registering a standalone function and multiple methods from a module in a single call. ```python allow('my_func', {np.linalg: ['norm', 'det']}) ``` -------------------------------- ### Importing Fastcore Script Utilities Source: https://github.com/answerdotai/safepyrun/blob/main/nbs/00_core.ipynb Imports necessary components from the fastcore library for creating command-line interfaces. ```python #| export from fastcore.script import call_parse, Param ``` -------------------------------- ### Handling User Code Exceptions Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/errors.md This example shows how Safepyrun catches and re-raises exceptions originating from the user's code, cleaning the traceback to point to the user's source file (e.g., ''). It preserves the original exception context. ```python python = RunPython() try: await python('1 / 0') except ZeroDivisionError as e: print(e) # "division by zero" print(e.__traceback__.tb_frame.f_code.co_filename) # "" ``` -------------------------------- ### Execute Python Code via API Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/module-overview.md Demonstrates the primary Python API usage for executing code. It initializes RunPython and uses asyncio to run a simple expression. ```python from safepyrun import RunPython, allow import asyncio python = RunPython() result = asyncio.run(python('1 + 1')) ``` -------------------------------- ### IPython Extension Usage Source: https://github.com/answerdotai/safepyrun/blob/main/_autodocs/module-overview.md Illustrates how to load and use the safepyrun IPython extension. It shows loading the extension and executing code using magic commands. ```ipython %load_ext safepyrun await python('1 + 1') ``` ```ipython %%py x = [1, 2, 3] x ```