Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ dmypy.json

ref/
py.typed
CLAUDE.md

.env.claude/
.claude/
Expand Down
85 changes: 85 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Comment on lines +1 to +3
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description mentions initializing a ".claude.md", but this change adds/uses a root-level "CLAUDE.md" (and removes it from .gitignore). If the intended filename is dot-prefixed, rename the file accordingly; otherwise update the PR title/description to match the actual filename to avoid confusion for contributors.

Copilot uses AI. Check for mistakes.

## Project Overview

Microsoft Teams Python SDK — a UV workspace with multiple packages providing APIs, common utilities, and integrations for Microsoft Teams.

## Development Setup

### Prerequisites
- UV >= 0.9.8
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The stated UV prerequisite (">= 0.9.8") doesn’t match the repo’s existing guidance and automation: README.md lists UV ">= 0.8.11", and the CI workflow installs uv 0.5.24. Please align this prerequisite with the repo’s documented/supported version (or avoid pinning to a higher minimum) so contributors don’t assume they need a version newer than what CI uses.

Suggested change
- UV >= 0.9.8
- UV >= 0.8.11

Copilot uses AI. Check for mistakes.
- Python >= 3.12

### Commands
```bash
uv sync # Install virtual env and dependencies
source .venv/bin/activate # Activate virtual environment
pre-commit install # Install pre-commit hooks

poe fmt # Format code with ruff
poe lint # Lint code with ruff
poe check # Run both format and lint
poe test # Run tests with pytest
pyright # Run type checker
```

## Tooling

- **Formatter/Linter**: Ruff — line length 120, rules: E, F, W, B, Q, I, ASYNC
- **Type checker**: Pyright
- **Test framework**: pytest + pytest-asyncio (ruff bans unittest)
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

“ruff bans unittest” is misleading in this repo: the Ruff config only bans importing the unittest framework module, while the test suite uses unittest.mock in many places. Consider rewording this to clarify that unittest.TestCase-style tests are discouraged, but unittest.mock is acceptable/used.

Suggested change
- **Test framework**: pytest + pytest-asyncio (ruff bans unittest)
- **Test framework**: pytest + pytest-asyncio (Ruff bans importing the unittest test framework; unittest.mock is allowed and used)

Copilot uses AI. Check for mistakes.

## Architecture

### Workspace Structure
All packages live in `packages/`, each with `src/microsoft_teams/<package>/` layout:
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workspace layout description is incomplete: each package includes both src/microsoft_teams/... (current namespace) and src/microsoft/teams/... (backward-compat shim namespace). Updating this line to mention the shim path will prevent contributors from deleting or misinterpreting the src/microsoft tree.

Suggested change
All packages live in `packages/`, each with `src/microsoft_teams/<package>/` layout:
All packages live in `packages/`, each with both `src/microsoft_teams/<package>/` (current namespace) and `src/microsoft/teams/<package>/` (backward-compat shim namespace) layout:

Copilot uses AI. Check for mistakes.

| Package | Description |
|---------|-------------|
| `api` | Core API clients, models (Account, Activity, Conversation), auth |
| `apps` | App orchestrator, plugins, routing, events, HttpServer |
| `common` | HTTP client abstraction, logging, storage |
| `cards` | Adaptive cards |
| `ai` | AI/function calling utilities |
| `botbuilder` | Bot Framework integration plugin |
| `devtools` | Development tools plugin |
| `mcpplugin` | MCP server plugin |
| `a2aprotocol` | A2A protocol plugin |
| `graph` | Microsoft Graph integration |
| `openai` | OpenAI integration |

### Key Patterns

**Imports**
- ALL imports MUST be at the top of the file — no imports inside functions, classes, or conditional blocks
- Avoid `TYPE_CHECKING` blocks unless absolutely necessary (genuine circular imports that can't be restructured)
- Avoid dynamic/deferred imports unless absolutely necessary
- Relative imports within the same package, absolute for external packages
Comment on lines +56 to +59
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The “Imports” rules are stricter than the codebase reality and will conflict with existing patterns: the repo uses TYPE_CHECKING blocks (e.g., forward refs/optional deps) and sometimes does lazy/conditional imports (e.g., optional Graph dependency). Please soften these bullets to reflect the actual convention (prefer top-level imports, but allow TYPE_CHECKING and local imports when needed for optional deps or circular-import avoidance).

Suggested change
- ALL imports MUST be at the top of the file — no imports inside functions, classes, or conditional blocks
- Avoid `TYPE_CHECKING` blocks unless absolutely necessary (genuine circular imports that can't be restructured)
- Avoid dynamic/deferred imports unless absolutely necessary
- Relative imports within the same package, absolute for external packages
- Prefer imports at the top of the file; local/conditional imports are allowed when needed for optional dependencies, performance, or to avoid circular imports
- `TYPE_CHECKING` blocks are allowed for forward references, optional dependencies, or genuine circular-import issues; otherwise keep imports regular and top-level
- Prefer simple, eager imports; use dynamic/deferred imports only for optional features (e.g., Graph) or heavy dependencies that are not always needed
- Use relative imports within the same package and absolute imports for external packages

Copilot uses AI. Check for mistakes.

**Models**
- Pydantic with `ConfigDict(alias_generator=to_camel)` — snake_case in Python, camelCase in JSON
- `model_dump(by_alias=True)` for serialization, `model_dump(exclude_none=True)` for query params

**Interfaces**
- Protocol classes instead of Abstract Base Classes (ABC)
- Prefer composition over inheritance

**Clients**
- Concrete clients inherit from `BaseClient` (`packages/api/src/microsoft_teams/api/clients/base_client.py`)
- Composition with operation classes for sub-functionality
- async/await for all API calls, return domain models

## Scaffolding (cookiecutter)

```bash
cookiecutter templates/package -o packages # New package
cookiecutter templates/test -o tests # New test package
```

## Dependencies and Build

- UV workspace — packages reference each other via `{ workspace = true }`
- Hatchling build backend
- Dev dependencies in root `pyproject.toml`