Add Web PubSub Chat service client - #48882
Conversation
|
Azure Pipelines: Successfully started running 1 pipeline(s). 10 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
There was a problem hiding this comment.
🔵 Needs a closer look
The new authentication client has blocking package-coexistence, credential-exposure, live-test, and spec-reproducibility issues.
Pull request overview
Adds the initial preview of the Azure Web PubSub Chat service client, including authentication, synchronous/asynchronous APIs, documentation, samples, and live-test infrastructure.
Changes:
- Adds generated Chat service clients, models, paging operations, and custom token authentication.
- Adds packaging metadata, API snapshots, documentation, and samples.
- Adds unit/live tests, test resources, and CI registration.
File summaries
| File | Description |
|---|---|
.chronus/changes/webpubsub-chat-customization-2026-08-17.md |
Records the feature addition. |
eng/ignore-links.txt |
Excludes pre-publication links. |
sdk/webpubsub/ci.yml |
Registers the package artifact. |
sdk/webpubsub/tests.yml |
Uses explicit package selection. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/CHANGELOG.md |
Documents the preview release. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/LICENSE |
Adds licensing terms. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/MANIFEST.in |
Configures source distribution contents. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/README.md |
Documents setup and usage. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/_metadata.json |
Records the service API version. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/api.md |
Captures the public API surface. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/api.metadata.yml |
Records API snapshot metadata. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/apiview-properties.json |
Maps cross-language API definitions. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/assets.json |
References test assets. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/dev_requirements.txt |
Adds development dependencies. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/package-lock.json |
Adds npm lock metadata. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/pyproject.toml |
Defines package metadata and dependencies. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/setup.py |
Adds setuptools packaging support. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/test-resources.bicep |
Provisions live-test resources. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/tests.yml |
Defines package live-test CI. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/tsp-location.yaml |
Pins the generating specification. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/__init__.py |
Declares the Azure namespace. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/__init__.py |
Declares the messaging namespace. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/__init__.py |
Adds the parent package initializer. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/__init__.py |
Exports the synchronous client. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/_client.py |
Implements the generated sync client. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/_configuration.py |
Configures sync policies. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/_constants.py |
Defines built-in Chat roles. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/_operations/__init__.py |
Initializes sync operations. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/_operations/_operations.py |
Implements sync REST operations. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/_operations/_patch.py |
Provides operation customization hooks. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/_patch.py |
Customizes sync authentication and tokens. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/_shared.py |
Adds shared authentication helpers. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/_utils/__init__.py |
Initializes generated utilities. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/_utils/model_base.py |
Supports generated models. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/_utils/serialization.py |
Supports wire serialization. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/_utils/utils.py |
Handles conditional request headers. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/_version.py |
Defines version 1.0.0b1. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/aio/__init__.py |
Exports the asynchronous client. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/aio/_client.py |
Implements the generated async client. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/aio/_configuration.py |
Configures async policies. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/aio/_operations/__init__.py |
Initializes async operations. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/aio/_operations/_operations.py |
Implements async REST operations. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/aio/_operations/_patch.py |
Provides async operation hooks. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/aio/_patch.py |
Customizes async authentication and tokens. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/models/__init__.py |
Exports generated models. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/models/_enums.py |
Defines permissions and user kinds. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/models/_models.py |
Defines Chat resource models. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/models/_patch.py |
Provides model customization hooks. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/py.typed |
Marks typed package support. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/types.py |
Defines JSON-compatible typed dictionaries. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/generated_tests/conftest.py |
Configures generated tests. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/generated_tests/testpreparer.py |
Prepares generated sync tests. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/generated_tests/testpreparer_async.py |
Prepares generated async tests. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/generated_tests/test_web_pub_sub_chat_service.py |
Adds generated sync operation tests. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/generated_tests/test_web_pub_sub_chat_service_async.py |
Adds generated async operation tests. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/tests/chat_message_seed.py |
Seeds messages through WebSockets. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/tests/conftest.py |
Configures test proxy behavior. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/tests/test_chat_message_seed.py |
Tests WebSocket seeding helpers. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/tests/test_client.py |
Tests synchronous custom behavior. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/tests/test_client_async.py |
Tests asynchronous custom behavior. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/tests/test_live.py |
Exercises synchronous service workflows. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/tests/test_live_async.py |
Exercises asynchronous service workflows. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/tests/testcase.py |
Provides shared live-test helpers. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/samples/sample_authentication.py |
Demonstrates authentication options. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/samples/sample_client_access.py |
Demonstrates sync client credentials. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/samples/sample_client_access_async.py |
Demonstrates async client credentials. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/samples/sample_message_history.py |
Demonstrates sync message history. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/samples/sample_message_history_async.py |
Demonstrates async message history. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/samples/sample_message_management.py |
Demonstrates message updates and deletion. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/samples/sample_roles_and_permissions.py |
Demonstrates sync resource management. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/samples/sample_roles_and_permissions_async.py |
Demonstrates async resource management. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/generated_samples/chat/create_or_replace_role.py |
Generated role creation sample. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/generated_samples/chat/create_or_replace_room.py |
Generated room creation sample. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/generated_samples/chat/create_or_replace_room_member.py |
Generated membership creation sample. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/generated_samples/chat/create_or_replace_user.py |
Generated user creation sample. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/generated_samples/chat/delete_message.py |
Generated message deletion sample. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/generated_samples/chat/delete_role.py |
Generated role deletion sample. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/generated_samples/chat/delete_room.py |
Generated room deletion sample. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/generated_samples/chat/delete_room_member.py |
Generated membership deletion sample. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/generated_samples/chat/delete_user.py |
Generated user deletion sample. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/generated_samples/chat/get_conversation.py |
Generated conversation retrieval sample. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/generated_samples/chat/get_role.py |
Generated role retrieval sample. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/generated_samples/chat/get_room.py |
Generated room retrieval sample. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/generated_samples/chat/get_user.py |
Generated user retrieval sample. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/generated_samples/chat/list_messages.py |
Generated message listing sample. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/generated_samples/chat/list_roles.py |
Generated role listing sample. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/generated_samples/chat/list_room_members.py |
Generated membership listing sample. |
sdk/webpubsub/azure-messaging-webpubsubchatservice/generated_samples/chat/update_message.py |
Generated message update sample. |
Review details
Files not reviewed (1)
- sdk/webpubsub/azure-messaging-webpubsubchatservice/package-lock.json: Generated file
- Files reviewed: 86/88 changed files
- Comments generated: 5
- Review effort level: Balanced
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
| @@ -0,0 +1 @@ | |||
| __path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore | |||
| raise ValueError( | ||
| "Malformed connection string - expected 'key=value', found segment '{}' in '{}'".format( | ||
| segment, connection_string | ||
| ) | ||
| ) |
| :rtype: str | ||
| """ | ||
| audience = endpoint + path + hub | ||
| ttl = timedelta(minutes=minutes_to_expire) |
| async def test_async_client_access_token( | ||
| self, | ||
| wps_chat_endpoint, | ||
| wps_chat_connection_string, | ||
| ): | ||
| token_client = self.create_async_client(wps_chat_endpoint) | ||
| key_client = self.create_async_key_client(wps_chat_connection_string) | ||
| try: | ||
| token_access = await token_client.get_client_access_token( | ||
| user_id="python-async-e2e-token-access-user" | ||
| ) | ||
| await self.assert_client_access_async(token_access, wps_chat_endpoint) | ||
|
|
||
| key_access = await key_client.get_client_access_token( | ||
| user_id="python-async-e2e-key-access-user" | ||
| ) | ||
| await self.assert_client_access_async(key_access, wps_chat_endpoint) | ||
| finally: | ||
| await token_client.close() | ||
| await key_client.close() |
| @@ -0,0 +1,5 @@ | |||
| directory: specification/webpubsub/data-plane/WebPubSubChat | |||
| commit: f58a62e4a14eb2fdb76a6826646e08fc18aac208 | |||
060288d to
6d547e2
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Namespace compatibility, test configuration, typing, and resource-security defects must be resolved.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Files not reviewed (1)
- sdk/webpubsub/azure-messaging-webpubsubchatservice/package-lock.json: Generated file
- Files reviewed: 86/88 changed files
- Comments generated: 6
- Review effort level: Balanced
| # The Chat client currently ships separately under this namespace. Extend the | ||
| # path so both distributions can coexist; revisit after Architecture Board review. | ||
| __path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore |
| request.http_request.headers["Authorization"] = "Bearer " + self._encode(url) | ||
| return super(JwtCredentialPolicy, self).on_request(request) | ||
|
|
||
| def _encode(self, url: AzureKeyCredential) -> str: |
| properties: { | ||
| allowBlobPublicAccess: false | ||
| minimumTlsVersion: 'TLS1_2' |
| if wps_chat_disable_local_auth.lower() == "true": | ||
| pytest.skip("Local authentication is disabled") | ||
|
|
||
| token_client = self.create_async_client(wps_chat_endpoint) | ||
| key_client = self.create_async_key_client(wps_chat_connection_string) | ||
| try: | ||
| token_access = await token_client.get_client_access_token( | ||
| user_id="python-async-e2e-token-access-user" | ||
| ) | ||
| await self.assert_client_access_async(token_access, wps_chat_endpoint) | ||
|
|
||
| key_access = await key_client.get_client_access_token( | ||
| user_id="python-async-e2e-key-access-user" | ||
| ) | ||
| await self.assert_client_access_async(key_access, wps_chat_endpoint) | ||
| finally: | ||
| await token_client.close() | ||
| await key_client.close() |
| wps_chat_connection_string=( | ||
| "Endpoint=https://myservice.webpubsub.azure.com;" | ||
| "AccessKey=ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGH;" | ||
| ), | ||
| ) |
| default: | ||
| - azure-mgmt-webpubsub | ||
| - azure-messaging-webpubsubservice | ||
| - azure-messaging-webpubsubclient |
There was a problem hiding this comment.
🟡 Changes recommended
The generation pin does not reproduce the submitted API, and safe-secret live runs skip Entra token coverage.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Files not reviewed (1)
- sdk/webpubsub/azure-messaging-webpubsubchatservice/package-lock.json: Generated file
Suppressed comments (2)
sdk/webpubsub/azure-messaging-webpubsubchatservice/tests/test_live_async.py:304
- Safe-secret runs disable local authentication, but the Entra-backed token request remains valid and should still be exercised. The early skip currently removes the only live coverage for that path; create and assert the key client only when local auth is enabled.
sdk/webpubsub/azure-messaging-webpubsubchatservice/tsp-location.yaml:2 - The pinned source commit predates the linked correction PR, but this generated surface already includes corrections from that PR (for example,
ChatPermission, which #44881 adds tomodels.tsp). Regenerating from this file will therefore produce a different API and discard those corrections. Please update the pin to the merged correction commit and regenerate before merging this SDK.
- Files reviewed: 89/91 changed files
- Comments generated: 1
- Review effort level: Balanced
There was a problem hiding this comment.
🔵 Needs a closer look
Client input validation is inconsistent and the JWT helper has an incorrect type annotation.
Review details
Files not reviewed (1)
- sdk/webpubsub/azure-messaging-webpubsubchatservice/package-lock.json: Generated file
Suppressed comments (3)
Previously missed (2) — in code that hasn't changed since the last review.
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/_patch.py:116
- This slices the endpoint as though it is always HTTP(S), so values such as
example.comorftp://...produce malformed WebSocket URLs instead of rejecting the documented-invalid endpoint.minutes_to_expireis also validated only in the key-credential branch; token credentials send non-positive values to the service. Validate both inputs before branching so both authentication modes behave consistently.
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/aio/_patch.py:113 - This async path has the same input inconsistency as the sync client: slicing assumes an HTTP(S) endpoint and silently creates a malformed WebSocket URL for any other scheme, while non-positive expiration is rejected only for key credentials. Validate both values before selecting the authentication path.
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/_shared.py:62
on_requestpassesrequest.http_request.urlhere, which is a string, not anAzureKeyCredential. The incorrect annotation misdocuments the helper and causes static type checkers to flag the call.
def _encode(self, url: AzureKeyCredential) -> str:
- Files reviewed: 89/91 changed files
- Comments generated: 0 new
- Review effort level: Balanced
There was a problem hiding this comment.
🟡 Changes recommended
Endpoint validation, split-package compatibility, and an incorrect type contract must be addressed before approval.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Files not reviewed (1)
- sdk/webpubsub/azure-messaging-webpubsubchatservice/package-lock.json: Generated file
Suppressed comments (3)
Previously missed (2) — in code that hasn't changed since the last review.
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/_patch.py:118
endpoint[4:]assumes an HTTP(S) prefix. Inputs such asmyservice.webpubsub.azure.comor another scheme therefore return a malformed WebSocket URL instead of the validation error provided by the existing Web PubSub client. Reject unsupported schemes before slicing the endpoint.
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/aio/_patch.py:115- The async path has the same unchecked
endpoint[4:]assumption as the sync client, so a non-HTTP(S) endpoint produces an invalid access URL. Validate the scheme before deriving the WebSocket URL.
sdk/webpubsub/azure-messaging-webpubsubchatservice/azure/messaging/webpubsubservice/chat/_shared.py:62
_encodereceivesrequest.http_request.urland uses it as the JWT audience, so this parameter is a string rather than anAzureKeyCredential. The current annotation gives static analysis and maintainers an incorrect contract.
def _encode(self, url: AzureKeyCredential) -> str:
- Files reviewed: 90/92 changed files
- Comments generated: 1
- Review effort level: Balanced
| dependencies = [ | ||
| "isodate>=0.6.1", | ||
| "azure-core>=1.37.0", | ||
| "pyjwt>=2.6.0", | ||
| "typing-extensions>=4.6.0", | ||
| ] |
yzt (Y-Sindo)
left a comment
There was a problem hiding this comment.
I found two issues in the current revision.
| request.http_request.headers["Authorization"] = "Bearer " + self._encode(url) | ||
| return super(JwtCredentialPolicy, self).on_request(request) | ||
|
|
||
| def _encode(self, url: AzureKeyCredential) -> str: |
There was a problem hiding this comment.
url comes from request.http_request.url and is used as the JWT aud string, so AzureKeyCredential is the wrong annotation here. Please annotate it as str; the credential is already held in self._credential.
Description
Add an initial version of Web PubSub Chat service client.
Generated from Spec
All SDK Contribution checklist:
General Guidelines and Best Practices
Testing Guidelines