KAP Tool#
To upload a Python package compatible with Linux to Kappa-Automate, you need to obtain the Linux-compatible distribution files for the package. We have developed the KAP Tool to simplify this procedure.
Follow these steps:
Copy the code below into a Python file named kap.py:
import os
import sys
import tempfile
import shutil
import subprocess
import argparse
import textwrap
import zipfile
from pathlib import Path
parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter)
subparsers = parser.add_subparsers(title='available commands')
pack_parser = subparsers.add_parser('pack', help="Create a KAPPA-Automate package based on requirements file")
pack_parser.add_argument('requirements', type=str, help='Create a KAPPA-Automate user task package from the given requirements file')
install_parser = subparsers.add_parser('install', help="Create a KAPPA-Automate package based on requirements file and install it on KAPPA-Automate")
install_parser.add_argument('requirements', type=str, help='Create a KAPPA-Automate user task package from the given requirements file')
parser.epilog = textwrap.dedent(f"{pack_parser.format_usage()}{install_parser.format_usage()}")
args = parser.parse_args(args=None if sys.argv[1:] else ['--help'])
with tempfile.TemporaryDirectory() as temp_dir:
print("Downloading:")
shutil.rmtree(temp_dir)
download_dir = Path(temp_dir) / "downloaded_packages"
os.makedirs(download_dir)
# Try different approaches in order of preference
download_commands = [
# First try: exact platform with binary only
[sys.executable, "-m", "pip", "download", f"--dest={download_dir}", "--platform=manylinux_2_17_x86_64.manylinux2014_x86_64", "--only-binary=:all:", "-r", args.requirements],
# Second try: broader platform tag
[sys.executable, "-m", "pip", "download", f"--dest={download_dir}", "--platform=manylinux_2_17_x86_64", "--prefer-binary", "-r", args.requirements],
# Third try: no platform restriction, binary preferred
[sys.executable, "-m", "pip", "download", f"--dest={download_dir}", "--prefer-binary", "-r", args.requirements],
# Final try: allow everything
[sys.executable, "-m", "pip", "download", f"--dest={download_dir}", "-r", args.requirements]
]
success = False
for i, cmd in enumerate(download_commands):
try:
print(f"Attempt {i+1}: {' '.join(cmd[4:])}") # Show the relevant flags
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode == 0:
print("Download successful!")
if result.stdout.strip():
print(result.stdout)
success = True
break
else:
print(f"Attempt {i+1} failed: {result.stderr.strip()}")
except Exception as e:
print(f"Attempt {i+1} encountered error: {e}")
if not success:
print("All download attempts failed!")
exit(1)
print("Unpacking:")
ka_package_dir = Path(temp_dir) / "ka_package"
os.makedirs(ka_package_dir)
for whl_file in os.listdir(download_dir):
with zipfile.ZipFile(Path(download_dir) / whl_file) as f:
f.extractall(ka_package_dir)
print(f"{whl_file} -> {ka_package_dir}")
print("Re-packing:")
requirements_path = Path(args.requirements)
ka_package_file = requirements_path.parent / (requirements_path.stem + ".zip")
with zipfile.ZipFile(ka_package_file, "w", zipfile.ZIP_DEFLATED) as zf:
src_path = Path(ka_package_dir).expanduser().resolve(strict=True)
for file in src_path.rglob('*'):
zf.write(file, file.relative_to(src_path))
print(f"{file} -> {ka_package_file}")
print("Uploading:")
Create a “requirements.txt” file listing all packages you want to use.
From a terminal in the directory containing kap.py, run:
python -m kap pack requirements.txt
This will generate a zip file containing all the specified packages.
Example: If you only need numpy 2.0.0, add numpy==2.0.0
to your requirements.txt file and run the command above.