GitHub Copilot ChatGPT Claude Codex CLI Cursor opencode Skill Text

azure-messaging-webpubsubservice-py

Azure Web PubSub Service SDK for Python. Use for real-time messaging, WebSocket connections, and pub/sub patterns. Triggers: "azure-messaging-webpubsubservice", "WebPubSubServiceClient", "real-time", "WebSocket", "pub/sub".

Ciza · 0 points · 10 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download microsoft-skills-.github_plugins_azure-sdk-python_skills_azure-messaging-webpubsubservice-py-e58528d.zip · 4 KB
Part of microsoft/skills — 195 skills

Install

skills CLI npx skills add https://github.com/microsoft/skills/tree/main/.github/plugins/azure-sdk-python/skills/azure-messaging-webpubsubservice-py
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install microsoft-skills@llmmart
Git git clone https://github.com/microsoft/skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole microsoft/skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Azure Web PubSub Service SDK for Python

Real-time messaging with WebSocket connections at scale.

Installation

# Service SDK (server-side)
pip install azure-messaging-webpubsubservice

# Client SDK (for Python WebSocket clients)
pip install azure-messaging-webpubsubclient

Environment Variables

AZURE_WEBPUBSUB_HUB=my-hub  # Required for all auth methods
AZURE_TOKEN_CREDENTIALS=prod # Required only if DefaultAzureCredential is used in production

Authentication & Lifecycle

🔑 Two rules apply to every code sample below:

  1. Prefer DefaultAzureCredential. It works locally (Azure CLI / VS Code / Developer CLI) and in Azure (managed identity, workload identity) with no code change. Avoid connection strings, account/API keys — they bypass Entra audit and rotation.
    • Local dev: DefaultAzureCredential works as-is.
    • Production: set AZURE_TOKEN_CREDENTIALS=prod (or AZURE_TOKEN_CREDENTIALS=<specific_credential>) to constrain the credential chain to production-safe credentials.
  2. Wrap every client in a context manager so HTTP transports, sockets, and token caches are released deterministically:
    • Sync: with <Client>(...) as client:
    • Async: async with <Client>(...) as client: and async with DefaultAzureCredential() as credential: (from azure.identity.aio)

Snippets may abbreviate this setup, but production code should always follow both rules.

Service Client (Server-Side)

Authentication

from azure.messaging.webpubsubservice import WebPubSubServiceClient
from azure.identity import DefaultAzureCredential, ManagedIdentityCredential

# Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=<specific_credential>
credential = DefaultAzureCredential(require_envvar=True)
# Or use a specific credential directly in production:
# See https://learn.microsoft.com/python/api/overview/azure/identity-readme?view=azure-python#credential-classes
# credential = ManagedIdentityCredential()

with WebPubSubServiceClient(
    endpoint="https://<name>.webpubsub.azure.com",
    hub="my-hub",
    credential=credential
) as client:
    # Use `client` for all subsequent operations (see examples below)
    ...

Generate Client Access Token

# Token for anonymous user
token = client.get_client_access_token()
print(f"URL: {token['url']}")

# Token with user ID
token = client.get_client_access_token(
    user_id="user123",
    roles=["webpubsub.sendToGroup", "webpubsub.joinLeaveGroup"]
)

# Token with groups
token = client.get_client_access_token(
    user_id="user123",
    groups=["group1", "group2"]
)

Send to All Clients

# Send text
client.send_to_all(message="Hello everyone!", content_type="text/plain")

# Send JSON
client.send_to_all(
    message={"type": "notification", "data": "Hello"},
    content_type="application/json"
)

Send to User

client.send_to_user(
    user_id="user123",
    message="Hello user!",
    content_type="text/plain"
)

Send to Group

client.send_to_group(
    group="my-group",
    message="Hello group!",
    content_type="text/plain"
)

Send to Connection

client.send_to_connection(
    connection_id="abc123",
    message="Hello connection!",
    content_type="text/plain"
)

Group Management

# Add user to group
client.add_user_to_group(group="my-group", user_id="user123")

# Remove user from group
client.remove_user_from_group(group="my-group", user_id="user123")

# Add connection to group
client.add_connection_to_group(group="my-group", connection_id="abc123")

# Remove connection from group
client.remove_connection_from_group(group="my-group", connection_id="abc123")

Connection Management

# Check if connection exists
exists = client.connection_exists(connection_id="abc123")

# Check if user has connections
exists = client.user_exists(user_id="user123")

# Check if group has connections
exists = client.group_exists(group="my-group")

# Close connection
client.close_connection(connection_id="abc123", reason="Session ended")

# Close all connections for user
client.close_all_connections(user_id="user123")

Grant/Revoke Permissions

from azure.messaging.webpubsubservice import WebPubSubServiceClient

# Grant permission
client.grant_permission(
    permission="joinLeaveGroup",
    connection_id="abc123",
    target_name="my-group"
)

# Revoke permission
client.revoke_permission(
    permission="joinLeaveGroup",
    connection_id="abc123",
    target_name="my-group"
)

# Check permission
has_permission = client.check_permission(
    permission="joinLeaveGroup",
    connection_id="abc123",
    target_name="my-group"
)

Client SDK (Python WebSocket Client)

from azure.messaging.webpubsubclient import WebPubSubClient

with WebPubSubClient(credential=token["url"]) as client:
    @client.on("connected")
    def on_connected(e):
        print(f"Connected: {e.connection_id}")

    @client.on("server-message")
    def on_message(e):
        print(f"Message: {e.data}")

    @client.on("group-message")
    def on_group_message(e):
        print(f"Group {e.group}: {e.data}")

    client.send_to_group("my-group", "Hello from Python!")

Async Service Client

from azure.messaging.webpubsubservice.aio import WebPubSubServiceClient
from azure.identity.aio import DefaultAzureCredential

async def broadcast():
    async with DefaultAzureCredential() as credential:
        async with WebPubSubServiceClient(
            endpoint="https://<name>.webpubsub.azure.com",
            hub="my-hub",
            credential=credential
        ) as client:
            await client.send_to_all("Hello async!", content_type="text/plain")

Client Operations

Operation Description
get_client_access_token Generate WebSocket connection URL
send_to_all Broadcast to all connections
send_to_user Send to specific user
send_to_group Send to group members
send_to_connection Send to specific connection
add_user_to_group Add user to group
remove_user_from_group Remove user from group
close_connection Disconnect client
connection_exists Check connection status

Best Practices

  1. Pick sync OR async and stay consistent. Do not mix azure.xxx sync clients with azure.xxx.aio async clients in the same call path. Choose one mode per module.
  2. Always use context managers for clients and async credentials. Wrap every client in with Client(...) as client: (sync) or async with Client(...) as client: (async). For async DefaultAzureCredential from azure.identity.aio, also use async with credential: so tokens and transports are cleaned up.
  3. Use DefaultAzureCredential for portable auth across local dev and Azure (avoid connection strings / access keys when possible).
  4. Use roles to limit client permissions
  5. Use groups for targeted messaging
  6. Generate short-lived tokens for security
  7. Use user IDs to send to users across connections
  8. Handle reconnection in client applications
  9. Use JSON content type for structured data
  10. Close connections gracefully with reasons

Reference Files

File Contents
references/capabilities.md Additional non-hero capabilities, operation-group coverage, and production checklists.
references/non-hero-scenarios.md Dedicated non-hero examples for secondary/advanced scenarios.
Files (skills)
  • references
    • capabilities.md 1.2 KB
      # azure-messaging-webpubsubservice-py capability coverage
      
      **SDK/package**: `azure-messaging-webpubsubservice`
      
      This index maps hero scenarios in `SKILL.md` and links non-hero scenarios documented in dedicated reference files.
      
      ## Hero scenarios covered in SKILL.md
      
      - `Service Client (Server-Side)`
      - `Client SDK (Python WebSocket Client)`
      - `Async Service Client`
      - `Client Operations`
      
      ## Non-hero scenarios
      
      - `Operational hardening`: Use this section for retries, timeouts, pagination, and cleanup patterns specific to this SDK.  
        See: [`non-hero-scenarios.md#operational-hardening`](non-hero-scenarios.md#operational-hardening)
      
      ## Related deep-dive references
      
      - [`non-hero-scenarios.md`](non-hero-scenarios.md): Dedicated non-hero examples and implementation notes.
      
      ## API breadth checklist
      
      - Verify client/auth mode for the environment before coding.
      - Confirm operation-group/method names against current Microsoft Learn API reference.
      - For Python SDKs with both sync and async clients, document both forms without a blanket preference.
      - Include cleanup/delete paths for created resources in examples.
      - Prefer idempotent create/update operations where available.
      - Validate paging/LRO/error-handling patterns for production paths.
      
    • non-hero-scenarios.md 3.3 KB
      # azure-messaging-webpubsubservice-py non-hero scenarios
      
      These scenarios are intentionally separate from hero flows in `SKILL.md`.
      They cover secondary/advanced patterns typically used after the primary end-to-end path is working.
      
      ## Operational hardening
      
      ### Retry Policy
      
      Configure retries for transient failures via `azure-core` retry policy:
      
      ```python
      import os
      from azure.messaging.webpubsubservice import WebPubSubServiceClient
      from azure.identity import DefaultAzureCredential
      from azure.core.pipeline.policies import RetryPolicy
      
      retry_policy = RetryPolicy(retry_total=3, retry_backoff_factor=2)
      credential = DefaultAzureCredential()
      
      with WebPubSubServiceClient(
          endpoint=os.environ["WEBPUBSUB_ENDPOINT"],
          hub=os.environ["AZURE_WEBPUBSUB_HUB"],
          credential=credential,
          retry_policy=retry_policy,
      ) as client:
          client.send_to_all("Hello!", content_type="text/plain")
      ```
      
      ### Broadcast with Connection Exclusion
      
      Send to all connections except the sender:
      
      ```python
      # Exclude the sender's connection ID from the broadcast
      client.send_to_all(
          message={"type": "chat", "text": "Hello everyone!"},
          content_type="application/json",
          excluded_connections=["sender-connection-id"],
      )
      ```
      
      ### Connection Lifecycle Check
      
      Verify connection and user state before sending:
      
      ```python
      connection_id = "abc123"
      user_id = "user123"
      
      if client.connection_exists(connection_id=connection_id):
          client.send_to_connection(
              connection_id=connection_id,
              message="You have a message!",
              content_type="text/plain",
          )
      
      if client.user_exists(user_id=user_id):
          client.send_to_user(
              user_id=user_id,
              message="Personal message",
              content_type="text/plain",
          )
      else:
          print(f"User {user_id} has no active connections")
      ```
      
      ### Group Cleanup
      
      Remove all connections from a group before deleting it:
      
      ```python
      # Remove a user from all groups, then close their connections
      client.remove_user_from_all_groups(user_id="user123")
      client.close_user_connections(user_id="user123", reason="Session ended")
      ```
      
      ### Short-lived Access Tokens
      
      Issue tokens with a limited TTL to reduce credential exposure:
      
      ```python
      from datetime import timedelta
      
      # 30-minute token with limited roles
      token = client.get_client_access_token(
          user_id="user123",
          roles=["webpubsub.sendToGroup.my-group"],
          minutes_to_expire=30,
          groups=["my-group"],
      )
      # Pass the URL directly to the authorized client — do not log it (it embeds a bearer token)
      connect_url = token["url"]
      ```
      
      ### Async Client
      
      Use the async client for high-concurrency workloads:
      
      ```python
      import os
      from azure.messaging.webpubsubservice.aio import WebPubSubServiceClient
      from azure.identity.aio import DefaultAzureCredential
      
      async def broadcast_notifications(user_ids: list[str], message: str):
          async with DefaultAzureCredential() as credential:
              async with WebPubSubServiceClient(
                  endpoint=os.environ["WEBPUBSUB_ENDPOINT"],
                  hub=os.environ["AZURE_WEBPUBSUB_HUB"],
                  credential=credential,
              ) as client:
                  for user_id in user_ids:
                      if await client.user_exists(user_id=user_id):
                          await client.send_to_user(
                              user_id=user_id,
                              message=message,
                              content_type="text/plain",
                          )
      ```
      
  • SKILL.md 7.9 KB
    ---
    name: azure-messaging-webpubsubservice-py
    description: |
      Azure Web PubSub Service SDK for Python. Use for real-time messaging, WebSocket connections, and pub/sub patterns.
      Triggers: "azure-messaging-webpubsubservice", "WebPubSubServiceClient", "real-time", "WebSocket", "pub/sub".
    license: MIT
    metadata:
      author: Microsoft
      version: "1.0.0"
      package: azure-messaging-webpubsubservice
    ---
    
    # Azure Web PubSub Service SDK for Python
    
    Real-time messaging with WebSocket connections at scale.
    
    ## Installation
    
    ```bash
    # Service SDK (server-side)
    pip install azure-messaging-webpubsubservice
    
    # Client SDK (for Python WebSocket clients)
    pip install azure-messaging-webpubsubclient
    ```
    
    ## Environment Variables
    
    ```bash
    AZURE_WEBPUBSUB_HUB=my-hub  # Required for all auth methods
    AZURE_TOKEN_CREDENTIALS=prod # Required only if DefaultAzureCredential is used in production
    ```
    
    ## Authentication & Lifecycle
    
    > **🔑 Two rules apply to every code sample below:**
    >
    > 1. **Prefer `DefaultAzureCredential`.** It works locally (Azure CLI / VS Code / Developer CLI) and in Azure (managed identity, workload identity) with no code change. Avoid connection strings, account/API keys — they bypass Entra audit and rotation.
    >    - Local dev: `DefaultAzureCredential` works as-is.
    >    - Production: set `AZURE_TOKEN_CREDENTIALS=prod` (or `AZURE_TOKEN_CREDENTIALS=<specific_credential>`) to constrain the credential chain to production-safe credentials.
    > 2. **Wrap every client in a context manager** so HTTP transports, sockets, and token caches are released deterministically:
    >    - Sync: `with <Client>(...) as client:`
    >    - Async: `async with <Client>(...) as client:` **and** `async with DefaultAzureCredential() as credential:` (from `azure.identity.aio`)
    >
    > Snippets may abbreviate this setup, but production code should always follow both rules.
    
    ## Service Client (Server-Side)
    
    ### Authentication
    
    ```python
    from azure.messaging.webpubsubservice import WebPubSubServiceClient
    from azure.identity import DefaultAzureCredential, ManagedIdentityCredential
    
    # Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=<specific_credential>
    credential = DefaultAzureCredential(require_envvar=True)
    # Or use a specific credential directly in production:
    # See https://learn.microsoft.com/python/api/overview/azure/identity-readme?view=azure-python#credential-classes
    # credential = ManagedIdentityCredential()
    
    with WebPubSubServiceClient(
        endpoint="https://<name>.webpubsub.azure.com",
        hub="my-hub",
        credential=credential
    ) as client:
        # Use `client` for all subsequent operations (see examples below)
        ...
    ```
    
    ### Generate Client Access Token
    
    ```python
    # Token for anonymous user
    token = client.get_client_access_token()
    print(f"URL: {token['url']}")
    
    # Token with user ID
    token = client.get_client_access_token(
        user_id="user123",
        roles=["webpubsub.sendToGroup", "webpubsub.joinLeaveGroup"]
    )
    
    # Token with groups
    token = client.get_client_access_token(
        user_id="user123",
        groups=["group1", "group2"]
    )
    ```
    
    ### Send to All Clients
    
    ```python
    # Send text
    client.send_to_all(message="Hello everyone!", content_type="text/plain")
    
    # Send JSON
    client.send_to_all(
        message={"type": "notification", "data": "Hello"},
        content_type="application/json"
    )
    ```
    
    ### Send to User
    
    ```python
    client.send_to_user(
        user_id="user123",
        message="Hello user!",
        content_type="text/plain"
    )
    ```
    
    ### Send to Group
    
    ```python
    client.send_to_group(
        group="my-group",
        message="Hello group!",
        content_type="text/plain"
    )
    ```
    
    ### Send to Connection
    
    ```python
    client.send_to_connection(
        connection_id="abc123",
        message="Hello connection!",
        content_type="text/plain"
    )
    ```
    
    ### Group Management
    
    ```python
    # Add user to group
    client.add_user_to_group(group="my-group", user_id="user123")
    
    # Remove user from group
    client.remove_user_from_group(group="my-group", user_id="user123")
    
    # Add connection to group
    client.add_connection_to_group(group="my-group", connection_id="abc123")
    
    # Remove connection from group
    client.remove_connection_from_group(group="my-group", connection_id="abc123")
    ```
    
    ### Connection Management
    
    ```python
    # Check if connection exists
    exists = client.connection_exists(connection_id="abc123")
    
    # Check if user has connections
    exists = client.user_exists(user_id="user123")
    
    # Check if group has connections
    exists = client.group_exists(group="my-group")
    
    # Close connection
    client.close_connection(connection_id="abc123", reason="Session ended")
    
    # Close all connections for user
    client.close_all_connections(user_id="user123")
    ```
    
    ### Grant/Revoke Permissions
    
    ```python
    from azure.messaging.webpubsubservice import WebPubSubServiceClient
    
    # Grant permission
    client.grant_permission(
        permission="joinLeaveGroup",
        connection_id="abc123",
        target_name="my-group"
    )
    
    # Revoke permission
    client.revoke_permission(
        permission="joinLeaveGroup",
        connection_id="abc123",
        target_name="my-group"
    )
    
    # Check permission
    has_permission = client.check_permission(
        permission="joinLeaveGroup",
        connection_id="abc123",
        target_name="my-group"
    )
    ```
    
    ## Client SDK (Python WebSocket Client)
    
    ```python
    from azure.messaging.webpubsubclient import WebPubSubClient
    
    with WebPubSubClient(credential=token["url"]) as client:
        @client.on("connected")
        def on_connected(e):
            print(f"Connected: {e.connection_id}")
    
        @client.on("server-message")
        def on_message(e):
            print(f"Message: {e.data}")
    
        @client.on("group-message")
        def on_group_message(e):
            print(f"Group {e.group}: {e.data}")
    
        client.send_to_group("my-group", "Hello from Python!")
    ```
    
    ## Async Service Client
    
    ```python
    from azure.messaging.webpubsubservice.aio import WebPubSubServiceClient
    from azure.identity.aio import DefaultAzureCredential
    
    async def broadcast():
        async with DefaultAzureCredential() as credential:
            async with WebPubSubServiceClient(
                endpoint="https://<name>.webpubsub.azure.com",
                hub="my-hub",
                credential=credential
            ) as client:
                await client.send_to_all("Hello async!", content_type="text/plain")
    ```
    
    ## Client Operations
    
    | Operation | Description |
    |-----------|-------------|
    | `get_client_access_token` | Generate WebSocket connection URL |
    | `send_to_all` | Broadcast to all connections |
    | `send_to_user` | Send to specific user |
    | `send_to_group` | Send to group members |
    | `send_to_connection` | Send to specific connection |
    | `add_user_to_group` | Add user to group |
    | `remove_user_from_group` | Remove user from group |
    | `close_connection` | Disconnect client |
    | `connection_exists` | Check connection status |
    
    ## Best Practices
    
    1. **Pick sync OR async and stay consistent.** Do not mix `azure.xxx` sync clients with `azure.xxx.aio` async clients in the same call path. Choose one mode per module.
    2. **Always use context managers for clients and async credentials.** Wrap every client in `with Client(...) as client:` (sync) or `async with Client(...) as client:` (async). For async `DefaultAzureCredential` from `azure.identity.aio`, also use `async with credential:` so tokens and transports are cleaned up.
    3. **Use `DefaultAzureCredential`** for portable auth across local dev and Azure (avoid connection strings / access keys when possible).
    4. **Use roles** to limit client permissions
    4. **Use groups** for targeted messaging
    5. **Generate short-lived tokens** for security
    6. **Use user IDs** to send to users across connections
    7. **Handle reconnection** in client applications
    8. **Use JSON** content type for structured data
    9. **Close connections** gracefully with reasons
    
    ## Reference Files
    
    | File | Contents |
    |------|----------|
    | [references/capabilities.md](references/capabilities.md) | Additional non-hero capabilities, operation-group coverage, and production checklists. |
    | [references/non-hero-scenarios.md](references/non-hero-scenarios.md) | Dedicated non-hero examples for secondary/advanced scenarios. |
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related