# FastAPI Teams Bot π€
[](https://pypi.org/project/fastapi-teams-bot/)
[](https://pypi.org/project/fastapi-teams-bot/)
[](https://opensource.org/licenses/MIT)
A FastAPI-based framework for building Microsoft Teams bots with pluggable message processing. Perfect for integrating with LangGraph, LangChain, or any custom async message processor.
## β¨ Features
- π **FastAPI Integration**: Modern, fast, async web framework
- π **Pluggable Architecture**: Bring your own message processor
- π **File Handling**: Built-in CSV upload/download support
- π΄ **Adaptive Cards**: Native support for rich interactive cards
- β‘ **Typing Indicators**: Professional user experience
- π **Authentication**: Complete Bot Framework authentication handling
- π§ͺ **Well Tested**: Comprehensive test coverage
- π **Type Safe**: Full type hints with mypy support
## π Quick Start
### Installation
```bash
pip install fastapi-teams-bot
```
### Minimal Example
```python
from fastapi_teams_bot import create_teams_bot
async def my_message_processor(user_message, user, conversation_id, metadata):
"""Your custom message processing logic."""
return {
"message": f"Hello {user['name']}! You said: {user_message}",
}
# Create the bot
app = create_teams_bot(my_message_processor)
# Run with uvicorn
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=3001)
```
### With Environment Variables
```bash
# Set these environment variables:
export MICROSOFT_APP_ID="your-app-id"
export MICROSOFT_APP_PASSWORD="your-password"
export MICROSOFT_APP_TENANT_ID="your-tenant-id" # Optional
```
```python
from fastapi_teams_bot import create_teams_bot
from my_agent import process_message
app = create_teams_bot(process_message)
```
## π Integration Examples
### With LangGraph
```python
from fastapi_teams_bot import create_teams_bot
from langgraph.graph import StateGraph
# Your LangGraph workflow
graph = StateGraph(...)
# ... define your graph ...
async def process_with_langgraph(user_message, user, conversation_id, metadata):
"""Process message through LangGraph."""
result = await graph.ainvoke({
"user_message": user_message,
"user_id": user["id"],
"conversation_id": conversation_id,
})
return {
"message": result["response"],
"adaptive_card": result.get("card", {}),
}
app = create_teams_bot(process_with_langgraph)
```
### With LangChain
```python
from fastapi_teams_bot import create_teams_bot
from langchain.agents import AgentExecutor
agent = AgentExecutor(...) # Your LangChain agent
async def process_with_langchain(user_message, user, conversation_id, metadata):
"""Process message through LangChain."""
result = await agent.ainvoke({"input": user_message})
return {"message": result["output"]}
app = create_teams_bot(process_with_langchain)
```
### With Adaptive Cards
```python
async def my_processor(user_message, user, conversation_id, metadata):
"""Return an adaptive card."""
card = {
"type": "AdaptiveCard",
"version": "1.4",
"body": [
{
"type": "TextBlock",
"text": f"Hello {user['name']}!",
"size": "Large",
"weight": "Bolder"
}
],
"actions": [
{
"type": "Action.Submit",
"title": "Click me",
"data": {"action": "button_clicked"}
}
]
}
return {
"message": "Here's an interactive card:",
"adaptive_card": card,
}
app = create_teams_bot(my_processor)
```
### With CSV Export
```python
async def export_data(user_message, user, conversation_id, metadata):
"""Export data as CSV."""
csv_content = "Name,Email,Status\nJohn,john@example.com,Active\n"
return {
"message": "Here's your data export:",
"csv": {
"csv_content": csv_content,
"filename": "export.csv"
}
}
app = create_teams_bot(export_data)
```
### Handling CSV Uploads
```python
async def handle_csv(user_message, user, conversation_id, metadata):
"""Handle uploaded CSV files."""
if metadata and metadata.get("action_type") == "csv_upload":
csv_data = metadata["csv_data"]
# Process the CSV
lines = csv_data.split("\n")
row_count = len(lines) - 1 # Minus header
return {
"message": f"Processed CSV with {row_count} rows!",
}
return {"message": "Please upload a CSV file."}
app = create_teams_bot(handle_csv)
```
## π§ Advanced Configuration
```python
from fastapi_teams_bot import TeamsBot, BotConfig
config = BotConfig(
app_id="your-app-id",
app_password="your-password",
app_tenant_id="your-tenant-id",
endpoint_path="/api/messages",
enable_typing_indicator=True,
max_file_size_mb=20,
supported_file_types=["text/csv", "application/pdf"],
)
bot = TeamsBot(config)
app = bot.create_app(message_processor=my_processor)
# Add custom routes
@app.get("/health")
async def health():
return {"status": "healthy"}
```
## π API Reference
### MessageProcessor Protocol
Your message processor must implement this signature:
```python
async def message_processor(
user_message: str,
user: User, # {"name": str, "id": str}
conversation_id: str,
metadata: Optional[Dict[str, Any]] = None
) -> MessageResponse: # {"message": str, "csv": dict, "adaptive_card": dict}
...
```
### Metadata Types
**CSV Upload:**
```python
metadata = {
"action_type": "csv_upload",
"csv_data": str # CSV content as string
}
```
**Button Click:**
```python
metadata = {
"action_type": str, # e.g., "add_to_cart"
"action_data": dict # Full action payload from Adaptive Card
}
```
### BotConfig Options
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `app_id` | str | required | Microsoft App ID |
| `app_password` | str | required | Microsoft App Password |
| `app_tenant_id` | str | None | Microsoft Tenant ID (optional) |
| `endpoint_path` | str | "/api/messages" | Bot endpoint path |
| `enable_typing_indicator` | bool | True | Show typing indicator |
| `max_file_size_mb` | int | 10 | Max file upload size |
| `supported_file_types` | list[str] | ["text/csv"] | Supported MIME types |
## π§ͺ Testing
```python
import pytest
from fastapi_teams_bot import User
@pytest.mark.asyncio
async def test_my_processor():
"""Test your message processor."""
result = await my_message_processor(
user_message="Hello",
user={"name": "Test User", "id": "test-123"},
conversation_id="conv-456",
)
assert "Hello" in result["message"]
```
## π― Use Cases
This library is perfect for:
- **Customer Support Bots**: Integrate with your support knowledge base
- **Sales Assistants**: Help users browse products and place orders
- **Data Analysis Bots**: Upload CSV files and get insights
- **Workflow Automation**: Trigger actions through conversational interface
- **Internal Tools**: Company directory, IT helpdesk, HR assistant
- **AI Agents**: Connect LLMs (GPT, Claude, etc.) to Teams
## π¦ What's Included
- β
Bot endpoint (`/api/messages`)
- β
Authentication & token validation
- β
Message processing
- β
Typing indicators
- β
Adaptive Cards
- β
CSV upload/download
- β
File consent handling
- β
Error handling
- β
Logging
- β
Type definitions
## π οΈ Development
### Setup
```bash
git clone https://github.com/vishalgoel2/fastapi-teams-bot.git
cd fastapi-teams-bot
# Sync dependencies
uv sync
# Or install in development mode
uv pip install -e ".[dev]"
```
### Run Tests
```bash
# Run all tests with coverage
uv run pytest tests/ -v --cov=fastapi_teams_bot
# Run with HTML coverage report
uv run pytest tests/ --cov=fastapi_teams_bot --cov-report=html
```
### Code Quality
```bash
# Format code
uv run black src/ tests/
# Lint code
uv run ruff check src/ tests/
# Type checking
uv run mypy src/
```
## π€ Contributing
Contributions are welcome! Please check out our [Contributing Guide](CONTRIBUTING.md).
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
## π License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## π Acknowledgments
- Built with [FastAPI](https://fastapi.tiangolo.com/)
- Uses [Microsoft Bot Framework](https://dev.botframework.com/)
- Inspired by the need for simple, flexible Teams bot development
## π§ Support
- π [Documentation](https://github.com/vishalgoel2/fastapi-teams-bot#readme)
- π [Issue Tracker](https://github.com/vishalgoel2/fastapi-teams-bot/issues)
- π¬ [Discussions](https://github.com/vishalgoel2/fastapi-teams-bot/discussions)
## πΊοΈ Roadmap
- [ ] Support for more file types (PDF, images, etc.)
- [ ] Built-in rate limiting
- [ ] Conversation state management helpers
- [ ] Teams app manifest generator
- [ ] Deployment templates (Azure, Docker)
- [ ] More examples (OpenAI, Anthropic, etc.)
## β Star History
If you find this project helpful, please consider giving it a star!
---
Made with β€οΈ by [Vishal Goel](https://github.com/vishalgoel2)
Raw data
{
"_id": null,
"home_page": null,
"name": "fastapi-teams-bot",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "bot, chatbot, fastapi, langchain, langgraph, microsoft, teams",
"author": null,
"author_email": "Vishal Goel <vishal@example.com>",
"download_url": "https://files.pythonhosted.org/packages/fb/71/b53524c13efbbb92d26a92e87f58cfa5f3ba6b8ebd3b90d8a58d559d1b90/fastapi_teams_bot-0.1.0.tar.gz",
"platform": null,
"description": "# FastAPI Teams Bot \ud83e\udd16\n\n[](https://pypi.org/project/fastapi-teams-bot/)\n[](https://pypi.org/project/fastapi-teams-bot/)\n[](https://opensource.org/licenses/MIT)\n\nA FastAPI-based framework for building Microsoft Teams bots with pluggable message processing. Perfect for integrating with LangGraph, LangChain, or any custom async message processor.\n\n## \u2728 Features\n\n- \ud83d\ude80 **FastAPI Integration**: Modern, fast, async web framework\n- \ud83d\udd0c **Pluggable Architecture**: Bring your own message processor\n- \ud83d\udcce **File Handling**: Built-in CSV upload/download support\n- \ud83c\udfb4 **Adaptive Cards**: Native support for rich interactive cards\n- \u26a1 **Typing Indicators**: Professional user experience\n- \ud83d\udd10 **Authentication**: Complete Bot Framework authentication handling\n- \ud83e\uddea **Well Tested**: Comprehensive test coverage\n- \ud83d\udcdd **Type Safe**: Full type hints with mypy support\n\n## \ud83d\ude80 Quick Start\n\n### Installation\n\n```bash\npip install fastapi-teams-bot\n```\n\n### Minimal Example\n\n```python\nfrom fastapi_teams_bot import create_teams_bot\n\nasync def my_message_processor(user_message, user, conversation_id, metadata):\n \"\"\"Your custom message processing logic.\"\"\"\n return {\n \"message\": f\"Hello {user['name']}! You said: {user_message}\",\n }\n\n# Create the bot\napp = create_teams_bot(my_message_processor)\n\n# Run with uvicorn\nif __name__ == \"__main__\":\n import uvicorn\n uvicorn.run(app, host=\"0.0.0.0\", port=3001)\n```\n\n### With Environment Variables\n\n```bash\n# Set these environment variables:\nexport MICROSOFT_APP_ID=\"your-app-id\"\nexport MICROSOFT_APP_PASSWORD=\"your-password\"\nexport MICROSOFT_APP_TENANT_ID=\"your-tenant-id\" # Optional\n```\n\n```python\nfrom fastapi_teams_bot import create_teams_bot\nfrom my_agent import process_message\n\napp = create_teams_bot(process_message)\n```\n\n## \ud83d\udcda Integration Examples\n\n### With LangGraph\n\n```python\nfrom fastapi_teams_bot import create_teams_bot\nfrom langgraph.graph import StateGraph\n\n# Your LangGraph workflow\ngraph = StateGraph(...)\n# ... define your graph ...\n\nasync def process_with_langgraph(user_message, user, conversation_id, metadata):\n \"\"\"Process message through LangGraph.\"\"\"\n result = await graph.ainvoke({\n \"user_message\": user_message,\n \"user_id\": user[\"id\"],\n \"conversation_id\": conversation_id,\n })\n \n return {\n \"message\": result[\"response\"],\n \"adaptive_card\": result.get(\"card\", {}),\n }\n\napp = create_teams_bot(process_with_langgraph)\n```\n\n### With LangChain\n\n```python\nfrom fastapi_teams_bot import create_teams_bot\nfrom langchain.agents import AgentExecutor\n\nagent = AgentExecutor(...) # Your LangChain agent\n\nasync def process_with_langchain(user_message, user, conversation_id, metadata):\n \"\"\"Process message through LangChain.\"\"\"\n result = await agent.ainvoke({\"input\": user_message})\n \n return {\"message\": result[\"output\"]}\n\napp = create_teams_bot(process_with_langchain)\n```\n\n### With Adaptive Cards\n\n```python\nasync def my_processor(user_message, user, conversation_id, metadata):\n \"\"\"Return an adaptive card.\"\"\"\n card = {\n \"type\": \"AdaptiveCard\",\n \"version\": \"1.4\",\n \"body\": [\n {\n \"type\": \"TextBlock\",\n \"text\": f\"Hello {user['name']}!\",\n \"size\": \"Large\",\n \"weight\": \"Bolder\"\n }\n ],\n \"actions\": [\n {\n \"type\": \"Action.Submit\",\n \"title\": \"Click me\",\n \"data\": {\"action\": \"button_clicked\"}\n }\n ]\n }\n \n return {\n \"message\": \"Here's an interactive card:\",\n \"adaptive_card\": card,\n }\n\napp = create_teams_bot(my_processor)\n```\n\n### With CSV Export\n\n```python\nasync def export_data(user_message, user, conversation_id, metadata):\n \"\"\"Export data as CSV.\"\"\"\n csv_content = \"Name,Email,Status\\nJohn,john@example.com,Active\\n\"\n \n return {\n \"message\": \"Here's your data export:\",\n \"csv\": {\n \"csv_content\": csv_content,\n \"filename\": \"export.csv\"\n }\n }\n\napp = create_teams_bot(export_data)\n```\n\n### Handling CSV Uploads\n\n```python\nasync def handle_csv(user_message, user, conversation_id, metadata):\n \"\"\"Handle uploaded CSV files.\"\"\"\n if metadata and metadata.get(\"action_type\") == \"csv_upload\":\n csv_data = metadata[\"csv_data\"]\n \n # Process the CSV\n lines = csv_data.split(\"\\n\")\n row_count = len(lines) - 1 # Minus header\n \n return {\n \"message\": f\"Processed CSV with {row_count} rows!\",\n }\n \n return {\"message\": \"Please upload a CSV file.\"}\n\napp = create_teams_bot(handle_csv)\n```\n\n## \ud83d\udd27 Advanced Configuration\n\n```python\nfrom fastapi_teams_bot import TeamsBot, BotConfig\n\nconfig = BotConfig(\n app_id=\"your-app-id\",\n app_password=\"your-password\",\n app_tenant_id=\"your-tenant-id\",\n endpoint_path=\"/api/messages\",\n enable_typing_indicator=True,\n max_file_size_mb=20,\n supported_file_types=[\"text/csv\", \"application/pdf\"],\n)\n\nbot = TeamsBot(config)\napp = bot.create_app(message_processor=my_processor)\n\n# Add custom routes\n@app.get(\"/health\")\nasync def health():\n return {\"status\": \"healthy\"}\n```\n\n## \ud83d\udcd6 API Reference\n\n### MessageProcessor Protocol\n\nYour message processor must implement this signature:\n\n```python\nasync def message_processor(\n user_message: str,\n user: User, # {\"name\": str, \"id\": str}\n conversation_id: str,\n metadata: Optional[Dict[str, Any]] = None\n) -> MessageResponse: # {\"message\": str, \"csv\": dict, \"adaptive_card\": dict}\n ...\n```\n\n### Metadata Types\n\n**CSV Upload:**\n```python\nmetadata = {\n \"action_type\": \"csv_upload\",\n \"csv_data\": str # CSV content as string\n}\n```\n\n**Button Click:**\n```python\nmetadata = {\n \"action_type\": str, # e.g., \"add_to_cart\"\n \"action_data\": dict # Full action payload from Adaptive Card\n}\n```\n\n### BotConfig Options\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `app_id` | str | required | Microsoft App ID |\n| `app_password` | str | required | Microsoft App Password |\n| `app_tenant_id` | str | None | Microsoft Tenant ID (optional) |\n| `endpoint_path` | str | \"/api/messages\" | Bot endpoint path |\n| `enable_typing_indicator` | bool | True | Show typing indicator |\n| `max_file_size_mb` | int | 10 | Max file upload size |\n| `supported_file_types` | list[str] | [\"text/csv\"] | Supported MIME types |\n\n## \ud83e\uddea Testing\n\n```python\nimport pytest\nfrom fastapi_teams_bot import User\n\n@pytest.mark.asyncio\nasync def test_my_processor():\n \"\"\"Test your message processor.\"\"\"\n result = await my_message_processor(\n user_message=\"Hello\",\n user={\"name\": \"Test User\", \"id\": \"test-123\"},\n conversation_id=\"conv-456\",\n )\n \n assert \"Hello\" in result[\"message\"]\n```\n\n## \ud83c\udfaf Use Cases\n\nThis library is perfect for:\n\n- **Customer Support Bots**: Integrate with your support knowledge base\n- **Sales Assistants**: Help users browse products and place orders\n- **Data Analysis Bots**: Upload CSV files and get insights\n- **Workflow Automation**: Trigger actions through conversational interface\n- **Internal Tools**: Company directory, IT helpdesk, HR assistant\n- **AI Agents**: Connect LLMs (GPT, Claude, etc.) to Teams\n\n## \ud83d\udce6 What's Included\n\n- \u2705 Bot endpoint (`/api/messages`)\n- \u2705 Authentication & token validation\n- \u2705 Message processing\n- \u2705 Typing indicators\n- \u2705 Adaptive Cards\n- \u2705 CSV upload/download\n- \u2705 File consent handling\n- \u2705 Error handling\n- \u2705 Logging\n- \u2705 Type definitions\n\n## \ud83d\udee0\ufe0f Development\n\n### Setup\n\n```bash\ngit clone https://github.com/vishalgoel2/fastapi-teams-bot.git\ncd fastapi-teams-bot\n\n# Sync dependencies\nuv sync\n\n# Or install in development mode\nuv pip install -e \".[dev]\"\n```\n\n### Run Tests\n\n```bash\n# Run all tests with coverage\nuv run pytest tests/ -v --cov=fastapi_teams_bot\n\n# Run with HTML coverage report\nuv run pytest tests/ --cov=fastapi_teams_bot --cov-report=html\n```\n\n### Code Quality\n\n```bash\n# Format code\nuv run black src/ tests/\n\n# Lint code\nuv run ruff check src/ tests/\n\n# Type checking\nuv run mypy src/\n```\n\n## \ud83e\udd1d Contributing\n\nContributions are welcome! Please check out our [Contributing Guide](CONTRIBUTING.md).\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n## \ud83d\udcdd License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## \ud83d\ude4f Acknowledgments\n\n- Built with [FastAPI](https://fastapi.tiangolo.com/)\n- Uses [Microsoft Bot Framework](https://dev.botframework.com/)\n- Inspired by the need for simple, flexible Teams bot development\n\n## \ud83d\udce7 Support\n\n- \ud83d\udcd6 [Documentation](https://github.com/vishalgoel2/fastapi-teams-bot#readme)\n- \ud83d\udc1b [Issue Tracker](https://github.com/vishalgoel2/fastapi-teams-bot/issues)\n- \ud83d\udcac [Discussions](https://github.com/vishalgoel2/fastapi-teams-bot/discussions)\n\n## \ud83d\uddfa\ufe0f Roadmap\n\n- [ ] Support for more file types (PDF, images, etc.)\n- [ ] Built-in rate limiting\n- [ ] Conversation state management helpers\n- [ ] Teams app manifest generator\n- [ ] Deployment templates (Azure, Docker)\n- [ ] More examples (OpenAI, Anthropic, etc.)\n\n## \u2b50 Star History\n\nIf you find this project helpful, please consider giving it a star!\n\n---\n\nMade with \u2764\ufe0f by [Vishal Goel](https://github.com/vishalgoel2)\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "FastAPI-based framework for building Microsoft Teams bots with pluggable message processing",
"version": "0.1.0",
"project_urls": {
"Documentation": "https://github.com/vishalgoel2/fastapi-teams-bot#readme",
"Homepage": "https://github.com/vishalgoel2/fastapi-teams-bot",
"Issues": "https://github.com/vishalgoel2/fastapi-teams-bot/issues",
"Repository": "https://github.com/vishalgoel2/fastapi-teams-bot"
},
"split_keywords": [
"bot",
" chatbot",
" fastapi",
" langchain",
" langgraph",
" microsoft",
" teams"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "4f697d977d4635581fcc1f72675f8cf12708376362ea38fe636190a5b5556f53",
"md5": "84813b5e16bd17745e354278e011e1dd",
"sha256": "b769b6d99888d613d89e88f0efc347483b847c6dfa710d8eb1dcb06251cc8bfa"
},
"downloads": -1,
"filename": "fastapi_teams_bot-0.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "84813b5e16bd17745e354278e011e1dd",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 13486,
"upload_time": "2025-10-19T15:44:46",
"upload_time_iso_8601": "2025-10-19T15:44:46.564267Z",
"url": "https://files.pythonhosted.org/packages/4f/69/7d977d4635581fcc1f72675f8cf12708376362ea38fe636190a5b5556f53/fastapi_teams_bot-0.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "fb71b53524c13efbbb92d26a92e87f58cfa5f3ba6b8ebd3b90d8a58d559d1b90",
"md5": "829463e345aef38546dc8e64a399d983",
"sha256": "7a0ad74785564472a98bd5ee2795b98355d58ec8b1a05e89d712ad571ee652cd"
},
"downloads": -1,
"filename": "fastapi_teams_bot-0.1.0.tar.gz",
"has_sig": false,
"md5_digest": "829463e345aef38546dc8e64a399d983",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 21371,
"upload_time": "2025-10-19T15:44:47",
"upload_time_iso_8601": "2025-10-19T15:44:47.657767Z",
"url": "https://files.pythonhosted.org/packages/fb/71/b53524c13efbbb92d26a92e87f58cfa5f3ba6b8ebd3b90d8a58d559d1b90/fastapi_teams_bot-0.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-19 15:44:47",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "vishalgoel2",
"github_project": "fastapi-teams-bot#readme",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "fastapi-teams-bot"
}