Skip to content

Image Profiles

Kubiya SDK provides predefined Docker image profiles to simplify tool development. These profiles include common environments and dependencies for different types of tools.

Using Image Profiles

Image profiles can be used with the @kubiya.tool decorator:

Python
from kubiya_sdk import kubiya

@kubiya.tool(
    description="Analyze data in a Pandas DataFrame",
    image=kubiya.Image.Python.DATA_SCIENCE
)
def analyze_dataset(url: str):
    import pandas as pd

    df = pd.read_csv(url)
    return {
        "shape": df.shape,
        "columns": list(df.columns),
        "summary": df.describe().to_dict()
    }

Available Profiles

Python Profiles

Python.BASE

A minimal Python 3.12 environment:

Python
@kubiya.tool(image=kubiya.Image.Python.BASE)
def my_python_tool(arg: str):
    # Basic Python environment
    return {"result": arg}

This profile uses: - python:3.12-slim Docker image - No additional packages

Python.DATA_SCIENCE

A Python environment with common data science libraries:

Python
@kubiya.tool(image=kubiya.Image.Python.DATA_SCIENCE)
def analyze_data(data: list):
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    from sklearn.cluster import KMeans

    # Convert input data to numpy array
    data_array = np.array(data)

    # Perform k-means clustering
    kmeans = KMeans(n_clusters=3, random_state=0).fit(data_array)

    return {
        "centroids": kmeans.cluster_centers_.tolist(),
        "labels": kmeans.labels_.tolist()
    }

This profile includes: - python:3.12-slim Docker image - numpy, pandas, matplotlib, scikit-learn packages - An optimized build process using uv package manager

Python.WEB

A Python environment for web development:

Python
@kubiya.tool(image=kubiya.Image.Python.WEB)
def serve_api_endpoint(data: dict):
    from fastapi import FastAPI
    import uvicorn
    import requests
    import json
    import os

    # Create a temporary FastAPI app
    app = FastAPI()

    @app.get("/")
    def read_root():
        return data

    # Save the app to a file
    with open("/tmp/app.py", "w") as f:
        f.write("""
from fastapi import FastAPI
app = FastAPI()

@app.get("/")
def read_root():
    return {data}
""".format(data=json.dumps(data)))

    # Run the FastAPI app in the background
    os.system("uvicorn /tmp/app:app --host 0.0.0.0 --port 8000 &")

    # Make a request to the app
    response = requests.get("http://localhost:8000/")

    return {
        "status": "API endpoint created",
        "response": response.json()
    }

This profile includes: - python:3.12-slim Docker image - fastapi, uvicorn, requests packages - An optimized build process using uv package manager

Python.AWS

A Python environment for AWS operations:

Python
@kubiya.tool(
    image=kubiya.Image.Python.AWS,
    secrets=["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"]
)
def list_s3_buckets():
    import boto3
    import os

    # Configure AWS credentials from secrets
    s3 = boto3.client(
        's3',
        aws_access_key_id=os.environ.get('AWS_ACCESS_KEY_ID'),
        aws_secret_access_key=os.environ.get('AWS_SECRET_ACCESS_KEY')
    )

    # List S3 buckets
    response = s3.list_buckets()

    # Extract bucket names
    buckets = [bucket['Name'] for bucket in response['Buckets']]

    return {
        "buckets": buckets,
        "count": len(buckets)
    }

This profile includes: - python:3.12-slim Docker image - boto3 AWS SDK - An optimized build process using uv package manager

Node.js Profiles

Node.BASE

A minimal Node.js environment:

Python
@kubiya.tool(image=kubiya.Image.Node.BASE)
def run_javascript(code: str):
    import subprocess
    import tempfile
    import os

    # Create a temporary JS file
    with tempfile.NamedTemporaryFile(suffix='.js', delete=False) as f:
        f.write(code.encode())
        temp_file = f.name

    try:
        # Execute the JS file with Node.js
        result = subprocess.run(
            ['node', temp_file],
            capture_output=True,
            text=True
        )

        return {
            "stdout": result.stdout,
            "stderr": result.stderr,
            "exit_code": result.returncode
        }
    finally:
        # Clean up the temporary file
        os.unlink(temp_file)

This profile uses: - node:18-slim Docker image - No additional packages

Node.WEB

A Node.js environment for web development:

Python
@kubiya.tool(image=kubiya.Image.Node.WEB)
def create_express_app(routes: list):
    import subprocess
    import tempfile
    import os
    import json

    # Create a temporary directory for the Express app
    temp_dir = tempfile.mkdtemp()

    try:
        # Write package.json
        with open(os.path.join(temp_dir, 'package.json'), 'w') as f:
            f.write(json.dumps({
                "name": "express-app",
                "version": "1.0.0",
                "main": "app.js",
                "dependencies": {
                    "express": "^4.18.2"
                }
            }))

        # Write app.js with the provided routes
        with open(os.path.join(temp_dir, 'app.js'), 'w') as f:
            f.write("""
const express = require('express');
const app = express();
const port = 3000;

app.use(express.json());

""")

            # Add each route
            for route in routes:
                path = route.get('path', '/')
                method = route.get('method', 'get').lower()
                response = json.dumps(route.get('response', {'message': 'OK'}))

                f.write(f"""
app.{method}('{path}', (req, res) => {{
  res.json({response});
}});
""")

            f.write("""
app.listen(port, () => {
  console.log(`Express app listening on port ${port}`);
});
""")

        # Install dependencies and start the app
        subprocess.run(['npm', 'install'], cwd=temp_dir, check=True)

        # Start the app (don't wait for it to finish)
        process = subprocess.Popen(
            ['node', 'app.js'],
            cwd=temp_dir,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True
        )

        # Wait a bit for the app to start
        import time
        time.sleep(2)

        return {
            "status": "Express app created and started",
            "output": process.stdout.readline() if process.stdout else "",
            "routes": routes
        }
    except Exception as e:
        return {"error": str(e)}

This profile includes: - node:18-slim Docker image - express, axios, lodash packages

Go Profiles

Go.BASE

A minimal Go environment:

Python
@kubiya.tool(image=kubiya.Image.Go.BASE)
def run_go_code(code: str):
    import subprocess
    import tempfile
    import os

    # Create a temporary directory
    temp_dir = tempfile.mkdtemp()

    try:
        # Create a Go module
        subprocess.run(['go', 'mod', 'init', 'example/tool'], cwd=temp_dir, check=True)

        # Write the Go code to a file
        main_file = os.path.join(temp_dir, 'main.go')
        with open(main_file, 'w') as f:
            f.write(code)

        # Run the Go code
        result = subprocess.run(
            ['go', 'run', 'main.go'],
            cwd=temp_dir,
            capture_output=True,
            text=True
        )

        return {
            "stdout": result.stdout,
            "stderr": result.stderr,
            "exit_code": result.returncode
        }
    except Exception as e:
        return {"error": str(e)}

This profile uses: - golang:1.21-alpine Docker image - No additional packages

Creating Custom Profiles

You can create custom image profiles using the Kubiya.Image.Custom.create method:

Python
custom_profile = kubiya.Image.Custom.create(
    image="python:3.10-slim",
    requirements=["tensorflow", "keras", "opencv-python"],
    custom_on_build="""
    apt-get update && apt-get install -y libgl1 libglib2.0-0
    """
)

@kubiya.tool(image=custom_profile)
def process_image(image_url: str):
    import cv2
    import numpy as np
    import tensorflow as tf
    from keras.applications import ResNet50
    from keras.applications.resnet50 import preprocess_input, decode_predictions
    import requests
    from io import BytesIO

    # Download image
    response = requests.get(image_url)
    img = cv2.imdecode(np.frombuffer(response.content, np.uint8), -1)

    # Preprocess for ResNet50
    img = cv2.resize(img, (224, 224))
    img = np.expand_dims(img, axis=0)
    img = preprocess_input(img)

    # Load model and predict
    model = ResNet50(weights='imagenet')
    preds = model.predict(img)

    # Decode and return top-5 predictions
    return {
        "predictions": decode_predictions(preds, top=5)[0]
    }

The create method accepts the following parameters: - image (str): The base Docker image to use - requirements (List[str], optional): Packages to install - custom_on_build (str, optional): Custom commands to run during build

Profile Implementation Details

Each image profile is implemented as a dictionary with the following structure:

Python
profile = {
    "image": "base-image:tag",
    "requirements": ["package1", "package2"],
    "on_build": "shell commands to run during build"
}

These profiles are then used by the @kubiya.tool decorator to create the appropriate Dockerfiles and container environments for your tools.