Spaces:
Sleeping
Sleeping
| import requests | |
| from crewai.tools import BaseTool | |
| import re | |
| from typing import Any | |
| from merchs.merch import Merchant, NaturaMerchant, MercadoLivreMerchant | |
| def get_valid_image_url(url): | |
| """ | |
| Checks if an image URL is accessible. | |
| Returns the URL if it's valid, otherwise returns None. | |
| """ | |
| if not url: | |
| return None | |
| try: | |
| # Use a HEAD request to check headers without downloading the full image | |
| # A timeout is added as a good practice | |
| response = requests.head(url, allow_redirects=True, timeout=5) | |
| # Check if the status code is 200 (OK) | |
| if response.status_code == 200: | |
| print(f"URL is valid: {url}") | |
| return url | |
| else: | |
| print(f"URL is invalid, status code: {response.status_code}") | |
| return None | |
| except requests.RequestException as e: | |
| # Handle connection errors, timeouts, etc. | |
| print(f"An error occurred while checking the URL: {e}") | |
| return None | |
| class CalculateDiscountedPriceTool(BaseTool): | |
| """ | |
| A tool to calculate the final price of an item after a discount is applied. | |
| """ | |
| name: str = "Calculate Discounted Price Tool" | |
| description: str = "Calculates the price after applying a given discount percentage." | |
| def _run(self, original_price: float, discount_percentage: float) -> float: | |
| """Calculates the discounted price and the total discount amount. | |
| This method takes an original price and a discount percentage, validates | |
| the inputs, and then computes the final price after the discount is | |
| applied, as well as the amount saved. | |
| Args: | |
| original_price: The initial price of the item as a float or integer. | |
| Returns: | |
| float: | |
| - The final discounted price, rounded to 2 decimal places. | |
| """ | |
| if not isinstance(original_price, (int, float)) or not isinstance(discount_percentage, (int, float)): | |
| raise ValueError("Both original_price and discount_percentage must be numbers.") | |
| if discount_percentage < 0 or discount_percentage > 100: | |
| raise ValueError("Discount percentage must be between 0 and 100.") | |
| discount_amount = original_price * (discount_percentage / 100) | |
| discounted_price = original_price - discount_amount | |
| return round(discounted_price, 2) | |
| class CalculateDiscountValueTool(BaseTool): | |
| """ | |
| A tool to calculate the final discount value of an item after comparing the original value and the final value. | |
| """ | |
| name: str = "Calculate Discount Value Tool" | |
| description: str = "Calculates the discount value after comparing two values." | |
| def _run(self, original_price: float, final_price: float) -> int: | |
| """Calculates the total discounted amount give the original and final price. | |
| This method takes an original price and a final price, validates | |
| the inputs, and then computes the final discounted value. | |
| Args: | |
| original_price: The initial price of the item as a float or integer. | |
| final_price: The final price after discount as a float or integer. | |
| Returns: | |
| float: | |
| - The final discount value, rounded to 0 decimal places. | |
| """ | |
| if not isinstance(original_price, (int, float)) or not isinstance(final_price, (int, float)): | |
| raise ValueError("Both original_price and final_price must be numbers.") | |
| discount_value = original_price - final_price | |
| discount_percentage = (discount_value / original_price) * 100 | |
| return int(discount_percentage) | |
| class GetImageUrlTool(BaseTool): | |
| """ | |
| A tool to retrieve the image URL for a given product URL. | |
| """ | |
| name: str = "Get Image URL Tool" | |
| description: str = "Retrieves the image URL for a given product URL." | |
| def _run(self, product_url: str) -> str: | |
| """ | |
| Retrieves the image URL for a given product URL. | |
| Example: | |
| product_url = ( | |
| "https://minhaloja.natura.com/p/refil-shampoo-mamae-e-bebe/" | |
| "NATBRA-92791?product=refil-shampoo-mamae-e-bebe&productId=NATBRA-92791" | |
| "&consultoria=lidimelocosmeticos&marca=natura" | |
| ) | |
| image_url = GetImageUrlTool()._run(product_url) | |
| # Returns: | |
| # "https://production.na01.natura.com/on/demandware.static/-/Sites-natura-br-storefront-catalog/default/dw68595724/NATBRA-92791_1.jpg" | |
| """ | |
| if not isinstance(product_url, str): | |
| raise ValueError("product_url must be a string.") | |
| # Extract the numeric part after "NATBRA-" or "AVNBRA-" using a regular expression. | |
| match = re.search(r"(NATBRA|AVNBRA)-(\d+)", product_url) | |
| if not match: | |
| raise ValueError( | |
| "Could not extract product_id from the provided URL. " | |
| "Expected a pattern like 'NATBRA-<digits>' or 'AVNBRA-<digits>'." | |
| ) | |
| product_type = match.group(1) | |
| product_id = match.group(2) | |
| # Build the final image URL based on product type. | |
| if product_type == "NATBRA": | |
| image_url = ( | |
| f"https://production.na01.natura.com/on/demandware.static/-/Sites-natura-br-storefront-catalog/" | |
| f"default/dw68595724/NATBRA-{product_id}_1.jpg" | |
| ) | |
| elif product_type == "AVNBRA": | |
| image_url = ( | |
| f"https://production.na01.natura.com/on/demandware.static/-/Sites-avon-br-storefront-catalog/" | |
| f"default/dw4b952185/produtos/AVNBRA-{product_id}_1.jpg" | |
| ) | |
| else: | |
| raise ValueError(f"Unsupported product type: {product_type}") | |
| image_url = get_valid_image_url(image_url) | |
| return image_url | |
| class MerchantSelectorTool(BaseTool): | |
| name: str = "Merchant Selector Tool" | |
| description: str = "Selects the merchant based on url." | |
| natura_api_token: str | |
| def _run(self, original_url: str) -> Merchant: | |
| if "mercadolivre" in original_url or "ml.com.br" in original_url: | |
| return MercadoLivreMerchant() | |
| elif "natura.com" in original_url: | |
| return NaturaMerchant(natura_api_token=self.natura_api_token) | |
| else: | |
| raise ValueError("Unsupported merchant in URL.") |