from typing import Any from fastapi import APIRouter, Body, Depends, Query, Response, status from .config import settings from .graph_client import MicrosoftGraphClient from .schemas import CalendarEventRequest, DriveUploadRequest, SendMailRequest from .services import CalendarService, DriveService, GroupsService, MailService, UsersService router = APIRouter(prefix="/microsoft365", tags=["microsoft365"]) graph_client = MicrosoftGraphClient(settings) def get_graph_client() -> MicrosoftGraphClient: return graph_client def get_users_service(graph: MicrosoftGraphClient = Depends(get_graph_client)) -> UsersService: return UsersService(graph) def get_mail_service(graph: MicrosoftGraphClient = Depends(get_graph_client)) -> MailService: return MailService(graph) def get_calendar_service(graph: MicrosoftGraphClient = Depends(get_graph_client)) -> CalendarService: return CalendarService(graph) def get_drive_service(graph: MicrosoftGraphClient = Depends(get_graph_client)) -> DriveService: return DriveService(graph) def get_groups_service(graph: MicrosoftGraphClient = Depends(get_graph_client)) -> GroupsService: return GroupsService(graph) @router.get("/status") def microsoft365_status() -> dict[str, Any]: return { "configured": settings.is_configured, "tenant_id": bool(settings.tenant_id), "client_id": bool(settings.client_id), "client_secret": bool(settings.client_secret), "graph_base_url": settings.graph_base_url, } @router.get("/users") async def list_users( top: int = Query(25, ge=1, le=999), search: str | None = None, service: UsersService = Depends(get_users_service), ) -> Any: return await service.list_users(top=top, search=search) @router.get("/users/{user_id}") async def get_user(user_id: str, service: UsersService = Depends(get_users_service)) -> Any: return await service.get_user(user_id) @router.get("/users/{user_id}/mail/messages") async def list_messages( user_id: str, folder: str = "Inbox", top: int = Query(25, ge=1, le=100), service: MailService = Depends(get_mail_service), ) -> Any: return await service.list_messages(user_id=user_id, folder=folder, top=top) @router.post("/users/{user_id}/mail/send", status_code=status.HTTP_202_ACCEPTED) async def send_mail( user_id: str, request: SendMailRequest, response: Response, service: MailService = Depends(get_mail_service), ) -> None: await service.send_mail(user_id=user_id, request=request) response.status_code = status.HTTP_202_ACCEPTED @router.get("/users/{user_id}/calendar/events") async def list_events( user_id: str, top: int = Query(25, ge=1, le=100), service: CalendarService = Depends(get_calendar_service), ) -> Any: return await service.list_events(user_id=user_id, top=top) @router.post("/users/{user_id}/calendar/events", status_code=status.HTTP_201_CREATED) async def create_event( user_id: str, request: CalendarEventRequest, service: CalendarService = Depends(get_calendar_service), ) -> Any: return await service.create_event(user_id=user_id, request=request) @router.get("/users/{user_id}/drive/root/children") async def list_drive_root_children( user_id: str, top: int = Query(25, ge=1, le=200), service: DriveService = Depends(get_drive_service), ) -> Any: return await service.list_root_children(user_id=user_id, top=top) @router.put("/users/{user_id}/drive/root/{path:path}") async def upload_small_file( user_id: str, path: str, request: DriveUploadRequest = Body(...), service: DriveService = Depends(get_drive_service), ) -> Any: return await service.upload_small_file(user_id=user_id, path=path, request=request) @router.get("/groups") async def list_groups( top: int = Query(25, ge=1, le=999), service: GroupsService = Depends(get_groups_service), ) -> Any: return await service.list_groups(top=top) @router.get("/teams/{team_id}/channels") async def list_team_channels(team_id: str, service: GroupsService = Depends(get_groups_service)) -> Any: return await service.list_team_channels(team_id=team_id)