Skip to main content

Requests Toolkit

We can use the Requests toolkit to construct agents that generate HTTP requests.

For detailed documentation of all API toolkit features and configurations head to the API reference for RequestsToolkit.

โš ๏ธ Security note โš ๏ธโ€‹

There are inherent risks in giving models discretion to execute real-world actions. Take precautions to mitigate these risks:

  • Make sure that permissions associated with the tools are narrowly-scoped (e.g., for database operations or API requests);
  • When desired, make use of human-in-the-loop workflows.

Setupโ€‹

Installationโ€‹

This toolkit lives in the langchain-community package:

%pip install -qU langchain-community

Note that if you want to get automated tracing from runs of individual tools, you can also set your LangSmith API key by uncommenting below:

# os.environ["LANGSMITH_API_KEY"] = getpass.getpass("Enter your LangSmith API key: ")
# os.environ["LANGSMITH_TRACING"] = "true"

Instantiationโ€‹

First we will demonstrate a minimal example.

NOTE: There are inherent risks in giving models discretion to execute real-world actions. We must "opt-in" to these risks by setting allow_dangerous_request=True to use these tools. This can be dangerous for calling unwanted requests. Please make sure your custom OpenAPI spec (yaml) is safe and that permissions associated with the tools are narrowly-scoped.

ALLOW_DANGEROUS_REQUEST = True

We can use the JSONPlaceholder API as a testing ground.

Let's create (a subset of) its API spec:

from typing import Any, Dict, Union

import requests
import yaml


def _get_schema(response_json: Union[dict, list]) -> dict:
if isinstance(response_json, list):
response_json = response_json[0] if response_json else {}
return {key: type(value).__name__ for key, value in response_json.items()}


def _get_api_spec() -> str:
base_url = "https://jsonplaceholder.typicode.com"
endpoints = [
"/posts",
"/comments",
]
common_query_parameters = [
{
"name": "_limit",
"in": "query",
"required": False,
"schema": {"type": "integer", "example": 2},
"description": "Limit the number of results",
}
]
openapi_spec: Dict[str, Any] = {
"openapi": "3.0.0",
"info": {"title": "JSONPlaceholder API", "version": "1.0.0"},
"servers": [{"url": base_url}],
"paths": {},
}
# Iterate over the endpoints to construct the paths
for endpoint in endpoints:
response = requests.get(base_url + endpoint)
if response.status_code == 200:
schema = _get_schema(response.json())
openapi_spec["paths"][endpoint] = {
"get": {
"summary": f"Get {endpoint[1:]}",
"parameters": common_query_parameters,
"responses": {
"200": {
"description": "Successful response",
"content": {
"application/json": {
"schema": {"type": "object", "properties": schema}
}
},
}
},
}
}
return yaml.dump(openapi_spec, sort_keys=False)


api_spec = _get_api_spec()

Next we can instantiate the toolkit. We require no authorization or other headers for this API:

from langchain_community.agent_toolkits.openapi.toolkit import RequestsToolkit
from langchain_community.utilities.requests import TextRequestsWrapper

toolkit = RequestsToolkit(
requests_wrapper=TextRequestsWrapper(headers={}),
allow_dangerous_requests=ALLOW_DANGEROUS_REQUEST,
)

Toolsโ€‹

View available tools:

tools = toolkit.get_tools()

tools
[RequestsGetTool(requests_wrapper=TextRequestsWrapper(headers={}, aiosession=None, auth=None, response_content_type='text', verify=True), allow_dangerous_requests=True),
RequestsPostTool(requests_wrapper=TextRequestsWrapper(headers={}, aiosession=None, auth=None, response_content_type='text', verify=True), allow_dangerous_requests=True),
RequestsPatchTool(requests_wrapper=TextRequestsWrapper(headers={}, aiosession=None, auth=None, response_content_type='text', verify=True), allow_dangerous_requests=True),
RequestsPutTool(requests_wrapper=TextRequestsWrapper(headers={}, aiosession=None, auth=None, response_content_type='text', verify=True), allow_dangerous_requests=True),
RequestsDeleteTool(requests_wrapper=TextRequestsWrapper(headers={}, aiosession=None, auth=None, response_content_type='text', verify=True), allow_dangerous_requests=True)]

Use within an agentโ€‹

from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent

llm = ChatOpenAI(model="gpt-4o-mini")

system_message = """
You have access to an API to help answer user queries.
Here is documentation on the API:
{api_spec}
""".format(api_spec=api_spec)

agent_executor = create_react_agent(llm, tools, state_modifier=system_message)
example_query = "Fetch the top two posts. What are their titles?"

events = agent_executor.stream(
{"messages": [("user", example_query)]},
stream_mode="values",
)
for event in events:
event["messages"][-1].pretty_print()
================================ Human Message =================================

Fetch the top two posts. What are their titles?
================================== Ai Message ==================================
Tool Calls:
requests_get (call_RV2SOyzCnV5h2sm4WPgG8fND)
Call ID: call_RV2SOyzCnV5h2sm4WPgG8fND
Args:
url: https://jsonplaceholder.typicode.com/posts?_limit=2
================================= Tool Message =================================
Name: requests_get

[
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
},
{
"userId": 1,
"id": 2,
"title": "qui est esse",
"body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
}
]
================================== Ai Message ==================================

The titles of the top two posts are:
1. "sunt aut facere repellat provident occaecati excepturi optio reprehenderit"
2. "qui est esse"

API referenceโ€‹

For detailed documentation of all API toolkit features and configurations head to the API reference for RequestsToolkit.


Was this page helpful?


You can also leave detailed feedback on GitHub.