Azure / Azure/azure-functions-python-worker

Support async startup and shutdown lifecycle hooks for Python Function Apps

Open
#1,904 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
357
Forks
116
Avg merge
32m
Merged PRs (30d)
1

Description

### Binding Type

Not binding-specific. This is a Python worker / Python v2 programming-model lifecycle capability for any Function App that owns process-scoped async resources.

### Expected Behavior

Provide supported worker-process startup and shutdown hooks that Python applications and libraries can register through the v2 `FunctionApp` programming model.

The shutdown callback should:

- run once per Python language-worker process during graceful host shutdown, local `func stop`, and scale-in;
- execute on the worker's active asyncio event loop so async SDK clients can be awaited safely;
- define ordering, timeout, cancellation, and exception-handling semantics;
- not run concurrently with new invocations after shutdown begins;
- work consistently for `FunctionApp` and Durable `DFApp` applications;
- remain process-local when `FUNCTIONS_WORKER_PROCESS_COUNT` or scale-out creates multiple workers.

This enables deterministic cleanup of module-level/shared Azure SDK clients while following Azure Functions guidance to reuse SDK client instances across invocations.

### Relevant sample code snipped

```python
import azure.functions as func

app = func.FunctionApp()

@app.on_startup
async def startup() -> None:
await resources.initialize()

@app.on_shutdown
async def shutdown() -> None:
await resources.close()
```

The exact API shape is open for discussion; a registration API or worker-extension lifecycle contract would also satisfy the requirement.

### Additional Information

Azure Functions recommends sharing SDK clients across invocations to reduce latency, socket exhaustion, and SNAT pressure:

https://learn.microsoft.com/azure/azure-functions/manage-connections#manage-sdk-client-connections

Today `FunctionApp` and `DFApp` do not expose a supported async shutdown hook. Libraries must choose between per-invocation client churn, process-lifetime clients without deterministic cleanup, or fragile `atexit`/signal handling that may run after the event loop is unavailable.

A concrete example is Azure/azure-functions-agents-runtime#157 and its proposed fix in Azure/azure-functions-agents-runtime#158. Microsoft Foundry clients own both async httpx and aiohttp transports. Sharing these clients fixes steady-state connection churn, but deterministic graceful shutdown cannot be integrated safely without a worker lifecycle hook.

Suggested acceptance coverage:

- async callback executes on the worker event loop;
- exactly once per process for graceful stop and scale-in;
- callback completion is bounded by a documented timeout;
- callback errors are logged without skipping other registered callbacks;
- no new invocation begins after shutdown callbacks start;
- Core Tools integration test covers `func start` followed by graceful stop;
- multiple worker processes each invoke their own callbacks.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.