apps Package
Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT License.
Classes
| ActivityContext |
Context object passed to activity handlers with middleware support. Note The single-connection OAuth surface here - <xref:is_signed_in>, <xref:user_token>, user_graph, sign_in, sign_out and get_user_token - predates multi-connection support and is deprecated. Register connections with app.add_oauth_flow(name) and use the returned OAuthFlow, which pins every operation to the connection that owns it. |
| ActivityEvent |
Event emitted when an activity is processed. |
| ActivityResponseEvent |
Event emitted by a plugin before an invoke response is returned. |
| ActivitySentEvent |
Event emitted when an activity is sent. |
| Agent365Baggage |
Opt-in Agent365 OpenTelemetry baggage bridge for Teams activity context. |
| Agent365BaggageKeys |
Agent365-compatible OpenTelemetry baggage keys. |
| Agent365BaggageOptions |
Host-wide options for Agent365 baggage derived from inbound activities. |
| Agent365ScopeOpener |
Opens a proactive Agent365 baggage scope with bound host policy. |
| Agent365ScopeOptions |
Host-wide defaults for proactive Agent365 baggage scopes. |
| App |
The main Teams application orchestrator. Manages plugins, tokens, and application lifecycle for Microsoft Teams apps. |
| AppOptions |
Configuration options for the Teams App. |
| AppTelemetryOptions |
Telemetry options applied across SDK-owned app flows. |
| AppTokenProvider |
Public token source backed by the credentials configured on an App. |
| ClientContext |
Runtime information about the client and session in Microsoft Teams. |
| CoreActivity |
Core activity fields that all transports need to know about. Extensible for protocol-specific fields via extra="allow". Create a new model by parsing and validating input data from keyword arguments. Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model. self is explicitly positional-only to allow self as a field name. |
| DependencyMetadata |
Information associated with a plugin dependency |
| DownloadedFile |
A buffered, point-in-time snapshot of a downloaded file's bytes that the caller owns. Returned by IncomingFile.download(). The bytes are already in memory, so the convenience readers here are synchronous and never re-download. Because it is a snapshot, holding one and reusing it is the way to read the same file several ways without re-fetching through the live IncomingFile handle. |
| ErrorEvent |
Event emitted when an error occurs. |
| EventMetadata |
Information associated with the plugin event |
| EventProtocol |
Protocol for event objects in the Teams app system. |
| FastAPIAdapter |
Default HttpServerAdapter implementation wrapping FastAPI + uvicorn. |
| FileAccessError |
Raised when the identity used was refused by the storage service. Distinct from FileUrlExpiredError, which means a pre-authorized URL lapsed and no usable Graph route existed. This error means the Graph route was the one that failed, refused by the service after the request was made. |
| FileCredentialError |
Raised when no credential was available for the Graph call. Detectable before any HTTP request. Distinct from FileUrlExpiredError, which means a pre-authorized URL lapsed and no usable Graph route existed. This error means the Graph route was ruled out before the request, because no usable credential was available: either a token could not be acquired, or the one acquired carries no file-capable permission. |
| FileError |
Base class for the diagnosable failures on the inbound-file path: an expired URL, an unsupported scope, and a refused Graph read. Lets a caller catch those with one except clause, so a new one can be added without callers changing. A transport or service failure the SDK cannot attribute, such as a Graph 5xx, is not one of these and surfaces as a plain RuntimeError. |
| FileScopeNotSupportedError |
Raised when file bytes are requested for a conversation scope whose download path is not implemented. Only personal (1:1) uploaded files download directly. groupChat files are surfaced by list(), but fetching their bytes needs Graph; download()/stream() throws until that path lands. |
| FileUrlExpiredError |
Raised when an inbound file's short-lived download URL has expired and can no longer fetch bytes. A personal file's pre-authorized tempauth download URL is valid only briefly. A fetch after it lapses gets a 401/403 from the platform. A handler that downloads once (and does not keep the handle) should not hit this. reason distinguishes the two cases:
|
| FilesAccessor |
Accessor for the uploaded files on the current inbound activity, exposed as ctx.files. "Files" is the uploaded-file view over the raw ctx.activity.attachments array. Uploaded files arrive as attachments where content_type is file.download.info, carrying file metadata rather than the bytes themselves. The metadata names where the bytes live: a pre-authorized download_url when the platform issues one, otherwise a content_url that locates the item so Graph can resolve it. This accessor maps each to an IncomingFile, and skips everything else in attachments (adaptive cards, mentions, other non-file content) as well as malformed file entries, never throwing. For each file it returns, the original wire attachment (the metadata object, not the bytes) is retained on IncomingFile.raw. A malformed or non-file attachment is reachable only through the raw activity.attachments array. This covers the file-upload path, not "any uploaded media". What matters is how the content arrived, not the file's MIME type, so file type is unrestricted (pdf, docx, png, etc.) as long as it was sent as an uploaded file. An image sent as a file appears here, but the same image pasted inline does not. The optional client is the app's shared httpx.AsyncClient, threaded into every IncomingFile so downloads reuse one connection pool instead of building and tearing down a client per file. It is the raw client rather than the SDK's wrapper on purpose: a download URL embeds its own tempauth credential, so the request must not pick up the bot's Authorization header. When omitted, each download creates and closes its own client. |
| FunctionContext |
Context provided to a remote function execution in a Teams app. |
| HtmlWidgetMarkdownOptions |
Options for building an HTML widget markdown string. |
| HttpServer |
Core Teams HTTP server. Not a plugin — owned directly by the App. Manages an HttpServerAdapter instance and handles JWT validation and activity processing for the Teams protocol. |
| HttpServerAdapter |
Protocol for framework-specific HTTP server adapters. Implement this adapter to plug in any HTTP framework (FastAPI, Starlette, Flask, etc.).
The SDK calls these methods with framework-agnostic |
| HttpStream |
HTTP-based streaming implementation for Microsoft Teams activities. Flow:
The timeout cancellation ensures only one flush operation is scheduled at a time. The delays between flushes is to ensure we dont hit API rate limits with Microsoft Teams. Initialize a new HttpStream instance. |
| InboundActivityTokenValidator |
Validator for inbound Teams activities. Classic bot activities use Bot Framework connector tokens. Agent ID activities use Entra tokens whose audience is the Agent 365 app blueprint app ID. |
| IncomingFile |
A lazy handle to a file attached to the current inbound activity. Nothing is downloaded until a byte method is called. The handle stays live and holds no memoized bytes, so each of stream()/download()/text()/save_as() fetches afresh. For a personal file that re-fetch is bounded by the short-lived download URL lifetime and may hit its expiry; to read the same file several ways, call download() once and reuse the returned DownloadedFile. |
| InjectWidgetProtocolOptions |
Options for injecting the MCP Apps protocol into widget HTML. |
| OAuthFlow |
One named OAuth connection, plus the handlers attached to it. Created via |
| OAuthFlowRegistry |
Case-insensitive, insertion-ordered collection of Subclasses |
| PluginActivityEvent |
Event emitted by a plugin when an activity is received. Create new instance of PluginActivityEvent(token, activity, conversation_ref) |
| PluginActivityResponseEvent |
Event emitted before an activity response is sent Create new instance of PluginActivityResponseEvent(activity, conversation_ref, response) |
| PluginActivitySentEvent |
Event emitted when an activity is sent. Create new instance of PluginActivitySentEvent(activity, conversation_ref) |
| PluginBase |
The base plugin for Teams app plugins. |
| PluginErrorEvent |
Event emitted when an error occurs. Create new instance of PluginErrorEvent(error, activity) |
| PluginOptions |
Plugin metadata |
| PluginStartEvent |
Event emitted when the plugin is started. Create new instance of PluginStartEvent(port,) |
| SecurityPolicyWarning |
A warning produced by validate_security_policy when the widget HTML references an external origin not present in the declared security policy. Diagnostic: ExperimentalTeamsHtmlWidget |
| SignInEvent | |
| SignInFailureEvent | |
| StartEvent |
Event emitted when the app starts. |
| StateOptions |
Configuration for the per-turn state layer. Scope keys are namespaced under |
| StopEvent |
Event emitted when the app stops. |
| StreamCancelledError |
Raised when a stream operation is attempted after the stream has been cancelled. |
| StreamNotAllowedError |
Raised when streaming is not allowed for this user or bot. |
| StreamTimedOutError |
Raised when the bot failed to complete streaming within the two-minute limit. |
| TeamsBotApplicationTelemetry |
OpenTelemetry source names for the Teams app orchestration package. |
| TerminalStreamError |
Base class for terminal streaming errors (HTTP 403) that should not be retried. |
| TokenValidator |
JWT token validator using PyJWKClient for simplified validation. Initialize the token validator. |
| TurnState |
One state scope for a single turn. Behaves like a
Values must be JSON-serializable. Each scope is encoded with
|
| TurnStateContainer |
The state scopes loaded for one turn, together with the identity they were loaded for.
Only the identity is bound. Constructor arguments are keyword-only so the public constructor is not tied to positional order and can evolve without breaking callers. |
| TurnStateSealedError |
Raised when a sealed TurnState is accessed after its turn ends. |
Functions
Plugin
Turns any class into a plugin using the decorator pattern.
Plugin(name: str | None = None, version: str | None = None, description: str | None = None) -> Callable[[Type[T]], Type[T]]
Parameters
| Name | Description |
|---|---|
|
name
|
Default value: None
|
|
version
|
Default value: None
|
|
description
|
Default value: None
|
agent365_baggage
agent365_baggage(source: Activity | _ActivityContextSource | None = None, *, include: Iterable[Literal['senderName', 'agentName', 'agentDescription', 'senderEmail', 'agentEmail']] | None = None, operation_source: str | int | float | None = None, channel_link: str | int | float | None = None, additional_baggage: Mapping[str, str | int | float | None] | None = None) -> Agent365Baggage
Parameters
| Name | Description |
|---|---|
|
source
|
Default value: None
|
Keyword-Only Parameters
| Name | Description |
|---|---|
|
include
|
Default value: None
|
|
operation_source
|
Default value: None
|
|
channel_link
|
Default value: None
|
|
additional_baggage
|
Default value: None
|
build_html_widget_markdown
Wraps an HTML widget payload in the >>``<<>>`<<html-widget markdown code fence format required by Teams to render the widget in a message.
Diagnostic: ExperimentalTeamsHtmlWidget
build_html_widget_markdown(payload: HtmlWidgetPayload, options: HtmlWidgetMarkdownOptions | None = None) -> str
Parameters
| Name | Description |
|---|---|
|
payload
Required
|
|
|
options
|
Default value: None
|
build_html_widget_message
Builds a message activity containing an HTML widget, ready to be sent.
Diagnostic: ExperimentalTeamsHtmlWidget
build_html_widget_message(payload: HtmlWidgetPayload, options: HtmlWidgetMarkdownOptions | None = None) -> MessageActivityInput
Parameters
| Name | Description |
|---|---|
|
payload
Required
|
|
|
options
|
Default value: None
|
create_agent365_scope
Create a reusable proactive Agent365 baggage scope opener.
create_agent365_scope(options: Agent365ScopeOptions | Literal[False] | None = None) -> Agent365ScopeOpener
Parameters
| Name | Description |
|---|---|
|
options
|
Default value: None
|
create_state_loader
Resolve the App(state=...) option into a loader (or None when off).
state is the opt-in value: falsy disables state; True enables it with
defaults; a StateOptions configures it. The loader's storage is the one on
StateOptions when provided, otherwise the app's shared fallback_storage.
A warning is logged when that resolves to in-memory LocalStorage.
create_state_loader(state: bool | StateOptions | None, fallback_storage: Storage[str, Any]) -> TurnStateLoader | None
Parameters
| Name | Description |
|---|---|
|
state
Required
|
|
|
fallback_storage
Required
|
|
get_event_type_from_signature
Extract event type from function signature by inspecting the first parameter's type hint.
get_event_type_from_signature(func: Callable[[...], Any]) -> Literal['activity', 'error', 'start', 'stop', 'sign_in', 'sign_in_failure', 'activity_response', 'activity_sent'] | str | None
Parameters
| Name | Description |
|---|---|
|
func
Required
|
Function to inspect |
Returns
| Type | Description |
|---|---|
|
Event type string if detectable, None otherwise |
get_metadata
Get plugin metadata from a class.
get_metadata(cls: Type[PluginBase]) -> PluginOptions
Parameters
| Name | Description |
|---|---|
|
cls
Required
|
|
inject_widget_protocol
Injects the MCP Apps protocol script into widget HTML.
This sets up:
- The ui/initialize handshake (required for rendering)
- Size reporting via ui/notifications/size-changed
- Optional notification hooks (opt-in via notifications option)
If the HTML already contains the protocol (detected by 'ui/initialize'), it is returned unchanged.
Diagnostic: ExperimentalTeamsHtmlWidget
inject_widget_protocol(html: str, options: InjectWidgetProtocolOptions | None = None) -> str
Parameters
| Name | Description |
|---|---|
|
html
Required
|
|
|
options
|
Default value: None
|
is_registered_event
Check if an event name is registered.
is_registered_event(event_name: str) -> bool
Parameters
| Name | Description |
|---|---|
|
event_name
Required
|
Event name to check |
Returns
| Type | Description |
|---|---|
|
True if registered, False otherwise |
to_threaded_conversation_id
Construct a threaded conversation ID by appending ;messageid={message_id} to the conversation ID. This is the format the service uses to route messages to a specific thread.
to_threaded_conversation_id(conversation_id: str, message_id: str) -> str
Parameters
| Name | Description |
|---|---|
|
conversation_id
Required
|
The conversation to thread into (e.g. 19:abc@thread.skype) |
|
message_id
Required
|
The thread root message ID (must be a non-zero numeric string) |
Returns
| Type | Description |
|---|---|
|
<xref:mailto:abc@thread.skype>;messageid=123`) |
try_get_widget_model_context
Attempt to extract an MCP UI update-model-context request from a message activity's value.
A widget can request that content be added to the model context by reusing the messageBack mechanism (like Action.Submit for adaptive cards). Such a request arrives as a normal message activity whose value carries the McpUiUpdateModelContextRequest payload. This is fire-and-forget: the bot does not respond.
This helper is tolerant of two wire shapes:
The raw request object ({"method": "ui/update-model-context", "params": ...}).
An envelope of the form {"type": "widgetModelContext", "data": <request>}.
Diagnostic: ExperimentalTeamsHtmlWidget
try_get_widget_model_context(activity: Any) -> McpUiUpdateModelContextRequest | None
Parameters
| Name | Description |
|---|---|
|
activity
Required
|
A message activity (or any object with a value attribute). |
Returns
| Type | Description |
|---|---|
|
The parsed request, or None if value is not a valid update-model-context request. |
validate_remote_function_request
Validate JWT and extract client context from request headers for remote function calls.
async validate_remote_function_request(headers: Dict[str, str], entra_token_validator: TokenValidator | None) -> tuple[Optional[microsoft_teams.apps.contexts.client_context.ClientContext], Optional[str]]
Parameters
| Name | Description |
|---|---|
|
headers
Required
|
Request headers dict. |
|
entra_token_validator
Required
|
TokenValidator instance for Entra ID tokens. |
Returns
| Type | Description |
|---|---|
|
Tuple of (ClientContext, None) on success or (None, error_message) on failure. |
validate_security_policy
Validates that external references in widget HTML are covered by the declared security policy. Returns a list of warnings for any references to origins not present in the appropriate policy field.
This is a static analysis tool - it cannot catch dynamically constructed URLs. Use the debug_csp_violations option on inject_widget_protocol for runtime detection.
Diagnostic: ExperimentalTeamsHtmlWidget
validate_security_policy(html: str, policy: HtmlWidgetSecurityPolicy) -> list[microsoft_teams.apps.utils.html_widget.SecurityPolicyWarning]
Parameters
| Name | Description |
|---|---|
|
html
Required
|
|
|
policy
Required
|
|