mirror of
https://github.com/Mintplex-Labs/langchain-python.git
synced 2026-07-21 00:35:23 -04:00
d84a3bcf7a
#### Background With the development of [structured tools](https://blog.langchain.dev/structured-tools/), the LangChain team expanded the platform's functionality to meet the needs of new applications. The GMail tool, empowered by structured tools, now supports multiple arguments and powerful search capabilities, demonstrating LangChain's ability to interact with dynamic data sources like email servers. #### Challenge The current GMail tool only supports GMail, while users often utilize other email services like Outlook in Office365. Additionally, the proposed calendar tool in PR https://github.com/hwchase17/langchain/pull/652 only works with Google Calendar, not Outlook. #### Changes This PR implements an Office365 integration for LangChain, enabling seamless email and calendar functionality with a single authentication process. #### Future Work With the core Office365 integration complete, future work could include integrating other Office365 tools such as Tasks and Address Book. #### Who can review? @hwchase17 or @vowelparrot can review this PR #### Appendix @janscas, I utilized your [O365](https://github.com/O365/python-o365) library extensively. Given the rising popularity of LangChain and similar AI frameworks, the convergence of libraries like O365 and tools like this one is likely. So, I wanted to keep you updated on our progress. --------- Co-authored-by: Dev 2049 <dev.dev2049@gmail.com>
75 lines
2.1 KiB
Python
75 lines
2.1 KiB
Python
"""O365 tool utils."""
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
import os
|
|
from typing import TYPE_CHECKING
|
|
|
|
if TYPE_CHECKING:
|
|
from O365 import Account
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def clean_body(body: str) -> str:
|
|
"""Clean body of a message or event."""
|
|
try:
|
|
from bs4 import BeautifulSoup
|
|
|
|
try:
|
|
# Remove HTML
|
|
soup = BeautifulSoup(str(body), "html.parser")
|
|
body = soup.get_text()
|
|
|
|
# Remove return characters
|
|
body = "".join(body.splitlines())
|
|
|
|
# Remove extra spaces
|
|
body = " ".join(body.split())
|
|
|
|
return str(body)
|
|
except Exception:
|
|
return str(body)
|
|
except ImportError:
|
|
return str(body)
|
|
|
|
|
|
def authenticate() -> Account:
|
|
"""Authenticate using the Microsoft Grah API"""
|
|
try:
|
|
from O365 import Account
|
|
except ImportError as e:
|
|
raise ImportError(
|
|
"Cannot import 0365. Please install the package with `pip install O365`."
|
|
) from e
|
|
|
|
if "CLIENT_ID" in os.environ and "CLIENT_SECRET" in os.environ:
|
|
client_id = os.environ["CLIENT_ID"]
|
|
client_secret = os.environ["CLIENT_SECRET"]
|
|
credentials = (client_id, client_secret)
|
|
else:
|
|
logger.error(
|
|
"Error: The CLIENT_ID and CLIENT_SECRET environmental variables have not "
|
|
"been set. Visit the following link on how to acquire these authorization "
|
|
"tokens: https://learn.microsoft.com/en-us/graph/auth/"
|
|
)
|
|
return None
|
|
|
|
account = Account(credentials)
|
|
|
|
if account.is_authenticated is False:
|
|
if not account.authenticate(
|
|
scopes=[
|
|
"https://graph.microsoft.com/Mail.ReadWrite",
|
|
"https://graph.microsoft.com/Mail.Send",
|
|
"https://graph.microsoft.com/Calendars.ReadWrite",
|
|
"https://graph.microsoft.com/MailboxSettings.ReadWrite",
|
|
]
|
|
):
|
|
print("Error: Could not authenticate")
|
|
return None
|
|
else:
|
|
return account
|
|
else:
|
|
return account
|