or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

code-completion.mdevent-streaming.mdfile-system.mdhttp-client.mdindex.mdnetwork-utilities.mdpackage-management.mdsvelte-integration.mdworker-management.md
tile.json

package-management.mddocs/

Package Management

Python package installation and management within the WebAssembly environment. Provides support for installing packages from PyPI and managing dependencies in the isolated worker environment.

Capabilities

Package Installation

Install Python packages in the worker environment using the standard package installation interface.

/**
 * Install Python packages in the worker environment
 * @param requirements - Array of package names to install (supports pip syntax)
 * @returns Promise that resolves when packages are installed
 */
install(requirements: string[]): Promise<void>;

Usage Examples:

import { WorkerProxy } from "@gradio/wasm";

const worker = new WorkerProxy({
  gradioWheelUrl: "https://example.com/gradio.whl",
  gradioClientWheelUrl: "https://example.com/gradio_client.whl",
  files: {},
  requirements: [], // Can specify initial requirements here
  sharedWorkerMode: false
});

worker.addEventListener("initialization-completed", async () => {
  // Install basic data science packages
  await worker.install([
    "numpy>=1.21.0",
    "pandas>=1.3.0",
    "matplotlib>=3.4.0",
    "scikit-learn>=1.0.0"
  ]);

  // Install packages with specific versions
  await worker.install([
    "requests==2.28.1",
    "pillow==9.2.0"
  ]);

  // Install packages from different sources
  await worker.install([
    "scipy",                    // Latest version
    "tensorflow==2.9.0",       // Specific version
    "torch>=1.12.0,<2.0.0"    // Version range
  ]);

  // Install development tools
  await worker.install([
    "pytest",
    "black",
    "flake8"
  ]);

  // Verify installations
  await worker.runPythonCode(`
import sys
import pkg_resources

print("Installed packages:")
installed_packages = [d for d in pkg_resources.working_set]
for package in sorted(installed_packages, key=lambda x: x.project_name):
    print(f"  {package.project_name}: {package.version}")

print(f"\\nPython version: {sys.version}")
print(f"Python path: {sys.path}")
`);
});

Installation During Initialization

Packages can be specified during worker initialization for automatic installation:

import { WorkerProxy } from "@gradio/wasm";

// Specify requirements during initialization
const worker = new WorkerProxy({
  gradioWheelUrl: "https://example.com/gradio.whl",
  gradioClientWheelUrl: "https://example.com/gradio_client.whl",
  files: {
    "requirements.txt": {
      data: `
numpy>=1.21.0
pandas>=1.3.0
matplotlib>=3.4.0
scikit-learn>=1.0.0
requests==2.28.1
pillow==9.2.0
`.trim(),
      opts: { encoding: "utf8" }
    }
  },
  requirements: [
    "numpy>=1.21.0",
    "pandas>=1.3.0", 
    "matplotlib>=3.4.0",
    "scikit-learn>=1.0.0",
    "requests==2.28.1",
    "pillow==9.2.0"
  ],
  sharedWorkerMode: false
});

worker.addEventListener("initialization-completed", async () => {
  // Packages are already installed and ready to use
  await worker.runPythonCode(`
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestClassifier
import requests
from PIL import Image

print("All packages successfully imported!")

# Demonstrate package functionality
data = np.random.randn(100, 5)
df = pd.DataFrame(data, columns=['A', 'B', 'C', 'D', 'E'])
print(f"Created DataFrame with shape: {df.shape}")

# Create a simple plot
plt.figure(figsize=(8, 6))
plt.plot(df['A'])
plt.title("Sample Data Plot")
plt.savefig("sample_plot.png")
print("Plot saved to sample_plot.png")

# Initialize ML model
model = RandomForestClassifier(n_estimators=10)
print(f"Created model: {type(model).__name__}")
`);
});

Dynamic Package Installation

Install packages dynamically based on user requirements or runtime conditions:

import { WorkerProxy } from "@gradio/wasm";

class DynamicPackageManager {
  private worker: WorkerProxy;
  private installedPackages: Set<string> = new Set();

  constructor(options: WorkerProxyOptions) {
    this.worker = new WorkerProxy(options);
    this.setupWorker();
  }

  private setupWorker() {
    this.worker.addEventListener("initialization-completed", () => {
      console.log("Worker ready for dynamic package management");
      this.trackInstalledPackages();
    });
  }

  private async trackInstalledPackages() {
    // Get list of initially installed packages
    await this.worker.runPythonCode(`
import pkg_resources

installed = [d.project_name for d in pkg_resources.working_set]
print("INSTALLED_PACKAGES:", ",".join(installed))
`);

    // In a real implementation, you'd parse the stdout to get the package list
    // For now, we'll track packages as we install them
  }

  async installIfNeeded(packages: string[]): Promise<string[]> {
    const packagesToInstall = packages.filter(pkg => {
      const packageName = pkg.split(/[>=<!=]/)[0];
      return !this.installedPackages.has(packageName);
    });

    if (packagesToInstall.length === 0) {
      console.log("All packages already installed");
      return [];
    }

    console.log(`Installing new packages: ${packagesToInstall.join(", ")}`);
    await this.worker.install(packagesToInstall);

    // Track newly installed packages
    packagesToInstall.forEach(pkg => {
      const packageName = pkg.split(/[>=<!=]/)[0];
      this.installedPackages.add(packageName);
    });

    return packagesToInstall;
  }

  async installForWorkflow(workflowType: string): Promise<void> {
    const workflows = {
      "data-analysis": [
        "numpy>=1.21.0",
        "pandas>=1.3.0", 
        "matplotlib>=3.4.0",
        "seaborn>=0.11.0",
        "plotly>=5.0.0"
      ],
      "machine-learning": [
        "numpy>=1.21.0",
        "pandas>=1.3.0",
        "scikit-learn>=1.0.0",
        "xgboost>=1.6.0",
        "lightgbm>=3.3.0"
      ],
      "deep-learning": [
        "numpy>=1.21.0",
        "torch>=1.12.0",
        "torchvision>=0.13.0",
        "transformers>=4.20.0"
      ],
      "web-scraping": [
        "requests>=2.28.0",
        "beautifulsoup4>=4.11.0",
        "lxml>=4.9.0",
        "selenium>=4.3.0"
      ],
      "image-processing": [
        "numpy>=1.21.0",
        "pillow>=9.2.0",
        "opencv-python>=4.6.0",
        "scikit-image>=0.19.0"
      ]
    };

    const packages = workflows[workflowType];
    if (!packages) {
      throw new Error(`Unknown workflow type: ${workflowType}`);
    }

    const installed = await this.installIfNeeded(packages);
    console.log(`Workflow '${workflowType}' ready. Installed: ${installed.length} new packages`);
  }

  async checkPackageCompatibility(packages: string[]): Promise<boolean> {
    // Check if packages can be installed together
    try {
      await this.worker.runPythonCode(`
import pkg_resources
import sys

packages_to_check = ${JSON.stringify(packages)}
print(f"Checking compatibility for: {packages_to_check}")

# This is a simplified compatibility check
# In practice, you might want to use pip's dependency resolver
for package in packages_to_check:
    try:
        # Try to parse the requirement
        req = pkg_resources.Requirement.parse(package)
        print(f"✓ {package} - valid requirement")
    except Exception as e:
        print(f"✗ {package} - invalid requirement: {e}")
        sys.exit(1)

print("All packages appear compatible")
`);
      return true;
    } catch (error) {
      console.error("Package compatibility check failed:", error);
      return false;
    }
  }

  getInstalledPackages(): Set<string> {
    return new Set(this.installedPackages);
  }
}

// Usage
const packageManager = new DynamicPackageManager({
  gradioWheelUrl: "https://example.com/gradio.whl",
  gradioClientWheelUrl: "https://example.com/gradio_client.whl",
  files: {},
  requirements: ["numpy"], // Minimal initial requirements
  sharedWorkerMode: false
});

// Install packages for specific workflows
await packageManager.installForWorkflow("data-analysis");
await packageManager.installForWorkflow("machine-learning");

// Check what's installed
console.log("Installed packages:", Array.from(packageManager.getInstalledPackages()));

Package Version Management

Handle package versions and conflicts:

import { WorkerProxy } from "@gradio/wasm";

class VersionManager {
  private worker: WorkerProxy;

  constructor(worker: WorkerProxy) {
    this.worker = worker;
  }

  async getPackageVersion(packageName: string): Promise<string | null> {
    try {
      await this.worker.runPythonCode(`
import pkg_resources

try:
    version = pkg_resources.get_distribution("${packageName}").version
    print(f"PACKAGE_VERSION:{packageName}:{version}")
except pkg_resources.DistributionNotFound:
    print(f"PACKAGE_VERSION:{packageName}:NOT_FOUND")
`);

      // In a real implementation, parse stdout to get the version
      return "unknown"; // Placeholder
    } catch (error) {
      return null;
    }
  }

  async upgradePackage(packageName: string, targetVersion?: string): Promise<void> {
    const packageSpec = targetVersion ? `${packageName}==${targetVersion}` : packageName;
    
    console.log(`Upgrading ${packageName}${targetVersion ? ` to ${targetVersion}` : " to latest"}`);
    
    await this.worker.install([packageSpec]);
    
    const newVersion = await this.getPackageVersion(packageName);
    console.log(`${packageName} upgraded to version: ${newVersion}`);
  }

  async checkForUpdates(packages: string[]): Promise<Record<string, { current: string; latest: string }>> {
    const updates: Record<string, { current: string; latest: string }> = {};

    await this.worker.runPythonCode(`
import pkg_resources
import json

packages_to_check = ${JSON.stringify(packages)}
update_info = {}

for package_name in packages_to_check:
    try:
        current_version = pkg_resources.get_distribution(package_name).version
        # In a real implementation, you would check PyPI for the latest version
        # For now, we'll just report the current version
        update_info[package_name] = {
            "current": current_version,
            "latest": current_version  # Placeholder
        }
    except pkg_resources.DistributionNotFound:
        update_info[package_name] = {
            "current": "NOT_INSTALLED",
            "latest": "UNKNOWN"
        }

print("UPDATE_INFO:" + json.dumps(update_info))
`);

    // In a real implementation, parse stdout to get update info
    return updates;
  }
}

Error Handling and Troubleshooting

Robust error handling for package installation issues:

import { WorkerProxy } from "@gradio/wasm";

class RobustPackageInstaller {
  private worker: WorkerProxy;
  private installationLog: Array<{ package: string; success: boolean; error?: string }> = [];

  constructor(worker: WorkerProxy) {
    this.worker = worker;
  }

  async installWithRetry(packages: string[], maxRetries = 3): Promise<void> {
    for (const packageSpec of packages) {
      let success = false;
      let lastError: any = null;

      for (let attempt = 1; attempt <= maxRetries; attempt++) {
        try {
          console.log(`Installing ${packageSpec} (attempt ${attempt}/${maxRetries})`);
          await this.worker.install([packageSpec]);
          
          success = true;
          this.installationLog.push({ package: packageSpec, success: true });
          console.log(`✓ Successfully installed ${packageSpec}`);
          break;

        } catch (error) {
          lastError = error;
          console.warn(`✗ Failed to install ${packageSpec} (attempt ${attempt}): ${error}`);
          
          if (attempt < maxRetries) {
            const delay = 1000 * Math.pow(2, attempt - 1); // Exponential backoff
            console.log(`Retrying in ${delay}ms...`);
            await new Promise(resolve => setTimeout(resolve, delay));
          }
        }
      }

      if (!success) {
        this.installationLog.push({ 
          package: packageSpec, 
          success: false, 
          error: lastError?.toString() 
        });
        console.error(`Failed to install ${packageSpec} after ${maxRetries} attempts`);
      }
    }
  }

  async validateInstallation(packages: string[]): Promise<string[]> {
    const failedPackages: string[] = [];

    await this.worker.runPythonCode(`
import pkg_resources

packages_to_validate = ${JSON.stringify(packages.map(pkg => pkg.split(/[>=<!=]/)[0]))}
failed_imports = []

for package_name in packages_to_validate:
    try:
        pkg_resources.get_distribution(package_name)
        print(f"✓ {package_name} is installed")
    except pkg_resources.DistributionNotFound:
        print(f"✗ {package_name} is NOT installed")
        failed_imports.append(package_name)

if failed_imports:
    print(f"FAILED_PACKAGES: {','.join(failed_imports)}")
else:
    print("All packages validated successfully")
`);

    // In a real implementation, parse stdout to get failed packages
    return failedPackages;
  }

  getInstallationLog(): Array<{ package: string; success: boolean; error?: string }> {
    return [...this.installationLog];
  }

  printInstallationSummary(): void {
    const successful = this.installationLog.filter(log => log.success).length;
    const failed = this.installationLog.filter(log => !log.success).length;
    
    console.log(`\nInstallation Summary:`);
    console.log(`  ✓ Successful: ${successful}`);
    console.log(`  ✗ Failed: ${failed}`);
    
    if (failed > 0) {
      console.log(`\nFailed installations:`);
      this.installationLog
        .filter(log => !log.success)
        .forEach(log => {
          console.log(`  - ${log.package}: ${log.error}`);
        });
    }
  }
}

// Usage
const worker = new WorkerProxy(options);
const installer = new RobustPackageInstaller(worker);

worker.addEventListener("initialization-completed", async () => {
  const packages = [
    "numpy>=1.21.0",
    "pandas>=1.3.0",
    "matplotlib>=3.4.0",
    "invalid-package-name", // This will fail
    "scikit-learn>=1.0.0"
  ];

  await installer.installWithRetry(packages);
  
  const failedPackages = await installer.validateInstallation(packages);
  if (failedPackages.length > 0) {
    console.warn("Some packages failed to install:", failedPackages);
  }
  
  installer.printInstallationSummary();
});