Skip to main content

A Python package for dynamic function and method handling with LLM support.

Project description

DynamicFunctioneer

Auto-generate and improve Python methods with decorators powered by LLMs.

Prerequisites

A version of Python 3.8 or higher is required.

Before proceeding, install uv to manage the virtual environment and dependencies:

For macOS and Linux:

curl -LsSf https://astral.sh/uv/install.sh | sh

For Windows:

powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

After installing, ensure uv is accessible by verifying the version:

uv --version

If uv is not recognized, ensure the installation path (e.g., ~/.local/bin on macOS/Linux or %USERPROFILE%\.local\bin on Windows) is added to your system's PATH environment variable.

Installation

Clone the repository:

git clone https://github.com/eramireztorres/DynamicFunctioneer.git

Navigate to the directory:

cd DynamicFunctioneer

Create virtual environment

You can create and manage the environment using uv:

uv venv

After creating the environment, activate it:

  • Linux/Mac: source .venv/bin/activate
  • Windows: .venv\Scripts\activate

Make sure to activate this environment whenever working with Gpt4CLI.

Install the package:

uv sync

Export the API keys of your models

OpenAI Models

For OpenAI models, export your API key as an environment variable:

Linux or macOS:

export OPENAI_API_KEY='your_openai_api_key_here'

Or in windows:

setx OPENAI_API_KEY "your_openai_api_key_here"

Other Models via OpenRouter

To use Llama, Gemini or models with OpenRouter, follow these steps:

  1. Visit OpenRouter and log in or create an account.
  2. Navigate to the API keys section in your account dashboard and generate a new API key.
  3. Export the API key as an environment variable:
    • For Linux or macOS:
      export OPENROUTER_API_KEY='your_openrouter_api_key_here'
      
    • For Windows:
      setx OPENROUTER_API_KEY "your_openrouter_api_key_here"
      

Overview

@dynamic_function is a Python decorator designed to enhance the flexibility and robustness of your functions and methods by dynamically generating, testing, and improving their implementation. Powered by large language models (LLMs), this decorator enables seamless integration of dynamic logic into your codebase, providing:

  • Automatic Implementation: Generates function or method code dynamically based on provided descriptions and examples.
  • Error Handling: Automatically detects and fixes runtime errors using iterative retries and LLM-based suggestions.
  • Unit Testing Integration: Optionally generates and executes unit tests for the dynamic code to ensure reliability.
  • Customization: Allows developers to configure models, retries, testing, and other parameters to suit their specific requirements.

By leveraging @dynamic_function, developers can prototype faster, maintain cleaner code, and handle edge cases with minimal manual intervention.

@dynamic_function Decorator

The @dynamic_function decorator dynamically generates, tests, and improves the implementation of functions or methods using the power of large language models (LLMs). It integrates features like automatic code generation, runtime error fixing, and optional unit testing to provide a highly flexible and automated development workflow.

Arguments

  • model (str, default="gpt-4o")
    Specifies the LLM to use for generating the function or method code.

  • prompt (str, optional)
    A custom prompt to guide the LLM for generating code. If None, a default prompt is used.

  • dynamic_file (str, optional)
    Path to the file where the dynamically generated function/method code will be stored. Defaults to a file in the same directory as the decorated function or method.

  • dynamic_test_file (str, optional)
    Path to the file where generated unit test code will be stored, if unit testing is enabled.

  • extra_info (str, optional)
    Additional information or examples to provide context to the LLM for code generation.

  • fix_dynamically (bool, default=True)
    If True, the decorator attempts to fix runtime errors dynamically by generating corrected code using the LLM.

  • error_trials (int, default=3)
    The number of attempts the LLM should make to fix runtime errors.

  • error_model (str, default="gpt-4o")
    The LLM model to use for generating fixes for runtime errors.

  • error_prompt (str, optional)
    A custom prompt to guide the LLM for fixing runtime errors. If None, a default error-fixing prompt is used.

  • hs_condition (callable, optional)
    A condition that, when met, triggers hot-swapping of the function or method with a new dynamically generated version.

  • hs_model (str, default="gpt-4o")
    The LLM model to use for hot-swapping logic when the hs_condition is met.

  • hs_prompt (str, optional)
    A custom prompt to guide the LLM for hot-swapping the function or method.

  • execution_context (dict, optional)
    A dictionary of additional context or variables required during code execution or testing.

  • keep_ok_version (bool, default=True)
    If True, retains the last known working version of the dynamically generated code before attempting any fixes or updates.

  • unit_test (bool, default=False)
    (Only for functions) If True, the decorator generates and executes unit tests for the dynamic code. Unit testing is skipped if set to False.

Usage Example: Dynamic function

@dynamic_function()
def calculate_average(numbers):
    """
    Calculates the average of a list of numbers.

    Args:
        numbers (list of float): A list of numeric values.

    Returns:
        float: The average of the list.

    Raises:
        ValueError: If the list is empty or contains invalid values.
    """
    pass

Usage Example: Dynamic Methods in a Class 1

The @dynamic_function decorator can be applied to methods within a class to dynamically generate, test, and fix their implementation.

from dynamic_functioneer.dynamic_decorator import dynamic_function

class TaskManager:
    """
    A class to represent a task management system.
    """

    def __init__(self):
        """
        Initializes the task manager with an empty task dictionary.
        """
        self.tasks = {}

    @dynamic_function(
        model="meta-llama/llama-3.2-3b-instruct:free",
        extra_info="Adds a new task with a given priority. Updates priority if the task already exists.",
        error_model="meta-llama/llama-3.2-3b-instruct:free"
    )
    def add_task(self, task_name, priority):
        """
        Adds or updates a task in the task list.

        Args:
            task_name (str): The name of the task.
            priority (int): The priority level of the task.

        Returns:
            str: Confirmation message about the added or updated task.
        """
        pass

    @dynamic_function(
        model="meta-llama/llama-3.2-3b-instruct:free",
        extra_info="Retrieves the priority of a given task. Raises an error if the task does not exist.",
        error_model="meta-llama/llama-3.2-3b-instruct:free"
    )
    def get_task_priority(self, task_name):
        """
        Retrieves the priority of a specified task.

        Args:
            task_name (str): The name of the task.

        Returns:
            int: The priority level of the task.

        Raises:
            KeyError: If the task does not exist.
        """
        pass


# Example Usage
if __name__ == "__main__":
    manager = TaskManager()

    # Add tasks
    print(manager.add_task("Finish report", 1))
    print(manager.add_task("Buy groceries", 2))

    # Update an existing task
    print(manager.add_task("Finish report", 3))

    # Retrieve task priorities
    print(manager.get_task_priority("Finish report"))  # Output: 3
    print(manager.get_task_priority("Buy groceries"))  # Output: 2

Usage Example: Dynamic Methods in a Class 2

Example using different models for creating code and fix errors.

from dynamic_functioneer.dynamic_decorator import dynamic_function

class StudentGrades:
    """
    A class to manage student grades in a course.
    """

    def __init__(self):
        """
        Initializes the StudentGrades class with an empty dictionary for student records.
        """
        self.grades = {}

    @dynamic_function(
        model="meta-llama/llama-3.2-1b-instruct:free",
        extra_info="Adds or updates a student's grade for a specific course.",
        error_model="chatgpt-4o-latest"
    )

    def add_grade(self, student_name, course_name, grade):
        """
        Adds or updates a student's grade for a specific course.

        Args:
            student_name (str): The name of the student.
            course_name (str): The name of the course.
            grade (float): The grade to assign to the student for the course.

        Returns:
            str: Confirmation message about the added or updated grade.

        Examples:
            >>> grades = StudentGrades()
            >>> grades.add_grade("Alice", "Math", 95.0)
            'Added grade for Alice in Math with grade 95.0'

            >>> grades.add_grade("Alice", "Math", 98.0)
            'Updated grade for Alice in Math to 98.0'

            >>> grades.grades
            {'Alice': {'Math': 98.0}}
        """

        pass


    @dynamic_function(
        model="gpt-4o-mini",
        extra_info="Retrieves the grade for a student in a specific course. Raises an error if the student or course is not found.",
        error_model="chatgpt-4o-latest"
    )

    def get_grade(self, student_name, course_name):
        """
        Retrieves the grade for a specific course.

        Args:
            student_name (str): The name of the student.
            course_name (str): The name of the course.

        Returns:
            float: The grade for the course.

        Raises:
            KeyError: If the student or course does not exist.

        Examples:
            >>> grades = StudentGrades()
            >>> grades.add_grade("Alice", "Math", 95.0)
            >>> grades.get_grade("Alice", "Math")
            95.0

            >>> grades.get_grade("Bob", "Math")
            Traceback (most recent call last):
                ...
            KeyError: "Student 'Bob' not found."

            >>> grades.get_grade("Alice", "Science")
            Traceback (most recent call last):
                ...
            KeyError: "Course 'Science' not found for student 'Alice'."
        """

        pass


# Example Usage
if __name__ == "__main__":
    grades = StudentGrades()

    # Add grades
    print(grades.add_grade("Alice", "Math", 95.0))
    print(grades.add_grade("Bob", "Math", 88.5))
    print(grades.add_grade("Alice", "Science", 89.0))

    # # Update a grade
    print(grades.add_grade("Alice", "Math", 98.0))  # Should update the Math grade for Alice

    # # Retrieve grades
    print(f"Alice's Math grade: {grades.get_grade('Alice', 'Math')}")  # Output: 98.0
    print(f"Bob's Math grade: {grades.get_grade('Bob', 'Math')}")      # Output: 88.5
    print(f"Alice's Science grade: {grades.get_grade('Alice', 'Science')}")  # Output: 89.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dynamic_functioneer-0.1.0.tar.gz (52.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dynamic_functioneer-0.1.0-py3-none-any.whl (71.5 kB view details)

Uploaded Python 3

File details

Details for the file dynamic_functioneer-0.1.0.tar.gz.

File metadata

  • Download URL: dynamic_functioneer-0.1.0.tar.gz
  • Upload date:
  • Size: 52.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.13

File hashes

Hashes for dynamic_functioneer-0.1.0.tar.gz
Algorithm Hash digest
SHA256 6ca5cb09894480f3a6677eb0c759e7667cdd1df9447db1374c7996c6f2e40835
MD5 3a998726e4cc6f432082be92a295d3d6
BLAKE2b-256 0a45bc55822184ab442a0a23deea5389e1984762febd8124c97cc32793de9f83

See more details on using hashes here.

File details

Details for the file dynamic_functioneer-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for dynamic_functioneer-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a9e920d7247f57e0b65cae3b1bed7ad70d99dcf5ea4140b113c438a2fbdb25d4
MD5 994b8e0287e21c0eb64fd928d627588f
BLAKE2b-256 c46d183fc082c78d692c4dac624aca6195344f3656c03f7392ac868a15f159b8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page