Spaces:
Runtime error
Runtime error
| #!/usr/bin/env python3 | |
| """ | |
| Custom HTTP Request Tool for Hugging Face Spaces | |
| Replaces strands-tools http_request to avoid npm permission issues | |
| """ | |
| import requests | |
| from bs4 import BeautifulSoup | |
| import html2text | |
| from strands import tool | |
| from typing import Optional | |
| def http_request(url: str, method: str = "GET", headers: Optional[dict] = None, | |
| data: Optional[dict] = None, timeout: int = 30) -> str: | |
| """ | |
| Make HTTP requests and return content as markdown | |
| Args: | |
| url: The URL to fetch | |
| method: HTTP method (GET, POST, etc.) | |
| headers: Optional headers dictionary | |
| data: Optional data for POST requests | |
| timeout: Request timeout in seconds | |
| Returns: | |
| Content converted to markdown format | |
| """ | |
| print(f"π Making {method} request to: {url}") | |
| try: | |
| # Set default headers | |
| if headers is None: | |
| headers = { | |
| 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' | |
| } | |
| # Make the HTTP request | |
| if method.upper() == "POST": | |
| response = requests.post(url, headers=headers, json=data, timeout=timeout) | |
| elif method.upper() == "PUT": | |
| response = requests.put(url, headers=headers, json=data, timeout=timeout) | |
| elif method.upper() == "DELETE": | |
| response = requests.delete(url, headers=headers, timeout=timeout) | |
| else: | |
| response = requests.get(url, headers=headers, timeout=timeout) | |
| # Check if request was successful | |
| response.raise_for_status() | |
| # Get content type | |
| content_type = response.headers.get('content-type', '').lower() | |
| # Handle different content types | |
| if 'application/json' in content_type: | |
| # Return JSON as formatted text | |
| import json | |
| return json.dumps(response.json(), indent=2) | |
| elif 'text/html' in content_type: | |
| # Convert HTML to markdown | |
| soup = BeautifulSoup(response.text, 'html.parser') | |
| # Remove script and style tags | |
| for tag in soup(["script", "style", "nav", "footer", "header"]): | |
| tag.decompose() | |
| # Convert to markdown | |
| h = html2text.HTML2Text() | |
| h.ignore_links = False | |
| h.ignore_images = False | |
| h.body_width = 0 # No line wrapping | |
| markdown_content = h.handle(str(soup)) | |
| # Add metadata | |
| result = f"# Content from {url}\n\n" | |
| result += f"**Status Code:** {response.status_code}\n" | |
| result += f"**Content Type:** {content_type}\n\n" | |
| result += markdown_content | |
| print(f"β Successfully fetched and converted HTML content ({len(result)} chars)") | |
| return result | |
| else: | |
| # Return plain text | |
| result = f"# Content from {url}\n\n" | |
| result += f"**Status Code:** {response.status_code}\n" | |
| result += f"**Content Type:** {content_type}\n\n" | |
| result += response.text | |
| print(f"β Successfully fetched text content ({len(result)} chars)") | |
| return result | |
| except requests.exceptions.Timeout: | |
| error_msg = f"Request to {url} timed out after {timeout} seconds" | |
| print(f"β {error_msg}") | |
| return error_msg | |
| except requests.exceptions.RequestException as e: | |
| error_msg = f"HTTP request failed for {url}: {str(e)}" | |
| print(f"β {error_msg}") | |
| return error_msg | |
| except Exception as e: | |
| error_msg = f"Error processing HTTP request for {url}: {str(e)}" | |
| print(f"β {error_msg}") | |
| return error_msg | |