Skip to content

Expose public per-request token and client accessors on SlackAdapter #47

@patrick-chinchill

Description

@patrick-chinchill

Summary

In multi-workspace mode, SlackAdapter resolves a per-team token via its InstallationStore and binds it to a ContextVar for the duration of a request. Code running inside a handler that needs to call the Slack Web API directly (e.g. to resolve the caller's email via users.info, or to perform any bookkeeping call outside the SDK's normal post path) has no public way to access the currently-bound token or a preconfigured AsyncWebClient.

Today this requires calling:

  • adapter._get_token() — underscore-prefixed, returns the bound str
  • adapter._get_client() — underscore-prefixed, returns AsyncWebClient

Both are private by naming convention. Neither is re-exported from src/chat_sdk/adapters/slack/__init__.py. There's no public @property equivalent.

Request

Expose stable public accessors, e.g.:

adapter.current_token   # str, raises if no active request context
adapter.current_client  # AsyncWebClient preconfigured with the bound token

Both should be documented as valid inside any handler invoked by the SDK (webhook or registered callback). Outside a request context they can raise a clear error.

Why it matters for downstream code

Any consumer that runs Slack API calls from inside a handler (email resolution, user profile fetches, reaction bookkeeping, etc.) currently depends on private implementation details and has to suppress static-analysis warnings for the underscore access.


Upstream TS parity

Vercel TS (vercel/chat) also keeps getToken() private on SlackAdapter (packages/adapter-slack/src/index.ts) and does not expose a public read accessor. TS exposes withBotToken(callback) for token-context injection from external async code — the Python port has the equivalent with_bot_context_async(token, bot_user_id, fn) — but neither port has a way to read the currently-bound token/client from inside a handler that's already in context.

Proposed fix (Python-only extension)

Add public accessors to the Python port as a documented Python-only extension under UPSTREAM_SYNC.md ("Python-only additions"):

  • adapter.current_token: str — property that reads from the existing ContextVar; raises a clear error outside request context.
  • adapter.current_client: AsyncWebClient — preconfigured with the bound token.

This is additive and doesn't affect TS parity. The same pattern should apply to Teams and any other adapter that uses a request-bound token.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions