Skip to content

httpx dependency is unbounded while the SDK imports httpx private modules, so httpx 1.0 will break installs #568

Description

@corinagum

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:

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 <module>
    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:

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions