Skip to content

Commit 646e5d3

Browse files
Create langchain_example.py (#67)
* Create langchain_example.py Signed-off-by: Blaise <[email protected]> * Update langchain_example.py --------- Signed-off-by: Blaise <[email protected]> Co-authored-by: Ads Dawson <[email protected]>
1 parent 6c7b5f6 commit 646e5d3

File tree

1 file changed

+177
-0
lines changed

1 file changed

+177
-0
lines changed

examples/langchain_example.py

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
from os import getenv
2+
from typing import Dict, List, Optional, Type
3+
import requests
4+
5+
from langchain_core.tools import BaseTool
6+
from pydantic import BaseModel, Field, create_model
7+
8+
_SERVER_URL = getenv("ROBOPAGES_SERVER", "http://127.0.0.1:8000")
9+
10+
class RoboPagesTool(BaseTool):
11+
name: str
12+
description: str
13+
parameters: List[Dict]
14+
args_schema: Optional[ArgsSchema]
15+
16+
__baseURL: str = _SERVER_URL
17+
18+
def _run(self, *args, **kwargs):
19+
process_url = f"{self.__baseURL}/process"
20+
headers = {"Content-type": "application/json"}
21+
22+
payload = [
23+
{
24+
"type": "function",
25+
"function": {
26+
"name": self.name,
27+
"arguments": kwargs
28+
}
29+
}
30+
]
31+
32+
response = requests.post(
33+
url=process_url,
34+
headers=headers,
35+
json=payload
36+
)
37+
return response.json()[0]
38+
39+
class RoboPagesOutput(BaseModel):
40+
tool: str = Field(description="The tool that was used")
41+
parameters: Dict = Field(description="The parameters for the requested tool")
42+
43+
class RoboPages:
44+
def __init__(self, server_url: str = None):
45+
"""Initialize RoboPages with an optional base URL override."""
46+
self.__server_url: str = server_url if server_url else _SERVER_URL
47+
self.__server_url += "/?flavor=rigging"
48+
self.tools: List[RoboPagesTool] = []
49+
self.RoboPagesOutput = RoboPagesOutput
50+
51+
def __get_tools(self):
52+
response = requests.get(self.__server_url)
53+
response.raise_for_status()
54+
return response.json()
55+
56+
def __create_tools(self) -> List[RoboPagesTool]:
57+
"""Create LangChain Tools based on the functions from the root endpoint."""
58+
functions = self.__get_tools()
59+
self.tools = []
60+
61+
for item in functions:
62+
for func in item["functions"]:
63+
name = func["name"]
64+
description = func["description"]
65+
parameters = func["parameters"]
66+
67+
#Building arg fields for pydantic
68+
args = {}
69+
for param in parameters:
70+
args[param["name"]] = (param["type"], Field(description=param["description"]))
71+
72+
tool = RoboPagesTool(
73+
name= name,
74+
description= description,
75+
parameters= parameters,
76+
args_schema= create_model( f"{name}_schema", **args),
77+
)
78+
self.tools.append(tool)
79+
80+
return self.tools
81+
82+
def get_tools(self) -> List[RoboPagesTool]:
83+
"""Return the list of created tools, fetching and creating tools if needed."""
84+
if not self.tools:
85+
self.__create_tools()
86+
return self.tools
87+
88+
def get_tool(self, name: str) -> RoboPagesTool | None:
89+
"""Retrieve a specific tool by its name, fetching and creating tools if needed."""
90+
if not self.tools:
91+
self.__create_tools()
92+
for tool in self.tools:
93+
if tool.name == name:
94+
return tool
95+
return None
96+
97+
def filter_tools(self, filter_string: str) -> List[RoboPagesTool] | None:
98+
"""Retrieve a set of tools with the filter_string in the name, fetching and creating tools if needed."""
99+
output: List[RoboPagesTool] = []
100+
if not self.tools:
101+
self.__create_tools()
102+
for tool in self.tools:
103+
if filter_string.lower() in tool.name:
104+
output.append(tool)
105+
if output:
106+
return output
107+
else:
108+
return None
109+
110+
111+
if __name__ == "__main__":
112+
# Testing RoboPagesTool with default http_get function parameters
113+
print("++ Test tool 'http_get':")
114+
RoboPagesTool_test_name = "http_get"
115+
RoboPagesTool_test_description = "Perform an HTTP GET request to a given URL."
116+
RoboPagesTool_test_parameters =[
117+
{
118+
"description": "The URL to perform the GET request on.",
119+
"examples": "",
120+
"name": "url",
121+
"type": "str"
122+
},
123+
{
124+
"description": "An optional, NON EMPTY User-Agent string to use for the request.",
125+
"examples": "",
126+
"name": "user_agent",
127+
"type": "str"
128+
}
129+
]
130+
http_get = RoboPagesTool(
131+
name=RoboPagesTool_test_name,
132+
description=RoboPagesTool_test_description,
133+
parameters=RoboPagesTool_test_parameters,
134+
args_schema=create_model(
135+
"http_get",
136+
url=(str, Field(description="The URL to perform the GET request on.")),
137+
user_agent=(str, Field(description="An optional, NON EMPTY User-Agent string to use for the request."))
138+
)
139+
)
140+
http_get_tool_call = http_get.invoke({
141+
"url": "http://example.com",
142+
"user_agent": "RoboPages"
143+
})
144+
if http_get_tool_call[0:15] == "<!doctype html>":
145+
print(f"\033[32mPassed!\033[0m")
146+
else:
147+
print(f"\033[91mFailed!\033[0m")
148+
149+
print("++ Test Class RoboPages:")
150+
print("--- Create Tools Function")
151+
rb = RoboPages()
152+
robo_tools = []
153+
robo_tools = rb.get_tools()
154+
if robo_tools:
155+
print(f"\033[32mPassed!\033[0m")
156+
else:
157+
print(f"\033[91mFailed!\033[0m")
158+
159+
print("--- Get Tool Function")
160+
rb = RoboPages()
161+
robo_tool = []
162+
robo_tool = rb.get_tool(name= "http_get")
163+
if robo_tool:
164+
print(f"\033[32mPassed!\033[0m")
165+
else:
166+
print(f"\033[91mFailed!\033[0m")
167+
print("Done!")
168+
169+
print("--- Filter Tool Function")
170+
rb = RoboPages()
171+
robo_tool = []
172+
robo_tool = rb.filter_tools(filter_string="http_get")
173+
if robo_tool:
174+
print(f"\033[32mPassed!\033[0m")
175+
else:
176+
print(f"\033[91mFailed!\033[0m")
177+
print("Done!")

0 commit comments

Comments
 (0)