from typing import Any from fastapi import APIRouter, Body, Depends, Query, Response, status from .config import Settings from .credentials import get_request_settings from .graph_client import MicrosoftGraphClient from .schemas import CalendarEventRequest, DriveUploadRequest, SendMailRequest from .services import CalendarService, DriveService, GroupsService, MailService, UsersService router = APIRouter(tags=["microsoft365"]) def get_graph_client(request_settings: Settings = Depends(get_request_settings)) -> MicrosoftGraphClient: return MicrosoftGraphClient(request_settings) 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(request_settings: Settings = Depends(get_request_settings)) -> dict[str, Any]: return { "configured": request_settings.is_configured, "tenant_id": bool(request_settings.tenant_id), "client_id": bool(request_settings.client_id), "client_secret": bool(request_settings.client_secret), "graph_base_url": request_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)