microsoft-teams-botbuilder 2.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,51 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.egg-info/
6
+
7
+ # Environments
8
+ .env
9
+ .venv
10
+ env/
11
+ venv/
12
+ ENV/
13
+ env.bak/
14
+ venv.bak/
15
+
16
+ # mypy
17
+ .mypy_cache/
18
+ .dmypy.json
19
+ dmypy.json
20
+
21
+ # pytest-cov
22
+ .coverage
23
+ .coverage.*
24
+ htmlcov/
25
+ coverage.xml
26
+
27
+ .copilot-instructions.md
28
+
29
+ # other
30
+ .DS_STORE
31
+ *.bak
32
+ *~
33
+ *.tmp
34
+
35
+ ref/
36
+ py.typed
37
+
38
+ .env.claude/
39
+ .claude/
40
+ tmpclaude-*-cwd
41
+
42
+ examples/**/.vscode/
43
+ examples/**/appPackage/
44
+ examples/**/infra/
45
+ examples/**/teamsapp*
46
+ examples/**/aad.manifest.json
47
+
48
+ # Node (from tab)
49
+ node_modules
50
+ dist/
51
+ build/
@@ -0,0 +1,33 @@
1
+ Metadata-Version: 2.4
2
+ Name: microsoft-teams-botbuilder
3
+ Version: 2.0.0
4
+ Summary: BotBuilder plugin for Microsoft Teams
5
+ Project-URL: Homepage, https://github.com/microsoft/teams.py/tree/main/packages/botbuilder/src/microsoft/teams/botbuilder
6
+ Author-email: Microsoft <TeamsAISDKFeedback@microsoft.com>
7
+ License-Expression: MIT
8
+ Keywords: agents,ai,bot,microsoft,teams
9
+ Requires-Python: <3.15,>=3.12
10
+ Requires-Dist: botbuilder-core>=4.14.0
11
+ Requires-Dist: botbuilder-integration-aiohttp>=4.17.0
12
+ Requires-Dist: microsoft-teams-api>=2.0.0
13
+ Requires-Dist: microsoft-teams-apps>=2.0.0
14
+ Requires-Dist: microsoft-teams-common>=2.0.0
15
+ Description-Content-Type: text/markdown
16
+
17
+ # Microsoft Teams BotBuilder
18
+
19
+ <p>
20
+ <a href="https://pypi.org/project/microsoft-teams-botbuilder/" target="_blank">
21
+ <img src="https://img.shields.io/pypi/v/microsoft-teams-botbuilder" />
22
+ </a>
23
+ <a href="https://pypi.org/project/microsoft-teams-botbuilder" target="_blank">
24
+ <img src="https://img.shields.io/pypi/dw/microsoft-teams-botbuilder" />
25
+ </a>
26
+ </p>
27
+
28
+ A package used to make the `microsoft-teams-apps` package backwards compatible with legacy bots built using
29
+ `BotBuilder`.
30
+
31
+ <a href="https://microsoft.github.io/teams-sdk" target="_blank">
32
+ <img src="https://img.shields.io/badge/📖 Getting Started-blue?style=for-the-badge" />
33
+ </a>
@@ -0,0 +1,17 @@
1
+ # Microsoft Teams BotBuilder
2
+
3
+ <p>
4
+ <a href="https://pypi.org/project/microsoft-teams-botbuilder/" target="_blank">
5
+ <img src="https://img.shields.io/pypi/v/microsoft-teams-botbuilder" />
6
+ </a>
7
+ <a href="https://pypi.org/project/microsoft-teams-botbuilder" target="_blank">
8
+ <img src="https://img.shields.io/pypi/dw/microsoft-teams-botbuilder" />
9
+ </a>
10
+ </p>
11
+
12
+ A package used to make the `microsoft-teams-apps` package backwards compatible with legacy bots built using
13
+ `BotBuilder`.
14
+
15
+ <a href="https://microsoft.github.io/teams-sdk" target="_blank">
16
+ <img src="https://img.shields.io/badge/📖 Getting Started-blue?style=for-the-badge" />
17
+ </a>
@@ -0,0 +1,41 @@
1
+ [project]
2
+ name = "microsoft-teams-botbuilder"
3
+ dynamic = ["version"]
4
+ description = "BotBuilder plugin for Microsoft Teams"
5
+ authors = [{ name = "Microsoft", email = "TeamsAISDKFeedback@microsoft.com" }]
6
+ readme = "README.md"
7
+ requires-python = ">=3.12,<3.15"
8
+ repository = "https://github.com/microsoft/teams.py"
9
+ keywords = ["microsoft", "teams", "ai", "bot", "agents"]
10
+ license = "MIT"
11
+ dependencies = [
12
+ "botbuilder-core>=4.14.0",
13
+ "botbuilder-integration-aiohttp>=4.17.0",
14
+ "microsoft-teams-apps",
15
+ "microsoft-teams-api",
16
+ "microsoft-teams-common"
17
+ ]
18
+
19
+ [project.urls]
20
+ Homepage = "https://github.com/microsoft/teams.py/tree/main/packages/botbuilder/src/microsoft/teams/botbuilder"
21
+
22
+
23
+ [build-system]
24
+ requires = ["hatchling", "hatch-teams-build"]
25
+ build-backend = "hatchling.build"
26
+
27
+ [tool.hatch.version]
28
+ source = "teams-build"
29
+
30
+ [tool.hatch.metadata.hooks.teams-build]
31
+
32
+ [tool.hatch.build.targets.wheel]
33
+ packages = ["src/microsoft_teams", "src/microsoft"]
34
+
35
+ [tool.hatch.build.targets.sdist]
36
+ include = ["src"]
37
+
38
+ [tool.uv.sources]
39
+ microsoft-teams-apps = { workspace = true }
40
+ microsoft-teams-api = { workspace = true }
41
+ microsoft-teams-common = { workspace = true }
@@ -0,0 +1,12 @@
1
+ """
2
+ Copyright (c) Microsoft Corporation. All rights reserved.
3
+ Licensed under the MIT License.
4
+ """
5
+
6
+ import logging
7
+
8
+ from .botbuilder_plugin import BotBuilderPlugin, BotBuilderPluginOptions
9
+
10
+ logging.getLogger(__name__).addHandler(logging.NullHandler())
11
+
12
+ __all__ = ["BotBuilderPlugin", "BotBuilderPluginOptions"]
@@ -0,0 +1,131 @@
1
+ """
2
+ Copyright (c) Microsoft Corporation. All rights reserved.
3
+ Licensed under the MIT License.
4
+ """
5
+
6
+ import importlib.metadata
7
+ import logging
8
+ from types import SimpleNamespace
9
+ from typing import Annotated, Optional, TypedDict, Unpack, cast
10
+
11
+ from microsoft_teams.api import Credentials
12
+ from microsoft_teams.apps import (
13
+ DependencyMetadata,
14
+ HttpServer,
15
+ Plugin,
16
+ PluginBase,
17
+ )
18
+ from microsoft_teams.apps.http import HttpRequest, HttpResponse
19
+
20
+ from botbuilder.core import (
21
+ ActivityHandler,
22
+ TurnContext,
23
+ )
24
+ from botbuilder.integration.aiohttp import (
25
+ CloudAdapter,
26
+ ConfigurationBotFrameworkAuthentication,
27
+ )
28
+ from botbuilder.schema import Activity
29
+
30
+ version = importlib.metadata.version("microsoft-teams-botbuilder")
31
+
32
+ logger = logging.getLogger(__name__)
33
+
34
+ # Constants for app types
35
+ SINGLE_TENANT = "singletenant"
36
+ MULTI_TENANT = "multitenant"
37
+
38
+
39
+ class BotBuilderPluginOptions(TypedDict, total=False):
40
+ """Options for configuring the BotBuilder plugin."""
41
+
42
+ handler: ActivityHandler
43
+ adapter: CloudAdapter
44
+
45
+
46
+ @Plugin(name="botbuilder", version=version, description="BotBuilder plugin for Microsoft Bot Framework integration")
47
+ class BotBuilderPlugin(PluginBase):
48
+ """
49
+ BotBuilder plugin that provides Microsoft Bot Framework integration.
50
+ """
51
+
52
+ # Dependency injections
53
+ credentials: Annotated[Optional[Credentials], DependencyMetadata(optional=True)]
54
+ http_server: Annotated[HttpServer, DependencyMetadata()]
55
+
56
+ def __init__(self, **options: Unpack[BotBuilderPluginOptions]):
57
+ """
58
+ Initialize the BotBuilder plugin.
59
+
60
+ Args:
61
+ options: Configuration options for the plugin
62
+ """
63
+ super().__init__()
64
+ self.handler: Optional[ActivityHandler] = options.get("handler")
65
+ self.adapter: Optional[CloudAdapter] = options.get("adapter")
66
+
67
+ async def on_init(self) -> None:
68
+ """Initialize the plugin when the app starts."""
69
+ if not self.adapter:
70
+ # Extract credentials for Bot Framework authentication
71
+ client_id: Optional[str] = None
72
+ client_secret: Optional[str] = None
73
+ tenant_id: Optional[str] = None
74
+
75
+ if self.credentials:
76
+ client_id = getattr(self.credentials, "client_id", None)
77
+ client_secret = getattr(self.credentials, "client_secret", None)
78
+ tenant_id = getattr(self.credentials, "tenant_id", None)
79
+
80
+ config = SimpleNamespace(
81
+ APP_TYPE=SINGLE_TENANT if tenant_id else MULTI_TENANT,
82
+ APP_ID=client_id,
83
+ APP_PASSWORD=client_secret,
84
+ APP_TENANTID=tenant_id,
85
+ )
86
+
87
+ bot_framework_auth = ConfigurationBotFrameworkAuthentication(configuration=config)
88
+ self.adapter = CloudAdapter(bot_framework_auth)
89
+
90
+ logger.debug("BotBuilder plugin initialized successfully")
91
+
92
+ # Register the messaging endpoint route via adapter (bypasses HttpServer's default route)
93
+ self.http_server.adapter.register_route("POST", self.http_server.messaging_endpoint, self._handle_activity)
94
+
95
+ async def _handle_activity(self, request: HttpRequest) -> HttpResponse:
96
+ """
97
+ Handler for the messaging endpoint.
98
+
99
+ Runs Bot Framework CloudAdapter auth + handler first,
100
+ then routes through HttpServer.handle_request for SDK-level JWT validation and pipeline.
101
+ """
102
+ if not self.adapter:
103
+ raise RuntimeError("plugin not registered")
104
+
105
+ body = request["body"]
106
+ headers = request["headers"]
107
+
108
+ try:
109
+ # Parse activity from body
110
+ activity_bf = cast(Activity, Activity().deserialize(body))
111
+
112
+ if not activity_bf.type:
113
+ return HttpResponse(status=400, body={"detail": "Missing activity type"})
114
+
115
+ async def logic(turn_context: TurnContext) -> None:
116
+ if not turn_context.activity.id:
117
+ return
118
+ # Handle activity with botframework handler
119
+ if self.handler:
120
+ await self.handler.on_turn(turn_context)
121
+
122
+ # Grab the auth header from the inbound request
123
+ auth_header = headers.get("authorization") or headers.get("Authorization") or ""
124
+ await self.adapter.process_activity(auth_header, activity_bf, logic)
125
+
126
+ # Route through HttpServer for SDK auth + Teams pipeline
127
+ return await self.http_server.handle_request(request)
128
+
129
+ except Exception as err:
130
+ logger.error(f"Error processing activity: {err}", exc_info=True)
131
+ return HttpResponse(status=500, body={"detail": str(err)})