microsoft / microsoft/teams.py
httpx dependency is unbounded while the SDK imports httpx private modules, so httpx 1.0 will break installs
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 65
- Forks
- 30
- Avg merge
- 1d 4h
- Merged PRs (30d)
- 23
Description
## Summary
`microsoft-teams-common` imports from httpx's **private** modules while declaring an **unbounded** httpx requirement. httpx 1.0 removes those modules, so once 1.0 is released as stable, a fresh `pip install microsoft-teams-apps` will resolve to httpx 1.0 and fail at import time.
This is not yet affecting users: current httpx stable is 0.28.1, and dev releases aren't selected by default resolvers. Filing it now because httpx 1.0 is actively moving (`1.0.dev4` was published 2026-08-19) and this breaks the moment it ships.
## The two halves of the problem
**1. Private API imports** in `packages/common/src/microsoft_teams/common/http/client.py`:
```python
from httpx._models import Request, Response
from httpx._types import QueryParamTypes, RequestContent, RequestData, RequestFiles
```
**2. No upper bound** on the requirement:
| File | Constraint |
|---|---|
| `packages/common/pyproject.toml` | `httpx>=0.28.1` |
| `packages/apps/pyproject.toml` | `httpx>=0.27.0` |
| `examples/a2a/pyproject.toml` | `httpx>=0.27` |
Either alone would be survivable. Together they mean the next httpx major silently becomes an install-time failure.
## Reproduction
```
$ uv pip install --prerelease=allow "httpx==1.0.dev4" "microsoft-teams-api==2.1.0a2"
$ python -c "import microsoft_teams.api"
...
File ".../microsoft_teams/common/http/client.py", line 13, in
from httpx._models import Request, Response
ModuleNotFoundError: No module named 'httpx._models'
```
I hit this accidentally while verifying the 2.1.0a2 release: `--prerelease=allow` applied globally, pulled httpx `1.0.dev4`, and every `import microsoft_teams.*` failed.
## Why 1.0 breaks it
httpx 1.0 is a significant restructure. `_models.py` and `_types.py` no longer exist; the module layout is now `_request.py`, `_response.py`, `_client.py`, `_content.py`, and friends.
```
httpx 0.28.1 : httpx._models OK, httpx._types OK
httpx 1.0.dev4: httpx._models -> ModuleNotFoundError
httpx._types -> ModuleNotFoundError
```
## Fixing the imports
The two lines are not equally easy.
`Request` and `Response` are public in both 0.x and 1.0, so that import has a direct public replacement:
```python
from httpx import Request, Response
```
The `_types` aliases (`QueryParamTypes`, `RequestContent`, `RequestData`, `RequestFiles`) are the harder half. They are **not** exported publicly in 0.x or 1.0, so there is no drop-in swap. Options: define our own type aliases in `common/http`, or loosen those annotations. Worth a deliberate decision rather than a mechanical edit, since they appear in public method signatures.
## Suggested actions
1. Switch `Request`/`Response` to the public `from httpx import ...` (safe, works on both).
2. Decide how to replace the `_types` aliases, most likely SDK-owned aliases in `common/http`.
3. Add an upper bound (`httpx>=0.28.1,<1.0`) as a stopgap so a future httpx release can't break installs before 1 and 2 land.
Doing 3 alone is enough to stop the bleeding, but it shouldn't be the permanent answer: the underlying issue is depending on private API.
## Affected
`main`, `release/v2.0` (2.0.16), and `release/v2.1` (2.1.0a2) all carry both private imports and the unbounded constraint.
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 packages/common/src/microsoft_teams/common/http/client.py and the httpx constraints in packages/common/pyproject.toml, packages/apps/pyproject.toml, and examples/a2a/pyproject.toml. Reproduce the import failure with httpx 1.0.dev4, then determine how to replace the private type aliases and bound the dependency. Done means the SDK imports successfully without private httpx modules and future installs cannot select an incompatible major release.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend-api-design, build-system
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 56/100