> ## Documentation Index
> Fetch the complete documentation index at: https://developer.watson-orchestrate.ibm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Importing Python toolkits

After you create your Python tools, import them as a Python toolkit. A Python toolkit groups related tools so you can deploy and run them together in a single Python process. To meet this goal, design every tool in the toolkit to be thread-safe and reentrant. This approach gives you faster execution because the tools share the same process.

When you run Python tools outside a toolkit (as standalone Python tools), the system starts a lightweight process each time the tool runs. This design supports tools that use non-thread-safe operations, but it increases execution time by approximately 100-300ms per invocation compared to a toolkit.

<Note>
  **When to use Python toolkits vs standalone Python tools:**

  * **Use Python toolkits** when you have multiple related tools that are thread-safe, called frequently, or share dependencies
  * **Use standalone Python tools** when tools use non-thread-safe operations, are called infrequently, or need process isolation

  For detailed guidance, see [Choosing a tool type](/tools/toolkits/choosing_tool_type).
</Note>

To create a Python toolkit, place all required Python tools in one folder. Each tool can include one or more Python files. In those files, define your functions and apply the `@tool` decorator so watsonx Orchestrate exposes each function as a usable tool.

You can place tools that multiple agents use into a single toolkit. When you update tools inside a toolkit, redeploy all related agents to the live environment so you use the updated versions. Choose the number of tools in each toolkit based on the level of concurrent requests you expect. For more information, see [CPU and memory allocation for Python toolkits](#cpu-and-memory-allocation-for-python-toolkits).

### CPU and memory allocation for Python toolkits

**Draft environment:**

* All imported Python toolkits and Python tools run in a single Kubernetes deployment container per tenant
* Process overheads per tool call exist in draft (approximately 100-300ms per invocation)
* Container resources: 2 vCPUs, 2 GB of memory, and 5 workers
* Deployment supports two replicas

**Live environment (premium plan):**

* You can import up to five Python toolkits per tenant
* Each toolkit runs in its own dedicated Kubernetes deployment container
* **No process overheads per tool call** - tools run in a persistent process
* Container resources per toolkit: 2 vCPUs, 2 GB of memory, and 5 workers
* Each deployment supports two replicas
* Supports up to 10 concurrent requests per toolkit (5 workers × 2 replicas)

**Live environment (non-premium plan):**

* Similar to draft environment with shared container model
* Contact support to request premium access for dedicated toolkit containers

<Tip>
  **Performance optimization:** In live premium environments, Python toolkits eliminate process startup overhead, reducing tool execution time by 100-300ms per call compared to standalone Python tools. For frequently called tools (>10 calls/minute), this can significantly improve agent response times.
</Tip>

### Add Python toolkits using the ADK CLI

Use the `orchestrate toolkits add` command to add a Python toolkit.

```bash BASH theme={null}
orchestrate toolkits add \
  --kind python \
  --name <toolkit-name> \
  --description <toolkit-description> \
  --tier <deployment-tier> \
  --package_root <toolkit-path>
```

<Expandable title="command flags">
  <ResponseField name="kind" required>
    The type of toolkit to import. For Python toolkits, use
    `python`.
  </ResponseField>

  <ResponseField name="name" required>
    The name of the toolkit.
  </ResponseField>

  <ResponseField name="description" required>
    The description for the toolkit.
  </ResponseField>

  <ResponseField name="package-root" required>
    The path for the toolkit.
  </ResponseField>

  <ResponseField name="app-id">
    The `app_id` to of a connection to associate with this toolkit. **Only `key_value` connections are supported.** Each key and value within the connection will be exposed as environment variables to the mcp server. For more information, see [Connections](../../connections/overview).
  </ResponseField>

  <ResponseField name="tier" type="string">
    Assigns a dedicated deployment tier to the Python toolkit. This option applies only when <code>--kind</code> is set to <code>python</code>.
  </ResponseField>
</Expandable>

### Import Python toolkits from a file

You can also import a Python toolkit from a YAML file. This file defines the same configuration options as the add command and fits well into import scripts and CI/CD pipelines.

Use the `orchestrate toolkits import` command to import a toolkit from a file.

```bash BASH theme={null}
orchestrate toolkits import -f <path to spec> --app-id <connection>
```

<Expandable title="command flags">
  <ResponseField name="-f, --file" required>
    Path to the YAML specification file that defines the toolkit.
  </ResponseField>

  <ResponseField name="app-id">
    The `app_id` to of a connection to associate with this toolkit. **Only `key_value` connections are supported.** Each key and value within the connection will be exposed as environment variables to the mcp server. For more information, see [Connections](../../connections/overview).
  </ResponseField>
</Expandable>

For the YAML file, configure the following:

<ResponseField name="spec_version" type="string" required>
  The version of the YAML specification.
</ResponseField>

<ResponseField name="kind" type="string" required>
  The type of toolkit. For Python toolkits, use `python`.
</ResponseField>

<ResponseField name="name" type="string" required>
  The name of the toolkit.
</ResponseField>

<ResponseField name="description" type="string">
  The description of the toolkit.
</ResponseField>

<ResponseField name="environment" type="object">
  Key-value pairs for the toolkit.
</ResponseField>

**Example:**

```yaml toolkit_name.yaml theme={null}
spec_version: v1
kind: python
name: toolkit_name
description: A toolkit sample
environment:
    key1: value1
```

### Thread-safety requirements

All tools in a Python toolkit must be thread-safe because they run in a shared process with concurrent requests. A tool is thread-safe when multiple threads can call it simultaneously without causing race conditions or data corruption.

**Thread-safe patterns:**

* No global mutable state
* Use immutable data structures
* Employ proper async/await patterns
* Use thread-safe libraries

**Non-thread-safe patterns to avoid:**

* Global variables that change
* File system writes
* Non-thread-safe libraries
* Shared database connections without pooling

For detailed guidance on thread-safety and migration from standalone tools, see [Migrating to Python toolkits](/tools/toolkits/migrating_to_toolkits).
