Skip to content

Guide to create a new Athon tool

Antonio Fin edited this page Nov 10, 2024 · 1 revision

Create Your First Tool

In this section, we guide you through creating and using your tool, starting from a "HelloWorld" template. This step-by-step process covers setting up your project repository, developing the source code, configuring your tool, writing tests, and preparing the project for distribution.

Step 1: Initialize Your Project Repository

To begin building your tool, create a project repository that mirrors the structure provided in the template. Below is an overview of the directory and file structure you should have:

Top-Level Files and Directories:

  • logs/: Directory for storing log files.
  • prompts/: Directory for storing prompt files, which may be used for command-line interfaces or logging.
  • src/: Source directory containing the main Python code.
  • tests/: Directory containing test cases for your code.
  • Dockerfile: A file containing all the commands needed to assemble a Docker image.
  • LICENSE: The license file specifying how others can use your project.
  • Makefile: A file containing a set of directives used by the make build automation tool.
  • README.md: A Markdown file with a description of the project, its usage, and other documentation.
  • setup.py: A Python script where you define the details about your package, such as its name, version, and dependencies.

Source Directory Details:

  • src/__init__.py: An empty file that indicates this directory is a Python package.
  • src/tool.py: The main module of your tool.

Test Directory Details:

  • tests/test_function.py: Test cases for individual functions.
  • tests/test_tool.py: Test cases for the tool's functionality.

Step 2: Create the Source Code

With the repository structure in place, the next step is to develop the source code for your tool.

Using the Template Code

The hello_world template is a good starting point. This example demonstrates how to integrate the AthonTool decorator with your tool’s logic.

Developing in src/tool.py

Place the core logic of your tool within the src/tool.py file. Here’s an example of how to implement the hello_world function and apply the AthonTool decorator:

# src/tool.py

from athon.system import AthonTool

# Example configuration and logger (these should be defined according to your tool's requirements)
config = {
    "greetings": "Hello World! Welcome, "
}
logger = None  # Replace with a properly configured logger

@AthonTool(config, logger)
def hello_world(query: str) -> str:
    """
    Example function that greets the user.

    Args:
        query (str): The name of the user or a query string.

    Returns:
        str: A greeting message.
    """
    greeting_message = f"{config['greetings']} {query}!!!"
    return greeting_message.capitalize()

Customizing Your Tool

Replace the placeholder code with your specific configuration and logging setup. The config dictionary should include settings relevant to your tool, and logger should be an appropriately configured logger instance.

Integration

Once your hello_world function (or its equivalent) is implemented in src/tool.py, integrate it with other components of your application as needed.

Step 3: Create the Configuration

Next, update the configuration file for your tool to match its specific requirements. This is typically done in a YAML file, which allows you to define the various parameters your application will use at runtime.

Configuring config.yaml

  1. Webapp Settings: Define the IP address, port, and SSL certificate details for your tool’s web interface.
  2. Tool Settings: Specify the name of your tool, the main function to invoke, and the arguments it accepts.
  3. Function Settings: Set default values, such as the greeting message or other configurations your tool requires.
  4. Prompts: Specify the location of prompt templates and any environment-specific settings.
  5. Logger: Configure logging details, including file locations, log levels, and formats.

Example config.yaml for HelloWorld

Here’s an example of how your config.yaml might look for a HelloWorld tool:

webapp:
  ip: 127.0.0.1
  port: 5001
  ssh_cert: adhoc

tool:
  name: HelloWorld
  function: $FUNCTION(hello_world)
  arguments:
    - name: user_name
      type: str
      description: $PROMPT(field_user_name_description)
      default: null
  description: $PROMPT(tool_description)
  return_direct: true
  interface:
    fields:
      - name: user_name
        label: "Insert the user name"
        type: string

function:
  greetings: "Hello World! Welcome,"

prompts:
  type: JinjaTemplate
  environment: prompts/
  templates:
    tool_description: tool_description.txt
    field_user_name_description: field_user_name_description.txt

logger:
  name: HELLO_WORLD
  log_file: tools/hello_world/logs/hello_world.log
  level: DEBUG

Customization Tips

  • Webapp: Adjust the webapp section based on your deployment method. If your tool isn’t web-based, this section can be modified or omitted.
  • Tool: The name should uniquely identify your tool, and function should point to the callable function in your source code.
  • Function: Update the greetings or other relevant fields according to your tool’s functionality.
  • Prompts: Ensure the paths in the prompts section correspond to where your prompt templates are stored in your repository.
  • Logger: Adjust the logger settings to reflect your logging preferences and ensure the file paths align with your repository structure.

Step 4: Set Up setup.py

To make your tool installable as a package, you’ll need to create a setup.py script. This script manages the distribution and installation of your package.

Defining Metadata and Dependencies

  1. Tool Description: Provide a clear and informative description highlighting your tool’s features and benefits.
  2. Package Metadata: Include necessary details like the package name, version, author information, and a description.
  3. Dependencies: List all dependencies your tool requires for proper functionality.

Example setup.py Script

Here’s a sample setup.py script that you can adapt to your tool’s needs:

from setuptools import setup, find_packages

# Replace this description with one tailored to your tool
TOOL_DESCRIPTION = """
Your Tool is a cutting-edge application designed to perform [main functionality]. 
It simplifies the process of [use case] by [how it improves the process], ensuring 
[benefits such as efficiency, accuracy, etc.]. Designed with [target audience] in 
mind, Your Tool offers a seamless and intuitive experience.
"""

setup(
    name='your_tool_name',
    version='1.0.0',
    author='Your Name',
    author_email='your_email@example.com',
    description='A brief description of your tool',
    long_description=TOOL_DESCRIPTION,
    long_description_content_type='text/plain',
    url='https://github.com/your_github/your_tool_repository',
    packages=find_packages(exclude=['tests*']),
    install_requires=[
        # List your dependencies here, for example:
        'some_dependency',
        'another_dependency',
    ],
    classifiers=[
        # Adjust classifiers to match your project's needs
        'Development Status :: 4 - Beta',
        'Intended Audience :: Developers',
        'Topic :: Software Development :: Build Tools',
        'License :: OSI Approved :: MIT License',
        'Programming Language :: Python :: 3',
    ],
    keywords='your_tool keywords',
    python_requires='>=3.6',
    entry_points={
        # This creates a command-line tool accessible from anywhere
        'console_scripts': ['your_tool=your_package.your_module:main_function']
    },
)

Customization Notes

  • Replace placeholders like your_tool_name, Your Name, and your_email@example.com with actual data relevant to your tool.
  • Modify the install_requires list to include all necessary packages.
  • Ensure the classifiers accurately reflect the development stage, intended audience, and environment of your tool.
  • Use entry_points to define a command-line interface if applicable.

Step 5: Test Your Tool

Testing is crucial to ensure your tool’s reliability and quality. Write separate tests for the business logic and any interfaces, such as REST APIs or local function interfaces. Below are examples adapted for a hypothetical HelloWorld tool. Customize these tests based on your tool’s specific requirements.

Testing the Function Logic (test_function.py)

Here’s how you might test the business logic of the hello_world function in the HelloWorld tool:

# tests/test_function.py

from src.tool import hello_world

def test_hello_world_greeting():
    """
    Test the hello_world function to ensure it returns the correct greeting.

    This test verifies that the hello_world function processes the input name 
    and returns a greeting message that contains the name and the predefined 
    greeting message.
    """
    user_name = "Alice"
    expected_greeting = "Hello World! Welcome, Alice!!!"
    greeting = hello_world(user_name)
    
    # Assert that the greeting is as expected
    assert greeting == expected_greeting.capitalize()

Testing the Tool’s Interface (test_tool.py)

Next, write tests for any REST APIs or local functions that expose your tool’s functionality. Here’s a generalized example:

# tests/test_tool.py

import pytest
from src.tool import app  # Assuming 'app' is your Flask app instance

@pytest.fixture
def client():
    """
    Pytest fixture to create a test client for the tool's Flask application.

    The client is used to simulate HTTP requests to the application during testing.
    """
    app.config['TESTING'] = True
    with app.test_client() as testing_client:
        yield testing_client

def test_hello_world_endpoint(client):
    """
    Test the '/hello_world' endpoint to ensure it returns the correct greeting.

    The test verifies that the endpoint correctly processes a GET request with a name 
    parameter and that the response contains the expected greeting message.
    """
    user_name = "Alice"
    response = client.get(f'/hello_world?name={user_name}')
    
    # Check the response status code and content
    assert response.status_code == 200
    assert response.data.decode('utf-8') == "Hello World! Welcome, Alice!!!".capitalize()

# Additional tests for different scenarios can be added here

Customize these examples by replacing placeholders like Alice and the endpoint /hello_world with specifics relevant to your tool.

Continue writing tests for all aspects of your tool’s functionality. You can then use a Continuous Integration (CI) system to automate test execution.

Step 6: Create Package Files

When preparing your tool for distribution, it’s essential to include specific files that make up the package. These include the license, Dockerfile, Makefile, and README. Below are adapted versions for the HelloWorld tool.

License (LICENSE)

# PROPRIETARY SOFTWARE LICENSE AGREEMENT

© 2024 Your Company Name. All rights reserved.

NOTICE: All information contained herein is, and remains the property of Your Company Name and its suppliers, if any. The intellectual and technical concepts contained herein are proprietary to Your Company Name and its suppliers and may be covered by U.S. and Foreign Patents, patents in process, and are protected by trade secret or copyright law.

This work is confidential and is intended solely for the use of Your Company personnel and authorized collaborators. Any duplication, reproduction, distribution, or disclosure of this work in any form, to any third party, is expressly forbidden without prior written permission from Your Company.

USAGE: The code and associated documentation are available to be used by employees and contractors of Your Company within the scope of their work assignments. No other use is permitted without explicit approval from Your Company.

NO WARRANTIES: The code is provided "as is" without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and non-infringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the code or the use or other dealings in the code.

RESTRICTIONS: The recipient of the software may not reverse engineer, decompile, or disassemble the Software, except and only to the extent that such activity is expressly permitted by applicable law notwithstanding this limitation.

Dockerfile

# Use an official Python runtime as a parent image
FROM python:3.11-slim

# Set the working directory in the container
WORKDIR /usr/src/app

# Copy the current directory contents into the container at /usr/src/app
COPY . .

# Install the package and its dependencies
RUN pip install .

# Make port available to the world outside this container
EXPOSE 5001

# Run main.py when the container launches
CMD ["python", "main.py"]

Makefile

.PHONY: install develop run test clean

# Install the package
install:
	python setup.py install

# Install the package in development mode
develop:
	python setup.py develop

# Run the application
run:
	python main.py

# Run tests with pytest or another test runner
test:
	pytest

# Clean up the project directory (e.g., remove build artifacts)
clean:
	python setup.py clean
	find . -type f -name '*.pyc' -delete
	find . -type d -name '__pycache__' -delete
	rm -rf build dist .egg *.egg-info

README.md

# HelloWorld

## Description

The HelloWorld tool provides a simple greeting to users. It utilizes user input to generate a personalized "Hello World" message, demonstrating the basic structure and execution of a Python-based command-line application.

## Features

- Personalizes the greeting with the user's name.
- Demonstrates the classic "Hello World" program with an additional twist.
- Easy to use and set up.

## Requirements

- Python 3.11
- Additional Python libraries as specified in `setup.py`

## Installation

To set up the project environment to run the HelloWorld tool, follow these steps:

```bash
# Clone the repository
git clone https://github.com/your-username/hello-world.git
cd hello-world

# Install required Python packages
pip install .

Replace the placeholders such as the repository URL with the actual information for your HelloWorld tool.