Metadata-Version: 2.4
Name: azure-dynamic-sessions-code-interpreter
Version: 1.0.0
Summary: Python client for Azure Container Apps dynamic code interpreter sessions (dynamic sessions API).
Keywords: azure,code-interpreter,dynamic-sessions,container-apps,llm
Author: Akindu Karunaratne
Author-email: Akindu Karunaratne <akindukaru23@gmail.com>
License-Expression: MIT
Requires-Dist: azure-core>=1.38.0
Requires-Dist: azure-identity~=1.16
Requires-Dist: requests~=2.31
Requires-Python: >=3.10
Project-URL: Repository, https://github.com/Akindu23/azure-dynamic-sessions-code-interpreter-tool
Description-Content-Type: text/markdown

# azure-dynamic-sessions-code-interpreter

Standalone Python client for [Azure Container Apps dynamic (code interpreter) sessions](https://learn.microsoft.com/azure/container-apps/session-pool). Use it to run sandboxed Python against your session pool from your own apps or LLM tooling, without pulling in LangChain.

**Repository:** [github.com/Akindu23/azure-dynamic-sessions-code-interpreter-tool](https://github.com/Akindu23/azure-dynamic-sessions-code-interpreter-tool)

## Installation

```bash
pip install -U azure-dynamic-sessions-code-interpreter
```

Requires Python 3.10+.

## Configuration

Create an Azure Container Apps session pool and copy its **management endpoint**. See [Configure a pool in Azure Container Apps](https://learn.microsoft.com/azure/container-apps/session-pool#configure-a-pool).

Authentication uses **`DefaultAzureCredential`**. If you use a user-assigned managed identity, set **`AZURE_CLIENT_ID`** to that identity’s client ID. Only Microsoft Entra ID tokens from a principal granted the **Azure ContainerApps Session Executor** role on the session pool may call the pool management API.

```azurecli
az role assignment create \
    --role "Azure ContainerApps Session Executor" \
    --assignee <PRINCIPAL_ID> \
    --scope <SESSION_POOL_RESOURCE_ID>
```

## Usage

Import `CodeInterpreterTool` from the installed package (sources live under `src/` in this repo):

```python
from io import BytesIO

from azure_dynamic_sessions_code_interpreter import CodeInterpreterTool

POOL_MANAGEMENT_ENDPOINT = "https://<your-pool-management-endpoint>/"

tool = CodeInterpreterTool(pool_management_endpoint=POOL_MANAGEMENT_ENDPOINT)

# Run Python in the session (returns JSON with result / stdout / stderr)
result = tool.execute("print('Hello, world!')")

# Upload a file into the session
tool.upload_file(data=BytesIO(b"Hello, world!"), remote_file_path="hello.txt")

# List files visible to the session
files = tool.list_files()

# Download a file from the session
tool.download_file(remote_file_path="hello.txt")
```

Optional arguments include `session_id` (reuse a session), `timeout_connect`, `timeout_read`, `max_retries`, and `sanitize_input`. See the docstring on `CodeInterpreterTool` in `core.py` for details.

### Azure OpenAI: tool definition, arguments, and tool results

`CodeInterpreterTool` includes helpers aligned with [function calling](https://platform.openai.com/docs/guides/function-calling) for **Chat Completions** and the **Responses** API. They expect `tool_call` to be the **object** returned by the model (with `.function` / `.arguments` or `.call_id`, etc.), matching how the Azure OpenAI Python SDK structures tool calls—not a plain `dict`.

#### 1. Tool definition (what you send to the model)

**Chat Completions** — wrap the function under `type` / `function`:

```python
code_interpreter = CodeInterpreterTool(pool_management_endpoint=POOL_MANAGEMENT_ENDPOINT)

tools = [
    code_interpreter.get_tool_definition(is_chat_completions_api=True),
]
# Pass `tools` into your chat completion request.
```

**Responses API** — flatter tool shape:

```python
code_interpreter = CodeInterpreterTool(pool_management_endpoint=POOL_MANAGEMENT_ENDPOINT)

available_tools = [
    code_interpreter.get_tool_definition(is_chat_completions_api=False),
]
# Pass `available_tools` into your responses request.
```

#### 2. Extract Python code from the model’s tool call

After the model emits a tool call, parse the `python_code` argument:

```python
is_chat_completions_api = True  # or False for Responses API

python_code = code_interpreter.get_tool_call_arguments(
    tool_call=tool_call_object_from_model,
    is_chat_completions_api=is_chat_completions_api,
)
```

#### 3. Run the sandbox and format the result for the next model turn

Execute the code and get a **message-shaped** payload to append to the conversation (role `tool` for Chat Completions, or `function_call_output` for Responses):

```python
tool_call_result = code_interpreter.execute_tool_call(
    tool_call=tool_call_object_from_model,
    python_code=python_code,
    is_chat_completions_api=is_chat_completions_api,
)
# Append `tool_call_result` to your messages / response inputs and call the model again.
```

#### 4. Typical branch when the model picks `code_interpreter`

This mirrors a common orchestration pattern (names like `output` / `logger` are only illustrative):

```python
if output_name == "code_interpreter":
    python_code = code_interpreter.get_tool_call_arguments(
        tool_call=output,
        is_chat_completions_api=is_chat_completions_api,
    )
    # e.g. log a short preview: python_code[:200]

    tool_call_result = code_interpreter.execute_tool_call(
        tool_call=output,
        python_code=python_code,
        is_chat_completions_api=is_chat_completions_api,
    )
    # feed `tool_call_result` back to Azure OpenAI
```

This library is aimed at Azure OpenAI (Chat Completions or Responses API) workflows; support for other providers is work in progress.

## Third-party notices

Parts of this project are derived from [langchain-azure](https://github.com/langchain-ai/langchain-azure) (MIT). Full attribution and license text are in [`THIRD_PARTY_NOTICES.TXT`](THIRD_PARTY_NOTICES.TXT).

## License

This project is licensed under the MIT License — see [`LICENSE`](LICENSE).
