Skip to content

Supporting RestChannelServiceClientFactory configuration from ChannelAdapter constructor - #513

Merged
Rodrigo Brandão (rodrigobr-msft) merged 4 commits into
mainfrom
users/robrandao/regionalized-client
Jul 31, 2026
Merged

Supporting RestChannelServiceClientFactory configuration from ChannelAdapter constructor#513
Rodrigo Brandão (rodrigobr-msft) merged 4 commits into
mainfrom
users/robrandao/regionalized-client

Conversation

@rodrigobr-msft

Copy link
Copy Markdown
Contributor

This pull request adds support for configuring the token_service_endpoint for the user token client in both the aiohttp and fastapi CloudAdapter classes. This is achieved by allowing an options dictionary to be passed to the channel service client factory, and by testing that the correct endpoint is used. The main changes are grouped below.

Feature: Configurable Token Service Endpoint

  • Added a channel_service_client_factory_options parameter to the CloudAdapter constructors in both aiohttp and fastapi adapters, allowing users to specify options such as token_service_endpoint. [1] [2]
  • Updated the base HTTP adapter (_http_adapter_base.py) to accept and forward channel_service_client_factory_options when constructing the channel service client factory, ensuring these options are used in client creation. [1] [2]

Testing

  • Added integration tests for both the aiohttp and fastapi adapters to verify that the UserTokenClient is correctly configured with the provided token_service_endpoint. [1] [2]…Adapter creation

Copilot AI review requested due to automatic review settings July 31, 2026 17:15
@rodrigobr-msft Rodrigo Brandão (rodrigobr-msft) linked an issue Jul 31, 2026 that may be closed by this pull request

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the HTTP-based hosting adapters (aiohttp/FastAPI) to allow configuring RestChannelServiceClientFactory construction via a channel_service_client_factory_options dictionary, enabling scenarios like overriding the token_service_endpoint used by UserTokenClient.

Changes:

  • Added channel_service_client_factory_options to aiohttp and FastAPI CloudAdapter constructors and forwarded it to the base adapter.
  • Updated HttpAdapterBase to pass the options through when instantiating RestChannelServiceClientFactory.
  • Added integration tests to verify UserTokenClient uses the configured token service endpoint.

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
libraries/microsoft-agents-hosting-fastapi/microsoft_agents/hosting/fastapi/cloud_adapter.py Exposes and forwards factory options from the FastAPI adapter constructor.
libraries/microsoft-agents-hosting-aiohttp/microsoft_agents/hosting/aiohttp/cloud_adapter.py Exposes and forwards factory options from the aiohttp adapter constructor.
libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/_http_adapter_base.py Wires the options into RestChannelServiceClientFactory construction.
dev/integration/tests/adapter/test_fastapi_cloud_adapter.py Adds integration coverage for configured token service endpoint (FastAPI).
dev/integration/tests/adapter/test_aiohttp_cloud_adapter.py Adds integration coverage for configured token service endpoint (aiohttp).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread dev/integration/tests/adapter/test_aiohttp_cloud_adapter.py
Comment thread dev/integration/tests/adapter/test_fastapi_cloud_adapter.py

@kylerohn-msft Kyle Rohn (kylerohn-msft) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changelog

Copilot AI review requested due to automatic review settings July 31, 2026 20:07
@rodrigobr-msft
Rodrigo Brandão (rodrigobr-msft) marked this pull request as ready for review July 31, 2026 20:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (3)

libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/_http_adapter_base.py:75

  • channel_service_client_factory_options is expanded directly into RestChannelServiceClientFactory via **kwargs. If a caller passes an unknown/typo key, this will raise a generic TypeError ("unexpected keyword argument") during adapter construction. Consider validating the allowed option keys and raising a clearer ValueError so API consumers get an actionable error message.
            factory = RestChannelServiceClientFactory(
                connection_manager,
                **(channel_service_client_factory_options or {}),
            )

dev/integration/tests/adapter/test_fastapi_cloud_adapter.py:50

  • This test asserts against aiohttp ClientSession's private attribute client._base_url. That makes the test brittle across aiohttp versions and also bakes in an internal detail of UserTokenClient. Prefer asserting via a public surface (e.g., expose the configured endpoint on UserTokenClient) so the test validates behavior without depending on private internals.
    try:
        assert str(client.client._base_url) == f"{token_service_endpoint}/"

dev/integration/tests/adapter/test_aiohttp_cloud_adapter.py:50

  • This test asserts against aiohttp ClientSession's private attribute client._base_url. That makes the test brittle across aiohttp versions and also bakes in an internal detail of UserTokenClient. Prefer asserting via a public surface (e.g., expose the configured endpoint on UserTokenClient) so the test validates behavior without depending on private internals.
    try:
        assert str(client.client._base_url) == f"{token_service_endpoint}/"

Copilot AI review requested due to automatic review settings July 31, 2026 20:11
@rodrigobr-msft
Rodrigo Brandão (rodrigobr-msft) merged commit c0ea087 into main Jul 31, 2026
9 of 10 checks passed
@rodrigobr-msft
Rodrigo Brandão (rodrigobr-msft) deleted the users/robrandao/regionalized-client branch July 31, 2026 20:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (4)

libraries/microsoft-agents-hosting-fastapi/microsoft_agents/hosting/fastapi/cloud_adapter.py:36

  • The docstring doesn’t indicate which keys are valid in channel_service_client_factory_options or that they are forwarded as keyword args to RestChannelServiceClientFactory. Listing supported keys (at least token_service_endpoint and token_service_audience) will prevent confusing runtime TypeError: __init__() got an unexpected keyword ... errors for typos.
        :param channel_service_client_factory_options: Optional dictionary of options to pass to the channel service client factory
            This is only used if channel_service_client_factory is not provided and connection_manager is provided.

libraries/microsoft-agents-hosting-aiohttp/microsoft_agents/hosting/aiohttp/cloud_adapter.py:35

  • The docstring doesn’t indicate which keys are valid in channel_service_client_factory_options or that they are forwarded as keyword args to RestChannelServiceClientFactory. Listing supported keys (at least token_service_endpoint and token_service_audience) will prevent confusing runtime TypeError: __init__() got an unexpected keyword ... errors for typos.
        :param channel_service_client_factory_options: Optional dictionary of options to pass to the channel service client factory
            This is only used if channel_service_client_factory is not provided and connection_manager is provided.

changelog.md:4

  • The release note says “Added optional argument to CloudAdapter to configure Token Service endpoint…”, but the actual API added is channel_service_client_factory_options (a dict forwarded as kwargs to RestChannelServiceClientFactory). Naming the parameter and the supported key(s) will make the changelog accurate and actionable for users.
- **Regionalized UserTokenClient Support**: Added optional argument to `CloudAdapter` to configure Token Service endpoint used by `RestChannelServiceClientFactory` when creating `UserTokenClient` instances. 

libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/_http_adapter_base.py:75

  • The new wiring that forwards channel_service_client_factory_options into RestChannelServiceClientFactory isn’t covered by the default CI test run: root pytest.ini sets testpaths = tests, so the newly added adapter tests under dev/integration/tests/adapter/ won’t execute in CI. To ensure regressions are caught, consider moving/duplicating these assertions into tests/hosting_aiohttp/ and tests/hosting_fastapi/, or updating the CI pytest invocation/config to include the dev integration suite.
            factory = RestChannelServiceClientFactory(
                connection_manager,
                **(channel_service_client_factory_options or {}),
            )

Copilot AI review requested due to automatic review settings July 31, 2026 20:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (7)

libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/_http_adapter_base.py:75

  • Using truthiness checks for channel_service_client_factory / connection_manager can mis-handle valid objects that define falsy __bool__/__len__. Also, if channel_service_client_factory_options contains invalid keys or non-string keys, the resulting TypeError is raised from RestChannelServiceClientFactory without any adapter context; wrapping it makes the error easier to diagnose for callers.
            factory = RestChannelServiceClientFactory(
                connection_manager,
                **(channel_service_client_factory_options or {}),
            )

libraries/microsoft-agents-hosting-aiohttp/microsoft_agents/hosting/aiohttp/cloud_adapter.py:36

  • channel_service_client_factory_options doesn’t state what options are accepted. Since this is a new public constructor parameter, it should at least name the primary supported key(s) (e.g., token_service_endpoint) so users don’t need to read the core factory implementation to discover them.
        :param connection_manager: Optional connection manager for OAuth.
        :param channel_service_client_factory: Factory for creating channel service clients.
        :param channel_service_client_factory_options: Optional dictionary of options to pass to the channel service client factory
            This is only used if channel_service_client_factory is not provided and connection_manager is provided.
        """

libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/_http_adapter_base.py:44

  • channel_service_client_factory_options is documented as a generic dict, but it doesn’t describe which keys are supported (or that they must match RestChannelServiceClientFactory keyword args). This makes the new public API hard to discover and use correctly.
        :param connection_manager: Optional connection manager for OAuth.
        :param channel_service_client_factory: Factory for creating channel service clients.
        :param channel_service_client_factory_options: Optional dictionary of options to pass to the channel service client factory
            This is only used if channel_service_client_factory is not provided and connection_manager is provided.

libraries/microsoft-agents-hosting-fastapi/microsoft_agents/hosting/fastapi/cloud_adapter.py:36

  • channel_service_client_factory_options doesn’t state what options are accepted. Since this is a new public constructor parameter, it should at least name the primary supported key(s) (e.g., token_service_endpoint) so users don’t need to read the core factory implementation to discover them.
        :param connection_manager: Optional connection manager for OAuth.
        :param channel_service_client_factory: Factory for creating channel service clients.
        :param channel_service_client_factory_options: Optional dictionary of options to pass to the channel service client factory
            This is only used if channel_service_client_factory is not provided and connection_manager is provided.

dev/integration/tests/adapter/test_fastapi_cloud_adapter.py:24

  • These tests live under dev/integration/tests, but the repo’s default CI workflow runs pytest from the repo root and only discovers testpaths = tests (see pytest.ini). As a result, this coverage won’t run in PR CI unless a separate workflow/job runs dev/integration’s pytest config.
@pytest.mark.asyncio
@pytest.mark.parametrize(
    "token_service_endpoint",
    [
        "https://europe.api.botframework.com",
        "https://unitedstates.api.botframework.com",
        "https://india.api.botframework.com",
    ],
)
async def test_cloud_adapter_configures_user_token_client_endpoint(

dev/integration/tests/adapter/test_aiohttp_cloud_adapter.py:24

  • These tests live under dev/integration/tests, but the repo’s default CI workflow runs pytest from the repo root and only discovers testpaths = tests (see pytest.ini). As a result, this coverage won’t run in PR CI unless a separate workflow/job runs dev/integration’s pytest config.
@pytest.mark.asyncio
@pytest.mark.parametrize(
    "token_service_endpoint",
    [
        "https://europe.api.botframework.com",
        "https://unitedstates.api.botframework.com",
        "https://india.api.botframework.com",
    ],
)
async def test_cloud_adapter_configures_user_token_client_endpoint(

changelog.md:4

  • The changelog entry is a bit ambiguous about what the new CloudAdapter argument is called, and it includes a trailing space at the end of the line. Naming the parameter and the primary option key makes the release note more actionable for users.
- **Regionalized UserTokenClient Support**: Added optional argument to `CloudAdapter` to configure Token Service endpoint used by `RestChannelServiceClientFactory` when creating `UserTokenClient` instances. 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Regionalized UserTokenClient endpoint support

3 participants