# Run with Python SDK

Use the official `fetch-hive-sdk` package when you want to invoke a workflow deployment from Python. The SDK wraps the public [`POST /v1/workflow/invoke`](/api-reference/invoke-workflow.md) endpoint, handles authentication, and supports both synchronous and asynchronous runs.

## Installation

```bash
pip install fetch-hive-sdk
```

The SDK requires Python 3.9+ and uses `httpx` under the hood.

## Authentication

Set the `FETCH_HIVE_API_KEY` environment variable to your workspace API key (the SDK reads it automatically):

```bash
export FETCH_HIVE_API_KEY=fhk_...
```

```python
from fetch_hive_sdk import FetchHive

client = FetchHive()
```

Or pass the key explicitly:

```python
client = FetchHive(api_key="fhk_...")
```

See [API Keys](/your-workspace/api-keys.md) for how to create and rotate keys.

## Basic example

Run a workflow deployment synchronously — the call blocks until the workflow finishes:

```python
from fetch_hive_sdk import FetchHive

client = FetchHive()

run = client.invoke_workflow(
    deployment="YOUR_DEPLOYMENT_NAME",
    variant="YOUR_VARIANT_NAME",
    inputs={"topic": "State of enterprise AI in 2026"},
)

print(run["run_status"])
print(run["output"])
```

See the [sync response shape](/api-reference/invoke-workflow.md#response).

## Method reference

| Argument       | Type             | Required | Description                                                                           |
| -------------- | ---------------- | -------- | ------------------------------------------------------------------------------------- |
| `deployment`   | `str`            | Yes      | The workflow deployment name                                                          |
| `variant`      | `str`            | No       | The deployment variant name                                                           |
| `inputs`       | `dict[str, Any]` | No       | Key-value pairs for the variables defined on the **Start** step                       |
| `async_mode`   | `bool`           | No       | When `True`, return immediately and deliver the result via webhook                    |
| `callback_url` | `str`            | No       | Required when `async_mode=True` — the HTTPS webhook URL to call when the run finishes |
| `user`         | `str`            | No       | Opaque caller identifier surfaced in [User Tracking](/user-tracking/user-tracking.md) |

`invoke_workflow` builds the request body for you. When you pass `async_mode=True`, the SDK sends:

```json
{
  "async": { "enabled": true, "callback_url": "https://example.com/webhook" }
}
```

## Handling the response

```python
run = client.invoke_workflow(deployment="my-workflow", variant="default")

print(run["run_status"])    # "completed" | "failed" | "running" | "queued"
print(run["output"])        # final workflow output
print(run["request_id"])    # use this to look up the run in Logs
```

## Async runs and webhooks

Pass `async_mode=True` to queue the workflow and have Fetch Hive call your webhook when the run finishes:

```python
run = client.invoke_workflow(
    deployment="YOUR_DEPLOYMENT_NAME",
    variant="YOUR_VARIANT_NAME",
    inputs={"topic": "State of enterprise AI in 2026"},
    async_mode=True,
    callback_url="https://example.com/callback",
)

print("Queued:", run["run_status"])
print("Webhook secret:", run["webhook_secret"])
```

Store the `webhook_secret` so you can verify the signature on the incoming callback. See [Async and Webhooks](/workflows/async-and-webhooks.md) for the verification flow and signed payload shape.

## Configuration

| Option     | Default                        | Description                                                                  |
| ---------- | ------------------------------ | ---------------------------------------------------------------------------- |
| `api_key`  | `FETCH_HIVE_API_KEY` env var   | Bearer token from the dashboard                                              |
| `base_url` | `https://api.fetchhive.com/v1` | Override the API base URL                                                    |
| `timeout`  | `120`                          | Request timeout in seconds — increase for long-running synchronous workflows |

```python
client = FetchHive(
    api_key="fhk_...",
    base_url="https://api.fetchhive.com/v1",
    timeout=600,
)
```

## Errors

Non-2xx responses raise an `httpx.HTTPStatusError` with the status code and response body:

```python
import httpx

try:
    run = client.invoke_workflow(deployment="my-workflow", variant="default")
except httpx.HTTPStatusError as exc:
    print("Fetch Hive returned", exc.response.status_code, exc.response.text)
```

See [Error Handling](/workflows/error-handling.md) for workflow-specific failure cases and [Errors and Rate Limits](/api-reference/errors-and-rate-limits.md) for HTTP status code meanings.

## Links

* [Package on PyPI](https://pypi.org/project/fetch-hive-sdk/)
* [Source on GitHub](https://github.com/Fetch-Hive/python-sdk)

## Next steps

* [Async and Webhooks](/workflows/async-and-webhooks.md) - Verify callback signatures
* [Run with API](/workflows/run-with-api.md) - The same flow with cURL
* [Run with Node.js SDK](/workflows/run-with-nodejs-sdk.md)
* [Run with Ruby SDK](/workflows/run-with-ruby-sdk.md)
* [Run with PHP SDK](/workflows/run-with-php-sdk.md)
* [Invoke Workflow](/api-reference/invoke-workflow.md) - Full endpoint reference


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.fetchhive.com/workflows/run-with-python-sdk.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
