Metadata-Version: 2.4
Name: ff-sdk
Version: 0.1.0
Summary: Python client SDK for FireFoundry Agent Bundle services
Project-URL: Homepage, https://github.com/firebrandanalytics/ff-sdk-py
Project-URL: Repository, https://github.com/firebrandanalytics/ff-sdk-py
Project-URL: Bug Tracker, https://github.com/firebrandanalytics/ff-sdk-py/issues
Author-email: Firebrand Analytics <hello@firebrandanalytics.com>
License: MIT
License-File: LICENSE
Keywords: agents,ai,firefoundry,sdk
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Description-Content-Type: text/markdown

# ff-sdk-py

Python client SDK for [FireFoundry](https://firefoundry.ai) Agent Bundle services.

Use this SDK to invoke entity methods, run bots, and stream responses from FireFoundry Agent Bundle microservices deployed in your environment.

## Installation

```bash
pip install ff-sdk
```

## Quick Start

```python
from ff_sdk import RemoteAgentBundleClient

client = RemoteAgentBundleClient(
    base_url="https://your-agent-bundle.example.com",
    api_key="your-api-key",
)

# Invoke an entity method
result = client.invoke_entity_method("entity-uuid", "generate_report", {"format": "pdf"})

# Run a bot
output = client.run_bot("SummaryBot", {"input": "Summarize this document"})

# Stream bot responses
iterator = client.start_bot("AnalysisBot", {"input": "Analyze trends"})
for update in iterator:
    print(update)
```

## Async Usage

```python
from ff_sdk import AsyncRemoteAgentBundleClient

async def main():
    async with AsyncRemoteAgentBundleClient(
        base_url="https://your-agent-bundle.example.com",
        api_key="your-api-key",
    ) as client:
        result = await client.invoke_entity_method("entity-uuid", "my_method", "arg1")

        # Stream with async for
        iterator = await client.start_iterator("entity-uuid", "process")
        async for item in iterator:
            print(item)
        await iterator.cleanup()
```

## Entity Proxy

```python
from ff_sdk import RemoteAgentBundleClient, EntityProxy

client = RemoteAgentBundleClient(base_url="...", api_key="...")
proxy = EntityProxy(entity_id="entity-uuid", client=client)

# Property access dispatches to invoke_entity_method
result = proxy.generate_report({"format": "pdf"})
```

## Binary Data

```python
# Upload a file
with open("document.pdf", "rb") as f:
    pdf_bytes = f.read()

result = client.invoke_entity_method_with_blobs(
    entity_id="entity-uuid",
    method_name="process_document",
    args=[{"$blob": 0}, {"title": "My Doc"}],
    files=[pdf_bytes],
)

# Download binary output efficiently (no base64 overhead)
pdf_output: bytes = client.invoke_entity_method_binary(
    "entity-uuid", "generate_large_pdf", {"pages": 1000}
)
```

## Unified `invoke` Dispatcher

```python
# JSON result (default)
result = client.invoke("entity-uuid", "process", args=[{"key": "val"}])

# Binary result
pdf = client.invoke("entity-uuid", "generate_pdf", response_type="binary")

# Streaming iterator
iterator = client.invoke("entity-uuid", "start", response_type="iterator")
```

## Configuration

| Parameter | Type | Default | Description |
|---|---|---|---|
| `base_url` | `str` | required | Base URL of the Agent Bundle service |
| `api_key` | `str \| None` | `None` | API key for authentication |
| `timeout` | `float` | `200.0` | Request timeout in seconds |
| `is_external` | `bool` | `False` | Use gateway auth mode (plain key, no `Bearer` prefix) |

## License

MIT
