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:
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:
@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:
@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:
@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:
@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:
@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:
@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:
@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:
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:
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.