From fb462787457f995d4c18315348f373b672176155 Mon Sep 17 00:00:00 2001 From: "dylan@demand.io" Date: Fri, 28 Feb 2025 16:57:37 -0700 Subject: [PATCH] Add Viral Coin Agent: AI-powered agent for finding viral cryptocurrencies based on social metrics with trading capabilities --- FIRECRAWL.md | 491 ++++++++++++ alphaswarm/agents/viral_coin/__init__.py | 5 + .../agents/viral_coin/viral_coin_agent.py | 722 ++++++++++++++++++ alphaswarm/tools/firecrawl/__init__.py | 9 + alphaswarm/tools/firecrawl/firecrawl_tool.py | 341 +++++++++ config/viral_coin_agent.yaml | 102 +++ examples/viral_coin/README.md | 213 ++++++ examples/viral_coin/viral_coin_agent_cli.py | 139 ++++ examples/viral_coin/viral_coin_agent_cron.py | 185 +++++ .../viral_coin/viral_coin_agent_telegram.py | 721 +++++++++++++++++ poetry.lock | 485 ++++++------ pyproject.toml | 1 + 12 files changed, 3188 insertions(+), 226 deletions(-) create mode 100644 FIRECRAWL.md create mode 100644 alphaswarm/agents/viral_coin/__init__.py create mode 100644 alphaswarm/agents/viral_coin/viral_coin_agent.py create mode 100644 alphaswarm/tools/firecrawl/__init__.py create mode 100644 alphaswarm/tools/firecrawl/firecrawl_tool.py create mode 100644 config/viral_coin_agent.yaml create mode 100644 examples/viral_coin/README.md create mode 100755 examples/viral_coin/viral_coin_agent_cli.py create mode 100644 examples/viral_coin/viral_coin_agent_cron.py create mode 100644 examples/viral_coin/viral_coin_agent_telegram.py diff --git a/FIRECRAWL.md b/FIRECRAWL.md new file mode 100644 index 00000000..fd663300 --- /dev/null +++ b/FIRECRAWL.md @@ -0,0 +1,491 @@ + +Firecrawl Docs home pagedark logo +v1 + +Search or ask... +⌘K +Status +Support +mendableai/firecrawl +27,499 + +Documentation +SDKs +Learn +API Reference +Playground +Blog +Community +Talk to Us +Changelog +Get Started +Quickstart +Launch Week II (New) +Welcome to V1 +Rate Limits +Integrations +Advanced Scraping Guide +Features +Scrape +Crawl +Map +Extract (New) +Integrations +Langchain +Llamaindex +CrewAI +Dify +Flowise +Langflow +Camel AI +RAGaaS +Contributing +Open Source vs Cloud +Running locally +Self-hosting +Get Started +Quickstart +Firecrawl allows you to turn entire websites into LLM-ready markdown + +Hero Light +​ +Welcome to Firecrawl +Firecrawl is an API service that takes a URL, crawls it, and converts it into clean markdown. We crawl all accessible subpages and give you clean markdown for each. No sitemap required. + +​ +How to use it? +We provide an easy to use API with our hosted version. You can find the playground and documentation here. You can also self host the backend if you’d like. + +Check out the following resources to get started: + + API: Documentation + SDKs: Python, Node, Go, Rust + LLM Frameworks: Langchain (python), Langchain (js), Llama Index, Crew.ai, Composio, PraisonAI, Superinterface, Vectorize + Low-code Frameworks: Dify, Langflow, Flowise AI, Cargo, Pipedream + Others: Zapier, Pabbly Connect + Want an SDK or Integration? Let us know by opening an issue. +Self-host: To self-host refer to guide here. + +​ +API Key +To use the API, you need to sign up on Firecrawl and get an API key. + +​ +Features +Scrape: scrapes a URL and get its content in LLM-ready format (markdown, structured data via LLM Extract, screenshot, html) +Crawl: scrapes all the URLs of a web page and return content in LLM-ready format +Map: input a website and get all the website urls - extremely fast +​ +Powerful Capabilities +LLM-ready formats: markdown, structured data, screenshot, HTML, links, metadata +The hard stuff: proxies, anti-bot mechanisms, dynamic content (js-rendered), output parsing, orchestration +Customizability: exclude tags, crawl behind auth walls with custom headers, max crawl depth, etc… +Media parsing: pdfs, docx, images. +Reliability first: designed to get the data you need - no matter how hard it is. +Actions: click, scroll, input, wait and more before extracting data +You can find all of Firecrawl’s capabilities and how to use them in our documentation + +​ +Crawling +Used to crawl a URL and all accessible subpages. This submits a crawl job and returns a job ID to check the status of the crawl. + +​ +Installation + +Python + +Node + +Go + +Rust + +pip install firecrawl-py +​ +Usage + +Python + +Node + +Go + +Rust + +cURL + +from firecrawl import FirecrawlApp + +app = FirecrawlApp(api_key="fc-YOUR_API_KEY") + +# Crawl a website: +crawl_status = app.crawl_url( + 'https://firecrawl.dev', + params={ + 'limit': 100, + 'scrapeOptions': {'formats': ['markdown', 'html']} + }, + poll_interval=30 +) +print(crawl_status) +If you’re using cURL or async crawl functions on SDKs, this will return an ID where you can use to check the status of the crawl. + + +{ + "success": true, + "id": "123-456-789", + "url": "https://api.firecrawl.dev/v1/crawl/123-456-789" +} +​ +Check Crawl Job +Used to check the status of a crawl job and get its result. + + +Python + +Node + +Go + +Rust + +cURL + +crawl_status = app.check_crawl_status("") +print(crawl_status) +​ +Response +The response will be different depending on the status of the crawl. For not completed or large responses exceeding 10MB, a next URL parameter is provided. You must request this URL to retrieve the next 10MB of data. If the next parameter is absent, it indicates the end of the crawl data. + + +Scraping + +Completed + +{ + "status": "scraping", + "total": 36, + "completed": 10, + "creditsUsed": 10, + "expiresAt": "2024-00-00T00:00:00.000Z", + "next": "https://api.firecrawl.dev/v1/crawl/123-456-789?skip=10", + "data": [ + { + "markdown": "[Firecrawl Docs home page![light logo](https://mintlify.s3-us-west-1.amazonaws.com/firecrawl/logo/light.svg)!...", + "html": "...", + "metadata": { + "title": "Build a 'Chat with website' using Groq Llama 3 | Firecrawl", + "language": "en", + "sourceURL": "https://docs.firecrawl.dev/learn/rag-llama3", + "description": "Learn how to use Firecrawl, Groq Llama 3, and Langchain to build a 'Chat with your website' bot.", + "ogLocaleAlternate": [], + "statusCode": 200 + } + }, + ... + ] +} +​ +Scraping +To scrape a single URL, use the scrape_url method. It takes the URL as a parameter and returns the scraped data as a dictionary. + + +Python + +Node + +Go + +Rust + +cURL + +from firecrawl import FirecrawlApp + +app = FirecrawlApp(api_key="fc-YOUR_API_KEY") + +# Scrape a website: +scrape_result = app.scrape_url('firecrawl.dev', params={'formats': ['markdown', 'html']}) +print(scrape_result) +​ +Response +SDKs will return the data object directly. cURL will return the payload exactly as shown below. + + +{ + "success": true, + "data" : { + "markdown": "Launch Week I is here! [See our Day 2 Release 🚀](https://www.firecrawl.dev/blog/launch-week-i-day-2-doubled-rate-limits)[💥 Get 2 months free...", + "html": "

Firecrawl

" + } + ] + }, + "metadata": { + "title": "Home - Firecrawl", + "description": "Firecrawl crawls and converts any website into clean markdown.", + "language": "en", + "keywords": "Firecrawl,Markdown,Data,Mendable,Langchain", + "robots": "follow, index", + "ogTitle": "Firecrawl", + "ogDescription": "Turn any website into LLM-ready data.", + "ogUrl": "https://www.firecrawl.dev/", + "ogImage": "https://www.firecrawl.dev/og.png?123", + "ogLocaleAlternate": [], + "ogSiteName": "Firecrawl", + "sourceURL": "http://google.com", + "statusCode": 200 + } + } +} +​ +Open Source vs Cloud +Firecrawl is open source available under the AGPL-3.0 license. + +To deliver the best possible product, we offer a hosted version of Firecrawl alongside our open-source offering. The cloud solution allows us to continuously innovate and maintain a high-quality, sustainable service for all users. + +Firecrawl Cloud is available at firecrawl.dev and offers a range of features that are not available in the open source version: + +Firecrawl Cloud vs Open Source + +​ +Contributing +We love contributions! Please read our contributing guide before submitting a pull request. + +Suggest edits +Raise issue +Launch Week II (New) +x +github +linkedin +Powered by Mintlify +On this page +Welcome to Firecrawl +How to use it? +API Key +Features +Powerful Capabilities +Crawling +Installation +Usage +Check Crawl Job +Response +Scraping +Response +Extraction +Extracting without schema (New) +Extraction (v0) +Interacting with the page with Actions +Example +Output +Open Source vs Cloud +Contributing diff --git a/alphaswarm/agents/viral_coin/__init__.py b/alphaswarm/agents/viral_coin/__init__.py new file mode 100644 index 00000000..05e55f1b --- /dev/null +++ b/alphaswarm/agents/viral_coin/__init__.py @@ -0,0 +1,5 @@ +"""Viral Coin Agent for AlphaSwarm.""" + +from alphaswarm.agents.viral_coin.viral_coin_agent import ViralCoinAgent + +__all__ = ["ViralCoinAgent"] \ No newline at end of file diff --git a/alphaswarm/agents/viral_coin/viral_coin_agent.py b/alphaswarm/agents/viral_coin/viral_coin_agent.py new file mode 100644 index 00000000..f530542f --- /dev/null +++ b/alphaswarm/agents/viral_coin/viral_coin_agent.py @@ -0,0 +1,722 @@ +"""Viral Coin Agent for AlphaSwarm.""" + +from __future__ import annotations + +import asyncio +import datetime +import json +import logging +import os +import re +from dataclasses import dataclass +from decimal import Decimal +from pathlib import Path +from typing import Any, Dict, List, Optional, Tuple, Union + +import yaml +from pydantic import BaseModel, Field + +from alphaswarm.agent.agent import AlphaSwarmAgent +from alphaswarm.agent.clients import CronJobClient, TelegramClient +from alphaswarm.config import Config +from alphaswarm.services.alchemy import AlchemyClient +from alphaswarm.services.portfolio import Portfolio +from alphaswarm.tools.alchemy import GetAlchemyPriceHistoryByAddress +from alphaswarm.tools.core import GetTokenAddress +from alphaswarm.tools.exchanges import ExecuteTokenSwap, GetTokenPrice +from alphaswarm.tools.firecrawl import FirecrawlSearch, FirecrawlScrape + + +@dataclass +class CoinMention: + """Represents a mention of a coin in social media or other platforms.""" + + coin_symbol: str + coin_name: str + platform: str + url: str + mention_count: int + sentiment_score: Optional[float] = None + timestamp: datetime.datetime = datetime.datetime.now() + + +@dataclass +class ViralCoinMetrics: + """Metrics for a viral coin.""" + + coin_symbol: str + coin_name: str + address: str + market_cap: float + creation_date: Optional[datetime.datetime] + total_mentions: int + mentions_by_platform: Dict[str, int] + sentiment_score: float + volume_growth_24h: Optional[float] = None + holder_growth_7d: Optional[float] = None + price_volatility: Optional[float] = None + developer_activity: Optional[float] = None + virality_score: float = 0.0 + + def calculate_virality_score(self, weights: Dict[str, float]) -> float: + """Calculate the virality score based on the metrics and weights.""" + score = 0.0 + + # Mentions score (normalized by total mentions) + if self.total_mentions > 0: + mentions_weight = weights.get("mentions", 0.4) + score += mentions_weight * min(1.0, self.total_mentions / 100) + + # Sentiment score + if self.sentiment_score is not None: + sentiment_weight = weights.get("sentiment", 0.2) + # Normalize sentiment from [-1, 1] to [0, 1] + normalized_sentiment = (self.sentiment_score + 1) / 2 + score += sentiment_weight * normalized_sentiment + + # Volume growth score + if self.volume_growth_24h is not None: + volume_weight = weights.get("volume_growth", 0.15) + # Normalize volume growth (cap at 100%) + normalized_volume = min(1.0, max(0.0, self.volume_growth_24h / 100)) + score += volume_weight * normalized_volume + + # Holder growth score + if self.holder_growth_7d is not None: + holder_weight = weights.get("holder_growth", 0.15) + # Normalize holder growth (cap at 100%) + normalized_holder = min(1.0, max(0.0, self.holder_growth_7d / 100)) + score += holder_weight * normalized_holder + + # Price volatility score + if self.price_volatility is not None: + volatility_weight = weights.get("price_volatility", 0.05) + # Normalize volatility (cap at 50%) + normalized_volatility = min(1.0, max(0.0, self.price_volatility / 50)) + score += volatility_weight * normalized_volatility + + # Developer activity score + if self.developer_activity is not None: + dev_weight = weights.get("developer_activity", 0.05) + # Normalize developer activity (cap at 50 commits) + normalized_dev = min(1.0, max(0.0, self.developer_activity / 50)) + score += dev_weight * normalized_dev + + self.virality_score = score + return score + + +class ViralCoinReport(BaseModel): + """Report for viral coins.""" + + timestamp: str + top_coins: List[Dict[str, Any]] + search_parameters: Dict[str, Any] + network: str + report_id: str + + +class ViralCoinAgent(AlphaSwarmAgent): + """ + An agent that finds the most viral coins based on social metrics and allows trading. + + The agent uses Firecrawl to search for mentions of coins on social media platforms, + analyzes the results to identify the most viral coins, and allows trading based on + user-defined parameters. + """ + + def __init__( + self, + model_id: str, + config_path: Optional[str] = None, + chain: str = "ethereum_sepolia", + min_market_cap: float = 1000000, # $1M + max_age_days: int = 30, + top_coins_limit: int = 100, + search_depth: int = 50, + telegram_enabled: bool = True, + report_directory: str = "reports/viral_coins", + ) -> None: + """ + Initialize the ViralCoinAgent. + + Args: + model_id: ID of the LLM model to use + config_path: Path to the configuration file + chain: Chain to use for trading + min_market_cap: Minimum market cap for coins to consider + max_age_days: Maximum age in days for coins to consider + top_coins_limit: Number of top coins to search for + search_depth: Number of search results to analyze per platform + telegram_enabled: Whether to enable Telegram reporting + report_directory: Directory to save reports + """ + self.config = Config() + self.alchemy_client = AlchemyClient.from_env() + self.portfolio_client = Portfolio.from_config(self.config) + + # Load agent configuration + self.agent_config = self._load_config(config_path) + + # Set parameters + self.chain = chain + self.min_market_cap = min_market_cap + self.max_age_days = max_age_days + self.top_coins_limit = top_coins_limit + self.search_depth = search_depth + self.telegram_enabled = telegram_enabled + self.report_directory = report_directory + + # Ensure report directory exists + os.makedirs(self.report_directory, exist_ok=True) + + # Initialize tools + tools = [ + GetTokenAddress(config=self.config), + GetTokenPrice(config=self.config), + ExecuteTokenSwap(config=self.config), + GetAlchemyPriceHistoryByAddress(self.alchemy_client), + FirecrawlSearch(config=self.config), + FirecrawlScrape(config=self.config), + ] + + # Initialize logger + self.logger = logging.getLogger(__name__) + + super().__init__(model_id=model_id, tools=tools) + + def _load_config(self, config_path: Optional[str] = None) -> Dict[str, Any]: + """Load the agent configuration from a YAML file.""" + if config_path is None: + config_path = os.path.join("config", "viral_coin_agent.yaml") + + try: + with open(config_path, "r") as f: + config = yaml.safe_load(f) + return config.get("viral_coin_agent", {}) + except Exception as e: + self.logger.error(f"Error loading configuration: {str(e)}") + return {} + + async def find_viral_coins( + self, + min_market_cap: Optional[float] = None, + max_age_days: Optional[int] = None, + top_coins_limit: Optional[int] = None, + search_depth: Optional[int] = None, + ) -> List[ViralCoinMetrics]: + """ + Find the most viral coins based on social metrics. + + Args: + min_market_cap: Minimum market cap for coins to consider + max_age_days: Maximum age in days for coins to consider + top_coins_limit: Number of top coins to search for + search_depth: Number of search results to analyze per platform + + Returns: + List[ViralCoinMetrics]: List of viral coins with metrics + """ + # Use provided parameters or defaults + min_market_cap = min_market_cap or self.min_market_cap + max_age_days = max_age_days or self.max_age_days + top_coins_limit = top_coins_limit or self.top_coins_limit + search_depth = search_depth or self.search_depth + + # Get the top coins from CoinGecko or similar API + top_coins = await self._get_top_coins(min_market_cap, max_age_days, top_coins_limit) + + # Search for mentions of each coin on social platforms + coin_metrics = [] + for coin in top_coins: + metrics = await self._analyze_coin_virality(coin, search_depth) + coin_metrics.append(metrics) + + # Sort coins by virality score + coin_metrics.sort(key=lambda x: x.virality_score, reverse=True) + + return coin_metrics + + async def _get_top_coins(self, min_market_cap: float, max_age_days: int, limit: int) -> List[Dict[str, Any]]: + """ + Get the top coins from CoinGecko or similar API. + + This is a placeholder implementation. In a real implementation, you would use + a cryptocurrency API like CoinGecko to get the top coins. + + Args: + min_market_cap: Minimum market cap for coins to consider + max_age_days: Maximum age in days for coins to consider + limit: Number of top coins to return + + Returns: + List[Dict[str, Any]]: List of top coins + """ + # This is a placeholder implementation + # In a real implementation, you would use a cryptocurrency API + + # For testing purposes, we'll use a hardcoded list of coins + # In a real implementation, you would fetch this data from an API + + # For Ethereum Sepolia testnet, we'll use the tokens from the config + if self.chain == "ethereum_sepolia": + tokens = self.config.chain_config.get("ethereum_sepolia", {}).get("tokens", {}) + coins = [] + for symbol, token_info in tokens.items(): + coins.append({ + "symbol": symbol, + "name": symbol, + "address": token_info.get("address"), + "market_cap": 10000000, # Placeholder + "creation_date": datetime.datetime.now() - datetime.timedelta(days=10), # Placeholder + }) + return coins[:limit] + + # For real networks, we would fetch data from an API + # This is just a placeholder + return [] + + async def _analyze_coin_virality(self, coin: Dict[str, Any], search_depth: int) -> ViralCoinMetrics: + """ + Analyze the virality of a coin based on social metrics. + + Args: + coin: Coin information + search_depth: Number of search results to analyze per platform + + Returns: + ViralCoinMetrics: Metrics for the coin + """ + symbol = coin["symbol"] + name = coin["name"] + address = coin["address"] + + # Get platforms to search from config + platforms = [p["name"] for p in self.agent_config.get("virality_metrics", {}).get("platforms", [])] + if not platforms: + platforms = ["x.com", "reddit.com", "coingecko.com", "medium.com"] + + # Search for mentions of the coin on each platform + firecrawl_search = FirecrawlSearch(config=self.config) + mentions_by_platform = {} + total_mentions = 0 + sentiment_scores = [] + + for platform in platforms: + # Generate search queries for the platform + search_queries = self._generate_search_queries(symbol, name, platform) + + platform_mentions = 0 + for query in search_queries: + try: + # Search for the coin on the platform + search_results = firecrawl_search.forward( + query=query, + platforms=[platform], + limit=search_depth, + extract_prompt=f"Extract all mentions of {symbol} or {name} cryptocurrency and analyze the sentiment (positive, negative, or neutral)" + ) + + # Count mentions and analyze sentiment + platform_results = search_results.get(platform, []) + for result in platform_results: + content = result.content.get("markdown", "") + + # Count mentions + symbol_mentions = len(re.findall(rf'\b{re.escape(symbol)}\b', content, re.IGNORECASE)) + name_mentions = len(re.findall(rf'\b{re.escape(name)}\b', content, re.IGNORECASE)) + mentions = symbol_mentions + name_mentions + + platform_mentions += mentions + + # Analyze sentiment if we have JSON data + if "json" in result.content and result.content["json"]: + json_data = result.content["json"] + if isinstance(json_data, dict) and "sentiment" in json_data: + sentiment = json_data["sentiment"] + if isinstance(sentiment, str): + # Convert sentiment string to score + if sentiment.lower() == "positive": + sentiment_scores.append(1.0) + elif sentiment.lower() == "negative": + sentiment_scores.append(-1.0) + else: # neutral + sentiment_scores.append(0.0) + elif isinstance(sentiment, (int, float)): + sentiment_scores.append(float(sentiment)) + + except Exception as e: + self.logger.error(f"Error searching for {symbol} on {platform}: {str(e)}") + continue + + mentions_by_platform[platform] = platform_mentions + total_mentions += platform_mentions + + # Calculate average sentiment score + avg_sentiment = sum(sentiment_scores) / len(sentiment_scores) if sentiment_scores else 0.0 + + # Get additional metrics if available + volume_growth_24h = None + holder_growth_7d = None + price_volatility = None + developer_activity = None + + # Create metrics object + metrics = ViralCoinMetrics( + coin_symbol=symbol, + coin_name=name, + address=address, + market_cap=coin["market_cap"], + creation_date=coin.get("creation_date"), + total_mentions=total_mentions, + mentions_by_platform=mentions_by_platform, + sentiment_score=avg_sentiment, + volume_growth_24h=volume_growth_24h, + holder_growth_7d=holder_growth_7d, + price_volatility=price_volatility, + developer_activity=developer_activity, + ) + + # Calculate virality score + weights = { + "mentions": 0.4, + "sentiment": 0.2, + "volume_growth": 0.15, + "holder_growth": 0.15, + "price_volatility": 0.05, + "developer_activity": 0.05, + } + metrics.calculate_virality_score(weights) + + return metrics + + def _generate_search_queries(self, symbol: str, name: str, platform: str) -> List[str]: + """ + Generate search queries for a coin on a platform. + + Args: + symbol: Coin symbol + name: Coin name + platform: Platform to search on + + Returns: + List[str]: List of search queries + """ + # Get search terms for the platform from config + platform_config = next( + (p for p in self.agent_config.get("virality_metrics", {}).get("platforms", []) if p["name"] == platform), + None + ) + + if platform_config and "search_terms" in platform_config: + search_terms = platform_config["search_terms"] + queries = [term.format(coin_symbol=symbol, coin_name=name) for term in search_terms] + else: + # Default search terms + queries = [ + f"{symbol} crypto", + f"{name} cryptocurrency", + f"${symbol}", + ] + + return queries + + async def generate_report(self, viral_coins: List[ViralCoinMetrics], top_n: int = 10) -> str: + """ + Generate a report for the most viral coins. + + Args: + viral_coins: List of viral coins with metrics + top_n: Number of top coins to include in the report + + Returns: + str: Report in markdown format + """ + # Limit to top N coins + top_coins = viral_coins[:min(top_n, len(viral_coins))] + + # Generate report + timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + report_id = datetime.datetime.now().strftime("%Y%m%d%H%M%S") + + report = f"# Viral Coin Report\n\n" + report += f"**Generated:** {timestamp}\n\n" + report += f"**Network:** {self.chain}\n\n" + report += f"**Search Parameters:**\n" + report += f"- Minimum Market Cap: ${self.min_market_cap:,}\n" + report += f"- Maximum Age: {self.max_age_days} days\n" + report += f"- Top Coins Limit: {self.top_coins_limit}\n" + report += f"- Search Depth: {self.search_depth} results per platform\n\n" + + report += f"## Top {len(top_coins)} Most Viral Coins\n\n" + + for i, coin in enumerate(top_coins): + report += f"### {i+1}. {coin.coin_name} ({coin.coin_symbol})\n\n" + report += f"**Address:** {coin.address}\n\n" + report += f"**Virality Score:** {coin.virality_score:.2f}\n\n" + report += f"**Total Mentions:** {coin.total_mentions}\n\n" + + report += "**Mentions by Platform:**\n\n" + for platform, mentions in coin.mentions_by_platform.items(): + report += f"- {platform}: {mentions}\n" + + report += f"\n**Sentiment Score:** {coin.sentiment_score:.2f}\n\n" + + if coin.volume_growth_24h is not None: + report += f"**24h Volume Growth:** {coin.volume_growth_24h:.2f}%\n\n" + + if coin.holder_growth_7d is not None: + report += f"**7d Holder Growth:** {coin.holder_growth_7d:.2f}%\n\n" + + if coin.price_volatility is not None: + report += f"**Price Volatility:** {coin.price_volatility:.2f}%\n\n" + + if coin.developer_activity is not None: + report += f"**Developer Activity:** {coin.developer_activity:.2f}\n\n" + + report += "---\n\n" + + # Save report to file + report_path = os.path.join(self.report_directory, f"viral_coin_report_{report_id}.md") + os.makedirs(os.path.dirname(report_path), exist_ok=True) + + with open(report_path, "w") as f: + f.write(report) + + # Save report data as JSON + report_data = ViralCoinReport( + timestamp=timestamp, + top_coins=[{ + "symbol": coin.coin_symbol, + "name": coin.coin_name, + "address": coin.address, + "virality_score": coin.virality_score, + "total_mentions": coin.total_mentions, + "mentions_by_platform": coin.mentions_by_platform, + "sentiment_score": coin.sentiment_score, + "volume_growth_24h": coin.volume_growth_24h, + "holder_growth_7d": coin.holder_growth_7d, + "price_volatility": coin.price_volatility, + "developer_activity": coin.developer_activity, + } for coin in top_coins], + search_parameters={ + "min_market_cap": self.min_market_cap, + "max_age_days": self.max_age_days, + "top_coins_limit": self.top_coins_limit, + "search_depth": self.search_depth, + }, + network=self.chain, + report_id=report_id, + ) + + json_path = os.path.join(self.report_directory, f"viral_coin_report_{report_id}.json") + + with open(json_path, "w") as f: + f.write(json.dumps(report_data.dict(), indent=2)) + + return report + + async def buy_viral_coin( + self, + coin_address: str, + amount: Union[float, str], + slippage_percent: float = 2.0, + ) -> Dict[str, Any]: + """ + Buy a viral coin. + + Args: + coin_address: Address of the coin to buy + amount: Amount to buy in base token (e.g., ETH) + slippage_percent: Maximum slippage percentage + + Returns: + Dict[str, Any]: Transaction result + """ + # Get base token for the chain + base_token = self._get_base_token_for_chain() + + # Convert amount to Decimal if it's a string + if isinstance(amount, str): + amount = Decimal(amount) + + # Execute the swap + swap_tool = ExecuteTokenSwap(config=self.config) + result = swap_tool.forward( + chain=self.chain, + from_token=base_token, + to_token=coin_address, + amount=str(amount), + slippage_bps=int(slippage_percent * 100), # Convert percent to basis points + ) + + return result + + def _get_base_token_for_chain(self) -> str: + """Get the base token symbol for the current chain.""" + if self.chain == "ethereum" or self.chain == "ethereum_sepolia": + return "WETH" + elif self.chain == "base": + return "WETH" + else: + return "WETH" # Default + + async def setup_dca_buys( + self, + coin_address: str, + total_amount: Union[float, str], + num_intervals: int = 7, + interval_hours: int = 24, + slippage_percent: float = 2.0, + ) -> Dict[str, Any]: + """ + Set up dollar-cost averaging (DCA) buys for a viral coin. + + Args: + coin_address: Address of the coin to buy + total_amount: Total amount to buy in base token (e.g., ETH) + num_intervals: Number of intervals to spread the buys over + interval_hours: Hours between each buy + slippage_percent: Maximum slippage percentage + + Returns: + Dict[str, Any]: DCA setup result + """ + # Convert total_amount to Decimal if it's a string + if isinstance(total_amount, str): + total_amount = Decimal(total_amount) + + # Calculate amount per interval + amount_per_interval = total_amount / Decimal(num_intervals) + + # Get base token for the chain + base_token = self._get_base_token_for_chain() + + # Schedule the buys + schedule = [] + for i in range(num_intervals): + buy_time = datetime.datetime.now() + datetime.timedelta(hours=i * interval_hours) + schedule.append({ + "interval": i + 1, + "time": buy_time.strftime("%Y-%m-%d %H:%M:%S"), + "amount": str(amount_per_interval), + "from_token": base_token, + "to_token": coin_address, + }) + + # Save the DCA schedule + dca_id = datetime.datetime.now().strftime("%Y%m%d%H%M%S") + dca_path = os.path.join(self.report_directory, f"dca_schedule_{dca_id}.json") + + dca_data = { + "id": dca_id, + "coin_address": coin_address, + "total_amount": str(total_amount), + "num_intervals": num_intervals, + "interval_hours": interval_hours, + "slippage_percent": slippage_percent, + "chain": self.chain, + "schedule": schedule, + } + + with open(dca_path, "w") as f: + f.write(json.dumps(dca_data, indent=2)) + + return dca_data + + def get_trading_task(self) -> str: + """ + Generate a trading task based on viral coin analysis. + + Returns: + str: Trading task prompt + """ + task_prompt = ( + "=== Viral Coin Analysis Task ===\n\n" + "1. Find the most viral cryptocurrencies based on social media mentions and other metrics\n" + "2. Generate a report of the top 10 most viral coins\n" + "3. Recommend which coin to buy based on virality metrics\n\n" + f"Parameters:\n" + f"- Network: {self.chain}\n" + f"- Minimum Market Cap: ${self.min_market_cap:,}\n" + f"- Maximum Age: {self.max_age_days} days\n" + f"- Search Depth: {self.search_depth} results per platform\n\n" + "Please analyze the most viral cryptocurrencies and provide your recommendation." + ) + + return task_prompt + + +async def main() -> None: + """Main function to run the viral coin agent.""" + # Configure logging + logging.basicConfig( + format="%(asctime)s - %(levelname)s - %(name)s - %(filename)s:%(lineno)d - %(message)s", + datefmt="%Y-%m-%d %H:%M:%S", + level=logging.INFO, + ) + + # Load environment variables + import dotenv + dotenv.load_dotenv() + + # Initialize the agent + config = Config() + llm_config = config.get_default_llm_config("anthropic") + + agent = ViralCoinAgent( + model_id=llm_config.model_id, + chain="ethereum_sepolia", + min_market_cap=1000000, + max_age_days=30, + top_coins_limit=10, + search_depth=50, + telegram_enabled=True, + ) + + # Find viral coins + viral_coins = await agent.find_viral_coins() + + # Generate report + report = await agent.generate_report(viral_coins) + print(report) + + # Initialize Telegram client if enabled + if agent.telegram_enabled: + telegram_client = TelegramClient( + agent=agent, + client_id="Viral Coin Agent", + response_handler=lambda response: print(f"Telegram response: {response}"), + ) + + # Send report to Telegram + await telegram_client.send_message(report) + + # Example of buying a viral coin + if viral_coins: + top_coin = viral_coins[0] + print(f"Buying top viral coin: {top_coin.coin_name} ({top_coin.coin_symbol})") + + # Buy the coin + result = await agent.buy_viral_coin( + coin_address=top_coin.address, + amount="0.001", # Small amount for testing + slippage_percent=2.0, + ) + + print(f"Buy result: {result}") + + # Set up DCA buys + dca_result = await agent.setup_dca_buys( + coin_address=top_coin.address, + total_amount="0.01", + num_intervals=7, + interval_hours=24, + slippage_percent=2.0, + ) + + print(f"DCA setup result: {dca_result}") + + +if __name__ == "__main__": + asyncio.run(main()) \ No newline at end of file diff --git a/alphaswarm/tools/firecrawl/__init__.py b/alphaswarm/tools/firecrawl/__init__.py new file mode 100644 index 00000000..3bf37a7f --- /dev/null +++ b/alphaswarm/tools/firecrawl/__init__.py @@ -0,0 +1,9 @@ +"""Firecrawl tools for AlphaSwarm.""" + +from alphaswarm.tools.firecrawl.firecrawl_tool import ( + FirecrawlScrape, + FirecrawlCrawl, + FirecrawlSearch, +) + +__all__ = ["FirecrawlScrape", "FirecrawlCrawl", "FirecrawlSearch"] \ No newline at end of file diff --git a/alphaswarm/tools/firecrawl/firecrawl_tool.py b/alphaswarm/tools/firecrawl/firecrawl_tool.py new file mode 100644 index 00000000..734beea8 --- /dev/null +++ b/alphaswarm/tools/firecrawl/firecrawl_tool.py @@ -0,0 +1,341 @@ +"""Firecrawl tools for AlphaSwarm.""" + +from __future__ import annotations + +import logging +from dataclasses import dataclass +from typing import Any, Dict, List, Optional, Union + +from firecrawl import FirecrawlApp +from pydantic import BaseModel, Field + +from alphaswarm.config import Config +from alphaswarm.tools.core.base_tool import BaseTool + + +class FirecrawlScrapeInput(BaseModel): + """Input for FirecrawlScrape tool.""" + + url: str = Field(..., description="URL to scrape") + formats: List[str] = Field( + default=["markdown"], + description="Output formats to return (markdown, html, json, screenshot)", + ) + extract_prompt: Optional[str] = Field( + default=None, + description="Optional prompt for LLM extraction (e.g., 'Extract all mentions of cryptocurrency names')", + ) + + +class FirecrawlCrawlInput(BaseModel): + """Input for FirecrawlCrawl tool.""" + + url: str = Field(..., description="URL to crawl") + limit: int = Field( + default=50, + description="Maximum number of pages to crawl", + ) + formats: List[str] = Field( + default=["markdown"], + description="Output formats to return (markdown, html, json, screenshot)", + ) + extract_prompt: Optional[str] = Field( + default=None, + description="Optional prompt for LLM extraction (e.g., 'Extract all mentions of cryptocurrency names')", + ) + + +class FirecrawlSearchInput(BaseModel): + """Input for FirecrawlSearch tool.""" + + query: str = Field(..., description="Search query") + platforms: List[str] = Field( + default=["x.com", "reddit.com", "coingecko.com", "medium.com"], + description="Platforms to search on", + ) + limit: int = Field( + default=50, + description="Maximum number of results to return per platform", + ) + extract_prompt: Optional[str] = Field( + default=None, + description="Optional prompt for LLM extraction (e.g., 'Extract all mentions of cryptocurrency names')", + ) + + +@dataclass +class FirecrawlResult: + """Result from Firecrawl API.""" + + content: Dict[str, Any] + metadata: Dict[str, Any] + + +class FirecrawlScrape(BaseTool): + """Tool to scrape a URL using Firecrawl.""" + + name = "firecrawl_scrape" + description = "Scrapes a URL and returns its content in various formats using Firecrawl." + input_schema = FirecrawlScrapeInput + + def __init__(self, config: Optional[Config] = None): + """Initialize the FirecrawlScrape tool. + + Args: + config: AlphaSwarm config + """ + super().__init__(config) + self.api_key = self._get_api_key() + self.firecrawl = FirecrawlApp(api_key=self.api_key) + self.logger = logging.getLogger(__name__) + + def _get_api_key(self) -> str: + """Get Firecrawl API key from config or environment.""" + if self.config and hasattr(self.config, "firecrawl_api_key"): + return self.config.firecrawl_api_key + + import os + api_key = os.environ.get("FIRECRAWL_API_KEY") + if not api_key: + raise ValueError("Firecrawl API key not found in config or environment") + return api_key + + def _forward(self, url: str, formats: List[str], extract_prompt: Optional[str] = None) -> FirecrawlResult: + """Forward the request to Firecrawl API.""" + params = {"formats": formats} + + if extract_prompt: + params["jsonOptions"] = { + "prompt": extract_prompt + } + + # Make sure json format is included if we have an extraction prompt + if "json" not in formats: + params["formats"] = formats + ["json"] + + try: + self.logger.info(f"Scraping URL: {url}") + result = self.firecrawl.scrape_url(url, params=params) + + return FirecrawlResult( + content=result, + metadata=result.get("metadata", {}) + ) + except Exception as e: + self.logger.error(f"Error scraping URL {url}: {str(e)}") + raise + + def forward(self, url: str, formats: List[str] = None, extract_prompt: Optional[str] = None) -> FirecrawlResult: + """Scrape a URL using Firecrawl. + + Args: + url: URL to scrape + formats: Output formats to return (markdown, html, json, screenshot) + extract_prompt: Optional prompt for LLM extraction + + Returns: + FirecrawlResult: Result from Firecrawl API + """ + if formats is None: + formats = ["markdown"] + + return self._forward(url, formats, extract_prompt) + + +class FirecrawlCrawl(BaseTool): + """Tool to crawl a website using Firecrawl.""" + + name = "firecrawl_crawl" + description = "Crawls a website and returns content from all pages in various formats using Firecrawl." + input_schema = FirecrawlCrawlInput + + def __init__(self, config: Optional[Config] = None): + """Initialize the FirecrawlCrawl tool. + + Args: + config: AlphaSwarm config + """ + super().__init__(config) + self.api_key = self._get_api_key() + self.firecrawl = FirecrawlApp(api_key=self.api_key) + self.logger = logging.getLogger(__name__) + + def _get_api_key(self) -> str: + """Get Firecrawl API key from config or environment.""" + if self.config and hasattr(self.config, "firecrawl_api_key"): + return self.config.firecrawl_api_key + + import os + api_key = os.environ.get("FIRECRAWL_API_KEY") + if not api_key: + raise ValueError("Firecrawl API key not found in config or environment") + return api_key + + def forward(self, url: str, limit: int = 50, formats: List[str] = None, extract_prompt: Optional[str] = None) -> Dict[str, Any]: + """Crawl a website using Firecrawl. + + Args: + url: URL to crawl + limit: Maximum number of pages to crawl + formats: Output formats to return (markdown, html, json, screenshot) + extract_prompt: Optional prompt for LLM extraction + + Returns: + Dict[str, Any]: Result from Firecrawl API + """ + if formats is None: + formats = ["markdown"] + + params = { + "limit": limit, + "scrapeOptions": {"formats": formats} + } + + if extract_prompt: + params["scrapeOptions"]["jsonOptions"] = { + "prompt": extract_prompt + } + + # Make sure json format is included if we have an extraction prompt + if "json" not in formats: + params["scrapeOptions"]["formats"] = formats + ["json"] + + try: + self.logger.info(f"Crawling URL: {url} with limit: {limit}") + crawl_status = self.firecrawl.crawl_url(url, params=params, poll_interval=30) + return crawl_status + except Exception as e: + self.logger.error(f"Error crawling URL {url}: {str(e)}") + raise + + +class FirecrawlSearch(BaseTool): + """Tool to search for content across multiple platforms using Firecrawl.""" + + name = "firecrawl_search" + description = "Searches for content across multiple platforms and returns results using Firecrawl." + input_schema = FirecrawlSearchInput + + def __init__(self, config: Optional[Config] = None): + """Initialize the FirecrawlSearch tool. + + Args: + config: AlphaSwarm config + """ + super().__init__(config) + self.api_key = self._get_api_key() + self.firecrawl = FirecrawlApp(api_key=self.api_key) + self.scrape_tool = FirecrawlScrape(config) + self.logger = logging.getLogger(__name__) + + def _get_api_key(self) -> str: + """Get Firecrawl API key from config or environment.""" + if self.config and hasattr(self.config, "firecrawl_api_key"): + return self.config.firecrawl_api_key + + import os + api_key = os.environ.get("FIRECRAWL_API_KEY") + if not api_key: + raise ValueError("Firecrawl API key not found in config or environment") + return api_key + + def forward( + self, + query: str, + platforms: List[str] = None, + limit: int = 50, + extract_prompt: Optional[str] = None + ) -> Dict[str, List[FirecrawlResult]]: + """Search for content across multiple platforms using Firecrawl. + + Args: + query: Search query + platforms: Platforms to search on + limit: Maximum number of results to return per platform + extract_prompt: Optional prompt for LLM extraction + + Returns: + Dict[str, List[FirecrawlResult]]: Results from Firecrawl API grouped by platform + """ + if platforms is None: + platforms = ["x.com", "reddit.com", "coingecko.com", "medium.com"] + + results = {} + + for platform in platforms: + try: + search_url = f"https://www.google.com/search?q=site:{platform}+{query}&num={limit}" + self.logger.info(f"Searching on {platform} with query: {query}") + + # Use the scrape tool to get the search results + search_results = self.scrape_tool.forward( + url=search_url, + formats=["markdown", "html"], + extract_prompt=f"Extract all search result URLs that point to {platform} and contain information about {query}" + ) + + # Process the search results to extract URLs + if "json" in search_results.content and search_results.content["json"]: + # If we have structured data from the extraction + urls = self._extract_urls_from_json(search_results.content["json"], platform) + else: + # Fall back to regex extraction from markdown + urls = self._extract_urls_from_markdown(search_results.content["markdown"], platform) + + # Limit the number of URLs to process + urls = urls[:min(limit, len(urls))] + + # Scrape each URL + platform_results = [] + for url in urls: + try: + result = self.scrape_tool.forward( + url=url, + formats=["markdown"], + extract_prompt=extract_prompt + ) + platform_results.append(result) + except Exception as e: + self.logger.error(f"Error scraping URL {url}: {str(e)}") + continue + + results[platform] = platform_results + + except Exception as e: + self.logger.error(f"Error searching on {platform}: {str(e)}") + results[platform] = [] + + return results + + def _extract_urls_from_json(self, json_data: Dict[str, Any], platform: str) -> List[str]: + """Extract URLs from JSON data.""" + urls = [] + + # Handle different possible JSON structures + if isinstance(json_data, dict) and "urls" in json_data: + urls = json_data["urls"] + elif isinstance(json_data, dict) and "results" in json_data: + for result in json_data["results"]: + if isinstance(result, dict) and "url" in result: + urls.append(result["url"]) + elif isinstance(json_data, list): + for item in json_data: + if isinstance(item, dict) and "url" in item: + urls.append(item["url"]) + elif isinstance(item, str) and platform in item and item.startswith("http"): + urls.append(item) + + return urls + + def _extract_urls_from_markdown(self, markdown: str, platform: str) -> List[str]: + """Extract URLs from markdown content using regex.""" + import re + + # Pattern to match URLs in markdown links + pattern = r'\[.*?\]\((https?://[^)]+)\)' + urls = re.findall(pattern, markdown) + + # Filter URLs to only include those from the specified platform + urls = [url for url in urls if platform in url] + + return urls \ No newline at end of file diff --git a/config/viral_coin_agent.yaml b/config/viral_coin_agent.yaml new file mode 100644 index 00000000..2a3c2fc4 --- /dev/null +++ b/config/viral_coin_agent.yaml @@ -0,0 +1,102 @@ +# Viral Coin Agent Configuration +viral_coin_agent: + # General settings + name: "ViralCoinAgent" + description: "Agent that finds the most viral coins based on social metrics and allows trading" + version: "1.0.0" + + # Search settings + search: + min_market_cap: 1000000 # $1M minimum market cap + max_age_days: 30 # Only consider coins created in the last 30 days + top_coins_limit: 100 # Search among top 100 coins + + # Virality metrics + virality_metrics: + platforms: + - name: "x.com" + weight: 0.35 + search_terms: + - "{coin_symbol}" + - "#{coin_symbol}" + - "{coin_name}" + - name: "reddit.com" + weight: 0.25 + search_terms: + - "r/cryptocurrency {coin_symbol}" + - "{coin_name} crypto" + - name: "coingecko.com" + weight: 0.15 + search_terms: + - "{coin_symbol} forum" + - "{coin_name} discussion" + - name: "medium.com" + weight: 0.15 + search_terms: + - "{coin_symbol} crypto" + - "{coin_name} token" + - name: "discord.com" + weight: 0.10 + search_terms: + - "{coin_symbol} server" + - "{coin_name} community" + + # Additional metrics beyond mentions + additional_metrics: + - name: "24h_volume_growth" + weight: 0.3 + description: "Percentage growth in 24h trading volume" + - name: "holder_growth" + weight: 0.3 + description: "Percentage growth in number of holders" + - name: "price_volatility" + weight: 0.2 + description: "Price volatility in the last 7 days" + - name: "developer_activity" + weight: 0.2 + description: "GitHub commits and activity in the last 7 days" + + # Firecrawl settings + firecrawl: + search_depth: 50 # Number of results to analyze per search + formats: ["markdown"] # Output format for crawled content + max_retries: 3 # Maximum number of retries for failed requests + timeout_seconds: 30 # Timeout for requests + + # Trading settings + trading: + networks: + - name: "ethereum" + enabled: true + - name: "ethereum_sepolia" + enabled: true + is_test: true + - name: "base" + enabled: true + + # DCA (Dollar Cost Averaging) settings + dca: + enabled: true + interval_hours: 24 # Default interval between purchases + max_intervals: 7 # Default number of intervals + min_amount_per_interval: 0.001 # Minimum amount per interval in ETH + + # Risk management + risk_management: + max_slippage_percent: 2.0 # Maximum allowed slippage + max_single_trade_percent: 10.0 # Maximum percentage of portfolio for a single trade + stop_loss_percent: 15.0 # Default stop loss percentage + take_profit_percent: 30.0 # Default take profit percentage + + # Reporting settings + reporting: + telegram: + enabled: true + report_frequency: "daily" # Options: hourly, daily, on_trade + include_charts: true + detailed_metrics: true + + file_reports: + enabled: true + format: "markdown" # Options: markdown, json, csv + save_directory: "reports/viral_coins" \ No newline at end of file diff --git a/examples/viral_coin/README.md b/examples/viral_coin/README.md new file mode 100644 index 00000000..1d810839 --- /dev/null +++ b/examples/viral_coin/README.md @@ -0,0 +1,213 @@ +# Viral Coin Agent + +The Viral Coin Agent is an AI-powered agent that finds the most viral cryptocurrencies based on social metrics and allows trading. It uses Firecrawl to search for mentions of coins on social media platforms, analyzes the results to identify the most viral coins, and allows trading based on user-defined parameters. + +## How It Works + +```mermaid +flowchart TD + A[User Input] --> B[Initialize Agent] + B --> C[Get Top Coins by Market Cap] + C --> D[Search Social Platforms via Firecrawl] + D --> E[Analyze Mentions & Sentiment] + E --> F[Calculate Virality Score] + F --> G[Generate Report] + G --> H{User Decision} + H -->|Buy Now| I[Execute Single Purchase] + H -->|DCA| J[Setup Dollar Cost Averaging] + H -->|No Action| K[Save Report] + + subgraph "Social Analysis" + D --> D1[Search X/Twitter] + D --> D2[Search Reddit] + D --> D3[Search CoinGecko] + D --> D4[Search Medium] + D1 --> E + D2 --> E + D3 --> E + D4 --> E + end + + subgraph "Virality Metrics" + E --> E1[Count Mentions] + E --> E2[Analyze Sentiment] + E --> E3[Volume Growth] + E --> E4[Holder Growth] + E1 --> F + E2 --> F + E3 --> F + E4 --> F + end + + subgraph "Trading Options" + I --> I1[Swap Base Token for Viral Coin] + J --> J1[Schedule Multiple Buys] + J1 --> J2[Execute on Schedule] + end + + K --> L[Telegram Notification] + I --> L + J --> L +``` + +## Features + +- **Social Media Analysis**: Uses Firecrawl to search for mentions of cryptocurrencies on social platforms like X (Twitter), Reddit, CoinGecko forums, and more +- **Virality Metrics**: Analyzes mentions, sentiment, volume growth, holder growth, and other metrics to calculate a virality score +- **Automated Trading**: Allows buying the most viral coins with a single command +- **Dollar Cost Averaging (DCA)**: Supports setting up DCA buys for viral coins +- **Telegram Integration**: Provides a Telegram bot interface for easy interaction +- **Scheduled Tasks**: Can run on a schedule to continuously monitor and trade viral coins + +## Installation + +1. Make sure you have Poetry installed: + +```bash +curl -sSL https://install.python-poetry.org | python3 - +``` + +2. Install the dependencies: + +```bash +poetry install +``` + +3. Set up your environment variables in `.env` file: + +``` +# API Keys +FIRECRAWL_API_KEY=your_firecrawl_api_key +ANTHROPIC_API_KEY=your_anthropic_api_key +OPENAI_API_KEY=your_openai_api_key + +# Blockchain RPC URLs +ETH_RPC_URL=https://eth.llamarpc.com +ETH_SEPOLIA_RPC_URL=https://sepolia.drpc.org +BASE_RPC_URL=https://mainnet.base.org + +# Wallet Configuration +ETH_WALLET_ADDRESS=your_ethereum_wallet_address +ETH_SEPOLIA_WALLET_ADDRESS=your_sepolia_wallet_address +ETH_PRIVATE_KEY=your_ethereum_private_key +ETH_SEPOLIA_PRIVATE_KEY=your_sepolia_private_key + +# Telegram Configuration +TELEGRAM_BOT_TOKEN=your_telegram_bot_token +TELEGRAM_CHAT_ID=your_telegram_chat_id +``` + +## Usage + +### Command-Line Interface + +You can use the Viral Coin Agent from the command line: + +```bash +# Run a one-time search for viral coins +poetry run python examples/viral_coin/viral_coin_agent_cli.py --chain ethereum_sepolia --min-market-cap 1000000 --max-age-days 30 --search-depth 50 --top-n 10 + +# Run a search and buy the top viral coin +poetry run python examples/viral_coin/viral_coin_agent_cli.py --chain ethereum_sepolia --buy --buy-amount 0.001 + +# Run a search and set up DCA buys for the top viral coin +poetry run python examples/viral_coin/viral_coin_agent_cli.py --chain ethereum_sepolia --dca --dca-amount 0.01 --dca-intervals 7 --dca-interval-hours 24 + +# Run a search and send the report to Telegram +poetry run python examples/viral_coin/viral_coin_agent_cli.py --chain ethereum_sepolia --telegram +``` + +### Scheduled Task + +You can run the Viral Coin Agent as a scheduled task: + +```bash +# Run the agent every 24 hours +poetry run python examples/viral_coin/viral_coin_agent_cron.py --chain ethereum_sepolia --interval-hours 24 --telegram + +# Run the agent every 24 hours and buy the top viral coin +poetry run python examples/viral_coin/viral_coin_agent_cron.py --chain ethereum_sepolia --interval-hours 24 --buy --buy-amount 0.001 --telegram +``` + +### Telegram Bot + +You can run the Viral Coin Agent as a Telegram bot: + +```bash +# Start the Telegram bot +poetry run python examples/viral_coin/viral_coin_agent_telegram.py +``` + +Once the bot is running, you can interact with it using the following commands: + +- `/start` - Start a new search for viral coins +- `/report` - Generate a report of the last search results +- `/buy` - Buy the top viral coin from the last search +- `/dca` - Set up DCA buys for the top viral coin +- `/help` - Show help message +- `/cancel` - Cancel the current operation + +## Configuration + +The Viral Coin Agent can be configured using the `config/viral_coin_agent.yaml` file. This file contains settings for: + +- Search parameters (minimum market cap, maximum age, etc.) +- Virality metrics (platforms to search, weights for different metrics, etc.) +- Firecrawl settings (search depth, formats, etc.) +- Trading settings (networks, DCA settings, risk management, etc.) +- Reporting settings (Telegram, file reports, etc.) + +## Examples + +### Finding Viral Coins + +```python +from alphaswarm.agents.viral_coin.viral_coin_agent import ViralCoinAgent + +# Initialize the agent +agent = ViralCoinAgent( + model_id="claude-3-7-sonnet", + chain="ethereum_sepolia", + min_market_cap=1000000, + max_age_days=30, + top_coins_limit=10, + search_depth=50, +) + +# Find viral coins +viral_coins = await agent.find_viral_coins() + +# Generate report +report = await agent.generate_report(viral_coins) +print(report) +``` + +### Buying a Viral Coin + +```python +# Buy the top viral coin +result = await agent.buy_viral_coin( + coin_address=viral_coins[0].address, + amount="0.001", + slippage_percent=2.0, +) +print(f"Buy result: {result}") +``` + +### Setting Up DCA Buys + +```python +# Set up DCA buys +dca_result = await agent.setup_dca_buys( + coin_address=viral_coins[0].address, + total_amount="0.01", + num_intervals=7, + interval_hours=24, + slippage_percent=2.0, +) +print(f"DCA setup result: {dca_result}") +``` + +## License + +This project is licensed under the terms of the LICENSE file included in the repository. \ No newline at end of file diff --git a/examples/viral_coin/viral_coin_agent_cli.py b/examples/viral_coin/viral_coin_agent_cli.py new file mode 100755 index 00000000..b87791c7 --- /dev/null +++ b/examples/viral_coin/viral_coin_agent_cli.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python3 +"""Command-line interface for the Viral Coin Agent.""" + +import argparse +import asyncio +import logging +import os +import sys +from decimal import Decimal +from typing import Any, Dict, Optional + +import dotenv + +# Add the project root to the Python path +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../.."))) + +from alphaswarm.agents.viral_coin.viral_coin_agent import ViralCoinAgent +from alphaswarm.config import Config + + +async def run_viral_coin_agent(args: argparse.Namespace) -> None: + """Run the viral coin agent with the provided arguments.""" + # Initialize the agent + config = Config() + llm_config = config.get_default_llm_config(args.model_provider) + + agent = ViralCoinAgent( + model_id=llm_config.model_id, + chain=args.chain, + min_market_cap=args.min_market_cap, + max_age_days=args.max_age_days, + top_coins_limit=args.top_coins_limit, + search_depth=args.search_depth, + telegram_enabled=args.telegram, + report_directory=args.report_dir, + ) + + # Find viral coins + logging.info("Finding viral coins...") + viral_coins = await agent.find_viral_coins() + + # Generate report + logging.info("Generating report...") + report = await agent.generate_report(viral_coins, args.top_n) + print(report) + + # Initialize Telegram client if enabled + if args.telegram: + from alphaswarm.agent.clients import TelegramClient + + logging.info("Sending report to Telegram...") + telegram_client = TelegramClient( + agent=agent, + client_id="Viral Coin Agent", + response_handler=lambda response: logging.info(f"Telegram response: {response}"), + ) + + # Send report to Telegram + await telegram_client.send_message(report) + + # Buy coins if requested + if args.buy and viral_coins: + top_coin = viral_coins[0] + logging.info(f"Buying top viral coin: {top_coin.coin_name} ({top_coin.coin_symbol})") + + # Buy the coin + result = await agent.buy_viral_coin( + coin_address=top_coin.address, + amount=args.buy_amount, + slippage_percent=args.slippage, + ) + + logging.info(f"Buy result: {result}") + + # Set up DCA buys if requested + if args.dca and viral_coins: + top_coin = viral_coins[0] + logging.info(f"Setting up DCA buys for: {top_coin.coin_name} ({top_coin.coin_symbol})") + + # Set up DCA buys + dca_result = await agent.setup_dca_buys( + coin_address=top_coin.address, + total_amount=args.dca_amount, + num_intervals=args.dca_intervals, + interval_hours=args.dca_interval_hours, + slippage_percent=args.slippage, + ) + + logging.info(f"DCA setup result: {dca_result}") + + +def main() -> None: + """Main entry point for the command-line interface.""" + # Load environment variables + dotenv.load_dotenv() + + # Parse command-line arguments + parser = argparse.ArgumentParser(description="Viral Coin Agent CLI") + + # General options + parser.add_argument("--chain", type=str, default="ethereum_sepolia", help="Chain to use for trading") + parser.add_argument("--model-provider", type=str, default="anthropic", choices=["anthropic", "openai"], help="LLM provider to use") + parser.add_argument("--log-level", type=str, default="INFO", choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"], help="Logging level") + parser.add_argument("--report-dir", type=str, default="reports/viral_coins", help="Directory to save reports") + + # Search options + parser.add_argument("--min-market-cap", type=float, default=1000000, help="Minimum market cap for coins to consider") + parser.add_argument("--max-age-days", type=int, default=30, help="Maximum age in days for coins to consider") + parser.add_argument("--top-coins-limit", type=int, default=10, help="Number of top coins to search for") + parser.add_argument("--search-depth", type=int, default=50, help="Number of search results to analyze per platform") + parser.add_argument("--top-n", type=int, default=10, help="Number of top viral coins to include in the report") + + # Trading options + parser.add_argument("--buy", action="store_true", help="Buy the top viral coin") + parser.add_argument("--buy-amount", type=str, default="0.001", help="Amount to buy in base token (e.g., ETH)") + parser.add_argument("--dca", action="store_true", help="Set up DCA buys for the top viral coin") + parser.add_argument("--dca-amount", type=str, default="0.01", help="Total amount for DCA buys in base token (e.g., ETH)") + parser.add_argument("--dca-intervals", type=int, default=7, help="Number of intervals for DCA buys") + parser.add_argument("--dca-interval-hours", type=int, default=24, help="Hours between DCA buys") + parser.add_argument("--slippage", type=float, default=2.0, help="Maximum slippage percentage") + + # Reporting options + parser.add_argument("--telegram", action="store_true", help="Send report to Telegram") + + args = parser.parse_args() + + # Configure logging + logging.basicConfig( + format="%(asctime)s - %(levelname)s - %(name)s - %(filename)s:%(lineno)d - %(message)s", + datefmt="%Y-%m-%d %H:%M:%S", + level=getattr(logging, args.log_level), + ) + + # Run the agent + asyncio.run(run_viral_coin_agent(args)) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/examples/viral_coin/viral_coin_agent_cron.py b/examples/viral_coin/viral_coin_agent_cron.py new file mode 100644 index 00000000..de7b0b8d --- /dev/null +++ b/examples/viral_coin/viral_coin_agent_cron.py @@ -0,0 +1,185 @@ +#!/usr/bin/env python3 +"""Scheduled task for the Viral Coin Agent.""" + +import argparse +import asyncio +import logging +import os +import sys +from typing import Any, Dict, Optional + +import dotenv + +# Add the project root to the Python path +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../.."))) + +from alphaswarm.agent.clients import CronJobClient, TelegramClient +from alphaswarm.agents.viral_coin.viral_coin_agent import ViralCoinAgent +from alphaswarm.config import Config + + +async def run_viral_coin_agent_cron(args: argparse.Namespace) -> None: + """Run the viral coin agent as a scheduled task.""" + # Initialize the agent + config = Config() + llm_config = config.get_default_llm_config(args.model_provider) + + agent = ViralCoinAgent( + model_id=llm_config.model_id, + chain=args.chain, + min_market_cap=args.min_market_cap, + max_age_days=args.max_age_days, + top_coins_limit=args.top_coins_limit, + search_depth=args.search_depth, + telegram_enabled=args.telegram, + report_directory=args.report_dir, + ) + + # Initialize Telegram client if enabled + telegram_client = None + if args.telegram: + telegram_client = TelegramClient( + agent=agent, + client_id="Viral Coin Agent", + response_handler=lambda response: logging.info(f"Telegram response: {response}"), + ) + + # Define the task to run on schedule + async def scheduled_task() -> None: + try: + # Find viral coins + logging.info("Finding viral coins...") + viral_coins = await agent.find_viral_coins() + + # Generate report + logging.info("Generating report...") + report = await agent.generate_report(viral_coins, args.top_n) + + # Send report to Telegram if enabled + if telegram_client: + logging.info("Sending report to Telegram...") + await telegram_client.send_message(report) + + # Buy coins if requested + if args.buy and viral_coins: + top_coin = viral_coins[0] + logging.info(f"Buying top viral coin: {top_coin.coin_name} ({top_coin.coin_symbol})") + + # Buy the coin + result = await agent.buy_viral_coin( + coin_address=top_coin.address, + amount=args.buy_amount, + slippage_percent=args.slippage, + ) + + logging.info(f"Buy result: {result}") + + # Send buy notification to Telegram if enabled + if telegram_client: + buy_message = ( + f"🚨 **Viral Coin Purchase** 🚨\n\n" + f"Bought {args.buy_amount} {agent._get_base_token_for_chain()} worth of " + f"{top_coin.coin_name} ({top_coin.coin_symbol})\n\n" + f"Transaction: {result.get('tx_hash', 'N/A')}" + ) + await telegram_client.send_message(buy_message) + + # Set up DCA buys if requested + if args.dca and viral_coins: + top_coin = viral_coins[0] + logging.info(f"Setting up DCA buys for: {top_coin.coin_name} ({top_coin.coin_symbol})") + + # Set up DCA buys + dca_result = await agent.setup_dca_buys( + coin_address=top_coin.address, + total_amount=args.dca_amount, + num_intervals=args.dca_intervals, + interval_hours=args.dca_interval_hours, + slippage_percent=args.slippage, + ) + + logging.info(f"DCA setup result: {dca_result}") + + # Send DCA setup notification to Telegram if enabled + if telegram_client: + dca_message = ( + f"📊 **DCA Setup for Viral Coin** 📊\n\n" + f"Set up DCA buys for {top_coin.coin_name} ({top_coin.coin_symbol})\n\n" + f"Total Amount: {args.dca_amount} {agent._get_base_token_for_chain()}\n" + f"Intervals: {args.dca_intervals}\n" + f"Interval Hours: {args.dca_interval_hours}\n" + f"Schedule ID: {dca_result.get('id', 'N/A')}" + ) + await telegram_client.send_message(dca_message) + + except Exception as e: + logging.error(f"Error in scheduled task: {str(e)}") + if telegram_client: + error_message = f"❌ **Error in Viral Coin Agent** ❌\n\n{str(e)}" + await telegram_client.send_message(error_message) + + # Initialize the cron client + cron_client = CronJobClient( + agent=agent, + client_id="Viral Coin Agent Cron", + interval_seconds=args.interval_hours * 3600, # Convert hours to seconds + response_handler=lambda _: None, # We handle responses in the scheduled task + message_generator=lambda: agent.get_trading_task(), + max_history=2, # Last message pair only + on_interval=scheduled_task, # Custom task to run on schedule + ) + + # Start the cron client + logging.info(f"Starting Viral Coin Agent cron job with interval of {args.interval_hours} hours") + await cron_client.start() + + +def main() -> None: + """Main entry point for the scheduled task.""" + # Load environment variables + dotenv.load_dotenv() + + # Parse command-line arguments + parser = argparse.ArgumentParser(description="Viral Coin Agent Scheduled Task") + + # General options + parser.add_argument("--chain", type=str, default="ethereum_sepolia", help="Chain to use for trading") + parser.add_argument("--model-provider", type=str, default="anthropic", choices=["anthropic", "openai"], help="LLM provider to use") + parser.add_argument("--log-level", type=str, default="INFO", choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"], help="Logging level") + parser.add_argument("--report-dir", type=str, default="reports/viral_coins", help="Directory to save reports") + parser.add_argument("--interval-hours", type=int, default=24, help="Interval in hours between runs") + + # Search options + parser.add_argument("--min-market-cap", type=float, default=1000000, help="Minimum market cap for coins to consider") + parser.add_argument("--max-age-days", type=int, default=30, help="Maximum age in days for coins to consider") + parser.add_argument("--top-coins-limit", type=int, default=10, help="Number of top coins to search for") + parser.add_argument("--search-depth", type=int, default=50, help="Number of search results to analyze per platform") + parser.add_argument("--top-n", type=int, default=10, help="Number of top viral coins to include in the report") + + # Trading options + parser.add_argument("--buy", action="store_true", help="Buy the top viral coin") + parser.add_argument("--buy-amount", type=str, default="0.001", help="Amount to buy in base token (e.g., ETH)") + parser.add_argument("--dca", action="store_true", help="Set up DCA buys for the top viral coin") + parser.add_argument("--dca-amount", type=str, default="0.01", help="Total amount for DCA buys in base token (e.g., ETH)") + parser.add_argument("--dca-intervals", type=int, default=7, help="Number of intervals for DCA buys") + parser.add_argument("--dca-interval-hours", type=int, default=24, help="Hours between DCA buys") + parser.add_argument("--slippage", type=float, default=2.0, help="Maximum slippage percentage") + + # Reporting options + parser.add_argument("--telegram", action="store_true", help="Send report to Telegram") + + args = parser.parse_args() + + # Configure logging + logging.basicConfig( + format="%(asctime)s - %(levelname)s - %(name)s - %(filename)s:%(lineno)d - %(message)s", + datefmt="%Y-%m-%d %H:%M:%S", + level=getattr(logging, args.log_level), + ) + + # Run the agent + asyncio.run(run_viral_coin_agent_cron(args)) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/examples/viral_coin/viral_coin_agent_telegram.py b/examples/viral_coin/viral_coin_agent_telegram.py new file mode 100644 index 00000000..a35d78a7 --- /dev/null +++ b/examples/viral_coin/viral_coin_agent_telegram.py @@ -0,0 +1,721 @@ +#!/usr/bin/env python3 +"""Telegram bot for the Viral Coin Agent.""" + +import asyncio +import logging +import os +import re +import sys +from decimal import Decimal +from typing import Any, Dict, List, Optional, Tuple, Union + +import dotenv +from telegram import Update +from telegram.ext import ( + Application, + CommandHandler, + ContextTypes, + ConversationHandler, + MessageHandler, + filters, +) + +# Add the project root to the Python path +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../.."))) + +from alphaswarm.agents.viral_coin.viral_coin_agent import ViralCoinAgent, ViralCoinMetrics +from alphaswarm.config import Config + + +# Conversation states +CHAIN, MARKET_CAP, AGE, DEPTH, CONFIRM, BUY_CONFIRM, BUY_AMOUNT, DCA_CONFIRM, DCA_AMOUNT, DCA_INTERVALS = range(10) + + +class ViralCoinTelegramBot: + """Telegram bot for the Viral Coin Agent.""" + + def __init__(self) -> None: + """Initialize the Telegram bot.""" + # Load environment variables + dotenv.load_dotenv() + + # Configure logging + logging.basicConfig( + format="%(asctime)s - %(levelname)s - %(name)s - %(filename)s:%(lineno)d - %(message)s", + datefmt="%Y-%m-%d %H:%M:%S", + level=logging.INFO, + ) + + # Get Telegram bot token + self.token = os.environ.get("TELEGRAM_BOT_TOKEN") + if not self.token: + raise ValueError("TELEGRAM_BOT_TOKEN environment variable not set") + + # Initialize the agent + self.config = Config() + llm_config = self.config.get_default_llm_config("anthropic") + + self.agent = ViralCoinAgent( + model_id=llm_config.model_id, + chain="ethereum_sepolia", # Default chain + telegram_enabled=True, + ) + + # Initialize the application + self.application = Application.builder().token(self.token).build() + + # Add conversation handler + conv_handler = ConversationHandler( + entry_points=[CommandHandler("start", self.start)], + states={ + CHAIN: [MessageHandler(filters.TEXT & ~filters.COMMAND, self.chain)], + MARKET_CAP: [MessageHandler(filters.TEXT & ~filters.COMMAND, self.market_cap)], + AGE: [MessageHandler(filters.TEXT & ~filters.COMMAND, self.age)], + DEPTH: [MessageHandler(filters.TEXT & ~filters.COMMAND, self.depth)], + CONFIRM: [MessageHandler(filters.TEXT & ~filters.COMMAND, self.confirm)], + BUY_CONFIRM: [MessageHandler(filters.TEXT & ~filters.COMMAND, self.buy_confirm)], + BUY_AMOUNT: [MessageHandler(filters.TEXT & ~filters.COMMAND, self.buy_amount)], + DCA_CONFIRM: [MessageHandler(filters.TEXT & ~filters.COMMAND, self.dca_confirm)], + DCA_AMOUNT: [MessageHandler(filters.TEXT & ~filters.COMMAND, self.dca_amount)], + DCA_INTERVALS: [MessageHandler(filters.TEXT & ~filters.COMMAND, self.dca_intervals)], + }, + fallbacks=[CommandHandler("cancel", self.cancel)], + ) + + self.application.add_handler(conv_handler) + + # Add command handlers + self.application.add_handler(CommandHandler("help", self.help_command)) + self.application.add_handler(CommandHandler("report", self.report_command)) + self.application.add_handler(CommandHandler("buy", self.buy_command)) + self.application.add_handler(CommandHandler("dca", self.dca_command)) + + # Add error handler + self.application.add_error_handler(self.error_handler) + + # Logger + self.logger = logging.getLogger(__name__) + + async def start(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: + """Start the conversation and ask for the chain.""" + user = update.effective_user + await update.message.reply_text( + f"Hello {user.first_name}! I'm the Viral Coin Agent. " + "I can help you find the most viral cryptocurrencies based on social metrics.\n\n" + "Let's set up a search. First, which chain would you like to use?\n\n" + "Options: ethereum_sepolia (test), ethereum, base" + ) + + # Initialize user data + context.user_data["search_params"] = { + "chain": "ethereum_sepolia", + "min_market_cap": 1000000, + "max_age_days": 30, + "search_depth": 50, + "top_n": 10, + } + + return CHAIN + + async def chain(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: + """Store the chain and ask for the minimum market cap.""" + chain = update.message.text.strip().lower() + + # Validate chain + valid_chains = ["ethereum_sepolia", "ethereum", "base"] + if chain not in valid_chains: + await update.message.reply_text( + f"Invalid chain. Please choose from: {', '.join(valid_chains)}" + ) + return CHAIN + + context.user_data["search_params"]["chain"] = chain + + await update.message.reply_text( + "Great! Now, what's the minimum market cap (in USD) for coins to consider?\n\n" + "Default: 1000000 ($1M)" + ) + + return MARKET_CAP + + async def market_cap(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: + """Store the minimum market cap and ask for the maximum age.""" + try: + min_market_cap = float(update.message.text.strip().replace(",", "")) + if min_market_cap <= 0: + raise ValueError("Market cap must be positive") + + context.user_data["search_params"]["min_market_cap"] = min_market_cap + + await update.message.reply_text( + "What's the maximum age (in days) for coins to consider?\n\n" + "Default: 30 days" + ) + + return AGE + + except ValueError: + await update.message.reply_text( + "Please enter a valid number for the minimum market cap." + ) + return MARKET_CAP + + async def age(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: + """Store the maximum age and ask for the search depth.""" + try: + max_age_days = int(update.message.text.strip()) + if max_age_days <= 0: + raise ValueError("Age must be positive") + + context.user_data["search_params"]["max_age_days"] = max_age_days + + await update.message.reply_text( + "How many search results should I analyze per platform?\n\n" + "Default: 50 results" + ) + + return DEPTH + + except ValueError: + await update.message.reply_text( + "Please enter a valid number for the maximum age." + ) + return AGE + + async def depth(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: + """Store the search depth and ask for confirmation.""" + try: + search_depth = int(update.message.text.strip()) + if search_depth <= 0: + raise ValueError("Search depth must be positive") + + context.user_data["search_params"]["search_depth"] = search_depth + + # Summarize the search parameters + params = context.user_data["search_params"] + await update.message.reply_text( + "Here are your search parameters:\n\n" + f"Chain: {params['chain']}\n" + f"Minimum Market Cap: ${params['min_market_cap']:,}\n" + f"Maximum Age: {params['max_age_days']} days\n" + f"Search Depth: {params['search_depth']} results per platform\n\n" + "Do you want to proceed with the search? (yes/no)" + ) + + return CONFIRM + + except ValueError: + await update.message.reply_text( + "Please enter a valid number for the search depth." + ) + return DEPTH + + async def confirm(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: + """Confirm the search parameters and start the search.""" + response = update.message.text.strip().lower() + + if response in ["yes", "y"]: + await update.message.reply_text( + "Great! I'm starting the search for viral coins. This may take a few minutes..." + ) + + # Update agent parameters + params = context.user_data["search_params"] + self.agent.chain = params["chain"] + self.agent.min_market_cap = params["min_market_cap"] + self.agent.max_age_days = params["max_age_days"] + self.agent.search_depth = params["search_depth"] + + try: + # Find viral coins + viral_coins = await self.agent.find_viral_coins() + + # Store the results + context.user_data["viral_coins"] = viral_coins + + # Generate report + report = await self.agent.generate_report(viral_coins, params["top_n"]) + + # Send the report in chunks if it's too long + if len(report) > 4000: + chunks = self._split_text(report, 4000) + for chunk in chunks: + await update.message.reply_text(chunk) + else: + await update.message.reply_text(report) + + # Ask if the user wants to buy the top coin + if viral_coins: + top_coin = viral_coins[0] + await update.message.reply_text( + f"Would you like to buy the top viral coin: {top_coin.coin_name} ({top_coin.coin_symbol})? (yes/no)" + ) + return BUY_CONFIRM + + return ConversationHandler.END + + except Exception as e: + self.logger.error(f"Error in search: {str(e)}") + await update.message.reply_text( + f"An error occurred during the search: {str(e)}\n\n" + "Please try again with different parameters." + ) + return ConversationHandler.END + + elif response in ["no", "n"]: + await update.message.reply_text( + "Search cancelled. You can start a new search with /start" + ) + return ConversationHandler.END + + else: + await update.message.reply_text( + "Please answer with 'yes' or 'no'." + ) + return CONFIRM + + async def buy_confirm(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: + """Confirm buying the top viral coin.""" + response = update.message.text.strip().lower() + + if response in ["yes", "y"]: + await update.message.reply_text( + "How much would you like to buy? (in ETH)\n\n" + "Example: 0.001" + ) + return BUY_AMOUNT + + elif response in ["no", "n"]: + await update.message.reply_text( + "Would you like to set up DCA (Dollar Cost Averaging) buys for the top viral coin? (yes/no)" + ) + return DCA_CONFIRM + + else: + await update.message.reply_text( + "Please answer with 'yes' or 'no'." + ) + return BUY_CONFIRM + + async def buy_amount(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: + """Store the buy amount and execute the buy.""" + try: + amount = update.message.text.strip() + + # Validate amount + Decimal(amount) # This will raise an exception if the amount is invalid + + await update.message.reply_text( + f"Buying {amount} ETH worth of the top viral coin. Please wait..." + ) + + # Get the top coin + viral_coins = context.user_data.get("viral_coins", []) + if not viral_coins: + await update.message.reply_text( + "No viral coins found. Please start a new search with /start" + ) + return ConversationHandler.END + + top_coin = viral_coins[0] + + try: + # Buy the coin + result = await self.agent.buy_viral_coin( + coin_address=top_coin.address, + amount=amount, + slippage_percent=2.0, + ) + + # Send the result + await update.message.reply_text( + f"🚨 **Viral Coin Purchase** 🚨\n\n" + f"Bought {amount} {self.agent._get_base_token_for_chain()} worth of " + f"{top_coin.coin_name} ({top_coin.coin_symbol})\n\n" + f"Transaction: {result.get('tx_hash', 'N/A')}" + ) + + # Ask if the user wants to set up DCA buys + await update.message.reply_text( + "Would you like to set up DCA (Dollar Cost Averaging) buys for this coin? (yes/no)" + ) + return DCA_CONFIRM + + except Exception as e: + self.logger.error(f"Error buying coin: {str(e)}") + await update.message.reply_text( + f"An error occurred during the purchase: {str(e)}" + ) + return ConversationHandler.END + + except (ValueError, decimal.InvalidOperation): + await update.message.reply_text( + "Please enter a valid amount." + ) + return BUY_AMOUNT + + async def dca_confirm(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: + """Confirm setting up DCA buys.""" + response = update.message.text.strip().lower() + + if response in ["yes", "y"]: + await update.message.reply_text( + "What's the total amount you want to invest through DCA? (in ETH)\n\n" + "Example: 0.01" + ) + return DCA_AMOUNT + + elif response in ["no", "n"]: + await update.message.reply_text( + "Alright! You can start a new search with /start or get help with /help" + ) + return ConversationHandler.END + + else: + await update.message.reply_text( + "Please answer with 'yes' or 'no'." + ) + return DCA_CONFIRM + + async def dca_amount(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: + """Store the DCA amount and ask for the number of intervals.""" + try: + amount = update.message.text.strip() + + # Validate amount + Decimal(amount) # This will raise an exception if the amount is invalid + + # Store the amount + context.user_data["dca_amount"] = amount + + await update.message.reply_text( + "How many intervals do you want to spread the buys over?\n\n" + "Default: 7 intervals" + ) + return DCA_INTERVALS + + except (ValueError, decimal.InvalidOperation): + await update.message.reply_text( + "Please enter a valid amount." + ) + return DCA_AMOUNT + + async def dca_intervals(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: + """Store the number of intervals and set up DCA buys.""" + try: + intervals = int(update.message.text.strip()) + if intervals <= 0: + raise ValueError("Number of intervals must be positive") + + await update.message.reply_text( + f"Setting up DCA buys with {context.user_data['dca_amount']} ETH over {intervals} intervals. Please wait..." + ) + + # Get the top coin + viral_coins = context.user_data.get("viral_coins", []) + if not viral_coins: + await update.message.reply_text( + "No viral coins found. Please start a new search with /start" + ) + return ConversationHandler.END + + top_coin = viral_coins[0] + + try: + # Set up DCA buys + dca_result = await self.agent.setup_dca_buys( + coin_address=top_coin.address, + total_amount=context.user_data["dca_amount"], + num_intervals=intervals, + interval_hours=24, # Default to daily + slippage_percent=2.0, + ) + + # Send the result + await update.message.reply_text( + f"📊 **DCA Setup for Viral Coin** 📊\n\n" + f"Set up DCA buys for {top_coin.coin_name} ({top_coin.coin_symbol})\n\n" + f"Total Amount: {context.user_data['dca_amount']} {self.agent._get_base_token_for_chain()}\n" + f"Intervals: {intervals}\n" + f"Interval Hours: 24\n" + f"Schedule ID: {dca_result.get('id', 'N/A')}" + ) + + await update.message.reply_text( + "All done! You can start a new search with /start or get help with /help" + ) + return ConversationHandler.END + + except Exception as e: + self.logger.error(f"Error setting up DCA: {str(e)}") + await update.message.reply_text( + f"An error occurred while setting up DCA: {str(e)}" + ) + return ConversationHandler.END + + except ValueError: + await update.message.reply_text( + "Please enter a valid number for the intervals." + ) + return DCA_INTERVALS + + async def cancel(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: + """Cancel the conversation.""" + await update.message.reply_text( + "Operation cancelled. You can start a new search with /start" + ) + return ConversationHandler.END + + async def help_command(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: + """Send a message when the command /help is issued.""" + help_text = ( + "🚀 **Viral Coin Agent Help** 🚀\n\n" + "I can help you find the most viral cryptocurrencies based on social metrics and allow you to trade them.\n\n" + "**Commands:**\n" + "/start - Start a new search for viral coins\n" + "/report - Generate a report of the last search results\n" + "/buy - Buy the top viral coin from the last search\n" + "/dca - Set up DCA buys for the top viral coin\n" + "/help - Show this help message\n" + "/cancel - Cancel the current operation\n\n" + "**How it works:**\n" + "1. I search for mentions of cryptocurrencies on social media platforms\n" + "2. I analyze the results to identify the most viral coins\n" + "3. I generate a report of the top viral coins\n" + "4. You can choose to buy the top viral coin or set up DCA buys\n\n" + "**Supported chains:**\n" + "- ethereum_sepolia (test)\n" + "- ethereum\n" + "- base" + ) + + await update.message.reply_text(help_text) + + async def report_command(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: + """Generate a report of the last search results.""" + viral_coins = context.user_data.get("viral_coins") + + if not viral_coins: + await update.message.reply_text( + "No viral coins found. Please start a new search with /start" + ) + return + + await update.message.reply_text( + "Generating report of the last search results..." + ) + + try: + # Generate report + report = await self.agent.generate_report(viral_coins, 10) + + # Send the report in chunks if it's too long + if len(report) > 4000: + chunks = self._split_text(report, 4000) + for chunk in chunks: + await update.message.reply_text(chunk) + else: + await update.message.reply_text(report) + + except Exception as e: + self.logger.error(f"Error generating report: {str(e)}") + await update.message.reply_text( + f"An error occurred while generating the report: {str(e)}" + ) + + async def buy_command(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: + """Buy the top viral coin from the last search.""" + viral_coins = context.user_data.get("viral_coins") + + if not viral_coins: + await update.message.reply_text( + "No viral coins found. Please start a new search with /start" + ) + return + + await update.message.reply_text( + "How much would you like to buy? (in ETH)\n\n" + "Example: 0.001" + ) + + # Set up a one-time conversation handler for the buy amount + application = context.application + + async def buy_amount_handler(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: + try: + amount = update.message.text.strip() + + # Validate amount + Decimal(amount) # This will raise an exception if the amount is invalid + + await update.message.reply_text( + f"Buying {amount} ETH worth of the top viral coin. Please wait..." + ) + + top_coin = viral_coins[0] + + try: + # Buy the coin + result = await self.agent.buy_viral_coin( + coin_address=top_coin.address, + amount=amount, + slippage_percent=2.0, + ) + + # Send the result + await update.message.reply_text( + f"🚨 **Viral Coin Purchase** 🚨\n\n" + f"Bought {amount} {self.agent._get_base_token_for_chain()} worth of " + f"{top_coin.coin_name} ({top_coin.coin_symbol})\n\n" + f"Transaction: {result.get('tx_hash', 'N/A')}" + ) + + except Exception as e: + self.logger.error(f"Error buying coin: {str(e)}") + await update.message.reply_text( + f"An error occurred during the purchase: {str(e)}" + ) + + except (ValueError, decimal.InvalidOperation): + await update.message.reply_text( + "Please enter a valid amount." + ) + + # Remove the handler + application.remove_handler(buy_handler) + + buy_handler = MessageHandler(filters.TEXT & ~filters.COMMAND, buy_amount_handler) + application.add_handler(buy_handler) + + async def dca_command(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: + """Set up DCA buys for the top viral coin.""" + viral_coins = context.user_data.get("viral_coins") + + if not viral_coins: + await update.message.reply_text( + "No viral coins found. Please start a new search with /start" + ) + return + + await update.message.reply_text( + "What's the total amount you want to invest through DCA? (in ETH)\n\n" + "Example: 0.01" + ) + + # Set up a conversation handler for DCA setup + application = context.application + + async def dca_amount_handler(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: + try: + amount = update.message.text.strip() + + # Validate amount + Decimal(amount) # This will raise an exception if the amount is invalid + + # Store the amount + context.user_data["dca_amount"] = amount + + await update.message.reply_text( + "How many intervals do you want to spread the buys over?\n\n" + "Default: 7 intervals" + ) + + # Remove this handler and add the intervals handler + application.remove_handler(dca_amount_handler_obj) + application.add_handler(dca_intervals_handler_obj) + + except (ValueError, decimal.InvalidOperation): + await update.message.reply_text( + "Please enter a valid amount." + ) + + async def dca_intervals_handler(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: + try: + intervals = int(update.message.text.strip()) + if intervals <= 0: + raise ValueError("Number of intervals must be positive") + + await update.message.reply_text( + f"Setting up DCA buys with {context.user_data['dca_amount']} ETH over {intervals} intervals. Please wait..." + ) + + top_coin = viral_coins[0] + + try: + # Set up DCA buys + dca_result = await self.agent.setup_dca_buys( + coin_address=top_coin.address, + total_amount=context.user_data["dca_amount"], + num_intervals=intervals, + interval_hours=24, # Default to daily + slippage_percent=2.0, + ) + + # Send the result + await update.message.reply_text( + f"📊 **DCA Setup for Viral Coin** 📊\n\n" + f"Set up DCA buys for {top_coin.coin_name} ({top_coin.coin_symbol})\n\n" + f"Total Amount: {context.user_data['dca_amount']} {self.agent._get_base_token_for_chain()}\n" + f"Intervals: {intervals}\n" + f"Interval Hours: 24\n" + f"Schedule ID: {dca_result.get('id', 'N/A')}" + ) + + except Exception as e: + self.logger.error(f"Error setting up DCA: {str(e)}") + await update.message.reply_text( + f"An error occurred while setting up DCA: {str(e)}" + ) + + except ValueError: + await update.message.reply_text( + "Please enter a valid number for the intervals." + ) + + # Remove the handler + application.remove_handler(dca_intervals_handler_obj) + + dca_amount_handler_obj = MessageHandler(filters.TEXT & ~filters.COMMAND, dca_amount_handler) + dca_intervals_handler_obj = MessageHandler(filters.TEXT & ~filters.COMMAND, dca_intervals_handler) + + application.add_handler(dca_amount_handler_obj) + + async def error_handler(self, update: object, context: ContextTypes.DEFAULT_TYPE) -> None: + """Handle errors.""" + self.logger.error(f"Error: {context.error}") + + if update and isinstance(update, Update) and update.effective_message: + await update.effective_message.reply_text( + f"An error occurred: {context.error}" + ) + + def _split_text(self, text: str, max_length: int) -> List[str]: + """Split text into chunks of maximum length.""" + chunks = [] + current_chunk = "" + + for line in text.split("\n"): + if len(current_chunk) + len(line) + 1 <= max_length: + current_chunk += line + "\n" + else: + chunks.append(current_chunk) + current_chunk = line + "\n" + + if current_chunk: + chunks.append(current_chunk) + + return chunks + + def run(self) -> None: + """Run the bot.""" + self.application.run_polling() + + +def main() -> None: + """Main function.""" + bot = ViralCoinTelegramBot() + bot.run() + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index 74a8e752..68b110db 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.0.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand. [[package]] name = "aiofiles" @@ -7,7 +7,7 @@ description = "File support for asyncio." optional = false python-versions = ">=3.7" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "aiofiles-23.2.1-py3-none-any.whl", hash = "sha256:19297512c647d4b27a2cf7c34caa7e405c0d60b5560618a29a9fe027b18b0107"}, {file = "aiofiles-23.2.1.tar.gz", hash = "sha256:84ec2218d8419404abcb9f0c02df3f34c6e0a68ed41072acfb1cef5cbc29051a"}, @@ -20,7 +20,7 @@ description = "Happy Eyeballs for asyncio" optional = false python-versions = ">=3.8" groups = ["ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "aiohappyeyeballs-2.4.4-py3-none-any.whl", hash = "sha256:a980909d50efcd44795c4afeca523296716d50cd756ddca6af8c65b996e27de8"}, {file = "aiohappyeyeballs-2.4.4.tar.gz", hash = "sha256:5fdd7d87889c63183afc18ce9271f9b0a7d32c2303e394468dd45d514a757745"}, @@ -33,7 +33,7 @@ description = "Async http client/server framework (asyncio)" optional = false python-versions = ">=3.9" groups = ["ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "aiohttp-3.11.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a60804bff28662cbcf340a4d61598891f12eea3a66af48ecfdc975ceec21e3c8"}, {file = "aiohttp-3.11.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4b4fa1cb5f270fb3eab079536b764ad740bb749ce69a94d4ec30ceee1b5940d5"}, @@ -123,7 +123,7 @@ propcache = ">=0.2.0" yarl = ">=1.17.0,<2.0" [package.extras] -speedups = ["Brotli", "aiodns (>=3.2.0)", "brotlicffi"] +speedups = ["Brotli ; platform_python_implementation == \"CPython\"", "aiodns (>=3.2.0) ; sys_platform == \"linux\" or sys_platform == \"darwin\"", "brotlicffi ; platform_python_implementation != \"CPython\""] [[package]] name = "aiosignal" @@ -132,7 +132,7 @@ description = "aiosignal: a list of registered asynchronous callbacks" optional = false python-versions = ">=3.9" groups = ["ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "aiosignal-1.3.2-py2.py3-none-any.whl", hash = "sha256:45cde58e409a301715980c2b01d0c28bdde3770d8290b5eb2173759d9acb31a5"}, {file = "aiosignal-1.3.2.tar.gz", hash = "sha256:a8c255c66fafb1e499c9351d0bf32ff2d8a0321595ebac3b93713656d2436f54"}, @@ -148,7 +148,7 @@ description = "Reusable constraint types to use with typing.Annotated" optional = false python-versions = ">=3.8" groups = ["main", "ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, @@ -161,7 +161,7 @@ description = "High level compatibility layer for multiple asynchronous event lo optional = false python-versions = ">=3.9" groups = ["ai", "clients", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "anyio-4.8.0-py3-none-any.whl", hash = "sha256:b5011f270ab5eb0abf13385f851315585cc37ef330dd88e27ec3d34d651fd47a"}, {file = "anyio-4.8.0.tar.gz", hash = "sha256:1d9fe889df5212298c0c0723fa20479d1b94883a2df44bd3897aa91083316f7a"}, @@ -174,7 +174,7 @@ typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "trustme", "truststore (>=0.9.1) ; python_version >= \"3.10\"", "uvloop (>=0.21) ; platform_python_implementation == \"CPython\" and platform_system != \"Windows\" and python_version < \"3.14\""] trio = ["trio (>=0.26.1)"] [[package]] @@ -184,19 +184,19 @@ description = "Classes Without Boilerplate" optional = false python-versions = ">=3.8" groups = ["ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "attrs-25.1.0-py3-none-any.whl", hash = "sha256:c75a69e28a550a7e93789579c22aa26b0f5b83b75dc4e08fe092980051e1090a"}, {file = "attrs-25.1.0.tar.gz", hash = "sha256:1c97078a80c814273a76b2a298a932eb681c87415c11dee0a6921de7f1b02c3e"}, ] [package.extras] -benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +benchmark = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] +cov = ["cloudpickle ; platform_python_implementation == \"CPython\"", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] +dev = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] +tests = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\""] [[package]] name = "audioop-lts" @@ -249,7 +249,7 @@ description = "Screen-scraping library" optional = false python-versions = ">=3.6.0" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"}, {file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"}, @@ -272,7 +272,7 @@ description = "efficient arrays of booleans -- C extension" optional = false python-versions = "*" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "bitarray-3.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5ddbf71a97ad1d6252e6e93d2d703b624d0a5b77c153b12f9ea87d83e1250e0c"}, {file = "bitarray-3.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e0e7f24a0b01e6e6a0191c50b06ca8edfdec1988d9d2b264d669d2487f4f4680"}, @@ -420,7 +420,7 @@ description = "The uncompromising code formatter." optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "black-24.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6668650ea4b685440857138e5fe40cde4d652633b1bdffc62933d0db4ed9812"}, {file = "black-24.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1c536fcf674217e87b8cc3657b81809d3c085d7bf3ef262ead700da345bfa6ea"}, @@ -466,7 +466,7 @@ description = "A decorator for caching properties in classes." optional = false python-versions = "*" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "cached-property-1.5.2.tar.gz", hash = "sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130"}, {file = "cached_property-1.5.2-py2.py3-none-any.whl", hash = "sha256:df4f613cf7ad9a588cc381aaf4a512d26265ecebd5eb9e1ba12f1319eb85a6a0"}, @@ -479,7 +479,7 @@ description = "Extensible memoizing collections and decorators" optional = false python-versions = ">=3.7" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "cachetools-5.5.1-py3-none-any.whl", hash = "sha256:b76651fdc3b24ead3c648bbdeeb940c1b04d365b38b4af66788f9ec4a81d42bb"}, {file = "cachetools-5.5.1.tar.gz", hash = "sha256:70f238fbba50383ef62e55c6aff6d9673175fe59f7c6782c7a0b9e38f4a9df95"}, @@ -492,7 +492,7 @@ description = "A ~2x faster drop-in replacement for eth_utils.to_checksum_addres optional = false python-versions = "<4,>=3.8" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "cchecksum-0.0.4.tar.gz", hash = "sha256:612b7db7dc317c3303aa2db54e7ee71fb7ca2ccae46e420ae5afbefe6c8b01ed"}, ] @@ -508,7 +508,7 @@ description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" groups = ["main", "ai", "clients", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, @@ -521,7 +521,7 @@ description = "Foreign Function Interface for Python calling C code." optional = false python-versions = ">=3.8" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\") and platform_python_implementation != \"PyPy\"" +markers = "(implementation_name == \"cpython\" or implementation_name == \"pypy\") and platform_python_implementation != \"PyPy\"" files = [ {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, @@ -602,7 +602,7 @@ description = "The Real First Universal Charset Detector. Open, modern and activ optional = false python-versions = ">=3.7" groups = ["main", "ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, @@ -705,7 +705,7 @@ description = "Python bindings for C-KZG-4844" optional = false python-versions = "*" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "ckzg-1.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bdd082bc0f2a595e3546658ecbe1ff78fe65b0ab7e619a8197a62d94f46b5b46"}, {file = "ckzg-1.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:50ca4af4e2f1a1e8b0a7e97b3aef39dedbb0d52d90866ece424f13f8df1b5972"}, @@ -801,7 +801,7 @@ description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" groups = ["ai", "dev", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, @@ -821,7 +821,7 @@ files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] -markers = {ai = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\") and platform_system == \"Windows\"", dev = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\") and (platform_system == \"Windows\" or sys_platform == \"win32\")", web3 = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\") and platform_system == \"Windows\""} +markers = {ai = "(implementation_name == \"cpython\" or implementation_name == \"pypy\") and platform_system == \"Windows\"", dev = "(implementation_name == \"cpython\" or implementation_name == \"pypy\") and (platform_system == \"Windows\" or sys_platform == \"win32\")", web3 = "(implementation_name == \"cpython\" or implementation_name == \"pypy\") and platform_system == \"Windows\""} [[package]] name = "construct" @@ -830,7 +830,7 @@ description = "A powerful declarative symmetric parser/builder for binary data" optional = false python-versions = ">=3.6" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "construct-2.10.68.tar.gz", hash = "sha256:7b2a3fd8e5f597a5aa1d614c3bd516fa065db01704c72a1efaaeec6ef23d8b45"}, ] @@ -845,7 +845,7 @@ description = "Extension for the python package 'construct' that adds typing fea optional = false python-versions = ">=3.7" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "construct-typing-0.5.6.tar.gz", hash = "sha256:0dc501351cd6b308f15ec54e5fe7c0fbc07cc1530a1b77b4303062a0a93c1297"}, {file = "construct_typing-0.5.6-py3-none-any.whl", hash = "sha256:39c948329e880564e33521cba497b21b07967c465b9c9037d6334e2cffa1ced9"}, @@ -861,7 +861,7 @@ description = "Code coverage measurement for Python" optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "coverage-7.6.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5c912978f7fbf47ef99cec50c4401340436d200d41d714c7a4766f377c5b7b78"}, {file = "coverage-7.6.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a01ec4af7dfeb96ff0078ad9a48810bb0cc8abcb0115180c6013a6b26237626c"}, @@ -928,7 +928,7 @@ files = [ ] [package.extras] -toml = ["tomli"] +toml = ["tomli ; python_full_version <= \"3.11.0a6\""] [[package]] name = "cryptography" @@ -937,7 +937,7 @@ description = "cryptography is a package which provides cryptographic recipes an optional = false python-versions = "!=3.9.0,!=3.9.1,>=3.7" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "cryptography-44.0.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:84111ad4ff3f6253820e6d3e58be2cc2a00adb29335d4cacb5ab4d4d34f2a123"}, {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15492a11f9e1b62ba9d73c210e2416724633167de94607ec6069ef724fad092"}, @@ -972,10 +972,10 @@ files = [ cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} [package.extras] -docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=3.0.0)"] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=3.0.0) ; python_version >= \"3.8\""] docstest = ["pyenchant (>=3)", "readme-renderer (>=30.0)", "sphinxcontrib-spelling (>=7.3.1)"] -nox = ["nox (>=2024.4.15)", "nox[uv] (>=2024.3.2)"] -pep8test = ["check-sdist", "click (>=8.0.1)", "mypy (>=1.4)", "ruff (>=0.3.6)"] +nox = ["nox (>=2024.4.15)", "nox[uv] (>=2024.3.2) ; python_version >= \"3.8\""] +pep8test = ["check-sdist ; python_version >= \"3.8\"", "click (>=8.0.1)", "mypy (>=1.4)", "ruff (>=0.3.6)"] sdist = ["build (>=1.0.0)"] ssh = ["bcrypt (>=3.1.5)"] test = ["certifi (>=2024)", "cryptography-vectors (==44.0.0)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"] @@ -988,7 +988,7 @@ description = "Cython implementation of Toolz: High performance functional utili optional = false python-versions = ">=3.8" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and implementation_name == \"cpython\"" +markers = "implementation_name == \"cpython\"" files = [ {file = "cytoolz-1.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cec9af61f71fc3853eb5dca3d42eb07d1f48a4599fa502cbe92adde85f74b042"}, {file = "cytoolz-1.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:140bbd649dbda01e91add7642149a5987a7c3ccc251f2263de894b89f50b6608"}, @@ -1105,7 +1105,7 @@ description = "Distro - an OS platform information API" optional = false python-versions = ">=3.6" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2"}, {file = "distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed"}, @@ -1118,7 +1118,7 @@ description = "Parse Python docstrings in reST, Google and Numpydoc format" optional = false python-versions = ">=3.6,<4.0" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "docstring_parser-0.16-py3-none-any.whl", hash = "sha256:bf0a1387354d3691d102edef7ec124f219ef639982d096e26e3b60aeffa90637"}, {file = "docstring_parser-0.16.tar.gz", hash = "sha256:538beabd0af1e2db0146b6bd3caa526c35a34d61af9fd2887f3a8a27a739aa6e"}, @@ -1131,7 +1131,7 @@ description = "Search for words, documents, images, news, maps and text translat optional = false python-versions = ">=3.9" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "duckduckgo_search-7.3.0-py3-none-any.whl", hash = "sha256:3a9c696ed98148dbc6af3497ca9062fa6dc480266a33d53779cadd1ae1d90b8a"}, {file = "duckduckgo_search-7.3.0.tar.gz", hash = "sha256:52fc6a63055d8fbcadaddd292b11067affb87f9768a311f6f7d157a2bb5c40f6"}, @@ -1152,7 +1152,7 @@ description = "E2B SDK that give agents cloud environments" optional = false python-versions = "<4.0,>=3.8" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "e2b-1.0.6-py3-none-any.whl", hash = "sha256:4ae6e00d46e6b0b9ab05388c408f9155488ee9f022c5a6fd47939f492ccf3b58"}, {file = "e2b-1.0.6.tar.gz", hash = "sha256:e35d47f5581565060a5c18e4cb839cf61de310d275fa0a6589d8fc8bf65957a7"}, @@ -1174,7 +1174,7 @@ description = "E2B Code Interpreter - Stateful code execution" optional = false python-versions = "<4.0,>=3.8" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "e2b_code_interpreter-1.0.4-py3-none-any.whl", hash = "sha256:e8cea4946b3457072a524250aee712f7f8d44834b91cd9c13da3bdf96eda1a6e"}, {file = "e2b_code_interpreter-1.0.4.tar.gz", hash = "sha256:fec5651d98ca0d03dd038c5df943a0beaeb59c6d422112356f55f2b662d8dea1"}, @@ -1192,7 +1192,7 @@ description = "ECDSA cryptographic signature library (pure python)" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.6" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "ecdsa-0.19.0-py2.py3-none-any.whl", hash = "sha256:2cea9b88407fdac7bbeca0833b189e4c9c53f2ef1e1eaa29f6224dbc809b707a"}, {file = "ecdsa-0.19.0.tar.gz", hash = "sha256:60eaad1199659900dd0af521ed462b793bbdf867432b3948e87416ae4caf6bf8"}, @@ -1213,7 +1213,7 @@ description = "eth_abi: Python utilities for working with Ethereum ABI definitio optional = false python-versions = "<4,>=3.8" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "eth_abi-5.2.0-py3-none-any.whl", hash = "sha256:17abe47560ad753f18054f5b3089fcb588f3e3a092136a416b6c1502cb7e8877"}, {file = "eth_abi-5.2.0.tar.gz", hash = "sha256:178703fa98c07d8eecd5ae569e7e8d159e493ebb6eeb534a8fe973fbc4e40ef0"}, @@ -1237,7 +1237,7 @@ description = "eth-account: Sign Ethereum transactions and messages with local p optional = false python-versions = "<4,>=3.8" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "eth_account-0.11.3-py3-none-any.whl", hash = "sha256:16cf58aabc65171fc206489899b7e5546e3215e1a4debc12dbd55345c979081e"}, {file = "eth_account-0.11.3.tar.gz", hash = "sha256:a712a9534638a7cfaa4cc069f1b9d5cefeee70362cfc3a7b0a2534ee61ce76c9"}, @@ -1266,7 +1266,7 @@ description = "Python implementation of the Ethereum Trie structure" optional = false python-versions = ">=3.7, <4" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "eth-bloom-2.0.0.tar.gz", hash = "sha256:73576828dff7566b9216403e0898966912f370bae5734241dd3f50ce5664a825"}, {file = "eth_bloom-2.0.0-py3-none-any.whl", hash = "sha256:cc86ab9670577996f7fcb8445b7a164ecd211ac91d9c4c2b5a47678623419927"}, @@ -1288,7 +1288,7 @@ description = "eth-hash: The Ethereum hashing function, keccak256, sometimes (er optional = false python-versions = "<4,>=3.8" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "eth_hash-0.7.1-py3-none-any.whl", hash = "sha256:0fb1add2adf99ef28883fd6228eb447ef519ea72933535ad1a0b28c6f65f868a"}, {file = "eth_hash-0.7.1.tar.gz", hash = "sha256:d2411a403a0b0a62e8247b4117932d900ffb4c8c64b15f92620547ca5ce46be5"}, @@ -1302,7 +1302,7 @@ safe-pysha3 = {version = ">=1.0.0", optional = true, markers = "python_version > dev = ["build (>=0.9.0)", "bump_my_version (>=0.19.0)", "ipython", "mypy (==1.10.0)", "pre-commit (>=3.4.0)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)", "sphinx (>=6.0.0)", "sphinx-autobuild (>=2021.3.14)", "sphinx_rtd_theme (>=1.0.0)", "towncrier (>=24,<25)", "tox (>=4.0.0)", "twine", "wheel"] docs = ["sphinx (>=6.0.0)", "sphinx-autobuild (>=2021.3.14)", "sphinx_rtd_theme (>=1.0.0)", "towncrier (>=24,<25)"] pycryptodome = ["pycryptodome (>=3.6.6,<4)"] -pysha3 = ["pysha3 (>=1.0.0,<2.0.0)", "safe-pysha3 (>=1.0.0)"] +pysha3 = ["pysha3 (>=1.0.0,<2.0.0) ; python_version < \"3.9\"", "safe-pysha3 (>=1.0.0) ; python_version >= \"3.9\""] test = ["pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)"] [[package]] @@ -1312,7 +1312,7 @@ description = "eth-keyfile: A library for handling the encrypted keyfiles used t optional = false python-versions = "<4,>=3.8" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "eth_keyfile-0.8.1-py3-none-any.whl", hash = "sha256:65387378b82fe7e86d7cb9f8d98e6d639142661b2f6f490629da09fddbef6d64"}, {file = "eth_keyfile-0.8.1.tar.gz", hash = "sha256:9708bc31f386b52cca0969238ff35b1ac72bd7a7186f2a84b86110d3c973bec1"}, @@ -1335,7 +1335,7 @@ description = "Common API for Ethereum key operations." optional = false python-versions = "*" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "eth-keys-0.4.0.tar.gz", hash = "sha256:7d18887483bc9b8a3fdd8e32ddcb30044b9f08fcb24a380d93b6eee3a5bb3216"}, {file = "eth_keys-0.4.0-py3-none-any.whl", hash = "sha256:e07915ffb91277803a28a379418bdd1fad1f390c38ad9353a0f189789a440d5d"}, @@ -1347,10 +1347,10 @@ eth-utils = ">=2.0.0,<3.0.0" [package.extras] coincurve = ["coincurve (>=7.0.0,<16.0.0)"] -dev = ["asn1tools (>=0.146.2,<0.147)", "bumpversion (==0.5.3)", "eth-hash[pycryptodome]", "eth-hash[pysha3]", "eth-typing (>=3.0.0,<4)", "eth-utils (>=2.0.0,<3.0.0)", "factory-boy (>=3.0.1,<3.1)", "flake8 (==3.0.4)", "hypothesis (>=5.10.3,<6.0.0)", "mypy (==0.782)", "pyasn1 (>=0.4.5,<0.5)", "pytest (==6.2.5)", "tox (==3.20.0)", "twine"] +dev = ["asn1tools (>=0.146.2,<0.147)", "bumpversion (==0.5.3)", "eth-hash[pycryptodome] ; implementation_name == \"pypy\"", "eth-hash[pysha3] ; implementation_name == \"cpython\"", "eth-typing (>=3.0.0,<4)", "eth-utils (>=2.0.0,<3.0.0)", "factory-boy (>=3.0.1,<3.1)", "flake8 (==3.0.4)", "hypothesis (>=5.10.3,<6.0.0)", "mypy (==0.782)", "pyasn1 (>=0.4.5,<0.5)", "pytest (==6.2.5)", "tox (==3.20.0)", "twine"] eth-keys = ["eth-typing (>=3.0.0,<4)", "eth-utils (>=2.0.0,<3.0.0)"] lint = ["flake8 (==3.0.4)", "mypy (==0.782)"] -test = ["asn1tools (>=0.146.2,<0.147)", "eth-hash[pycryptodome]", "eth-hash[pysha3]", "factory-boy (>=3.0.1,<3.1)", "hypothesis (>=5.10.3,<6.0.0)", "pyasn1 (>=0.4.5,<0.5)", "pytest (==6.2.5)"] +test = ["asn1tools (>=0.146.2,<0.147)", "eth-hash[pycryptodome] ; implementation_name == \"pypy\"", "eth-hash[pysha3] ; implementation_name == \"cpython\"", "factory-boy (>=3.0.1,<3.1)", "hypothesis (>=5.10.3,<6.0.0)", "pyasn1 (>=0.4.5,<0.5)", "pytest (==6.2.5)"] [[package]] name = "eth-pydantic-types" @@ -1359,7 +1359,7 @@ description = "eth-pydantic-types: Pydantic Types for Ethereum" optional = false python-versions = "<4,>=3.9" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "eth-pydantic-types-0.1.3.tar.gz", hash = "sha256:4764ba82434ab6d0d98d3b7aee4ace0cc7b12cf47c7e53424525c33fb9b872af"}, {file = "eth_pydantic_types-0.1.3-py3-none-any.whl", hash = "sha256:7a54f253f32bb3c01b21dbbfc7022d476b53ad5b7da96dcc4dae24997ec69469"}, @@ -1386,7 +1386,7 @@ description = "Provides a decorator that automatically catches known transient e optional = false python-versions = "*" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "eth_retry-0.2.1-py3-none-any.whl", hash = "sha256:df90cc4fe2d742bfa0f03e0ae4eaf28730ba01d88b997cacaa2aa1955988f57e"}, {file = "eth_retry-0.2.1.tar.gz", hash = "sha256:12ffd9ca8e8a3e87cbd76019fdcf59b019ad9769f792a51135868b66c6f5a0ed"}, @@ -1402,7 +1402,7 @@ description = "eth-rlp: RLP definitions for common Ethereum objects in Python" optional = false python-versions = ">=3.8, <4" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "eth-rlp-1.0.1.tar.gz", hash = "sha256:d61dbda892ee1220f28fb3663c08f6383c305db9f1f5624dc585c9cd05115027"}, {file = "eth_rlp-1.0.1-py3-none-any.whl", hash = "sha256:dd76515d71654277377d48876b88e839d61553aaf56952e580bb7cebef2b1517"}, @@ -1426,7 +1426,7 @@ description = "Tools for testing Ethereum applications." optional = false python-versions = ">=3.6.8,<4" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "eth-tester-0.9.1b1.tar.gz", hash = "sha256:b9cbc93d0b17a6e8acbb52294dad214ee223cf88209fa5be66ead353937d274c"}, {file = "eth_tester-0.9.1b1-py3-none-any.whl", hash = "sha256:0e4367d99ae242efdb8c1d18ed99d1ff3f03149abb0a4c2427bc6d333ebef13b"}, @@ -1446,11 +1446,11 @@ rlp = ">=3.0.0,<4" semantic-version = ">=2.6.0,<3.0.0" [package.extras] -dev = ["black (>=22,<23)", "bumpversion (>=0.5.3,<1.0.0)", "eth-hash[pycryptodome] (>=0.1.4,<1.0.0)", "eth-hash[pycryptodome] (>=0.1.4,<1.0.0)", "eth-hash[pysha3] (>=0.1.4,<1.0.0)", "flake8 (>=3.5.0,<4.0.0)", "py-evm (==0.7.0a4)", "pytest (>=7.0.0)", "pytest-xdist (>=2.0.0,<3)", "towncrier (>=21,<22)", "tox (>=2.9.1,<3.0.0)", "wheel (>=0.30.0,<1.0.0)"] +dev = ["black (>=22,<23)", "bumpversion (>=0.5.3,<1.0.0)", "eth-hash[pycryptodome] (>=0.1.4,<1.0.0)", "eth-hash[pycryptodome] (>=0.1.4,<1.0.0) ; implementation_name == \"pypy\"", "eth-hash[pysha3] (>=0.1.4,<1.0.0) ; implementation_name == \"cpython\"", "flake8 (>=3.5.0,<4.0.0)", "py-evm (==0.7.0a4)", "pytest (>=7.0.0)", "pytest-xdist (>=2.0.0,<3)", "towncrier (>=21,<22)", "tox (>=2.9.1,<3.0.0)", "wheel (>=0.30.0,<1.0.0)"] docs = ["towncrier (>=21,<22)"] lint = ["black (>=22,<23)", "flake8 (>=3.5.0,<4.0.0)"] -py-evm = ["eth-hash[pycryptodome] (>=0.1.4,<1.0.0)", "eth-hash[pysha3] (>=0.1.4,<1.0.0)", "py-evm (==0.7.0a4)"] -pyevm = ["eth-hash[pycryptodome] (>=0.1.4,<1.0.0)", "eth-hash[pysha3] (>=0.1.4,<1.0.0)", "py-evm (==0.7.0a4)"] +py-evm = ["eth-hash[pycryptodome] (>=0.1.4,<1.0.0) ; implementation_name == \"pypy\"", "eth-hash[pysha3] (>=0.1.4,<1.0.0) ; implementation_name == \"cpython\"", "py-evm (==0.7.0a4)"] +pyevm = ["eth-hash[pycryptodome] (>=0.1.4,<1.0.0) ; implementation_name == \"pypy\"", "eth-hash[pysha3] (>=0.1.4,<1.0.0) ; implementation_name == \"cpython\"", "py-evm (==0.7.0a4)"] test = ["eth-hash[pycryptodome] (>=0.1.4,<1.0.0)", "pytest (>=7.0.0)", "pytest-xdist (>=2.0.0,<3)"] [[package]] @@ -1460,7 +1460,7 @@ description = "eth-typing: Common type annotations for ethereum python packages" optional = false python-versions = ">=3.7.2, <4" groups = ["dev", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "eth-typing-3.5.2.tar.gz", hash = "sha256:22bf051ddfaa35ff827c30090de167e5c5b8cc6d343f7f35c9b1c7553f6ab64d"}, {file = "eth_typing-3.5.2-py3-none-any.whl", hash = "sha256:1842e628fb1ffa929b94f89a9d33caafbeb9978dc96abb6036a12bc91f1c624b"}, @@ -1482,7 +1482,7 @@ description = "eth-utils: Common utility functions for python code that interact optional = false python-versions = "<4,>=3.7" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "eth_utils-2.3.2-py3-none-any.whl", hash = "sha256:4470be372674a25b8440b69cb35bda634a079876930853814ea307248c3d198b"}, {file = "eth_utils-2.3.2.tar.gz", hash = "sha256:1986d704b29202386c9bc4b27b948a134320c11c8104c45ca367e4663ae7d10e"}, @@ -1507,7 +1507,7 @@ description = "evm-trace: Ethereum Virtual Machine transaction tracing tool" optional = false python-versions = "<4,>=3.8" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "evm-trace-0.1.3.tar.gz", hash = "sha256:a05da6fb7bc6ad3e5d18527ca0b9cabe929359d7cea07812d5f059b3855b3a4b"}, {file = "evm_trace-0.1.3-py3-none-any.whl", hash = "sha256:b1472ed57baae076ae29567180f3292f6031beb3e220edafc9ab465484b3b602"}, @@ -1533,7 +1533,7 @@ description = "FastAPI framework, high performance, easy to learn, fast to code, optional = false python-versions = ">=3.8" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "fastapi-0.115.7-py3-none-any.whl", hash = "sha256:eb6a8c8bf7f26009e8147111ff15b5177a0e19bb4a45bc3486ab14804539d21e"}, {file = "fastapi-0.115.7.tar.gz", hash = "sha256:0f106da6c01d88a6786b3248fb4d7a940d071f6f488488898ad5d354b25ed015"}, @@ -1555,7 +1555,7 @@ description = "A simple Python wrapper for FFmpeg" optional = false python-versions = "<4.0,>=3.8" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "ffmpy-0.5.0-py3-none-any.whl", hash = "sha256:df3799cf5816daa56d4959a023630ee53c6768b66009dae6d131519ba4b80233"}, {file = "ffmpy-0.5.0.tar.gz", hash = "sha256:277e131f246d18e9dcfee9bb514c50749031c43582ce5ef82c57b51e3d3955c3"}, @@ -1568,7 +1568,7 @@ description = "A platform independent file lock." optional = false python-versions = ">=3.9" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "filelock-3.17.0-py3-none-any.whl", hash = "sha256:533dc2f7ba78dc2f0f531fc6c4940addf7b70a481e269a5a3b93be94ffbe8338"}, {file = "filelock-3.17.0.tar.gz", hash = "sha256:ee4e77401ef576ebb38cd7f13b9b28893194acc20a8e68e18730ba9c0e54660e"}, @@ -1577,7 +1577,27 @@ files = [ [package.extras] docs = ["furo (>=2024.8.6)", "sphinx (>=8.1.3)", "sphinx-autodoc-typehints (>=3)"] testing = ["covdefaults (>=2.3)", "coverage (>=7.6.10)", "diff-cover (>=9.2.1)", "pytest (>=8.3.4)", "pytest-asyncio (>=0.25.2)", "pytest-cov (>=6)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.28.1)"] -typing = ["typing-extensions (>=4.12.2)"] +typing = ["typing-extensions (>=4.12.2) ; python_version < \"3.11\""] + +[[package]] +name = "firecrawl-py" +version = "1.12.0" +description = "Python SDK for Firecrawl API" +optional = false +python-versions = ">=3.8" +groups = ["main"] +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" +files = [ + {file = "firecrawl_py-1.12.0-py3-none-any.whl", hash = "sha256:2b9c549315027da32421aca2a7ca597cb05cdbb968cfe0a89f389c7bb20afa4a"}, + {file = "firecrawl_py-1.12.0.tar.gz", hash = "sha256:bbf883f6c774f05a5426121b85978a5f7b5ab11e614aff609f0673b097c3e553"}, +] + +[package.dependencies] +nest-asyncio = "*" +pydantic = ">=2.10.3" +python-dotenv = "*" +requests = "*" +websockets = "*" [[package]] name = "frozenlist" @@ -1586,7 +1606,7 @@ description = "A list-like structure which implements collections.abc.MutableSeq optional = false python-versions = ">=3.8" groups = ["ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "frozenlist-1.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5b6a66c18b5b9dd261ca98dffcb826a525334b2f29e7caa54e182255c5f6a65a"}, {file = "frozenlist-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d1b3eb7b05ea246510b43a7e53ed1653e55c2121019a97e60cad7efb881a97bb"}, @@ -1689,7 +1709,7 @@ description = "File-system specification" optional = false python-versions = ">=3.8" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "fsspec-2024.12.0-py3-none-any.whl", hash = "sha256:b520aed47ad9804237ff878b504267a3b0b441e97508bd6d2d8774e3db85cee2"}, {file = "fsspec-2024.12.0.tar.gz", hash = "sha256:670700c977ed2fb51e0d9f9253177ed20cbde4a3e5c0283cc5385b5870c8533f"}, @@ -1730,7 +1750,7 @@ description = "Bulletproof concurrent.futures" optional = false python-versions = "*" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "futureproof-0.3.1-py2.py3-none-any.whl", hash = "sha256:849d664cc201c39eb4503e1aa35d81b437e89e99cf34c3960ed106d7bbf6f154"}, {file = "futureproof-0.3.1.tar.gz", hash = "sha256:274365159bfd8b7aa39677abfa7b16c8253a771d72d3c3ee9de4a03c8d6d2d9b"}, @@ -1751,7 +1771,7 @@ description = "gmpy2 interface to GMP, MPFR, and MPC for Python 3.7+" optional = false python-versions = ">=3.7" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "gmpy2-2.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:431d599e1542b6e0b3618d3e296702c25215c97fb461d596e27adbe69d765dc6"}, {file = "gmpy2-2.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5e51848975837751d1038e82d006e8bb488b179f093ba7fc8a59e1d8a2c61663"}, @@ -1815,7 +1835,7 @@ description = "Google API client core library" optional = false python-versions = ">=3.7" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "google_api_core-2.24.1-py3-none-any.whl", hash = "sha256:bc78d608f5a5bf853b80bd70a795f703294de656c096c0968320830a4bc280f1"}, {file = "google_api_core-2.24.1.tar.gz", hash = "sha256:f8b36f5456ab0dd99a1b693a40a31d1e7757beea380ad1b38faaf8941eae9d8a"}, @@ -1827,7 +1847,7 @@ googleapis-common-protos = ">=1.56.2,<2.0.dev0" grpcio = {version = ">=1.49.1,<2.0dev", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""} grpcio-status = {version = ">=1.49.1,<2.0.dev0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""} proto-plus = [ - {version = ">=1.22.3,<2.0.0dev", markers = "python_version < \"3.13\""}, + {version = ">=1.22.3,<2.0.0dev"}, {version = ">=1.25.0,<2.0.0dev", markers = "python_version >= \"3.13\""}, ] protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<6.0.0.dev0" @@ -1835,7 +1855,7 @@ requests = ">=2.18.0,<3.0.0.dev0" [package.extras] async-rest = ["google-auth[aiohttp] (>=2.35.0,<3.0.dev0)"] -grpc = ["grpcio (>=1.33.2,<2.0dev)", "grpcio (>=1.49.1,<2.0dev)", "grpcio-status (>=1.33.2,<2.0.dev0)", "grpcio-status (>=1.49.1,<2.0.dev0)"] +grpc = ["grpcio (>=1.33.2,<2.0dev)", "grpcio (>=1.49.1,<2.0dev) ; python_version >= \"3.11\"", "grpcio-status (>=1.33.2,<2.0.dev0)", "grpcio-status (>=1.49.1,<2.0.dev0) ; python_version >= \"3.11\""] grpcgcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"] grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"] @@ -1846,7 +1866,7 @@ description = "Google Authentication Library" optional = false python-versions = ">=3.7" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "google_auth-2.38.0-py2.py3-none-any.whl", hash = "sha256:e7dae6694313f434a2727bf2906f27ad259bae090d7aa896590d86feec3d9d4a"}, {file = "google_auth-2.38.0.tar.gz", hash = "sha256:8285113607d3b80a3f1543b75962447ba8a09fe85783432a784fdeef6ac094c4"}, @@ -1872,7 +1892,7 @@ description = "Google Cloud Kms API client library" optional = false python-versions = ">=3.7" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "google_cloud_kms-3.2.2-py2.py3-none-any.whl", hash = "sha256:1245ff835b8f4bd8b8b2f5f3832a21f5cfa21dae079a0dae69f2329f5355a6db"}, {file = "google_cloud_kms-3.2.2.tar.gz", hash = "sha256:db4a28aa9414d867402a547111e55980385f920a3d92ddac984e0036a417b704"}, @@ -1883,7 +1903,7 @@ google-api-core = {version = ">=1.34.1,<2.0.dev0 || >=2.11.dev0,<3.0.0dev", extr google-auth = ">=2.14.1,<2.24.0 || >2.24.0,<2.25.0 || >2.25.0,<3.0.0dev" grpc-google-iam-v1 = ">=0.12.4,<1.0.0dev" proto-plus = [ - {version = ">=1.22.3,<2.0.0dev", markers = "python_version < \"3.13\""}, + {version = ">=1.22.3,<2.0.0dev"}, {version = ">=1.25.0,<2.0.0dev", markers = "python_version >= \"3.13\""}, ] protobuf = ">=3.20.2,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<6.0.0dev" @@ -1895,7 +1915,7 @@ description = "Common protobufs used in Google APIs" optional = false python-versions = ">=3.7" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "googleapis_common_protos-1.66.0-py2.py3-none-any.whl", hash = "sha256:d7abcd75fabb2e0ec9f74466401f6c119a0b498e27370e9be4c94cb7e382b8ed"}, {file = "googleapis_common_protos-1.66.0.tar.gz", hash = "sha256:c3e7b33d15fdca5374cc0a7346dd92ffa847425cc4ea941d970f13680052ec8c"}, @@ -1915,7 +1935,7 @@ description = "Python library for easily interacting with trained machine learni optional = false python-versions = ">=3.10" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "gradio-5.13.1-py3-none-any.whl", hash = "sha256:ea5a5f2b1e0cd883211c1a8cc47d52343126e2c313762d26572bfcfb248da299"}, ] @@ -1960,7 +1980,7 @@ description = "Python library for easily interacting with trained machine learni optional = false python-versions = ">=3.10" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "gradio_client-1.6.0-py3-none-any.whl", hash = "sha256:172175510a0cc92928f5d376e95e93f94d1558e4a360969fcc0dfc4c9e313872"}, {file = "gradio_client-1.6.0.tar.gz", hash = "sha256:1c6fae52181d483c010cfbc4e4df8520da33ab4365ab412acabc798d7022ad98"}, @@ -1981,7 +2001,7 @@ description = "IAM API client library" optional = false python-versions = ">=3.7" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "grpc_google_iam_v1-0.14.0-py2.py3-none-any.whl", hash = "sha256:fb4a084b30099ba3ab07d61d620a0d4429570b13ff53bd37bac75235f98b7da4"}, {file = "grpc_google_iam_v1-0.14.0.tar.gz", hash = "sha256:c66e07aa642e39bb37950f9e7f491f70dad150ac9801263b42b2814307c2df99"}, @@ -1999,7 +2019,7 @@ description = "HTTP/2-based RPC framework" optional = false python-versions = ">=3.8" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "grpcio-1.70.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:95469d1977429f45fe7df441f586521361e235982a0b39e33841549143ae2851"}, {file = "grpcio-1.70.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:ed9718f17fbdb472e33b869c77a16d0b55e166b100ec57b016dc7de9c8d236bf"}, @@ -2068,7 +2088,7 @@ description = "Status proto mapping for gRPC" optional = false python-versions = ">=3.8" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "grpcio_status-1.70.0-py3-none-any.whl", hash = "sha256:fc5a2ae2b9b1c1969cc49f3262676e6854aa2398ec69cb5bd6c47cd501904a85"}, {file = "grpcio_status-1.70.0.tar.gz", hash = "sha256:0e7b42816512433b18b9d764285ff029bde059e9d41f8fe10a60631bd8348101"}, @@ -2086,7 +2106,7 @@ description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" optional = false python-versions = ">=3.7" groups = ["ai", "clients", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, @@ -2099,7 +2119,7 @@ description = "hexbytes: Python `bytes` subclass that decodes hex, with a readab optional = false python-versions = ">=3.7, <4" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "hexbytes-0.3.1-py3-none-any.whl", hash = "sha256:383595ad75026cf00abd570f44b368c6cdac0c6becfae5c39ff88829877f8a59"}, {file = "hexbytes-0.3.1.tar.gz", hash = "sha256:a3fe35c6831ee8fafd048c4c086b986075fc14fd46258fa24ecb8d65745f9a9d"}, @@ -2118,7 +2138,7 @@ description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" groups = ["ai", "clients", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, @@ -2141,7 +2161,7 @@ description = "The next generation HTTP client." optional = false python-versions = ">=3.8" groups = ["ai", "clients", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, @@ -2155,7 +2175,7 @@ idna = "*" sniffio = "*" [package.extras] -brotli = ["brotli", "brotlicffi"] +brotli = ["brotli ; platform_python_implementation == \"CPython\"", "brotlicffi ; platform_python_implementation != \"CPython\""] cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] @@ -2168,7 +2188,7 @@ description = "Client library to download and publish models, datasets and other optional = false python-versions = ">=3.8.0" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "huggingface_hub-0.28.0-py3-none-any.whl", hash = "sha256:71cff4e500efe68061d94b7f6d3114e183715088be7a90bf4dd84af83b5f5cdb"}, {file = "huggingface_hub-0.28.0.tar.gz", hash = "sha256:c2b18c02a47d4384763caddb4d0ab2a8fc6c16e0800d6de4d55d0a896244aba3"}, @@ -2204,7 +2224,7 @@ description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.6" groups = ["main", "ai", "clients", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, @@ -2220,7 +2240,7 @@ description = "Read metadata from Python packages" optional = false python-versions = ">=3.9" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "importlib_metadata-8.6.1-py3-none-any.whl", hash = "sha256:02a89390c1e15fdfdc0d7c6b25cb3e62650d0494005c97d6f148bf5b9787525e"}, {file = "importlib_metadata-8.6.1.tar.gz", hash = "sha256:310b41d755445d74569f993ccfc22838295d9fe005425094fad953d7f15c8580"}, @@ -2230,12 +2250,12 @@ files = [ zipp = ">=3.20" [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] enabler = ["pytest-enabler (>=2.2)"] perf = ["ipython"] -test = ["flufl.flake8", "importlib_resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] +test = ["flufl.flake8", "importlib_resources (>=1.3) ; python_version < \"3.9\"", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] type = ["pytest-mypy"] [[package]] @@ -2245,7 +2265,7 @@ description = "brain-dead simple config-ini parsing" optional = false python-versions = ">=3.7" groups = ["dev"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, @@ -2258,7 +2278,7 @@ description = "structured outputs for llm" optional = false python-versions = "<4.0,>=3.9" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "instructor-1.7.2-py3-none-any.whl", hash = "sha256:cb43d27f6d7631c31762b936b2fcb44d2a3f9d8a020430a0f4d3484604ffb95b"}, {file = "instructor-1.7.2.tar.gz", hash = "sha256:6c01b2b159766df24865dc81f7bf8457cbda88a3c0bbc810da3467d19b185ed2"}, @@ -2295,7 +2315,7 @@ description = "A Python utility / library to sort Python imports." optional = false python-versions = ">=3.8.0" groups = ["dev"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, @@ -2311,7 +2331,7 @@ description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" groups = ["ai", "dev"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, @@ -2330,7 +2350,7 @@ description = "Fast iterable JSON parser." optional = false python-versions = ">=3.8" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "jiter-0.8.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:ca8577f6a413abe29b079bc30f907894d7eb07a865c4df69475e868d73e71c7b"}, {file = "jiter-0.8.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b25bd626bde7fb51534190c7e3cb97cee89ee76b76d7585580e22f34f5e3f393"}, @@ -2417,7 +2437,7 @@ description = "A microlibrary that defines a Json type alias for Python." optional = false python-versions = ">=3.7,<4.0" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "jsonalias-0.1.1-py3-none-any.whl", hash = "sha256:a56d2888e6397812c606156504e861e8ec00e188005af149f003c787db3d3f18"}, {file = "jsonalias-0.1.1.tar.gz", hash = "sha256:64f04d935397d579fc94509e1fcb6212f2d081235d9d6395bd10baedf760a769"}, @@ -2430,7 +2450,7 @@ description = "An implementation of JSON Schema validation for Python" optional = false python-versions = ">=3.8" groups = ["ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566"}, {file = "jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4"}, @@ -2453,7 +2473,7 @@ description = "The JSON Schema meta-schemas and vocabularies, exposed as a Regis optional = false python-versions = ">=3.9" groups = ["ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "jsonschema_specifications-2024.10.1-py3-none-any.whl", hash = "sha256:a09a0680616357d9a0ecf05c12ad234479f549239d0f5b55f3deea67475da9bf"}, {file = "jsonschema_specifications-2024.10.1.tar.gz", hash = "sha256:0f38b83639958ce1152d02a7f062902c41c8fd20d558b0c34344292d417ae272"}, @@ -2469,7 +2489,7 @@ description = "Library to easily interface with LLM API providers" optional = false python-versions = "!=2.7.*,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,!=3.7.*,>=3.8" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "litellm-1.55.10-py3-none-any.whl", hash = "sha256:ed5c940105c1953dccb42d376f62de0a417b670f57752e76d6138bba1fba769a"}, {file = "litellm-1.55.10.tar.gz", hash = "sha256:e346f89244d4c9dd79524ab4b6e5fff3ada8488a25382a299aeb9dc6d535fa15"}, @@ -2499,7 +2519,7 @@ description = "An Dict like LRU container." optional = false python-versions = "*" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "lru-dict-1.2.0.tar.gz", hash = "sha256:13c56782f19d68ddf4d8db0170041192859616514c706b126d0df2ec72a11bd7"}, {file = "lru_dict-1.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:de906e5486b5c053d15b7731583c25e3c9147c288ac8152a6d1f9bccdec72641"}, @@ -2595,7 +2615,7 @@ description = "Powerful and Pythonic XML processing library combining libxml2/li optional = false python-versions = ">=3.6" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "lxml-5.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:dd36439be765e2dde7660212b5275641edbc813e7b24668831a5c8ac91180656"}, {file = "lxml-5.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ae5fe5c4b525aa82b8076c1a59d642c17b6e8739ecf852522c6321852178119d"}, @@ -2751,7 +2771,7 @@ description = "Python port of markdown-it. Markdown parsing, done right!" optional = false python-versions = ">=3.8" groups = ["ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, @@ -2777,7 +2797,7 @@ description = "Convert HTML to markdown." optional = false python-versions = "*" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "markdownify-0.14.1-py3-none-any.whl", hash = "sha256:4c46a6c0c12c6005ddcd49b45a5a890398b002ef51380cd319db62df5e09bc2a"}, {file = "markdownify-0.14.1.tar.gz", hash = "sha256:a62a7a216947ed0b8dafb95b99b2ef4a0edd1e18d5653c656f68f03db2bfb2f1"}, @@ -2794,7 +2814,7 @@ description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.7" groups = ["ai", "dev"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, @@ -2865,7 +2885,7 @@ description = "Markdown URL utilities" optional = false python-versions = ">=3.7" groups = ["ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, @@ -2878,7 +2898,7 @@ description = "A fast serialization and validation library, with builtin support optional = false python-versions = ">=3.9" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "msgspec-0.19.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d8dd848ee7ca7c8153462557655570156c2be94e79acec3561cf379581343259"}, {file = "msgspec-0.19.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0553bbc77662e5708fe66aa75e7bd3e4b0f209709c48b299afd791d711a93c36"}, @@ -2919,10 +2939,10 @@ files = [ ] [package.extras] -dev = ["attrs", "coverage", "eval-type-backport", "furo", "ipython", "msgpack", "mypy", "pre-commit", "pyright", "pytest", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "tomli", "tomli_w"] +dev = ["attrs", "coverage", "eval-type-backport ; python_version < \"3.10\"", "furo", "ipython", "msgpack", "mypy", "pre-commit", "pyright", "pytest", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "tomli ; python_version < \"3.11\"", "tomli_w"] doc = ["furo", "ipython", "sphinx", "sphinx-copybutton", "sphinx-design"] -test = ["attrs", "eval-type-backport", "msgpack", "pytest", "pyyaml", "tomli", "tomli_w"] -toml = ["tomli", "tomli_w"] +test = ["attrs", "eval-type-backport ; python_version < \"3.10\"", "msgpack", "pytest", "pyyaml", "tomli ; python_version < \"3.11\"", "tomli_w"] +toml = ["tomli ; python_version < \"3.11\"", "tomli_w"] yaml = ["pyyaml"] [[package]] @@ -2932,7 +2952,7 @@ description = "aggregate results from multiple ethereum contract calls" optional = false python-versions = "<4,>=3.8" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "multicall-0.9.3-py3-none-any.whl", hash = "sha256:bbe9e32f0338e61833ce38f94beeeb8e460b156decd3f75bd2cb9831fdd169c7"}, {file = "multicall-0.9.3.tar.gz", hash = "sha256:fa4454be14b0eb3c37ec00511d506f5f7206e947d1b29faeaaa7c72683967e81"}, @@ -2950,7 +2970,7 @@ description = "multidict implementation" optional = false python-versions = ">=3.8" groups = ["ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "multidict-6.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3380252550e372e8511d49481bd836264c009adb826b23fefcc5dd3c69692f60"}, {file = "multidict-6.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:99f826cbf970077383d7de805c0681799491cb939c25450b9b5b3ced03ca99f1"}, @@ -3053,7 +3073,7 @@ description = "Optional static typing for Python" optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "mypy-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:979e4e1a006511dacf628e36fadfecbcc0160a8af6ca7dad2f5025529e082c13"}, {file = "mypy-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c4bb0e1bd29f7d34efcccd71cf733580191e9a264a2202b0239da95984c5b559"}, @@ -3107,12 +3127,25 @@ description = "Type system extensions for programs checked with the mypy type ch optional = false python-versions = ">=3.5" groups = ["dev", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] +[[package]] +name = "nest-asyncio" +version = "1.6.0" +description = "Patch asyncio to allow nested event loops" +optional = false +python-versions = ">=3.5" +groups = ["main"] +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" +files = [ + {file = "nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c"}, + {file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"}, +] + [[package]] name = "numpy" version = "2.2.2" @@ -3120,7 +3153,7 @@ description = "Fundamental package for array computing in Python" optional = false python-versions = ">=3.10" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "numpy-2.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7079129b64cb78bdc8d611d1fd7e8002c0a2565da6a47c4df8062349fee90e3e"}, {file = "numpy-2.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2ec6c689c61df613b783aeb21f945c4cbe6c51c28cb70aae8430577ab39f163e"}, @@ -3186,7 +3219,7 @@ description = "The official Python library for the openai API" optional = false python-versions = ">=3.8" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "openai-1.58.1-py3-none-any.whl", hash = "sha256:e2910b1170a6b7f88ef491ac3a42c387f08bd3db533411f7ee391d166571d63c"}, {file = "openai-1.58.1.tar.gz", hash = "sha256:f5a035fd01e141fc743f4b0e02c41ca49be8fab0866d3b67f5f29b4f4d3c0973"}, @@ -3213,7 +3246,7 @@ description = "Fast, correct Python JSON library supporting dataclasses, datetim optional = false python-versions = ">=3.8" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "orjson-3.10.15-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:552c883d03ad185f720d0c09583ebde257e41b9521b74ff40e08b7dec4559c04"}, {file = "orjson-3.10.15-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:616e3e8d438d02e4854f70bfdc03a6bcdb697358dbaa6bcd19cbe24d24ece1f8"}, @@ -3303,7 +3336,7 @@ description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" groups = ["ai", "dev", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, @@ -3316,7 +3349,7 @@ description = "Powerful data structures for data analysis, time series, and stat optional = false python-versions = ">=3.9" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "pandas-2.2.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1948ddde24197a0f7add2bdc4ca83bf2b1ef84a1bc8ccffd95eda17fd836ecb5"}, {file = "pandas-2.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:381175499d3802cde0eabbaf6324cce0c4f5d52ca6f8c377c29ad442f50f6348"}, @@ -3403,7 +3436,7 @@ description = "(Soon to be) the fastest pure-Python PEG parser I could muster" optional = false python-versions = "*" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "parsimonious-0.10.0-py3-none-any.whl", hash = "sha256:982ab435fabe86519b57f6b35610aa4e4e977e9f02a14353edf4bbc75369fc0f"}, {file = "parsimonious-0.10.0.tar.gz", hash = "sha256:8281600da180ec8ae35427a4ab4f7b82bfec1e3d1e52f80cb60ea82b9512501c"}, @@ -3419,7 +3452,7 @@ description = "Utility library for gitignore style pattern matching of file path optional = false python-versions = ">=3.8" groups = ["dev"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, @@ -3432,7 +3465,7 @@ description = "Python Imaging Library (Fork)" optional = false python-versions = ">=3.9" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "pillow-11.1.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:e1abe69aca89514737465752b4bcaf8016de61b3be1397a8fc260ba33321b3a8"}, {file = "pillow-11.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c640e5a06869c75994624551f45e5506e4256562ead981cce820d5ab39ae2192"}, @@ -3512,7 +3545,7 @@ docs = ["furo", "olefile", "sphinx (>=8.1)", "sphinx-copybutton", "sphinx-inline fpx = ["olefile"] mic = ["olefile"] tests = ["check-manifest", "coverage (>=7.4.2)", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout", "trove-classifiers (>=2024.10.12)"] -typing = ["typing-extensions"] +typing = ["typing-extensions ; python_version < \"3.10\""] xmp = ["defusedxml"] [[package]] @@ -3522,7 +3555,7 @@ description = "A small Python package for determining appropriate platform-speci optional = false python-versions = ">=3.8" groups = ["dev"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, @@ -3540,7 +3573,7 @@ description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.8" groups = ["dev"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, @@ -3557,7 +3590,7 @@ description = "HTTP client that can impersonate web browsers, mimicking their he optional = false python-versions = ">=3.8" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "primp-0.11.0-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:59f65758dc2b46e5f3512ae1567687fed79c228d4a2b20959671bd1096ba3b49"}, {file = "primp-0.11.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:37c8507dbacb3db162e62af88a81552b8333fc96957a88d1af39c39180b1221d"}, @@ -3580,7 +3613,7 @@ description = "Accelerated property cache" optional = false python-versions = ">=3.9" groups = ["ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "propcache-0.2.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6b3f39a85d671436ee3d12c017f8fdea38509e4f25b28eb25877293c98c243f6"}, {file = "propcache-0.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d51fbe4285d5db5d92a929e3e21536ea3dd43732c5b177c7ef03f918dff9f2"}, @@ -3673,7 +3706,7 @@ description = "Beautiful, Pythonic protocol buffers" optional = false python-versions = ">=3.7" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "proto_plus-1.26.0-py3-none-any.whl", hash = "sha256:bf2dfaa3da281fc3187d12d224c707cb57214fb2c22ba854eb0c105a3fb2d4d7"}, {file = "proto_plus-1.26.0.tar.gz", hash = "sha256:6e93d5f5ca267b54300880fff156b6a3386b3fa3f43b1da62e680fc0c586ef22"}, @@ -3692,7 +3725,7 @@ description = "" optional = false python-versions = ">=3.8" groups = ["ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "protobuf-5.29.3-cp310-abi3-win32.whl", hash = "sha256:3ea51771449e1035f26069c4c7fd51fba990d07bc55ba80701c78f886bf9c888"}, {file = "protobuf-5.29.3-cp310-abi3-win_amd64.whl", hash = "sha256:a4fa6f80816a9a0678429e84973f2f98cbc218cca434abe8db2ad0bffc98503a"}, @@ -3714,7 +3747,7 @@ description = "Cross-platform lib for process and system monitoring in Python." optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "psutil-5.9.8-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:26bd09967ae00920df88e0352a91cff1a78f8d69b3ecabbfe733610c0af486c8"}, {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:05806de88103b25903dff19bb6692bd2e714ccf9e668d050d144012055cbca73"}, @@ -3735,7 +3768,7 @@ files = [ ] [package.extras] -test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] +test = ["enum34 ; python_version <= \"3.4\"", "ipaddress ; python_version < \"3.0\"", "mock ; python_version < \"3.0\"", "pywin32 ; sys_platform == \"win32\"", "wmi ; sys_platform == \"win32\""] [[package]] name = "py-ecc" @@ -3744,7 +3777,7 @@ description = "Elliptic curve crypto in python including secp256k1 and alt_bn128 optional = false python-versions = ">=3.6, <4" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "py_ecc-6.0.0-py3-none-any.whl", hash = "sha256:54e8aa4c30374fa62d582c599a99f352c153f2971352171318bd6910a643be0b"}, {file = "py_ecc-6.0.0.tar.gz", hash = "sha256:3fc8a79e38975e05dc443d25783fd69212a1ca854cc0efef071301a8f7d6ce1d"}, @@ -3768,7 +3801,7 @@ description = "Python implementation of the Ethereum Virtual Machine" optional = false python-versions = "*" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "py-evm-0.7.0a4.tar.gz", hash = "sha256:d40b6ac950485111dc7ad7bd29e3f61e00d5f81dc919e8c2b3afca30f228dc05"}, {file = "py_evm-0.7.0a4-py3-none-any.whl", hash = "sha256:1bf7b293faa70c03727358ae3e5cb0abf7282391461d9b52b82decd6ed18c2f7"}, @@ -3789,12 +3822,12 @@ trie = ">=2.0.0,<3" [package.extras] benchmark = ["termcolor (>=1.1.0,<2.0.0)", "web3 (>=4.1.0,<5.0.0)"] -dev = ["Sphinx (>=1.5.5,<2)", "black (>=23)", "bumpversion (>=0.5.3,<1)", "cached-property (>=1.5.1,<2)", "eth-bloom (>=1.0.3)", "eth-keys (>=0.4.0,<0.5.0)", "eth-typing (>=3.3.0,<4.0.0)", "eth-utils (>=2.0.0,<3.0.0)", "factory-boy (==2.11.1)", "flake8 (==6.0.0)", "flake8-bugbear (==23.3.23)", "hypothesis (>=5,<6)", "idna (==2.7)", "importlib-metadata (<5.0)", "isort (>=5.10.1)", "jinja2 (>=3.0.0,<3.1.0)", "lru-dict (>=1.1.6)", "mypy (==1.4.0)", "mypy-extensions (>=1.0.0)", "pexpect (>=4.6,<5)", "py-ecc (>=1.4.7,<7.0.0)", "py-evm (>=0.2.0-a.14)", "pydocstyle (>=6.0.0)", "pyethash (>=0.1.27,<1.0.0)", "pysha3 (>=1.0.0,<2.0.0)", "pytest (>=6.2.4,<7)", "pytest-asyncio (>=0.10.0,<0.11)", "pytest-cov (==2.5.1)", "pytest-timeout (>=1.4.2,<2)", "pytest-watch (>=4.1.0,<5)", "pytest-xdist (==2.3.0)", "requests (>=2.20,<3)", "rlp (>=3,<4)", "setuptools (>=36.2.0)", "sphinx-rtd-theme (>=0.1.9)", "sphinxcontrib-asyncio (>=0.2.0,<0.4)", "towncrier (>=21,<22)", "tox (>=4.0.0)", "trie (>=2.0.0,<3)", "twine", "types-setuptools", "wheel"] +dev = ["Sphinx (>=1.5.5,<2)", "black (>=23)", "bumpversion (>=0.5.3,<1)", "cached-property (>=1.5.1,<2)", "eth-bloom (>=1.0.3)", "eth-keys (>=0.4.0,<0.5.0)", "eth-typing (>=3.3.0,<4.0.0)", "eth-utils (>=2.0.0,<3.0.0)", "factory-boy (==2.11.1)", "flake8 (==6.0.0)", "flake8-bugbear (==23.3.23)", "hypothesis (>=5,<6)", "idna (==2.7)", "importlib-metadata (<5.0) ; python_version < \"3.8\"", "isort (>=5.10.1)", "jinja2 (>=3.0.0,<3.1.0)", "lru-dict (>=1.1.6)", "mypy (==1.4.0)", "mypy-extensions (>=1.0.0)", "pexpect (>=4.6,<5)", "py-ecc (>=1.4.7,<7.0.0)", "py-evm (>=0.2.0-a.14)", "pydocstyle (>=6.0.0)", "pyethash (>=0.1.27,<1.0.0)", "pysha3 (>=1.0.0,<2.0.0)", "pytest (>=6.2.4,<7)", "pytest-asyncio (>=0.10.0,<0.11)", "pytest-cov (==2.5.1)", "pytest-timeout (>=1.4.2,<2)", "pytest-watch (>=4.1.0,<5)", "pytest-xdist (==2.3.0)", "requests (>=2.20,<3)", "rlp (>=3,<4)", "setuptools (>=36.2.0)", "sphinx-rtd-theme (>=0.1.9)", "sphinxcontrib-asyncio (>=0.2.0,<0.4)", "towncrier (>=21,<22)", "tox (>=4.0.0)", "trie (>=2.0.0,<3)", "twine", "types-setuptools", "wheel"] docs = ["Sphinx (>=1.5.5,<2)", "jinja2 (>=3.0.0,<3.1.0)", "py-evm (>=0.2.0-a.14)", "pysha3 (>=1.0.0,<2.0.0)", "sphinx-rtd-theme (>=0.1.9)", "sphinxcontrib-asyncio (>=0.2.0,<0.4)", "towncrier (>=21,<22)"] eth = ["cached-property (>=1.5.1,<2)", "eth-bloom (>=1.0.3)", "eth-keys (>=0.4.0,<0.5.0)", "eth-typing (>=3.3.0,<4.0.0)", "eth-utils (>=2.0.0,<3.0.0)", "lru-dict (>=1.1.6)", "mypy-extensions (>=1.0.0)", "py-ecc (>=1.4.7,<7.0.0)", "pyethash (>=0.1.27,<1.0.0)", "rlp (>=3,<4)", "trie (>=2.0.0,<3)"] -eth-extra = ["blake2b-py (>=0.1.4,<0.2)", "coincurve (>=13.0.0,<14.0.0)", "eth-hash[pycryptodome]", "eth-hash[pysha3]", "plyvel (>=1.2.0,<2)"] -lint = ["black (>=23)", "flake8 (==6.0.0)", "flake8-bugbear (==23.3.23)", "importlib-metadata (<5.0)", "isort (>=5.10.1)", "mypy (==1.4.0)", "pydocstyle (>=6.0.0)", "types-setuptools"] -test = ["factory-boy (==2.11.1)", "hypothesis (>=5,<6)", "importlib-metadata (<5.0)", "pexpect (>=4.6,<5)", "pytest (>=6.2.4,<7)", "pytest-asyncio (>=0.10.0,<0.11)", "pytest-cov (==2.5.1)", "pytest-timeout (>=1.4.2,<2)", "pytest-watch (>=4.1.0,<5)", "pytest-xdist (==2.3.0)"] +eth-extra = ["blake2b-py (>=0.1.4,<0.2)", "coincurve (>=13.0.0,<14.0.0)", "eth-hash[pycryptodome] ; implementation_name == \"pypy\"", "eth-hash[pysha3] ; implementation_name == \"cpython\"", "plyvel (>=1.2.0,<2)"] +lint = ["black (>=23)", "flake8 (==6.0.0)", "flake8-bugbear (==23.3.23)", "importlib-metadata (<5.0) ; python_version < \"3.8\"", "isort (>=5.10.1)", "mypy (==1.4.0)", "pydocstyle (>=6.0.0)", "types-setuptools"] +test = ["factory-boy (==2.11.1)", "hypothesis (>=5,<6)", "importlib-metadata (<5.0) ; python_version < \"3.8\"", "pexpect (>=4.6,<5)", "pytest (>=6.2.4,<7)", "pytest-asyncio (>=0.10.0,<0.11)", "pytest-cov (==2.5.1)", "pytest-timeout (>=1.4.2,<2)", "pytest-watch (>=4.1.0,<5)", "pytest-xdist (==2.3.0)"] [[package]] name = "py-geth" @@ -3803,7 +3836,7 @@ description = "py-geth: Run Go-Ethereum as a subprocess" optional = false python-versions = "<4,>=3.8" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "py_geth-5.2.0-py3-none-any.whl", hash = "sha256:d317dcc9dd1e045027cbb1098f8af6e1ef2e07b267758467a818e5e808bbeb49"}, {file = "py_geth-5.2.0.tar.gz", hash = "sha256:b8c82f05506edec5cc44665b2023ae2e60b03a05be83c268b41a9ffff1203eba"}, @@ -3828,7 +3861,7 @@ description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs optional = false python-versions = ">=3.8" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629"}, {file = "pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034"}, @@ -3841,7 +3874,7 @@ description = "A collection of ASN.1-based protocols modules" optional = false python-versions = ">=3.8" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "pyasn1_modules-0.4.1-py3-none-any.whl", hash = "sha256:49bfa96b45a292b711e986f222502c1c9a5e1f4e568fc30e2574a6c7d07838fd"}, {file = "pyasn1_modules-0.4.1.tar.gz", hash = "sha256:c28e2dbf9c06ad61c71a075c7e0f9fd0f1b0bb2d2ad4377f240d33ac2ab60a7c"}, @@ -3857,7 +3890,7 @@ description = "C parser in Python" optional = false python-versions = ">=3.8" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\") and platform_python_implementation != \"PyPy\"" +markers = "(implementation_name == \"cpython\" or implementation_name == \"pypy\") and platform_python_implementation != \"PyPy\"" files = [ {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, @@ -3870,7 +3903,7 @@ description = "Cryptographic library for Python" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "pycryptodome-3.21.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:dad9bf36eda068e89059d1f07408e397856be9511d7113ea4b586642a429a4fd"}, {file = "pycryptodome-3.21.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:a1752eca64c60852f38bb29e2c86fca30d7672c024128ef5d70cc15868fa10f4"}, @@ -3913,7 +3946,7 @@ description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" groups = ["main", "ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584"}, {file = "pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236"}, @@ -3926,7 +3959,7 @@ typing-extensions = ">=4.12.2" [package.extras] email = ["email-validator (>=2.0.0)"] -timezone = ["tzdata"] +timezone = ["tzdata ; python_version >= \"3.9\" and platform_system == \"Windows\""] [[package]] name = "pydantic-core" @@ -3935,7 +3968,7 @@ description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" groups = ["main", "ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa"}, {file = "pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c"}, @@ -4049,7 +4082,7 @@ description = "Settings management using Pydantic" optional = false python-versions = ">=3.8" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "pydantic_settings-2.7.1-py3-none-any.whl", hash = "sha256:590be9e6e24d06db33a4262829edef682500ef008565a969c73d39d5f8bfb3fd"}, {file = "pydantic_settings-2.7.1.tar.gz", hash = "sha256:10c9caad35e64bfb3c2fbf70a078c0e25cc92499782e5200747f942a065dec93"}, @@ -4071,7 +4104,7 @@ description = "Manipulate audio with an simple and easy high level interface" optional = false python-versions = "*" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "pydub-0.25.1-py2.py3-none-any.whl", hash = "sha256:65617e33033874b59d87db603aa1ed450633288aefead953b30bded59cb599a6"}, {file = "pydub-0.25.1.tar.gz", hash = "sha256:980a33ce9949cab2a569606b65674d748ecbca4f0796887fd6f46173a7b0d30f"}, @@ -4084,7 +4117,7 @@ description = "Python wrappers for ethash, the ethereum proof of workhashing fun optional = false python-versions = "*" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "pyethash-0.1.27.tar.gz", hash = "sha256:ff66319ce26b9d77df1f610942634dac9742e216f2c27b051c0a2c2dec9c2818"}, ] @@ -4096,7 +4129,7 @@ description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.8" groups = ["ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c"}, {file = "pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f"}, @@ -4112,7 +4145,7 @@ description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" groups = ["dev"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, @@ -4134,7 +4167,7 @@ description = "Pytest plugin for measuring coverage." optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "pytest-cov-6.0.0.tar.gz", hash = "sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0"}, {file = "pytest_cov-6.0.0-py3-none-any.whl", hash = "sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35"}, @@ -4154,7 +4187,7 @@ description = "pytest plugin for generating HTML reports" optional = false python-versions = ">=3.8" groups = ["dev"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "pytest_html-4.1.1-py3-none-any.whl", hash = "sha256:c8152cea03bd4e9bee6d525573b67bbc6622967b72b9628dda0ea3e2a0b5dd71"}, {file = "pytest_html-4.1.1.tar.gz", hash = "sha256:70a01e8ae5800f4a074b56a4cb1025c8f4f9b038bba5fe31e3c98eb996686f07"}, @@ -4176,7 +4209,7 @@ description = "pytest plugin for test session metadata" optional = false python-versions = ">=3.8" groups = ["dev"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "pytest_metadata-3.1.1-py3-none-any.whl", hash = "sha256:c8e0844db684ee1c798cfa38908d20d67d0463ecb6137c72e91f418558dd5f4b"}, {file = "pytest_metadata-3.1.1.tar.gz", hash = "sha256:d2a29b0355fbc03f168aa96d41ff88b1a3b44a3b02acbe491801c98a048017c8"}, @@ -4195,7 +4228,7 @@ description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, @@ -4210,8 +4243,8 @@ version = "1.0.1" description = "Read key-value pairs from a .env file and set them as environment variables" optional = false python-versions = ">=3.8" -groups = ["ai", "dev", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +groups = ["main", "ai", "dev", "web3"] +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"}, {file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"}, @@ -4227,7 +4260,7 @@ description = "A streaming multipart parser for Python" optional = false python-versions = ">=3.8" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104"}, {file = "python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13"}, @@ -4240,7 +4273,7 @@ description = "We have made you a wrapper you can't refuse" optional = false python-versions = ">=3.9" groups = ["clients"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "python_telegram_bot-21.10-py3-none-any.whl", hash = "sha256:c874d2461d6bfa4b05c314cf6116cf1dafe537689aa8249924dd988603b6ba21"}, {file = "python_telegram_bot-21.10.tar.gz", hash = "sha256:40481a8c4814ce2e530a21ce45d389695b0b210c5fb9dc75b8529aba8c9e76f8"}, @@ -4250,12 +4283,12 @@ files = [ httpx = ">=0.27,<1.0" [package.extras] -all = ["aiolimiter (>=1.1,<1.3)", "apscheduler (>=3.10.4,<3.12.0)", "cachetools (>=5.3.3,<5.6.0)", "cffi (>=1.17.0rc1)", "cryptography (>=39.0.1)", "httpx[http2]", "httpx[socks]", "tornado (>=6.4,<7.0)"] +all = ["aiolimiter (>=1.1,<1.3)", "apscheduler (>=3.10.4,<3.12.0)", "cachetools (>=5.3.3,<5.6.0)", "cffi (>=1.17.0rc1) ; python_version > \"3.12\"", "cryptography (>=39.0.1)", "httpx[http2]", "httpx[socks]", "tornado (>=6.4,<7.0)"] callback-data = ["cachetools (>=5.3.3,<5.6.0)"] ext = ["aiolimiter (>=1.1,<1.3)", "apscheduler (>=3.10.4,<3.12.0)", "cachetools (>=5.3.3,<5.6.0)", "tornado (>=6.4,<7.0)"] http2 = ["httpx[http2]"] job-queue = ["apscheduler (>=3.10.4,<3.12.0)"] -passport = ["cffi (>=1.17.0rc1)", "cryptography (>=39.0.1)"] +passport = ["cffi (>=1.17.0rc1) ; python_version > \"3.12\"", "cryptography (>=39.0.1)"] rate-limiter = ["aiolimiter (>=1.1,<1.3)"] socks = ["httpx[socks]"] webhooks = ["tornado (>=6.4,<7.0)"] @@ -4267,7 +4300,7 @@ description = "World timezone definitions, modern and historical" optional = false python-versions = "*" groups = ["ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725"}, {file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"}, @@ -4280,7 +4313,7 @@ description = "Unicode normalization forms (NFC, NFKC, NFD, NFKD). A library ind optional = false python-versions = ">=3.6" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "pyunormalize-16.0.0-py3-none-any.whl", hash = "sha256:c647d95e5d1e2ea9a2f448d1d95d8518348df24eab5c3fd32d2b5c3300a49152"}, {file = "pyunormalize-16.0.0.tar.gz", hash = "sha256:2e1dfbb4a118154ae26f70710426a52a364b926c9191f764601f5a8cb12761f7"}, @@ -4293,7 +4326,7 @@ description = "Python for Window Extensions" optional = false python-versions = "*" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\") and platform_system == \"Windows\"" +markers = "(implementation_name == \"cpython\" or implementation_name == \"pypy\") and platform_system == \"Windows\"" files = [ {file = "pywin32-308-cp310-cp310-win32.whl", hash = "sha256:796ff4426437896550d2981b9c2ac0ffd75238ad9ea2d3bfa67a1abd546d262e"}, {file = "pywin32-308-cp310-cp310-win_amd64.whl", hash = "sha256:4fc888c59b3c0bef905ce7eb7e2106a07712015ea1c8234b703a088d46110e8e"}, @@ -4322,7 +4355,7 @@ description = "YAML parser and emitter for Python" optional = false python-versions = ">=3.8" groups = ["main", "ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, @@ -4386,7 +4419,7 @@ description = "JSON Referencing + Python" optional = false python-versions = ">=3.9" groups = ["ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "referencing-0.36.2-py3-none-any.whl", hash = "sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0"}, {file = "referencing-0.36.2.tar.gz", hash = "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa"}, @@ -4404,7 +4437,7 @@ description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" groups = ["ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, @@ -4509,7 +4542,7 @@ description = "Python HTTP for Humans." optional = false python-versions = ">=3.8" groups = ["main", "ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, @@ -4532,7 +4565,7 @@ description = "Render rich text, tables, progress bars, syntax highlighting, mar optional = false python-versions = ">=3.8.0" groups = ["ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90"}, {file = "rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098"}, @@ -4552,7 +4585,7 @@ description = "A package for Recursive Length Prefix encoding and decoding" optional = false python-versions = "*" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "rlp-3.0.0-py2.py3-none-any.whl", hash = "sha256:d2a963225b3f26795c5b52310e0871df9824af56823d739511583ef459895a7d"}, {file = "rlp-3.0.0.tar.gz", hash = "sha256:63b0465d2948cd9f01de449d7adfb92d207c1aef3982f20310f8009be4a507e8"}, @@ -4575,7 +4608,7 @@ description = "Python bindings to Rust's persistent data structures (rpds)" optional = false python-versions = ">=3.9" groups = ["ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "rpds_py-0.22.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:6c7b99ca52c2c1752b544e310101b98a659b720b21db00e65edca34483259967"}, {file = "rpds_py-0.22.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:be2eb3f2495ba669d2a985f9b426c1797b7d48d6963899276d22f23e33d47e37"}, @@ -4689,7 +4722,7 @@ description = "Pure-Python RSA implementation" optional = false python-versions = ">=3.6,<4" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "rsa-4.9-py3-none-any.whl", hash = "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7"}, {file = "rsa-4.9.tar.gz", hash = "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21"}, @@ -4705,7 +4738,7 @@ description = "An extremely fast Python linter and code formatter, written in Ru optional = false python-versions = ">=3.7" groups = ["ai", "dev"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "ruff-0.9.5-py3-none-linux_armv6l.whl", hash = "sha256:d466d2abc05f39018d53f681fa1c0ffe9570e6d73cde1b65d23bb557c846f442"}, {file = "ruff-0.9.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:38840dbcef63948657fa7605ca363194d2fe8c26ce8f9ae12eee7f098c85ac8a"}, @@ -4734,7 +4767,7 @@ description = "Safe Ecosystem Foundation utilities for Ethereum projects" optional = false python-versions = ">=3.10" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "safe_eth_py-6.0.0b42-py3-none-any.whl", hash = "sha256:dd7e57bd9c817ac25b241aeae5c5ccf201af0a7e21b6d9c0a6b2b1ded382457e"}, {file = "safe_eth_py-6.0.0b42.tar.gz", hash = "sha256:425c7f630b20576871434c720dd07eff7fdab4a7438b7614c35582500220fb0d"}, @@ -4757,7 +4790,7 @@ description = "SHA-3 (Keccak) for Python 3.9 - 3.11" optional = false python-versions = "*" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "safe-pysha3-1.0.4.tar.gz", hash = "sha256:e429146b1edd198b2ca934a2046a65656c5d31b0ec894bbd6055127f4deaff17"}, ] @@ -4769,7 +4802,7 @@ description = "A small Python library created to help developers protect their a optional = false python-versions = ">3.9" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "safehttpx-0.1.6-py3-none-any.whl", hash = "sha256:407cff0b410b071623087c63dd2080c3b44dc076888d8c5823c00d1e58cb381c"}, {file = "safehttpx-0.1.6.tar.gz", hash = "sha256:b356bfc82cee3a24c395b94a2dbeabbed60aff1aa5fa3b5fe97c4f2456ebce42"}, @@ -4788,7 +4821,7 @@ description = "" optional = false python-versions = ">=3.7" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "safetensors-0.5.2-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:45b6092997ceb8aa3801693781a71a99909ab9cc776fbc3fa9322d29b1d3bef2"}, {file = "safetensors-0.5.2-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:6d0d6a8ee2215a440e1296b843edf44fd377b055ba350eaba74655a2fe2c4bae"}, @@ -4827,14 +4860,14 @@ description = "A library implementing the 'SemVer' scheme." optional = false python-versions = ">=2.7" groups = ["ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "semantic_version-2.10.0-py2.py3-none-any.whl", hash = "sha256:de78a3b8e0feda74cabc54aab2da702113e33ac9d9eb9d2389bcf1f58b7d9177"}, {file = "semantic_version-2.10.0.tar.gz", hash = "sha256:bdabb6d336998cbb378d4b9db3a4b56a1e3235701dc05ea2690d9a997ed5041c"}, ] [package.extras] -dev = ["Django (>=1.11)", "check-manifest", "colorama (<=0.4.1)", "coverage", "flake8", "nose2", "readme-renderer (<25.0)", "tox", "wheel", "zest.releaser[recommended]"] +dev = ["Django (>=1.11)", "check-manifest", "colorama (<=0.4.1) ; python_version == \"3.4\"", "coverage", "flake8", "nose2", "readme-renderer (<25.0) ; python_version == \"3.4\"", "tox", "wheel", "zest.releaser[recommended]"] doc = ["Sphinx", "sphinx-rtd-theme"] [[package]] @@ -4844,7 +4877,7 @@ description = "Easily download, build, install, upgrade, and uninstall Python pa optional = false python-versions = ">=3.8" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "setuptools-70.0.0-py3-none-any.whl", hash = "sha256:54faa7f2e8d2d11bcd2c07bed282eef1046b5c080d1c32add737d7b5817b1ad4"}, {file = "setuptools-70.0.0.tar.gz", hash = "sha256:f211a66637b8fa059bb28183da127d4e86396c991a942b028c6650d4319c3fd0"}, @@ -4852,7 +4885,7 @@ files = [ [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21) ; python_version >= \"3.9\" and sys_platform != \"cygwin\"", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov ; platform_python_implementation != \"PyPy\"", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf ; sys_platform != \"cygwin\"", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\"", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "shellingham" @@ -4861,7 +4894,7 @@ description = "Tool to Detect Surrounding Shell" optional = false python-versions = ">=3.7" groups = ["ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"}, {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"}, @@ -4874,7 +4907,7 @@ description = "Python library for rounding numbers (with expected results)" optional = false python-versions = "<4.0,>=3.6" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "sigfig-1.3.18-py3-none-any.whl", hash = "sha256:cf423c85734b80917ac2f5150d9f5c4e06e77abdece0602f2ea2d2cef45bc0f3"}, {file = "sigfig-1.3.18.tar.gz", hash = "sha256:7c1e4cc10ae61f99a0bb0a96e0a5b1a4907570d5974016cb18d317f92ee36b5c"}, @@ -4890,7 +4923,7 @@ description = "Python 2 and 3 compatibility utilities" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" groups = ["ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, @@ -4903,7 +4936,7 @@ description = "🤗 smolagents: a barebones library for agents. Agents write pyt optional = false python-versions = ">=3.10" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "smolagents-1.2.2-py3-none-any.whl", hash = "sha256:d2fd4aeda810e7812e24467fc6adeb5184259ec98a314838a07a605ed1ade40a"}, {file = "smolagents-1.2.2.tar.gz", hash = "sha256:03fd4990f2bb850cd6e06aa100496c7635995a8d954da9485d31ba78f8ca53a8"}, @@ -4934,7 +4967,7 @@ description = "Sniff out which async library your code is running under" optional = false python-versions = ">=3.7" groups = ["ai", "clients", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, @@ -4947,7 +4980,7 @@ description = "Solana Python API" optional = false python-versions = "<4.0,>=3.9" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "solana-0.36.0-py3-none-any.whl", hash = "sha256:b12b97986c080e22f1310fe7ce1aac7e5c9914c783844b9ee66fe9ddcee9776d"}, {file = "solana-0.36.0.tar.gz", hash = "sha256:971b807e09f7ca4795c862d84d05b70e601fd797647ff35e50834d5938ea0fe2"}, @@ -4967,7 +5000,7 @@ description = "Python bindings for Solana Rust tools" optional = false python-versions = ">=3.7" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "solders-0.23.0-cp37-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:87c2865f4f634abf56cc3fe9cfea985ddd0a09097d01b7716ed83ff6ef2ad1c6"}, {file = "solders-0.23.0-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:183fdc05ed0d6004d24bef17c01794a17be4a90f71c31429207bf33ec2e7738d"}, @@ -4991,7 +5024,7 @@ description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" optional = false python-versions = "*" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0"}, {file = "sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88"}, @@ -5004,7 +5037,7 @@ description = "A modern CSS selector implementation for Beautiful Soup." optional = false python-versions = ">=3.8" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9"}, {file = "soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb"}, @@ -5017,7 +5050,7 @@ description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple optional = false python-versions = ">=3.8" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "sphinxcontrib-applehelp-1.0.4.tar.gz", hash = "sha256:828f867945bbe39817c210a1abfd1bc4895c8b73fcaade56d45357a348a07d7e"}, {file = "sphinxcontrib_applehelp-1.0.4-py3-none-any.whl", hash = "sha256:29d341f67fb0f6f586b23ad80e072c8e6ad0b48417db2bde114a4c9746feb228"}, @@ -5034,7 +5067,7 @@ description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp optional = false python-versions = ">=3.5" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, @@ -5051,7 +5084,7 @@ description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML h optional = false python-versions = ">=3.8" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "sphinxcontrib-htmlhelp-2.0.1.tar.gz", hash = "sha256:0cbdd302815330058422b98a113195c9249825d681e18f11e8b1f78a2f11efff"}, {file = "sphinxcontrib_htmlhelp-2.0.1-py3-none-any.whl", hash = "sha256:c38cb46dccf316c79de6e5515e1770414b797162b23cd3d06e67020e1d2a6903"}, @@ -5068,7 +5101,7 @@ description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp d optional = false python-versions = ">=3.5" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, @@ -5085,7 +5118,7 @@ description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs optional = false python-versions = ">=3.5" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"}, {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, @@ -5102,7 +5135,7 @@ description = "The little ASGI library that shines." optional = false python-versions = ">=3.9" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "starlette-0.45.3-py3-none-any.whl", hash = "sha256:dfb6d332576f136ec740296c7e8bb8c8a7125044e7c6da30744718880cdd059d"}, {file = "starlette-0.45.3.tar.gz", hash = "sha256:2cbcba2a75806f8a41c722141486f37c28e30a0921c5f6fe4346cb0dcee1302f"}, @@ -5121,7 +5154,7 @@ description = "Retry code until it succeeds" optional = false python-versions = ">=3.8" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "tenacity-9.0.0-py3-none-any.whl", hash = "sha256:93de0c98785b27fcf659856aa9f54bfbd399e29969b0621bc7f762bd441b4539"}, {file = "tenacity-9.0.0.tar.gz", hash = "sha256:807f37ca97d62aa361264d497b0e31e92b8027044942bfa756160d908320d73b"}, @@ -5138,7 +5171,7 @@ description = "tiktoken is a fast BPE tokeniser for use with OpenAI's models" optional = false python-versions = ">=3.9" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "tiktoken-0.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b07e33283463089c81ef1467180e3e00ab00d46c2c4bbcef0acab5f771d6695e"}, {file = "tiktoken-0.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9269348cb650726f44dd3bbb3f9110ac19a8dcc8f54949ad3ef652ca22a38e21"}, @@ -5187,7 +5220,7 @@ description = "" optional = false python-versions = ">=3.7" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "tokenizers-0.21.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:3c4c93eae637e7d2aaae3d376f06085164e1660f89304c0ab2b1d08a406636b2"}, {file = "tokenizers-0.21.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:f53ea537c925422a2e0e92a24cce96f6bc5046bbef24a1652a5edc8ba975f62e"}, @@ -5221,7 +5254,7 @@ description = "Style preserving TOML library" optional = false python-versions = ">=3.8" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde"}, {file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"}, @@ -5234,7 +5267,7 @@ description = "List processing tools and functional utilities" optional = false python-versions = ">=3.8" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "toolz-1.0.0-py3-none-any.whl", hash = "sha256:292c8f1c4e7516bf9086f8850935c799a874039c8bcf959d47b600e4c44a6236"}, {file = "toolz-1.0.0.tar.gz", hash = "sha256:2c86e3d9a04798ac556793bced838816296a2f085017664e4995cb40a1047a02"}, @@ -5247,7 +5280,7 @@ description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" groups = ["ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, @@ -5270,7 +5303,7 @@ description = "TQDM progress bar helpers for logging and other headless applicat optional = false python-versions = ">3.8" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "tqdm_loggable-0.2-py3-none-any.whl", hash = "sha256:9703046302b93a667166487759e6f3f49597e86c89eb132ba1f31caa07bf0941"}, {file = "tqdm_loggable-0.2.tar.gz", hash = "sha256:175abec3e1f63bbd2eac192fa5da075e80c7bb715d7ccf3cd1a29b7ab5af0617"}, @@ -5286,7 +5319,7 @@ description = "State-of-the-art Machine Learning for JAX, PyTorch and TensorFlow optional = false python-versions = ">=3.9.0" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "transformers-4.47.1-py3-none-any.whl", hash = "sha256:d2f5d19bb6283cd66c893ec7e6d931d6370bbf1cc93633326ff1f41a40046c9c"}, {file = "transformers-4.47.1.tar.gz", hash = "sha256:6c29c05a5f595e278481166539202bf8641281536df1c42357ee58a45d0a564a"}, @@ -5357,7 +5390,7 @@ description = "Python implementation of the Ethereum Trie structure" optional = false python-versions = ">=3.7, <4" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "trie-2.2.0-py3-none-any.whl", hash = "sha256:b6ad00305722b271cd05c9475e741c92a61f0ca53e6cc4fa9a5591e37eac34ca"}, {file = "trie-2.2.0.tar.gz", hash = "sha256:117a6f0844eb60f2f68ed45e621886690dacd16343394c1adfb3ff44231725bc"}, @@ -5371,7 +5404,7 @@ rlp = ">=3" sortedcontainers = ">=2.1.0" [package.extras] -dev = ["build (>=0.9.0)", "bumpversion (>=0.5.3)", "eth-hash (>=0.1.0,<1.0.0)", "hypothesis (>=6.56.4,<7)", "ipython", "pre-commit (>=3.4.0)", "pycryptodome", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)", "towncrier (>=21,<22)", "tox (>=4.0.0)", "twine", "wheel"] +dev = ["build (>=0.9.0)", "bumpversion (>=0.5.3)", "eth-hash (>=0.1.0,<1.0.0)", "hypothesis (>=6.56.4,<7)", "ipython", "pre-commit (>=3.4.0) ; python_version > \"3.7\"", "pycryptodome", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)", "towncrier (>=21,<22)", "tox (>=4.0.0)", "twine", "wheel"] docs = ["towncrier (>=21,<22)"] test = ["hypothesis (>=6.56.4,<7)", "pycryptodome", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)"] @@ -5382,7 +5415,7 @@ description = "Typer, build great CLIs. Easy to code. Based on Python type hints optional = false python-versions = ">=3.7" groups = ["ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "typer-0.15.1-py3-none-any.whl", hash = "sha256:7994fb7b8155b64d3402518560648446072864beefd44aa2dc36972a5972e847"}, {file = "typer-0.15.1.tar.gz", hash = "sha256:a0588c0a7fa68a1978a069818657778f86abe6ff5ea6abf472f940a08bfe4f0a"}, @@ -5401,7 +5434,7 @@ description = "Typing stubs for PyYAML" optional = false python-versions = ">=3.8" groups = ["dev"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "types_PyYAML-6.0.12.20241230-py3-none-any.whl", hash = "sha256:fa4d32565219b68e6dee5f67534c722e53c00d1cfc09c435ef04d7353e1e96e6"}, {file = "types_pyyaml-6.0.12.20241230.tar.gz", hash = "sha256:7f07622dbd34bb9c8b264fe860a17e0efcad00d50b5f27e93984909d9363498c"}, @@ -5414,7 +5447,7 @@ description = "Typing stubs for requests" optional = false python-versions = ">=3.8" groups = ["dev", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "types-requests-2.32.0.20241016.tar.gz", hash = "sha256:0d9cad2f27515d0e3e3da7134a1b6f28fb97129d86b867f24d9c726452634d95"}, {file = "types_requests-2.32.0.20241016-py3-none-any.whl", hash = "sha256:4195d62d6d3e043a4eaaf08ff8a62184584d2e8684e9d2aa178c7915a7da3747"}, @@ -5434,7 +5467,7 @@ files = [ {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] -markers = {main = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")", ai = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")", clients = "(python_version == \"3.11\" or python_version >= \"3.12\") and python_version < \"3.13\" and (implementation_name == \"cpython\" or implementation_name == \"pypy\")", dev = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")", web3 = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")"} +markers = {main = "implementation_name == \"cpython\" or implementation_name == \"pypy\"", ai = "implementation_name == \"cpython\" or implementation_name == \"pypy\"", clients = "(python_version == \"3.11\" or python_version == \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")", dev = "implementation_name == \"cpython\" or implementation_name == \"pypy\"", web3 = "implementation_name == \"cpython\" or implementation_name == \"pypy\""} [[package]] name = "tzdata" @@ -5443,7 +5476,7 @@ description = "Provider of IANA time zone data" optional = false python-versions = ">=2" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "tzdata-2025.1-py2.py3-none-any.whl", hash = "sha256:7e127113816800496f027041c570f50bcd464a020098a3b6b199517772303639"}, {file = "tzdata-2025.1.tar.gz", hash = "sha256:24894909e88cdb28bd1636c6887801df64cb485bd593f2fd83ef29075a81d694"}, @@ -5456,7 +5489,7 @@ description = "Ultra fast JSON encoder and decoder for Python" optional = false python-versions = ">=3.8" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "ujson-5.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2601aa9ecdbee1118a1c2065323bda35e2c5a2cf0797ef4522d485f9d3ef65bd"}, {file = "ujson-5.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:348898dd702fc1c4f1051bc3aacbf894caa0927fe2c53e68679c073375f732cf"}, @@ -5545,14 +5578,14 @@ description = "HTTP library with thread-safe connection pooling, file post, and optional = false python-versions = ">=3.9" groups = ["main", "ai", "dev", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] @@ -5564,7 +5597,7 @@ description = "The lightning-fast ASGI server." optional = false python-versions = ">=3.9" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\") and sys_platform != \"emscripten\"" +markers = "(implementation_name == \"cpython\" or implementation_name == \"pypy\") and sys_platform != \"emscripten\"" files = [ {file = "uvicorn-0.34.0-py3-none-any.whl", hash = "sha256:023dc038422502fa28a09c7a30bf2b6991512da7dcdb8fd35fe57cfc154126f4"}, {file = "uvicorn-0.34.0.tar.gz", hash = "sha256:404051050cd7e905de2c9a7e61790943440b3416f49cb409f965d9dcd0fa73e9"}, @@ -5575,7 +5608,7 @@ click = ">=7.0" h11 = ">=0.8" [package.extras] -standard = ["colorama (>=0.4)", "httptools (>=0.6.3)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] +standard = ["colorama (>=0.4) ; sys_platform == \"win32\"", "httptools (>=0.6.3)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1) ; sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\"", "watchfiles (>=0.13)", "websockets (>=10.4)"] [[package]] name = "web3" @@ -5584,7 +5617,7 @@ description = "web3.py" optional = false python-versions = ">=3.7.2" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "web3-6.14.0-py3-none-any.whl", hash = "sha256:e7023669ea05d6c9675d25e14342638da25d9b1a512d8a6472b860ed97914aec"}, {file = "web3-6.14.0.tar.gz", hash = "sha256:a3726289da9eff2ce30f9b1b49ec59e9245216f7aecbfa2007f73dbe94999717"}, @@ -5610,7 +5643,7 @@ typing-extensions = ">=4.0.1" websockets = ">=10.0.0" [package.extras] -dev = ["black (>=22.1.0)", "build (>=0.9.0)", "bumpversion", "eth-tester[py-evm] (==v0.9.1-b.1)", "flake8 (==3.8.3)", "flaky (>=3.7.0)", "hypothesis (>=3.31.2)", "importlib-metadata (<5.0)", "ipfshttpclient (==0.8.0a2)", "isort (>=5.11.0)", "mypy (==1.4.1)", "py-geth (>=3.11.0)", "pytest (>=7.0.0)", "pytest-asyncio (>=0.18.1,<0.23)", "pytest-mock (>=1.10)", "pytest-watch (>=4.2)", "pytest-xdist (>=1.29)", "setuptools (>=38.6.0)", "sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)", "tox (>=3.18.0)", "tqdm (>4.32)", "twine (>=1.13)", "types-protobuf (==3.19.13)", "types-requests (>=2.26.1)", "types-setuptools (>=57.4.4)", "when-changed (>=0.3.0)"] +dev = ["black (>=22.1.0)", "build (>=0.9.0)", "bumpversion", "eth-tester[py-evm] (==v0.9.1-b.1)", "flake8 (==3.8.3)", "flaky (>=3.7.0)", "hypothesis (>=3.31.2)", "importlib-metadata (<5.0) ; python_version < \"3.8\"", "ipfshttpclient (==0.8.0a2)", "isort (>=5.11.0)", "mypy (==1.4.1)", "py-geth (>=3.11.0)", "pytest (>=7.0.0)", "pytest-asyncio (>=0.18.1,<0.23)", "pytest-mock (>=1.10)", "pytest-watch (>=4.2)", "pytest-xdist (>=1.29)", "setuptools (>=38.6.0)", "sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)", "tox (>=3.18.0)", "tqdm (>4.32)", "twine (>=1.13)", "types-protobuf (==3.19.13)", "types-requests (>=2.26.1)", "types-setuptools (>=57.4.4)", "when-changed (>=0.3.0)"] docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)"] ipfs = ["ipfshttpclient (==0.8.0a2)"] linter = ["black (>=22.1.0)", "flake8 (==3.8.3)", "isort (>=5.11.0)", "mypy (==1.4.1)", "types-protobuf (==3.19.13)", "types-requests (>=2.26.1)", "types-setuptools (>=57.4.4)"] @@ -5623,7 +5656,7 @@ description = "Python library for Uniswap, Aave, ChainLink, Enzyme and other pro optional = false python-versions = "<4,>=3.10" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "web3_ethereum_defi-0.28-py3-none-any.whl", hash = "sha256:bddcfc565bed223038a2b57163004186da8c2ad1a4755b50b7b18c044fc88476"}, {file = "web3_ethereum_defi-0.28.tar.gz", hash = "sha256:f311ede0a74f5cce3c16d8095a1096c66d7beb5e4d0b5a00bd788beeaedf6c6e"}, @@ -5663,7 +5696,7 @@ description = "Cloud HSM to sign Web3.py Ethereum transactions" optional = false python-versions = ">=3.10" groups = ["web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "web3_google_hsm-0.1.0-py3-none-any.whl", hash = "sha256:770158608e121cc3caaa51452794f856b3a3ed6d2a740f551c1eab451e7aabb1"}, {file = "web3_google_hsm-0.1.0.tar.gz", hash = "sha256:37107455b35888537dd20731d78aefc3137800bb6c0dab4b967f3d76b7fe9d42"}, @@ -5689,8 +5722,8 @@ version = "12.0" description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" optional = false python-versions = ">=3.8" -groups = ["ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +groups = ["main", "ai", "web3"] +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "websockets-12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374"}, {file = "websockets-12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be"}, @@ -5773,7 +5806,7 @@ description = "Yet another URL library" optional = false python-versions = ">=3.9" groups = ["ai", "web3"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7df647e8edd71f000a5208fe6ff8c382a1de8edfbccdbbfe649d263de07d8c34"}, {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c69697d3adff5aa4f874b19c0e4ed65180ceed6318ec856ebc423aa5850d84f7"}, @@ -5871,21 +5904,21 @@ description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.9" groups = ["ai"] -markers = "(python_version == \"3.11\" or python_version >= \"3.12\") and (implementation_name == \"cpython\" or implementation_name == \"pypy\")" +markers = "implementation_name == \"cpython\" or implementation_name == \"pypy\"" files = [ {file = "zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931"}, {file = "zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] enabler = ["pytest-enabler (>=2.2)"] -test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] +test = ["big-O", "importlib-resources ; python_version < \"3.9\"", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] type = ["pytest-mypy"] [metadata] lock-version = "2.1" python-versions = ">=3.11,<4.0" -content-hash = "e35caba57e8b42340a24aabff8efae1d20589310a333ab3290b93f2eab79bdb0" +content-hash = "39311d7bac25abd50ec4c32e9660593fb73abe2ea5fd4bb8c620c15de01c61e0" diff --git a/pyproject.toml b/pyproject.toml index a9e0bef0..6246583c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,6 +17,7 @@ dependencies = [ "requests (>=2.32.3,<3.0.0)", "pyyaml (>=6.0.0,<7.0.0)", "pydantic (>=2.0.0,<3.0.0)", + "firecrawl-py (>=1.12.0,<2.0.0)", ] [tool.poetry.group.ai.dependencies]