Azure-Samples / Azure-Samples/simple-agent-functions-python

Top-level CopilotClient import crashes entire Function host if github-copilot-sdk fails to install

Open
#1 2 comments 1 reaction 2 assignees Claimed by @paulyuk View on GitHub
Dominant language
Bicep
Stars
4
Forks
5
PR merge metrics
No merged PRs in 30d

Description

## Problem

`function_app.py` imports `CopilotClient` and initializes it at module level:

```python
from copilot import CopilotClient, PermissionHandler
client = CopilotClient()
```

If the `github-copilot-sdk` package fails to install on Azure Functions Linux (Flex Consumption), this crashes the **entire** Function host with a 503. No endpoints load — not just the agent endpoint, but **all** HTTP triggers and **all** timer triggers become unavailable.

## Root Cause

Azure Functions Python v2 loads `function_app.py` at startup. Any top-level import failure prevents the module from loading, which prevents the Functions runtime from discovering and registering **any** routes. The host returns `Function host is not running` (503) for every request.

## Impact

- All HTTP endpoints return 503 (not just the agent endpoint)
- All timer triggers stop firing (scheduled jobs silently fail)
- No error is surfaced in the Azure Portal — the app appears deployed but is completely non-functional
- Difficult to diagnose: the deployment succeeds, the function list shows empty, and logs may not clearly indicate the import failure

## Reproduction

1. Deploy the sample to Azure Functions Flex Consumption (Python 3.12+)
2. If `github-copilot-sdk` fails to install (pip resolution error, platform incompatibility, etc.), the entire app is down
3. Observe: `curl https://.azurewebsites.net/` returns `Function host is not running`

## Suggested Fix

Make the Copilot SDK import lazy — only load when the agent endpoint is actually called:

```python
import azure.functions as func

app = func.FunctionApp()

# Lazy init — does not crash the host if copilot SDK is missing
_copilot_client = None

def _get_copilot_client():
global _copilot_client
if _copilot_client is None:
from copilot import CopilotClient
_copilot_client = CopilotClient()
return _copilot_client

@app.route(route="ask", methods=["POST"])
async def ask(req: func.HttpRequest) -> func.HttpResponse:
try:
client = _get_copilot_client()
# ... use client
except ImportError:
return func.HttpResponse("Copilot SDK not available", status_code=503)
```

This ensures that if the Copilot SDK is unavailable, only `/api/ask` fails — other endpoints and timer triggers continue to work normally.

## Additional Consideration

The same pattern applies to `from copilot.tools import define_tool` and `from pydantic import BaseModel` — these should also be lazily imported if used alongside other endpoints that should remain functional independently.

## Environment

- Azure Functions Flex Consumption (Python 3.12+)
- `github-copilot-sdk` (latest)
- Multi-endpoint function app with timer triggers + HTTP triggers

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.