Skip to content

Instantly share code, notes, and snippets.

@devalexandre
Created March 4, 2025 10:51
Show Gist options
  • Select an option

  • Save devalexandre/50e53cc8355278fdff7e684cd1d34e4c to your computer and use it in GitHub Desktop.

Select an option

Save devalexandre/50e53cc8355278fdff7e684cd1d34e4c to your computer and use it in GitHub Desktop.
import os
from agno.agent.agent import Agent
from agno.models.openai.like import OpenAILike
from tools.packt import PacktSearchTool
from agno.utils.log import logger
logger.info("Initializing agent")
agent: Agent = Agent(model=OpenAILike(
id="qwen-plus",
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
),
tools=[PacktSearchTool()],
show_tool_calls=True,
markdown=True
)
agent.print_response("What's top 5 from packt top Golang books")
# packt.py
from logging import log
from typing import Optional
from agno.tools.toolkit import Toolkit
import requests
from bs4 import BeautifulSoup, Tag
from agno.utils.log import logger
class PacktSearchTool(Toolkit):
def __init__(self):
super().__init__(name="packt_search_tool")
self.base_url = "https://www.packtpub.com/en-us/search?q="
self.register(self.run_search)
def run_search(self, query: str) -> str:
"""
Search PacktPub for books based on a query.
Return using rating asc
Args:
query (str): The search query.
Returns:
str: A formatted string containing the search results.
"""
url = f"{self.base_url}{query}"
headers = {'User-Agent': 'Mozilla/5.0'}
logger.info(f"Searching PacktPub for '{query}' at URL: {url}")
try:
response = requests.get(url, headers=headers)
if response.status_code != 200:
return f"Failed to retrieve data, status code: {response.status_code}"
logger.info(f"Received response with status code {response.status_code}")
soup = BeautifulSoup(response.text, 'html.parser')
items = soup.find_all('div', class_='product-card-v2') # Adjust based on actual HTML structure
if not items:
return "No results found."
results = []
for item in items: # Limiting to top 5 results for simplicity
if isinstance(item, Tag):
title_element = self._safe_find(item, 'div', class_='ellipsis-content product-card-v2-content-info-text')
link_element = self._safe_find(item, 'a')
year_element = self._safe_find(item, 'div', class_='product-meta product-card-v2-meta-info-text device--sm')
if title_element and link_element:
title = title_element.get_text(strip=True)
link = link_element.get('href', '')
year = year_element.get_text(strip=True) if year_element else None
rating = self._safe_find(item, 'div', class_='star-rating')
# Append result as a formatted string
results.append(
"\n".join([
f"Title: {title}",
f"Link: https://www.packtpub.com{link}",
f"Year: {year}",
f"Rating: {rating}"
])
)
# Combine all results into a single string separated by double newlines
return "\n\n".join(results) if results else "No results found."
except Exception as e:
logger.error(f"An error occurred: {e}")
return f"Error: {e}"
@staticmethod
def _safe_find(element: Tag, *args, **kwargs) -> Optional[Tag]:
"""
Safely finds an element and ensures the result is of type Tag or None.
Args:
element (Tag): The parent element to search within.
*args, **kwargs: Arguments passed to BeautifulSoup's find method.
Returns:
Optional[Tag]: The found element as a Tag, or None if not found.
"""
result = element.find(*args, **kwargs)
return result if isinstance(result, Tag) else None
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment