A MS Graph API (Users) Agent#
Collaborators:
Roberto Rodriguez (@Cyb3rWard0g)
References:
Download MS Graph (User) OpenAPI specification#
Location: microsoftgraph/msgraph-sdk-powershell
Load Open API Specification#
import os
import yaml
from langchain.agents.agent_toolkits.openapi.spec import reduce_openapi_spec
current_directory = os.path.abspath('')
data_directory = os.path.join(current_directory, "data")
msgraph_api_file = os.path.join(data_directory, "OpenAPI-MSGraph-v1.0-Users.yml")
raw_msgraph_api_spec = yaml.load(open(msgraph_api_file,encoding='utf-8').read(), Loader=yaml.Loader)
msgraph_api_spec = reduce_openapi_spec(raw_msgraph_api_spec,dereference=False)
MS Graph API Spec#
endpoints = [
(route, operation)
for route, operations in raw_msgraph_api_spec["paths"].items()
for operation in operations
if operation in ["get", "post"]
]
len(endpoints)
140
Initialize Open AI Key#
import os
from dotenv import load_dotenv
import openai
# Get your key: https://platform.openai.com/account/api-keys
load_dotenv()
openai.api_key = os.getenv("OPENAI_API_KEY")
Define OpenAI Chat API#
from langchain.chat_models import ChatOpenAI
from langchain.agents.agent_toolkits.openapi import planner
llm = ChatOpenAI(model_name="gpt-4", temperature=0.0)
msgraph_agent = planner.create_openapi_agent(msgraph_api_spec, requests_wrapper, llm)
Run Query#
user_query = (
"Search for user with id 3b83a100-f4b1-4b9a-934e-5626c7c00dbd"
)
msgraph_agent.run(user_query)
> Entering new AgentExecutor chain...
Action: api_planner
Action Input: Search for user with id 3b83a100-f4b1-4b9a-934e-5626c7c00dbd
Observation: 1. GET /users/{user-id} to retrieve the properties and relationships of the user with the id 3b83a100-f4b1-4b9a-934e-5626c7c00dbd.
Thought:I'm ready to execute the API call.
Action: api_controller
Action Input: GET /users/{user-id} to retrieve the properties and relationships of the user with the id 3b83a100-f4b1-4b9a-934e-5626c7c00dbd.
> Entering new AgentExecutor chain...
I need to use the requests_get tool to make a GET request to the /users/{user-id} endpoint of the API. The user-id is 3b83a100-f4b1-4b9a-934e-5626c7c00dbd. I don't need any parameters for this request. I will extract the id and name from the response.
Action: requests_get
Action Input:
{
"url": "https://graph.microsoft.com/v1.0/users/3b83a100-f4b1-4b9a-934e-5626c7c00dbd",
"params": {},
"output_instructions": {
"id": "id",
"name": "displayName"
}
}
Observation: {'id': '3b83a100-f4b1-4b9a-934e-5626c7c00dbd', 'name': 'Cyb3rWard0g'}
Thought:I have successfully retrieved the user's id and name. The user's id is 3b83a100-f4b1-4b9a-934e-5626c7c00dbd and the name is Cyb3rWard0g. I have completed the plan.
Final Answer: {'id': '3b83a100-f4b1-4b9a-934e-5626c00dbd', 'name': 'Cyb3rWard0g'}
> Finished chain.
Observation: {'id': '3b83a100-f4b1-4b9a-934e-5626c00dbd', 'name': 'Cyb3rWard0g'}
Thought:I am finished executing the plan and have the information the user asked for.
Final Answer: The user with id 3b83a100-f4b1-4b9a-934e-5626c7c00dbd is named 'Cyb3rWard0g'.
> Finished chain.
"The user with id 3b83a100-f4b1-4b9a-934e-5626c7c00dbd is named 'Cyb3rWard0g'."
One Cell Execution#
# Download MS Graph API OpenAPI Specification:
# https://github.com/microsoftgraph/msgraph-sdk-powershell/blob/dev/openApiDocs/v1.0/Users.yml
import os
import yaml
from langchain.agents.agent_toolkits.openapi.spec import reduce_openapi_spec
# Read File Locally
current_directory = os.path.abspath('')
msgraph_api_file = os.path.join('data', "OpenAPI-MSGraph-v1.0-Users.yml")
raw_msgraph_api_spec = yaml.load(open(msgraph_api_file,encoding='utf-8').read(), Loader=yaml.Loader)
# Read as OpenAPI Specification
msgraph_api_spec = reduce_openapi_spec(raw_msgraph_api_spec,dereference=False)
# Define LangChain Authorization Header Function
from azure.identity import InteractiveBrowserCredential
from langchain.requests import RequestsWrapper
def construct_auth_headers(raw_spec: dict):
credential = InteractiveBrowserCredential()
access_token = (credential.get_token("https://graph.microsoft.com/.default")).token
return {"Authorization": f"Bearer {access_token}"}
# Get Access Token -> Authorization Header.
headers = construct_auth_headers(raw_msgraph_api_spec)
requests_wrapper = RequestsWrapper(headers=headers)
# Define OpenAI Chat API
from langchain.chat_models import ChatOpenAI
from langchain.agents.agent_toolkits.openapi import planner
from dotenv import load_dotenv
import openai
# Initialize OpenAI Key. Get your key: https://platform.openai.com/account/api-keys
load_dotenv()
openai.api_key = os.getenv("OPENAI_API_KEY")
llm = ChatOpenAI(model_name="gpt-4", temperature=0.0)
# Create OpenAPI Agent
msgraph_agent = planner.create_openapi_agent(msgraph_api_spec, requests_wrapper, llm)
# Pass prompt (Natural Language) to Agent -> Call MS Graph API
msgraph_agent.run(("Search for user with id 3b83a100-f4b1-4b9a-934e-5626c7c00dbd"))
> Entering new AgentExecutor chain...
Action: api_planner
Action Input: Search for user with id 3b83a100-f4b1-4b9a-934e-5626c7c00dbd
Observation: 1. GET /users/{user-id} to retrieve the properties and relationships of the user with the id 3b83a100-f4b1-4b9a-934e-5626c7c00dbd.
Thought:I'm ready to execute the API call.
Action: api_controller
Action Input: GET /users/{user-id} to retrieve the properties and relationships of the user with the id 3b83a100-f4b1-4b9a-934e-5626c7c00dbd.
> Entering new AgentExecutor chain...
I need to use the requests_get tool to make a GET request to the /users/{user-id} endpoint of the API. The user-id in the path should be replaced with the actual user id.
Action: requests_get
Action Input:
{
"url": "https://graph.microsoft.com/v1.0/users/3b83a100-f4b1-4b9a-934e-5626c7c00dbd",
"params": {},
"output_instructions": "Extract the id and name of the user"
}
Observation: The user's ID is "3b83a100-f4b1-4b9a-934e-5626c7c00dbd" and the name is "Cyb3rWard0g".
Thought:I have successfully retrieved the user's information. The plan has been executed successfully.
Final Answer: The user's ID is "3b83a100-f4b1-4b9a-934e-5626c7c00dbd" and the name is "Cyb3rWard0g".
> Finished chain.
Observation: The user's ID is "3b83a100-f4b1-4b9a-934e-5626c7c00dbd" and the name is "Cyb3rWard0g".
Thought:I am finished executing the plan and have the information the user asked for.
Final Answer: The user's ID is "3b83a100-f4b1-4b9a-934e-5626c7c00dbd" and the name is "Cyb3rWard0g".
> Finished chain.
'The user\'s ID is "3b83a100-f4b1-4b9a-934e-5626c7c00dbd" and the name is "Cyb3rWard0g".'