Skip to content

Commit 188e3bb

Browse files
authored
feat: support cli to parse swagger (#122)
* support cli to parse swagger and bugfix for agno tools * more examples and tests * fix lint
1 parent d44ff3e commit 188e3bb

File tree

13 files changed

+745
-5
lines changed

13 files changed

+745
-5
lines changed

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,18 @@ supporting both synchronous and asynchronous operations.
3737
pip install https://github.com/ponytailer/pydantic-client.git
3838
```
3939

40+
41+
## Examples
42+
43+
See the [`example/`](./example/) directory for real-world usage of this library, including:
44+
45+
- `example_requests.py`: Synchronous usage with RequestsWebClient
46+
- `example_httpx.py`: Async usage with HttpxWebClient
47+
- `example_aiohttp.py`: Async usage with AiohttpWebClient
48+
- `example_tools.py`: How to register and use Agno tools
49+
50+
Each file is fully commented in English and can be run directly for reference.
51+
4052
## Quick Start
4153

4254
```python
@@ -82,7 +94,11 @@ class MyAPIClient(RequestsWebClient):
8294
# will get raw content, bytes type.
8395
...
8496

85-
@delete("/users", agno_tool=True, tool_description="this is the function to delete user")
97+
@delete(
98+
"/users",
99+
agno_tool=True,
100+
tool_description="description or use function annotation."
101+
)
86102
def delete_user(self, user_id: str, request_headers: Dict[str, Any]):
87103
...
88104

example/example_aiohttp.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
"""
2+
Example: Async API client with AiohttpWebClient and Agno tools
3+
"""
4+
import asyncio
5+
from pydantic import BaseModel
6+
from pydantic_client import AiohttpWebClient, get, post
7+
8+
class Order(BaseModel):
9+
id: int
10+
item: str
11+
quantity: int
12+
13+
class MyAiohttpClient(AiohttpWebClient):
14+
def __init__(self):
15+
super().__init__(base_url="https://api.example.com")
16+
17+
@get("/orders/{order_id}", agno_tool=True, tool_description="Get order info by ID")
18+
async def get_order(self, order_id: int) -> Order:
19+
"""
20+
:param order_id: Order ID
21+
"""
22+
...
23+
24+
@post("/orders", agno_tool=True, tool_description="Create a new order")
25+
async def create_order(self, order: Order) -> Order:
26+
"""
27+
:param order: Order object
28+
"""
29+
...
30+
31+
async def main():
32+
client = MyAiohttpClient()
33+
# order = await client.get_order(555)
34+
# print("Order info:", order)
35+
class DummyAgent:
36+
def register_tool(self, name, description, parameters, call):
37+
print(f"Register tool: {name}, desc: {description}, params: {parameters}")
38+
agent = DummyAgent()
39+
client.register_agno_tools(agent)
40+
41+
if __name__ == "__main__":
42+
asyncio.run(main())

example/example_httpx.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
"""
2+
Example: Async API client with HttpxWebClient and Agno tools
3+
"""
4+
import asyncio
5+
from pydantic import BaseModel
6+
from pydantic_client import HttpxWebClient, get, post
7+
8+
class Product(BaseModel):
9+
id: int
10+
name: str
11+
price: float
12+
13+
class MyHttpxClient(HttpxWebClient):
14+
def __init__(self):
15+
super().__init__(base_url="https://api.example.com")
16+
17+
@get("/products/{product_id}", agno_tool=True, tool_description="Get product info by ID")
18+
async def get_product(self, product_id: int) -> Product:
19+
"""
20+
:param product_id: Product ID
21+
"""
22+
...
23+
24+
@post("/products", agno_tool=True, tool_description="Create a new product")
25+
async def create_product(self, product: Product) -> Product:
26+
"""
27+
:param product: Product object
28+
"""
29+
...
30+
31+
async def main():
32+
client = MyHttpxClient()
33+
# product = await client.get_product(101)
34+
# print("Product info:", product)
35+
class DummyAgent:
36+
def register_tool(self, name, description, parameters, call):
37+
print(f"Register tool: {name}, desc: {description}, params: {parameters}")
38+
agent = DummyAgent()
39+
client.register_agno_tools(agent)
40+
41+
if __name__ == "__main__":
42+
asyncio.run(main())

example/example_requests.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
"""
2+
Example: Synchronous API client with RequestsWebClient and Agno tools
3+
"""
4+
from pydantic import BaseModel
5+
from pydantic_client import RequestsWebClient, get, post
6+
7+
class User(BaseModel):
8+
id: int
9+
name: str
10+
email: str
11+
12+
class MyAPIClient(RequestsWebClient):
13+
def __init__(self):
14+
super().__init__(base_url="https://api.example.com")
15+
16+
@get("/users/{user_id}", agno_tool=True, tool_description="Get user info by ID")
17+
def get_user(self, user_id: int) -> User:
18+
"""
19+
:param user_id: User ID
20+
"""
21+
...
22+
23+
@post("/users", agno_tool=True, tool_description="Create a new user")
24+
def create_user(self, user: User) -> User:
25+
"""
26+
:param user: User object
27+
"""
28+
...
29+
30+
if __name__ == "__main__":
31+
client = MyAPIClient()
32+
# Call as normal API
33+
# user = client.get_user(1)
34+
# print("User info:", user)
35+
# Register as agno tools
36+
class DummyAgent:
37+
def register_tool(self, name, description, parameters, call):
38+
print(f"Register tool: {name}, desc: {description}, params: {parameters}")
39+
agent = DummyAgent()
40+
client.register_agno_tools(agent)

example/example_tools.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"""
2+
Example: Registering multiple API endpoints as Agno tools
3+
"""
4+
from pydantic import BaseModel
5+
from pydantic_client import RequestsWebClient, get, post
6+
7+
class MathResult(BaseModel):
8+
result: int
9+
10+
class ToolClient(RequestsWebClient):
11+
def __init__(self):
12+
super().__init__(base_url="https://api.example.com")
13+
14+
@get("/add", agno_tool=True, tool_description="Add two numbers")
15+
def add(self, a: int, b: int) -> MathResult:
16+
"""
17+
:param a: First number
18+
:param b: Second number
19+
"""
20+
...
21+
22+
@post("/multiply", agno_tool=True, tool_description="Multiply two numbers")
23+
def multiply(self, a: int, b: int) -> MathResult:
24+
"""
25+
:param a: First number
26+
:param b: Second number
27+
"""
28+
...
29+
30+
if __name__ == "__main__":
31+
client = ToolClient()
32+
# result = client.add(2, 3)
33+
# print("Add result:", result)
34+
class DummyAgent:
35+
def register_tool(self, name, description, parameters, call):
36+
print(f"Register tool: {name}, desc: {description}, params: {parameters}")
37+
agent = DummyAgent()
38+
client.register_agno_tools(agent)

example/example_usage.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
from pydantic import BaseModel
2+
from pydantic_client.base import BaseWebClient
3+
from pydantic_client.tools.agno import register_agno_tool
4+
5+
6+
class User(BaseModel):
7+
id: int
8+
name: str
9+
email: str
10+
11+
12+
class ExampleClient(BaseWebClient):
13+
14+
@register_agno_tool("Get user info")
15+
def get_user(self, user_id: int) -> User:
16+
"""
17+
:param user_id: User ID
18+
"""
19+
return User(id=user_id, name="John", email="john@example.com")
20+
21+
22+
if __name__ == "__main__":
23+
client = ExampleClient(base_url="http://api.example.com")
24+
user = client.get_user(1)
25+
print("User info:", user)
26+
# Register agno tool to a dummy agent
27+
class DummyAgent:
28+
def register_tool(self, name, description, parameters, call):
29+
print(f"Register tool: {name}, desc: {description}, params: {parameters}")
30+
agent = DummyAgent()
31+
client.register_agno_tools(agent)

pydantic_client/base.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ def from_config(cls, config: Dict[str, Any]) -> 'BaseWebClient':
5858
base_url=config['base_url'],
5959
headers=config.get('headers'),
6060
timeout=config.get('timeout', 30),
61-
session=config.get('session', None)
61+
session=config.get('session', None),
62+
statsd_address=config.get('statsd_address')
6263
)
6364

6465
def before_request(self, request_params: Dict[str, Any]) -> Dict[str, Any]:

0 commit comments

Comments
 (0)