microsoft / microsoft/simplechat
Native Python App Service fails to start when AnyIO imports typing_extensions.sentinel
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 152
- Forks
- 116
- Avg merge
- 7h 7m
- Merged PRs (30d)
- 122
Description
## Summary
A native Python deployment of `application/single_app` to an Azure App Service deployment slot fails during Gunicorn worker startup.
The application never reaches Flask initialization because the Semantic Kernel MCP dependency chain raises an `ImportError` while importing AnyIO.
## Environment
- Azure App Service on Linux
- Native Python runtime
- Python 3.12.13
- Oryx build
- Gunicorn 25.0.3
- Startup command:
```text
python -m gunicorn -c gunicorn.conf.py app:app
```
- Deployment unit: `application/single_app`
- Affected application version: `0.261.030`
## Error
```text
ImportError: cannot import name 'sentinel' from 'typing_extensions'
(/agents/python/typing_extensions.py)
```
The relevant import chain is:
```text
app.py
-> semantic_kernel_loader.py
-> semantic_kernel_plugins/logged_plugin_loader.py
-> semantic_kernel_plugins/mcp_plugin_factory.py
-> semantic_kernel.connectors.mcp
-> mcp.client.session
-> anyio.streams.memory
-> anyio._core._typedattr
-> typing_extensions.sentinel
```
Both Gunicorn workers fail during startup and exit before the application can serve requests.
## Root Cause
Oryx prepends the App Service platform agent directory to `PYTHONPATH`:
```text
/agents/python:/opt/startup/app_logs:
```
As a result, `/agents/python/typing_extensions.py` shadows the newer `typing-extensions` package installed in the application's virtual environment.
The application's dependency set did not constrain AnyIO. It could therefore resolve AnyIO 4.11 or later, which imports `sentinel` from `typing_extensions`. The older App Service platform copy does not provide that symbol.
This creates an incompatibility between:
- AnyIO 4.11 or later
- The older `typing_extensions` module injected by the App Service platform agent
- The Semantic Kernel to MCP startup import path
## Proposed Fix
Pin AnyIO to version 4.10.0 in:
```text
application/single_app/requirements.txt
```
```text
anyio==4.10.0
```
AnyIO 4.10.0 is the latest release before the `typing_extensions.sentinel` import was introduced. It remains compatible with the dependency ranges declared by Semantic Kernel 1.39.4 and MCP.
The deployment must perform a fresh Oryx dependency build after applying the pin so the previous AnyIO installation is not reused.
## Validation Performed
- Confirmed AnyIO 4.11.0 imports `sentinel` from `typing_extensions`.
- Confirmed AnyIO 4.10.0 does not import that symbol.
- Confirmed `anyio.streams.memory` from AnyIO 4.10.0 imports successfully with `typing-extensions` 4.11.0.
- Confirmed pip can resolve:
- `semantic-kernel==1.39.4`
- `mcp==1.30.0`
- `anyio==4.10.0`
- `typing-extensions==4.16.0`
## Acceptance Criteria
- Native Python App Service deployments complete Gunicorn worker initialization.
- Semantic Kernel and MCP modules import successfully when the App Service agent directory precedes the application environment on `PYTHONPATH`.
- `requirements.txt` explicitly constrains AnyIO to the compatible release.
- Regression coverage verifies the compatibility constraint.
- A fresh deployment slot build starts and responds successfully.
## Impact
This blocks startup for affected native Python App Service deployments. Container-based deployments are not expected to be affected because they use the dependencies and import paths contained in the repository image.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with application/single_app/requirements.txt and reproduce the import using the App Service agent directory before the application environment on PYTHONPATH. Constrain AnyIO to 4.10.0, add regression coverage for the compatibility constraint, then perform a fresh Oryx deployment and verify Gunicorn, Semantic Kernel, and MCP initialize successfully.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- azure, python
- Domain
- backend, cloud
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 74/100