From 1a825db7a209880e110f5747992e4600fd176777 Mon Sep 17 00:00:00 2001 From: Gabriel Fior Date: Thu, 30 May 2024 18:19:55 +0200 Subject: [PATCH 1/8] First skeleton for omen_buy_yes_tokens --- packages/gnosis/__init__.py | 19 + packages/gnosis/customs/__init__.py | 19 + .../gnosis/customs/omen_buy_yes/__init__.py | 20 + .../customs/omen_buy_yes/component.yaml | 21 ++ .../customs/omen_buy_yes/omen_buy_yes.py | 346 ++++++++++++++++++ packages/packages.json | 2 +- .../valory/customs/prepare_tx/component.yaml | 1 - 7 files changed, 426 insertions(+), 2 deletions(-) create mode 100644 packages/gnosis/__init__.py create mode 100644 packages/gnosis/customs/__init__.py create mode 100644 packages/gnosis/customs/omen_buy_yes/__init__.py create mode 100644 packages/gnosis/customs/omen_buy_yes/component.yaml create mode 100644 packages/gnosis/customs/omen_buy_yes/omen_buy_yes.py diff --git a/packages/gnosis/__init__.py b/packages/gnosis/__init__.py new file mode 100644 index 00000000..ba697745 --- /dev/null +++ b/packages/gnosis/__init__.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# +# Copyright 2024 Valory AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------------ diff --git a/packages/gnosis/customs/__init__.py b/packages/gnosis/customs/__init__.py new file mode 100644 index 00000000..ba697745 --- /dev/null +++ b/packages/gnosis/customs/__init__.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# +# Copyright 2024 Valory AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------------ diff --git a/packages/gnosis/customs/omen_buy_yes/__init__.py b/packages/gnosis/customs/omen_buy_yes/__init__.py new file mode 100644 index 00000000..93e63121 --- /dev/null +++ b/packages/gnosis/customs/omen_buy_yes/__init__.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# +# Copyright 2023-2024 Valory AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------------ + +"""This module contains the bet amount per threshold strategy.""" diff --git a/packages/gnosis/customs/omen_buy_yes/component.yaml b/packages/gnosis/customs/omen_buy_yes/component.yaml new file mode 100644 index 00000000..1b4b3f89 --- /dev/null +++ b/packages/gnosis/customs/omen_buy_yes/component.yaml @@ -0,0 +1,21 @@ +name: omen_buy_yes +author: gnosis +version: 0.1.0 +type: custom +description: A tool to prepare a request for buying tokens corresponding to outcome Yes on Omen. +license: Apache-2.0 +aea_version: '>=1.0.0, <2.0.0' +fingerprint: + __init__.py: bafybeibbn67pnrrm4qm3n3kbelvbs3v7fjlrjniywmw2vbizarippidtvi + prediction_sum_url_content.py: bafybeieywowx265yycgf5735bw4zyabfy6ivwnntl6smxa2hicktipgeby +fingerprint_ignore_patterns: [] +entry_point: omen_buy_yes.py +callable: run +dependencies: + pydantic: + version: '>=1.9.0,<3' + prediction-market-agent-tooling: + git: https://github.com/gnosis/prediction-market-agent-tooling + ref: gabriel/olas-deps + langchain: + version: '^0.1.1' \ No newline at end of file diff --git a/packages/gnosis/customs/omen_buy_yes/omen_buy_yes.py b/packages/gnosis/customs/omen_buy_yes/omen_buy_yes.py new file mode 100644 index 00000000..97acb815 --- /dev/null +++ b/packages/gnosis/customs/omen_buy_yes/omen_buy_yes.py @@ -0,0 +1,346 @@ +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# +# Copyright 2024 Valory AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------------ + +""" +This module implements a tool which prepares a transaction for the transaction settlement skill. +Please note that the gnosis safe parameters are missing from the payload, e.g., `safe_tx_hash`, `safe_tx_gas`, etc. +""" +import functools +import os +import traceback +from typing import Any, Dict, Optional, Tuple, Callable + +import anthropic +import googleapiclient +import openai +from openai import OpenAI +from prediction_market_agent_tooling.markets.agent_market import AgentMarket +from prediction_market_agent_tooling.markets.omen.omen import OmenAgentMarket +from prediction_market_agent_tooling.markets.omen.omen_contracts import ( + OmenFixedProductMarketMakerContract, + OmenCollateralTokenContract, +) +from prediction_market_agent_tooling.tools.utils import check_not_none +from prediction_market_agent_tooling.tools.web3_utils import ( + prepare_tx, +) +from pydantic import BaseModel +from web3 import Web3 +from web3.types import TxParams + +MechResponse = Tuple[str, Optional[str], Optional[Dict[str, Any]], Any, Any] + + +def with_key_rotation(func: Callable): + @functools.wraps(func) + def wrapper(*args, **kwargs) -> MechResponse: + # this is expected to be a KeyChain object, + # although it is not explicitly typed as such + api_keys = kwargs["api_keys"] + retries_left: Dict[str, int] = api_keys.max_retries() + + def execute() -> MechResponse: + """Retry the function with a new key.""" + try: + result = func(*args, **kwargs) + return result + (api_keys,) + except anthropic.RateLimitError as e: + # try with a new key again + service = "anthropic" + if retries_left[service] <= 0: + raise e + retries_left[service] -= 1 + api_keys.rotate(service) + return execute() + except openai.RateLimitError as e: + # try with a new key again + if retries_left["openai"] <= 0 and retries_left["openrouter"] <= 0: + raise e + retries_left["openai"] -= 1 + retries_left["openrouter"] -= 1 + api_keys.rotate("openai") + api_keys.rotate("openrouter") + return execute() + except googleapiclient.errors.HttpError as e: + # try with a new key again + rate_limit_exceeded_code = 429 + if e.status_code != rate_limit_exceeded_code: + raise e + service = "google_api_key" + if retries_left[service] <= 0: + raise e + api_keys.rotate(service) + return execute() + except Exception as e: + return str(e), "", None, None, api_keys + + mech_response = execute() + return mech_response + + return wrapper + + +ENGINE = "gpt-3.5-turbo" +MAX_TOKENS = 500 +TEMPERATURE = 0.7 +TOOL_PREFIX = "transfer-" + + +"""NOTE: An LLM is used for generating a dict containing interpreted parameters from the response, such as "recipient_address", "market_address", etc. This could also be done if we could somehow publish the parameters needed by the run method and make it discoverable by the caller.""" + +# ToDo - rewrite PROMPT, add Pydantic object to prompt +BUY_YES_TOKENS_PROMPT = """You are an LLM inside a multi-agent system that takes in a prompt from a user requesting you to execute a native gas token (ETH) transfer to another public address on Ethereum. +The agent process you are sending your response to requires the unknown transaction parameters in the exact format below, written by you in your response as an input to sign/execute the transaction in the +agent process.The agent does not know the receiving address, “recipient_address", the value to send, “value”, or the denomination of the "value" given in wei "wei_value" which is converted by you without +use of any functions, the user prompt indicates to send. The unknown transaction parameters not known beforehand must be constructed by you from the user's prompt information. + +User Prompt: {user_prompt} + +only respond with the format below using curly brackets to encapsulate the variables within a json dictionary object and no other text: + +"to_address": recipient_address, +"value": value, +"wei_value": wei_value + +Do not respond with anything else other than the transaction object you constructed with the correct known variables the agent had before the request and the correct unknown values found in the user request prompt as input to the web3.py signing method. +""" + +client: Optional[OpenAI] = None + + +class BuyYesParams(BaseModel): + sender: str + recipient: str + market_id: str + outcome: bool + amount_to_buy: float + + +class OpenAIClientManager: + """Client context manager for OpenAI.""" + + def __init__(self, api_key: str): + self.api_key = api_key + + def __enter__(self) -> OpenAI: + global client + if client is None: + client = OpenAI(api_key=self.api_key) + return client + + def __exit__(self, exc_type, exc_value, traceback) -> None: + global client + if client is not None: + client.close() + client = None + + +def make_request_openai_request( + prompt: str, + engine: str = ENGINE, + max_tokens: Optional[int] = None, + temperature: Optional[float] = None, +) -> str: + # ToDo - Make request with Langchain and pydantic output + """Make openai request.""" + max_tokens = max_tokens or MAX_TOKENS + temperature = temperature or TEMPERATURE + moderation_result = client.moderations.create(input=prompt) + if moderation_result.results[0].flagged: + return "Moderation flagged the prompt as in violation of terms." + + messages = [ + {"role": "system", "content": "You are a helpful assistant."}, + {"role": "user", "content": prompt}, + ] + response = client.chat.completions.create( + model=engine, + messages=messages, + temperature=temperature, + max_tokens=max_tokens, + n=1, + timeout=120, + stop=None, + ) + return response.choices[0].message.content + + +def build_approval_tx_params( + buy_params: BuyYesParams, market: AgentMarket, w3: Web3 +) -> TxParams: + """ + # Approve the market maker to withdraw our collateral token. + """ + from_address_checksummed = Web3.to_checksum_address(buy_params.sender) + amount_wei = Web3.to_wei(buy_params.amount_to_buy, "ether") + + market_contract: OmenFixedProductMarketMakerContract = market.get_contract() + collateral_token_contract = OmenCollateralTokenContract() + + tx_params_approve = prepare_tx( + web3=w3, + contract_address=collateral_token_contract.address, + contract_abi=collateral_token_contract.abi, + from_address=from_address_checksummed, + function_name="approve", + function_params=[ + market_contract.address, + amount_wei, + ], + ) + return tx_params_approve + + +def check_balance_sufficient_for_buying_token( + buy_params: BuyYesParams, w3: Web3 +) -> bool: + # First, check if user has enough collateral to place bet. If not, abort. + # We restrict our bets to xDAI-denominated amounts for simplicity. + amount_wei = Web3.to_wei(buy_params.amount_to_buy, "ether") + + collateral_token_contract = OmenCollateralTokenContract() + + collateral_token_balance_wei = collateral_token_contract.balanceOf( + for_address=Web3.to_checksum_address(buy_params.sender), web3=w3 + ) + # Caller needs to make sure he has enough wxDAI (> amount_wei), else it should fail + if collateral_token_balance_wei < amount_wei: + return False + return True + + +def build_buy_tokens_tx_params( + buy_params: BuyYesParams, market: AgentMarket, w3: Web3 +) -> TxParams: + + from_address_checksummed = Web3.to_checksum_address(buy_params.sender) + amount_wei = Web3.to_wei(buy_params.amount_to_buy, "ether") + + market_contract: OmenFixedProductMarketMakerContract = market.get_contract() + + # Get the index of the outcome we want to buy. + outcome_str = "True" if buy_params.outcome else "False" + outcome_index: int = market.get_outcome_index(outcome_str) + + # Allow 1% slippage. + expected_shares = market_contract.calcBuyAmount(amount_wei, outcome_index, web3=w3) + + # Buy shares using the deposited xDai in the collateral token. + tx_params_buy = prepare_tx( + web3=w3, + contract_address=market_contract.address, + contract_abi=market_contract.abi, + from_address=from_address_checksummed, + function_name="buy", + function_params=[ + amount_wei, + outcome_index, + expected_shares, + ], + ) + return tx_params_buy + + +def build_buy_yes_tx( + prompt: str, +) -> Tuple[str, Optional[str], Optional[Dict[str, Any]], Any]: + """Perform native transfer.""" + tool_prompt = BUY_YES_TOKENS_PROMPT.format(user_prompt=prompt) + # This produces a dict having recipient, market_address, etc. + response = make_request_openai_request(prompt=tool_prompt) + + try: + # parse the response to get the transaction object string itself + # parsed_txs = ast.literal_eval(response) + buy_params = BuyYesParams.model_validate_json(response) + + # Calculate the amount of shares we will get for the given investment amount. + # ToDo - Clarify how to use RPC inside mech + GNOSIS_RPC_URL = check_not_none(os.environ["GNOSIS_RPC_URL"]) + if not GNOSIS_RPC_URL: + raise EnvironmentError("GNOSIS_RPC_URL not set. Aborting.") + w3 = Web3(Web3.HTTPProvider(GNOSIS_RPC_URL)) + + market: AgentMarket = OmenAgentMarket.get_binary_market(buy_params.market_id) + + is_balance_sufficient = check_balance_sufficient_for_buying_token( + buy_params, w3=w3 + ) + if not is_balance_sufficient: + return ( + f"Collateral token balance < amount to buy. Aborting.", + None, + None, + None, + ) + + tx_params_approve = build_approval_tx_params( + buy_params=buy_params, market=market, w3=w3 + ) + + tx_params_buy = build_buy_tokens_tx_params( + buy_params=buy_params, market=market, w3=w3 + ) + + # We return the transactions_dict below in order to be able to return multiple transactions for later execution instead of just one. + transaction_dict = {} + transaction_dict["1"] = tx_params_approve + transaction_dict["2"] = tx_params_buy + + return response, prompt, transaction_dict, None + + except Exception as e: + traceback.print_exception(e) + return response, None, None, None + + +AVAILABLE_TOOLS = { + "buy_yes_omen": build_buy_yes_tx, +} + + +def error_response(msg: str) -> Tuple[str, None, None, None]: + """Return an error mech response.""" + return msg, None, None, None + + +@with_key_rotation +def run(**kwargs) -> Tuple[str, Optional[str], Optional[Dict[str, Any]], Any]: + """Run the task""" + tool: str | None = kwargs.get("tool", None) + + if tool is None: + return error_response("No tool has been specified.") + + prompt: str | None = kwargs.get("prompt", None) + if prompt is None: + return error_response("No prompt has been given.") + + transaction_builder = AVAILABLE_TOOLS.get(tool) + if transaction_builder is None: + return error_response( + f"Tool {tool!r} is not in supported tools: {tuple(AVAILABLE_TOOLS.keys())}." + ) + + api_key: str | None = kwargs.get("api_keys", {}).get("openai", None) + if api_key is None: + return error_response("No api key has been given.") + + with OpenAIClientManager(api_key): + return transaction_builder(prompt) diff --git a/packages/packages.json b/packages/packages.json index 47a469ef..19382aca 100644 --- a/packages/packages.json +++ b/packages/packages.json @@ -15,7 +15,7 @@ "custom/napthaai/resolve_market_reasoning/0.1.0": "bafybeic43zq6xjkkc3o2gitxelr6v3nn6p2nctg6kf56tagrqvb6afxa6u", "custom/napthaai/prediction_request_rag/0.1.0": "bafybeie4z76wbnbvbsvborhrgeerbedtwxi3p2by7z3wyjhauwxwfgdaoa", "custom/napthaai/prediction_request_reasoning/0.1.0": "bafybeienoldwps2x4qwrpuah5aaxkvk7zqwzmyhyvyl7ktmiosbcpsuki4", - "custom/valory/prepare_tx/0.1.0": "bafybeidkghsricym5777edw3tvkuuzxkvmeai2r6phx43adfqwt3s5qwta", + "custom/valory/prepare_tx/0.1.0": "bafybeigo2yvfh63u6hdqufghng7flqesu76n7s5fchprndmjmdb3hqvyau", "custom/valory/short_maker/0.1.0": "bafybeif63rt4lkopu3rc3l7sg6tebrrwg2lxqufjx6dx4hoda5yzax43fa", "custom/napthaai/prediction_url_cot/0.1.0": "bafybeidu65l6abhfnxmeite6magzf6rqhmyyj427g3rtwms2oh5u5sc2eq", "custom/napthaai/prediction_url_cot_claude/0.1.0": "bafybeicbjywni5hx5ssoiv6tnnjbqzsck6cmtsdpr6m562z6afogz5eh44", diff --git a/packages/valory/customs/prepare_tx/component.yaml b/packages/valory/customs/prepare_tx/component.yaml index 1c74cffb..35db89a4 100644 --- a/packages/valory/customs/prepare_tx/component.yaml +++ b/packages/valory/customs/prepare_tx/component.yaml @@ -8,7 +8,6 @@ aea_version: '>=1.0.0, <2.0.0' fingerprint: __init__.py: bafybeieynbsr6aijx2totfi5iw6thjwgzko526zcs5plgvgrq2lufso2sy prepare_tx.py: bafybeib7no24trithxrj5nwovwtezb3q3k32cpvo6mkaa2wynvqrpdwkxi - utils/agent/build_goal.py: bafybeif7kj2x362bhguey252op7bbaidcc7zarpgovqkgfiv5qqk7fizra fingerprint_ignore_patterns: [] entry_point: prepare_tx.py callable: run From d3d52f325ba728860d9258017650b235e56a2132 Mon Sep 17 00:00:00 2001 From: Gabriel Fior Date: Fri, 31 May 2024 12:01:10 +0200 Subject: [PATCH 2/8] Improved LLM call with Pydantic output object --- .../customs/omen_buy_yes/component.yaml | 10 +- .../customs/omen_buy_yes/omen_buy_yes.py | 92 ++++++------------- 2 files changed, 38 insertions(+), 64 deletions(-) diff --git a/packages/gnosis/customs/omen_buy_yes/component.yaml b/packages/gnosis/customs/omen_buy_yes/component.yaml index 1b4b3f89..3e4db7a4 100644 --- a/packages/gnosis/customs/omen_buy_yes/component.yaml +++ b/packages/gnosis/customs/omen_buy_yes/component.yaml @@ -18,4 +18,12 @@ dependencies: git: https://github.com/gnosis/prediction-market-agent-tooling ref: gabriel/olas-deps langchain: - version: '^0.1.1' \ No newline at end of file + version: ==0.1.20 + langchain-core: + version: ==0.1.52 + langchain-openai: + version: ==0.1.6 + langchain_community: + version: ==0.2.1 + openai: + version: ==1.30.2 \ No newline at end of file diff --git a/packages/gnosis/customs/omen_buy_yes/omen_buy_yes.py b/packages/gnosis/customs/omen_buy_yes/omen_buy_yes.py index 97acb815..79d0f51a 100644 --- a/packages/gnosis/customs/omen_buy_yes/omen_buy_yes.py +++ b/packages/gnosis/customs/omen_buy_yes/omen_buy_yes.py @@ -29,6 +29,9 @@ import anthropic import googleapiclient import openai +from langchain_core.output_parsers import PydanticOutputParser +from langchain_core.prompts import PromptTemplate +from langchain_openai import ChatOpenAI from openai import OpenAI from prediction_market_agent_tooling.markets.agent_market import AgentMarket from prediction_market_agent_tooling.markets.omen.omen import OmenAgentMarket @@ -99,26 +102,20 @@ def execute() -> MechResponse: ENGINE = "gpt-3.5-turbo" MAX_TOKENS = 500 TEMPERATURE = 0.7 -TOOL_PREFIX = "transfer-" """NOTE: An LLM is used for generating a dict containing interpreted parameters from the response, such as "recipient_address", "market_address", etc. This could also be done if we could somehow publish the parameters needed by the run method and make it discoverable by the caller.""" -# ToDo - rewrite PROMPT, add Pydantic object to prompt -BUY_YES_TOKENS_PROMPT = """You are an LLM inside a multi-agent system that takes in a prompt from a user requesting you to execute a native gas token (ETH) transfer to another public address on Ethereum. -The agent process you are sending your response to requires the unknown transaction parameters in the exact format below, written by you in your response as an input to sign/execute the transaction in the -agent process.The agent does not know the receiving address, “recipient_address", the value to send, “value”, or the denomination of the "value" given in wei "wei_value" which is converted by you without -use of any functions, the user prompt indicates to send. The unknown transaction parameters not known beforehand must be constructed by you from the user's prompt information. +BUY_YES_TOKENS_PROMPT = """You are an LLM inside a multi-agent system that takes in a prompt from a user requesting you to produce transaction parameters which +will later be part of an Ethereum transaction. +Interpret the USER_PROMPT and extract the required information. +Do not use any functions. -User Prompt: {user_prompt} +[USER_PROMPT] +{user_prompt} -only respond with the format below using curly brackets to encapsulate the variables within a json dictionary object and no other text: - -"to_address": recipient_address, -"value": value, -"wei_value": wei_value - -Do not respond with anything else other than the transaction object you constructed with the correct known variables the agent had before the request and the correct unknown values found in the user request prompt as input to the web3.py signing method. +Follow the formatting instructions below for producing an output in the correct format. +{format_instructions} """ client: Optional[OpenAI] = None @@ -126,12 +123,26 @@ def execute() -> MechResponse: class BuyYesParams(BaseModel): sender: str - recipient: str market_id: str outcome: bool amount_to_buy: float +def build_buy_params_from_prompt(user_prompt: str) -> BuyYesParams: + model = ChatOpenAI(temperature=0) + parser = PydanticOutputParser(pydantic_object=BuyYesParams) + + prompt = PromptTemplate( + template=BUY_YES_TOKENS_PROMPT, + input_variables=["user_prompt"], + partial_variables={"format_instructions": parser.get_format_instructions()}, + ) + + chain = prompt | model | parser + + return chain.invoke({"user_prompt": user_prompt}) + + class OpenAIClientManager: """Client context manager for OpenAI.""" @@ -151,36 +162,6 @@ def __exit__(self, exc_type, exc_value, traceback) -> None: client = None -def make_request_openai_request( - prompt: str, - engine: str = ENGINE, - max_tokens: Optional[int] = None, - temperature: Optional[float] = None, -) -> str: - # ToDo - Make request with Langchain and pydantic output - """Make openai request.""" - max_tokens = max_tokens or MAX_TOKENS - temperature = temperature or TEMPERATURE - moderation_result = client.moderations.create(input=prompt) - if moderation_result.results[0].flagged: - return "Moderation flagged the prompt as in violation of terms." - - messages = [ - {"role": "system", "content": "You are a helpful assistant."}, - {"role": "user", "content": prompt}, - ] - response = client.chat.completions.create( - model=engine, - messages=messages, - temperature=temperature, - max_tokens=max_tokens, - n=1, - timeout=120, - stop=None, - ) - return response.choices[0].message.content - - def build_approval_tx_params( buy_params: BuyYesParams, market: AgentMarket, w3: Web3 ) -> TxParams: @@ -262,13 +243,10 @@ def build_buy_yes_tx( ) -> Tuple[str, Optional[str], Optional[Dict[str, Any]], Any]: """Perform native transfer.""" tool_prompt = BUY_YES_TOKENS_PROMPT.format(user_prompt=prompt) - # This produces a dict having recipient, market_address, etc. - response = make_request_openai_request(prompt=tool_prompt) - try: # parse the response to get the transaction object string itself # parsed_txs = ast.literal_eval(response) - buy_params = BuyYesParams.model_validate_json(response) + buy_params = build_buy_params_from_prompt(user_prompt=tool_prompt) # Calculate the amount of shares we will get for the given investment amount. # ToDo - Clarify how to use RPC inside mech @@ -279,21 +257,9 @@ def build_buy_yes_tx( market: AgentMarket = OmenAgentMarket.get_binary_market(buy_params.market_id) - is_balance_sufficient = check_balance_sufficient_for_buying_token( - buy_params, w3=w3 - ) - if not is_balance_sufficient: - return ( - f"Collateral token balance < amount to buy. Aborting.", - None, - None, - None, - ) - tx_params_approve = build_approval_tx_params( buy_params=buy_params, market=market, w3=w3 ) - tx_params_buy = build_buy_tokens_tx_params( buy_params=buy_params, market=market, w3=w3 ) @@ -303,11 +269,11 @@ def build_buy_yes_tx( transaction_dict["1"] = tx_params_approve transaction_dict["2"] = tx_params_buy - return response, prompt, transaction_dict, None + return "", prompt, transaction_dict, None except Exception as e: traceback.print_exception(e) - return response, None, None, None + return f"exception occurred - {e}", None, None, None AVAILABLE_TOOLS = { From 7edecf8bb1b05b9ed6ef3309a213d8d20cfd973b Mon Sep 17 00:00:00 2001 From: Gabriel Fior Date: Tue, 4 Jun 2024 13:05:00 -0300 Subject: [PATCH 3/8] Added sell token functionality --- .../{omen_buy_yes => omen_tools}/__init__.py | 0 .../component.yaml | 6 +- .../omen_buy_sell.py} | 285 +++++++++++------- 3 files changed, 179 insertions(+), 112 deletions(-) rename packages/gnosis/customs/{omen_buy_yes => omen_tools}/__init__.py (100%) rename packages/gnosis/customs/{omen_buy_yes => omen_tools}/component.yaml (82%) rename packages/gnosis/customs/{omen_buy_yes/omen_buy_yes.py => omen_tools/omen_buy_sell.py} (56%) diff --git a/packages/gnosis/customs/omen_buy_yes/__init__.py b/packages/gnosis/customs/omen_tools/__init__.py similarity index 100% rename from packages/gnosis/customs/omen_buy_yes/__init__.py rename to packages/gnosis/customs/omen_tools/__init__.py diff --git a/packages/gnosis/customs/omen_buy_yes/component.yaml b/packages/gnosis/customs/omen_tools/component.yaml similarity index 82% rename from packages/gnosis/customs/omen_buy_yes/component.yaml rename to packages/gnosis/customs/omen_tools/component.yaml index 3e4db7a4..0e362732 100644 --- a/packages/gnosis/customs/omen_buy_yes/component.yaml +++ b/packages/gnosis/customs/omen_tools/component.yaml @@ -1,15 +1,15 @@ -name: omen_buy_yes +name: omen_tools author: gnosis version: 0.1.0 type: custom -description: A tool to prepare a request for buying tokens corresponding to outcome Yes on Omen. +description: Collection of tools to prepare requests for interacting with prediction markets on Omen. license: Apache-2.0 aea_version: '>=1.0.0, <2.0.0' fingerprint: __init__.py: bafybeibbn67pnrrm4qm3n3kbelvbs3v7fjlrjniywmw2vbizarippidtvi prediction_sum_url_content.py: bafybeieywowx265yycgf5735bw4zyabfy6ivwnntl6smxa2hicktipgeby fingerprint_ignore_patterns: [] -entry_point: omen_buy_yes.py +entry_point: omen_buy_sell.py callable: run dependencies: pydantic: diff --git a/packages/gnosis/customs/omen_buy_yes/omen_buy_yes.py b/packages/gnosis/customs/omen_tools/omen_buy_sell.py similarity index 56% rename from packages/gnosis/customs/omen_buy_yes/omen_buy_yes.py rename to packages/gnosis/customs/omen_tools/omen_buy_sell.py index 79d0f51a..a49fcb3f 100644 --- a/packages/gnosis/customs/omen_buy_yes/omen_buy_yes.py +++ b/packages/gnosis/customs/omen_tools/omen_buy_sell.py @@ -26,8 +26,6 @@ import traceback from typing import Any, Dict, Optional, Tuple, Callable -import anthropic -import googleapiclient import openai from langchain_core.output_parsers import PydanticOutputParser from langchain_core.prompts import PromptTemplate @@ -38,6 +36,7 @@ from prediction_market_agent_tooling.markets.omen.omen_contracts import ( OmenFixedProductMarketMakerContract, OmenCollateralTokenContract, + OmenConditionalTokenContract, ) from prediction_market_agent_tooling.tools.utils import check_not_none from prediction_market_agent_tooling.tools.web3_utils import ( @@ -50,55 +49,6 @@ MechResponse = Tuple[str, Optional[str], Optional[Dict[str, Any]], Any, Any] -def with_key_rotation(func: Callable): - @functools.wraps(func) - def wrapper(*args, **kwargs) -> MechResponse: - # this is expected to be a KeyChain object, - # although it is not explicitly typed as such - api_keys = kwargs["api_keys"] - retries_left: Dict[str, int] = api_keys.max_retries() - - def execute() -> MechResponse: - """Retry the function with a new key.""" - try: - result = func(*args, **kwargs) - return result + (api_keys,) - except anthropic.RateLimitError as e: - # try with a new key again - service = "anthropic" - if retries_left[service] <= 0: - raise e - retries_left[service] -= 1 - api_keys.rotate(service) - return execute() - except openai.RateLimitError as e: - # try with a new key again - if retries_left["openai"] <= 0 and retries_left["openrouter"] <= 0: - raise e - retries_left["openai"] -= 1 - retries_left["openrouter"] -= 1 - api_keys.rotate("openai") - api_keys.rotate("openrouter") - return execute() - except googleapiclient.errors.HttpError as e: - # try with a new key again - rate_limit_exceeded_code = 429 - if e.status_code != rate_limit_exceeded_code: - raise e - service = "google_api_key" - if retries_left[service] <= 0: - raise e - api_keys.rotate(service) - return execute() - except Exception as e: - return str(e), "", None, None, api_keys - - mech_response = execute() - return mech_response - - return wrapper - - ENGINE = "gpt-3.5-turbo" MAX_TOKENS = 500 TEMPERATURE = 0.7 @@ -106,7 +56,7 @@ def execute() -> MechResponse: """NOTE: An LLM is used for generating a dict containing interpreted parameters from the response, such as "recipient_address", "market_address", etc. This could also be done if we could somehow publish the parameters needed by the run method and make it discoverable by the caller.""" -BUY_YES_TOKENS_PROMPT = """You are an LLM inside a multi-agent system that takes in a prompt from a user requesting you to produce transaction parameters which +BUY_OR_SELL_TOKENS_PROMPT = """You are an LLM inside a multi-agent system that takes in a prompt from a user requesting you to produce transaction parameters which will later be part of an Ethereum transaction. Interpret the USER_PROMPT and extract the required information. Do not use any functions. @@ -121,25 +71,22 @@ def execute() -> MechResponse: client: Optional[OpenAI] = None -class BuyYesParams(BaseModel): +class BuyOrSell(BaseModel): sender: str market_id: str outcome: bool amount_to_buy: float -def build_buy_params_from_prompt(user_prompt: str) -> BuyYesParams: +def build_params_from_prompt(user_prompt: str) -> BuyOrSell: model = ChatOpenAI(temperature=0) - parser = PydanticOutputParser(pydantic_object=BuyYesParams) - + parser = PydanticOutputParser(pydantic_object=BuyOrSell) prompt = PromptTemplate( - template=BUY_YES_TOKENS_PROMPT, + template=BUY_OR_SELL_TOKENS_PROMPT, input_variables=["user_prompt"], partial_variables={"format_instructions": parser.get_format_instructions()}, ) - chain = prompt | model | parser - return chain.invoke({"user_prompt": user_prompt}) @@ -162,14 +109,38 @@ def __exit__(self, exc_type, exc_value, traceback) -> None: client = None +def build_approval_for_all_tx_params( + buy_or_sell: BuyOrSell, market: AgentMarket, w3: Web3 +) -> TxParams: + """ + # Approve the market maker to withdraw our collateral token. + """ + from_address_checksummed = Web3.to_checksum_address(buy_or_sell.sender) + market_contract: OmenFixedProductMarketMakerContract = market.get_contract() + conditional_tokens_contract = OmenConditionalTokenContract() + + tx_params_approve_all = prepare_tx( + web3=w3, + contract_address=conditional_tokens_contract.address, + contract_abi=conditional_tokens_contract.abi, + from_address=from_address_checksummed, + function_name="setApprovalForAll", + function_params=[ + market_contract.address, + True, # approve=True + ], + ) + return tx_params_approve_all + + def build_approval_tx_params( - buy_params: BuyYesParams, market: AgentMarket, w3: Web3 + buy_or_sell: BuyOrSell, market: AgentMarket, w3: Web3 ) -> TxParams: """ # Approve the market maker to withdraw our collateral token. """ - from_address_checksummed = Web3.to_checksum_address(buy_params.sender) - amount_wei = Web3.to_wei(buy_params.amount_to_buy, "ether") + from_address_checksummed = Web3.to_checksum_address(buy_or_sell.sender) + amount_wei = Web3.to_wei(buy_or_sell.amount_to_buy, "ether") market_contract: OmenFixedProductMarketMakerContract = market.get_contract() collateral_token_contract = OmenCollateralTokenContract() @@ -188,35 +159,17 @@ def build_approval_tx_params( return tx_params_approve -def check_balance_sufficient_for_buying_token( - buy_params: BuyYesParams, w3: Web3 -) -> bool: - # First, check if user has enough collateral to place bet. If not, abort. - # We restrict our bets to xDAI-denominated amounts for simplicity. - amount_wei = Web3.to_wei(buy_params.amount_to_buy, "ether") - - collateral_token_contract = OmenCollateralTokenContract() - - collateral_token_balance_wei = collateral_token_contract.balanceOf( - for_address=Web3.to_checksum_address(buy_params.sender), web3=w3 - ) - # Caller needs to make sure he has enough wxDAI (> amount_wei), else it should fail - if collateral_token_balance_wei < amount_wei: - return False - return True - - def build_buy_tokens_tx_params( - buy_params: BuyYesParams, market: AgentMarket, w3: Web3 + buy_or_sell: BuyOrSell, market: AgentMarket, w3: Web3 ) -> TxParams: - from_address_checksummed = Web3.to_checksum_address(buy_params.sender) - amount_wei = Web3.to_wei(buy_params.amount_to_buy, "ether") + from_address_checksummed = Web3.to_checksum_address(buy_or_sell.sender) + amount_wei = Web3.to_wei(buy_or_sell.amount_to_buy, "ether") market_contract: OmenFixedProductMarketMakerContract = market.get_contract() # Get the index of the outcome we want to buy. - outcome_str = "True" if buy_params.outcome else "False" + outcome_str = "True" if buy_or_sell.outcome else "False" outcome_index: int = market.get_outcome_index(outcome_str) # Allow 1% slippage. @@ -238,47 +191,155 @@ def build_buy_tokens_tx_params( return tx_params_buy -def build_buy_yes_tx( +def build_sell_tokens_tx_params( + buy_or_sell: BuyOrSell, market: AgentMarket, w3: Web3 +) -> TxParams: + + from_address_checksummed = Web3.to_checksum_address(buy_or_sell.sender) + amount_wei = Web3.to_wei(buy_or_sell.amount_to_buy, "ether") + + market_contract: OmenFixedProductMarketMakerContract = market.get_contract() + conditional_token_contract = OmenConditionalTokenContract() + + # Verify, that markets uses conditional tokens that we expect. + if market_contract.conditionalTokens(web3=w3) != conditional_token_contract.address: + raise ValueError( + f"Market {market.id} uses conditional token that we didn't expect, {market_contract.conditionalTokens()} != {conditional_token_contract.address=}" + ) + + # Get the index of the outcome we want to buy. + outcome_index: int = market.get_outcome_index(outcome) + + # Calculate the amount of shares we will sell for the given selling amount of xdai. + max_outcome_tokens_to_sell = market_contract.calcSellAmount( + amount_wei, outcome_index, web3=web3 + ) + # Allow 1% slippage. + max_outcome_tokens_to_sell = add_fraction(max_outcome_tokens_to_sell, 0.01) + + # Sell the shares. + tx_params_sell = prepare_tx( + web3=w3, + contract_address=market_contract.address, + contract_abi=market_contract.abi, + from_address=from_address_checksummed, + function_name="sell", + function_params=[ + amount_wei, + outcome_index, + max_outcome_tokens_to_sell, + ], + ) + + return tx_params_sell + + +def fetch_params_from_prompt(prompt: str): + tool_prompt = BUY_OR_SELL_TOKENS_PROMPT.format(user_prompt=prompt) + # parse the response to get the transaction object string itself + # parsed_txs = ast.literal_eval(response) + buy_params = build_params_from_prompt(user_prompt=tool_prompt) + # Calculate the amount of shares we will get for the given investment amount. + market: AgentMarket = OmenAgentMarket.get_binary_market(buy_params.market_id) + return buy_params, market + + +def build_buy_tx( prompt: str, ) -> Tuple[str, Optional[str], Optional[Dict[str, Any]], Any]: - """Perform native transfer.""" - tool_prompt = BUY_YES_TOKENS_PROMPT.format(user_prompt=prompt) - try: - # parse the response to get the transaction object string itself - # parsed_txs = ast.literal_eval(response) - buy_params = build_buy_params_from_prompt(user_prompt=tool_prompt) + """Builds buy transaction request.""" - # Calculate the amount of shares we will get for the given investment amount. - # ToDo - Clarify how to use RPC inside mech - GNOSIS_RPC_URL = check_not_none(os.environ["GNOSIS_RPC_URL"]) - if not GNOSIS_RPC_URL: - raise EnvironmentError("GNOSIS_RPC_URL not set. Aborting.") - w3 = Web3(Web3.HTTPProvider(GNOSIS_RPC_URL)) - - market: AgentMarket = OmenAgentMarket.get_binary_market(buy_params.market_id) + try: + buy_params, market = fetch_params_from_prompt(prompt) + w3 = get_web3() tx_params_approve = build_approval_tx_params( - buy_params=buy_params, market=market, w3=w3 + buy_or_sell=buy_params, market=market, w3=w3 ) tx_params_buy = build_buy_tokens_tx_params( - buy_params=buy_params, market=market, w3=w3 + buy_or_sell=buy_params, market=market, w3=w3 + ) + + return build_return_from_tx_params([tx_params_approve, tx_params_buy], prompt) + + except Exception as e: + traceback.print_exception(e) + return f"exception occurred - {e}", None, None, None + + +def build_return_from_tx_params( + tx_params: list[TxParams], prompt: str +) -> Tuple[str, Optional[str], Optional[Dict[str, Any]], Any]: + # We return the transactions_dict below in order to be able to return multiple transactions for later execution instead of just one. + transaction_dict = {} + for i, tx_dict in enumerate(tx_params): + transaction_dict[str(i)] = tx_dict + + return "", prompt, transaction_dict, None + + +def get_web3() -> Web3: + GNOSIS_RPC_URL = check_not_none(os.environ["GNOSIS_RPC_URL"]) + if not GNOSIS_RPC_URL: + raise EnvironmentError("GNOSIS_RPC_URL not set. Aborting.") + return Web3(Web3.HTTPProvider(GNOSIS_RPC_URL)) + + +def build_sell_tx( + prompt: str, +) -> Tuple[str, Optional[str], Optional[Dict[str, Any]], Any]: + """Builds sell transaction request.""" + + try: + sell_params, market = fetch_params_from_prompt(prompt) + w3 = get_web3() + + tx_params_approve_all = build_approval_for_all_tx_params( + buy_or_sell=sell_params, market=market, w3=w3 ) - # We return the transactions_dict below in order to be able to return multiple transactions for later execution instead of just one. - transaction_dict = {} - transaction_dict["1"] = tx_params_approve - transaction_dict["2"] = tx_params_buy + tx_params_sell = build_sell_tokens_tx_params( + buy_or_sell=sell_params, market=market, w3=w3 + ) - return "", prompt, transaction_dict, None + return build_return_from_tx_params( + [tx_params_approve_all, tx_params_sell], prompt + ) except Exception as e: traceback.print_exception(e) return f"exception occurred - {e}", None, None, None -AVAILABLE_TOOLS = { - "buy_yes_omen": build_buy_yes_tx, -} +def with_key_rotation(func: Callable): + @functools.wraps(func) + def wrapper(*args, **kwargs) -> MechResponse: + # this is expected to be a KeyChain object, + # although it is not explicitly typed as such + api_keys = kwargs["api_keys"] + retries_left: Dict[str, int] = api_keys.max_retries() + + def execute() -> MechResponse: + """Retry the function with a new key.""" + try: + result = func(*args, **kwargs) + return result + (api_keys,) + except openai.RateLimitError as e: + # try with a new key again + if retries_left["openai"] <= 0 and retries_left["openrouter"] <= 0: + raise e + retries_left["openai"] -= 1 + retries_left["openrouter"] -= 1 + api_keys.rotate("openai") + api_keys.rotate("openrouter") + return execute() + except Exception as e: + return str(e), "", None, None, api_keys + + mech_response = execute() + return mech_response + + return wrapper def error_response(msg: str) -> Tuple[str, None, None, None]: @@ -286,6 +347,12 @@ def error_response(msg: str) -> Tuple[str, None, None, None]: return msg, None, None, None +AVAILABLE_TOOLS = { + "buy_omen": build_buy_tx, # buyYesTokens, buyNoTokens + "sell_omen": build_sell_tx, # sellYesTokens, sellNoTokens +} + + @with_key_rotation def run(**kwargs) -> Tuple[str, Optional[str], Optional[Dict[str, Any]], Any]: """Run the task""" From c53c5b2f395f4fc34ff6b9dd34b871dee6034def Mon Sep 17 00:00:00 2001 From: Gabriel Fior Date: Tue, 4 Jun 2024 13:05:32 -0300 Subject: [PATCH 4/8] Updated poetry dependencies --- poetry.lock | 1093 +++++++++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 3 +- 2 files changed, 1087 insertions(+), 9 deletions(-) diff --git a/poetry.lock b/poetry.lock index 6c94f927..cb856629 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. [[package]] name = "aiohttp" @@ -110,6 +110,31 @@ files = [ [package.dependencies] frozenlist = ">=1.1.0" +[[package]] +name = "altair" +version = "5.3.0" +description = "Vega-Altair: A declarative statistical visualization library for Python." +optional = false +python-versions = ">=3.8" +files = [ + {file = "altair-5.3.0-py3-none-any.whl", hash = "sha256:7084a1dab4d83c5e7e5246b92dc1b4451a6c68fd057f3716ee9d315c8980e59a"}, + {file = "altair-5.3.0.tar.gz", hash = "sha256:5a268b1a0983b23d8f9129f819f956174aa7aea2719ed55a52eba9979b9f6675"}, +] + +[package.dependencies] +jinja2 = "*" +jsonschema = ">=3.0" +numpy = "*" +packaging = "*" +pandas = ">=0.25" +toolz = "*" +typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} + +[package.extras] +all = ["altair-tiles (>=0.3.0)", "anywidget (>=0.9.0)", "pyarrow (>=11)", "vega-datasets (>=0.9.0)", "vegafusion[embed] (>=1.6.6)", "vl-convert-python (>=1.3.0)"] +dev = ["geopandas", "hatch", "ipython", "m2r", "mypy", "pandas-stubs", "pytest", "pytest-cov", "ruff (>=0.3.0)", "types-jsonschema", "types-setuptools"] +doc = ["docutils", "jinja2", "myst-parser", "numpydoc", "pillow (>=9,<10)", "pydata-sphinx-theme (>=0.14.1)", "scipy", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinxext-altair"] + [[package]] name = "annotated-types" version = "0.7.0" @@ -167,6 +192,20 @@ doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphin test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] trio = ["trio (>=0.23)"] +[[package]] +name = "art" +version = "6.2" +description = "ASCII Art Library For Python" +optional = false +python-versions = ">=3.5" +files = [ + {file = "art-6.2-py3-none-any.whl", hash = "sha256:d632d1d3f5fabcaf8673abe934b51df0017bc914d106e89d45ae4ebef0e3149a"}, + {file = "art-6.2.tar.gz", hash = "sha256:506a0c4f261289a0e0d088de7beffcb1835078c4e44b0c5353bdaf47b490e76f"}, +] + +[package.extras] +dev = ["bandit (>=1.5.1)", "coverage (>=4.1)", "pydocstyle (>=3.0.0)", "vulture (>=1.0)"] + [[package]] name = "asn1crypto" version = "1.4.0" @@ -208,6 +247,21 @@ tests = ["attrs[tests-no-zope]", "zope-interface"] tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] +[[package]] +name = "autoflake" +version = "2.3.1" +description = "Removes unused imports and unused variables" +optional = false +python-versions = ">=3.8" +files = [ + {file = "autoflake-2.3.1-py3-none-any.whl", hash = "sha256:3ae7495db9084b7b32818b4140e6dc4fc280b712fb414f5b8fe57b0a8e85a840"}, + {file = "autoflake-2.3.1.tar.gz", hash = "sha256:c98b75dc5b0a86459c4f01a1d32ac7eb4338ec4317a4469515ff1e687ecd909e"}, +] + +[package.dependencies] +pyflakes = ">=3.0.0" +tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""} + [[package]] name = "backoff" version = "2.2.1" @@ -433,6 +487,17 @@ files = [ {file = "bitarray-2.9.2.tar.gz", hash = "sha256:a8f286a51a32323715d77755ed959f94bef13972e9a2fe71b609e40e6d27957e"}, ] +[[package]] +name = "blinker" +version = "1.8.2" +description = "Fast, simple object-to-object and broadcast signaling" +optional = false +python-versions = ">=3.8" +files = [ + {file = "blinker-1.8.2-py3-none-any.whl", hash = "sha256:1779309f71bf239144b9399d06ae925637cf6634cf6bd131104184531bf67c01"}, + {file = "blinker-1.8.2.tar.gz", hash = "sha256:8f77b09d3bf7c795e969e9486f39c2c5e9c39d4ee07424be2bc594ece9642d83"}, +] + [[package]] name = "blis" version = "0.7.11" @@ -679,6 +744,100 @@ typer = ">=0.9.0" typing-extensions = ">=4.5.0" uvicorn = {version = ">=0.18.3", extras = ["standard"]} +[[package]] +name = "ckzg" +version = "1.0.2" +description = "Python bindings for C-KZG-4844" +optional = false +python-versions = "*" +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"}, + {file = "ckzg-1.0.2-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e9dc671b0a307ea65d0a216ca496c272dd3c1ed890ddc2a306da49b0d8ffc83"}, + {file = "ckzg-1.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d95e97a0d0f7758119bb905fb5688222b1556de465035614883c42fe4a047d1f"}, + {file = "ckzg-1.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27261672154cbd477d84d289845b0022fbdbe2ba45b7a2a2051c345fa04c8334"}, + {file = "ckzg-1.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c16d5ee1ddbbbad0367ff970b3ec9f6d1879e9f928023beda59ae9e16ad99e4c"}, + {file = "ckzg-1.0.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:09043738b029bdf4fdc82041b395cfc6f5b5cf63435e5d4d685d24fd14c834d3"}, + {file = "ckzg-1.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3c0afa232d2312e3101aaddb6971b486b0038a0f9171500bc23143f5749eff55"}, + {file = "ckzg-1.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:96e8281b6d58cf91b9559e1bd38132161d63467500838753364c68e825df2e2c"}, + {file = "ckzg-1.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b874167de1d6de72890a2ad5bd9aa7adbddc41c3409923b59cf4ef27f83f79da"}, + {file = "ckzg-1.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3d2ccd68b0743e20e853e31a08da490a8d38c7f12b9a0c4ee63ef5afa0dc2427"}, + {file = "ckzg-1.0.2-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e8d534ddbe785c44cf1cd62ee32d78b4310d66dd70e42851f5468af655b81f5"}, + {file = "ckzg-1.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c732cda00c76b326f39ae97edfc6773dd231b7c77288b38282584a7aee77c3a7"}, + {file = "ckzg-1.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abc5a27284db479ead4c053ff086d6e222914f1b0aa08b80eabfa116dbed4f7a"}, + {file = "ckzg-1.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e6bd5006cb3e802744309450183087a6594d50554814eee19065f7064dff7b05"}, + {file = "ckzg-1.0.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3594470134eda7adf2813ad3f1da55ced98c8a393262f47ce3890c5afa05b23e"}, + {file = "ckzg-1.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fea56f39e48b60c1ff6f751c47489e353d1bd95cae65c429cf5f87735d794431"}, + {file = "ckzg-1.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:f769eb2e1056ca396462460079f6849c778f58884bb24b638ff7028dd2120b65"}, + {file = "ckzg-1.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e3cb2f8c767aee57e88944f90848e8689ce43993b9ff21589cfb97a562208fe7"}, + {file = "ckzg-1.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b29889f5bc5db530f766871c0ff4133e7270ecf63aaa3ca756d3b2731980802"}, + {file = "ckzg-1.0.2-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfcc70fb76b3d36125d646110d5001f2aa89c1c09ff5537a4550cdb7951f44d4"}, + {file = "ckzg-1.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ca8a256cdd56d06bc5ef24caac64845240dbabca402c5a1966d519b2514b4ec"}, + {file = "ckzg-1.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ea91b0236384f93ad1df01d530672f09e254bd8c3cf097ebf486aebb97f6c8c"}, + {file = "ckzg-1.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:65311e72780105f239d1d66512629a9f468b7c9f2609b8567fc68963ac638ef9"}, + {file = "ckzg-1.0.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:0d7600ce7a73ac41d348712d0c1fe5e4cb6caa329377064cfa3a6fd8fbffb410"}, + {file = "ckzg-1.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:19893ee7bd7da8688382cb134cb9ee7bce5c38e3a9386e3ed99bb010487d2d17"}, + {file = "ckzg-1.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:c3e1a9a72695e777497e95bb2213316a1138f82d1bb5d67b9c029a522d24908e"}, + {file = "ckzg-1.0.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a2f59da9cb82b6a4be615f2561a255731eededa7ecd6ba4b2f2dedfc918ef137"}, + {file = "ckzg-1.0.2-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c915e1f2ef51657c3255d8b1e2aea6e0b93348ae316b2b79eaadfb17ad8f514e"}, + {file = "ckzg-1.0.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcc0d2031fcabc4be37e9e602c926ef9347238d2f58c1b07e0c147f60b9e760b"}, + {file = "ckzg-1.0.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cdaad2745425d7708e76e8e56a52fdaf5c5cc1cfefd5129d24ff8dbe06a012d"}, + {file = "ckzg-1.0.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:1ec775649daade1b93041aac9c1660c2ad9828b57ccd2eeb5a3074d8f05e544a"}, + {file = "ckzg-1.0.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:02f9cc3e38b3702ec5895a1ebf927fd02b8f5c2f93c7cb9e438581b5b74472c8"}, + {file = "ckzg-1.0.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:0e816af31951b5e94e6bc069f21fe783427c190526e0437e16c4488a34ddcacc"}, + {file = "ckzg-1.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:651ba33ee2d7fefff14ca519a72996b733402f8b043fbfef12d5fe2a442d86d8"}, + {file = "ckzg-1.0.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:489763ad92e2175fb6ab455411f03ec104c630470d483e11578bf2e00608f283"}, + {file = "ckzg-1.0.2-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:69e1376284e9a5094d7c4d3e552202d6b32a67c5acc461b0b35718d8ec5c7363"}, + {file = "ckzg-1.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb9d0b09ca1bdb5955b626d6645f811424ae0fcab47699a1a938a3ce0438c25f"}, + {file = "ckzg-1.0.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d87a121ace8feb6c9386f247e7e36ef55e584fc8a6b1bc2c60757a59c1efe364"}, + {file = "ckzg-1.0.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:97c27153fab853f017fed159333b27beeb2e0da834c92c9ecdc26d0e5c3983b3"}, + {file = "ckzg-1.0.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b26799907257c39471cb3665f66f7630797140131606085c2c94a7094ab6ddf2"}, + {file = "ckzg-1.0.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:283a40c625222560fda3dcb912b666f7d50f9502587b73c4358979f519f1c961"}, + {file = "ckzg-1.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:5f029822d27c52b9c3dbe5706408b099da779f10929be0422a09a34aa026a872"}, + {file = "ckzg-1.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:edaea8fb50b01c6c19768d9305ad365639a8cd804754277d5108dcae4808f00b"}, + {file = "ckzg-1.0.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:27be65c88d5d773a30e6f198719cefede7e25cad807384c3d65a09c11616fc9d"}, + {file = "ckzg-1.0.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9ac729c5c6f3d2c030c0bc8c9e10edc253e36f002cfe227292035009965d349"}, + {file = "ckzg-1.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1528bc2b95aac6d184a90b023602c40d7b11b577235848c1b5593c00cf51d37"}, + {file = "ckzg-1.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:071dc7fc179316ce1bfabaa056156e4e84f312c4560ab7b9529a3b9a84019df3"}, + {file = "ckzg-1.0.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:895044069de7010be6c7ee703f03fd7548267a0823cf60b9dd26ec50267dd9e8"}, + {file = "ckzg-1.0.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ed8c99cd3d9af596470e0481fd58931007288951719bad026f0dd486dd0ec11"}, + {file = "ckzg-1.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:74d87eafe561d4bfb544a4f3419d26c56ad7de00f39789ef0fdb09515544d12e"}, + {file = "ckzg-1.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:54d71e5ca416bd51c543f9f51e426e6792f8a0280b83aef92faad1b826f401ea"}, + {file = "ckzg-1.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:da2d9988781a09a4577ee7ea8f51fe4a94b4422789a523164f5ba3118566ad41"}, + {file = "ckzg-1.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d9e030af7d6acdcb356fddfb095048bc8e880fe4cd70ff2206c64f33bf384a0d"}, + {file = "ckzg-1.0.2-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:145ae31c3d499d1950567bd636dc5b24292b600296b9deb5523bc20d8f7b51c3"}, + {file = "ckzg-1.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d81e68e84d80084da298471ad5eaddfcc1cf73545cb24e9453550c8186870982"}, + {file = "ckzg-1.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c67064bbbeba1a6892c9c80b3d0c2a540ff48a5ca5356fdb2a8d998b264e43e6"}, + {file = "ckzg-1.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:99694917eb6decefc0d330d9887a89ea770824b2fa76eb830bab5fe57ea5c20c"}, + {file = "ckzg-1.0.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:fca227ce0ce3427254a113fdb3aed5ecd99c1fc670cb0c60cc8a2154793678e4"}, + {file = "ckzg-1.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a66a690d3d1801085d11de6825df47a99b465ff32dbe90be4a3c9f43c577da96"}, + {file = "ckzg-1.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:272adfe471380d10e4a0e1639d877e504555079a60233dd82249c799b15be81e"}, + {file = "ckzg-1.0.2-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f37be0054ebb4b8ac6e6d5267290b239b09e7ddc611776051b4c3c4032d161ba"}, + {file = "ckzg-1.0.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:611c03a170f0f746180eeb0cc28cdc6f954561b8eb9013605a046de86520ee6b"}, + {file = "ckzg-1.0.2-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:75b2f0ab341f3c33702ce64e1c101116c7462a25686d0b1a0193ca654ad4f96e"}, + {file = "ckzg-1.0.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab29fc61fbd32096b82b02e6b18ae0d7423048d3540b7b90805b16ae10bdb769"}, + {file = "ckzg-1.0.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e43741e7453262aa3ba1754623d7864250b33751bd850dd548e3ed6bd1911093"}, + {file = "ckzg-1.0.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:155eacc237cb28c9eafda1c47a89e6e4550f1c2e711f2eee21e0bb2f4df75546"}, + {file = "ckzg-1.0.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d31d7fbe396a51f43375e38c31bc3a96c7996882582f95f3fcfd54acfa7b3ce6"}, + {file = "ckzg-1.0.2-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d3d049186c9966e9140de39a9979d7adcfe22f8b02d2852c94d3c363235cc18"}, + {file = "ckzg-1.0.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88728fbd410d61bd5d655ac50b842714c38bc34ff717f73592132d28911fc88e"}, + {file = "ckzg-1.0.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:052d302058d72431acc9dd4a9c76854c8dfce10c698deef5252884e32a1ac7bf"}, + {file = "ckzg-1.0.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:633110a9431231664be2ad32baf10971547f18289d33967654581b9ae9c94a7e"}, + {file = "ckzg-1.0.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f439c9e5297ae29a700f6d55de1525e2e295dbbb7366f0974c8702fca9e536b9"}, + {file = "ckzg-1.0.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:94f7eb080c00c0ccbd4fafad69f0b35b624a6a229a28e11d365b60b58a072832"}, + {file = "ckzg-1.0.2-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f876783ec654b7b9525503c2a0a1b086e5d4f52ff65cac7e8747769b0c2e5468"}, + {file = "ckzg-1.0.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7e039800e50592580171830e788ef4a1d6bb54300d074ae9f9119e92aefc568"}, + {file = "ckzg-1.0.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13a8cccf0070a29bc01493179db2e61220ee1a6cb17f8ea41c68a2f043ace87f"}, + {file = "ckzg-1.0.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:4f86cef801d7b0838e17b6ee2f2c9e747447d91ad1220a701baccdf7ef11a3c8"}, + {file = "ckzg-1.0.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2433a89af4158beddebbdd66fae95b34d40f2467bee8dc40df0333de5e616b5f"}, + {file = "ckzg-1.0.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c49d5dc0918ad912777720035f9820bdbb6c7e7d1898e12506d44ab3c938d525"}, + {file = "ckzg-1.0.2-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:331d49bc72430a3f85ea6ecb55a0d0d65f66a21d61af5783b465906a741366d5"}, + {file = "ckzg-1.0.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e86627bc33bc63b8de869d7d5bfa9868619a4f3e4e7082103935c52f56c66b5"}, + {file = "ckzg-1.0.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab6a2ba2706b5eaa1ce6bc7c4e72970bf9587e2e0e482e5fb4df1996bccb7a40"}, + {file = "ckzg-1.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:8bca5e7c38d913fabc24ad09545f78ba23cfc13e1ac8250644231729ca908549"}, + {file = "ckzg-1.0.2.tar.gz", hash = "sha256:4295acc380f8d42ebea4a4a0a68c424a322bb335a33bad05c72ead8cbb28d118"}, +] + [[package]] name = "click" version = "8.0.2" @@ -693,6 +852,23 @@ files = [ [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} +[[package]] +name = "cloudevents" +version = "1.10.1" +description = "CloudEvents Python SDK" +optional = false +python-versions = "*" +files = [ + {file = "cloudevents-1.10.1-py3-none-any.whl", hash = "sha256:832f1e3cca0887ab8f993cd2c0645a2155e73792f740d86f7b4bc8620a10d50e"}, + {file = "cloudevents-1.10.1.tar.gz", hash = "sha256:984d90aa114deeb1c37ceecf78f9dc9d56f5866cf10b45142a23c84d22621ac9"}, +] + +[package.dependencies] +deprecation = ">=2.0,<3.0" + +[package.extras] +pydantic = ["pydantic (>=1.0.0,<3.0)"] + [[package]] name = "cloudpathlib" version = "0.16.0" @@ -845,6 +1021,21 @@ tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.1 [package.extras] toml = ["tomli"] +[[package]] +name = "cron-validator" +version = "1.0.8" +description = "Unix cron implementation by Python" +optional = false +python-versions = "*" +files = [ + {file = "cron-validator-1.0.8.tar.gz", hash = "sha256:dd485257adb6f590b3e9433f641440c801d307015259c1ee3eb6e21c964c8026"}, + {file = "cron_validator-1.0.8-py3-none-any.whl", hash = "sha256:6477fcc3d60bfbd1ec00a708f0b8b5136c1fef8140c10effea1f45b79d778653"}, +] + +[package.dependencies] +python-dateutil = "*" +pytz = "*" + [[package]] name = "cryptography" version = "42.0.7" @@ -1097,6 +1288,20 @@ files = [ {file = "decorator-4.4.2.tar.gz", hash = "sha256:e3a62f0520172440ca0dcc823749319382e377f37f140a0b99ef45fecb84bfe7"}, ] +[[package]] +name = "deprecation" +version = "2.1.0" +description = "A library to handle automated deprecations" +optional = false +python-versions = "*" +files = [ + {file = "deprecation-2.1.0-py2.py3-none-any.whl", hash = "sha256:a10811591210e1fb0e768a8c25517cabeabcba6f0bf96564f8ff45189f90b14a"}, + {file = "deprecation-2.1.0.tar.gz", hash = "sha256:72b3bde64e5d778694b0cf68178aed03d15e15477116add3fb773e581f9518ff"}, +] + +[package.dependencies] +packaging = "*" + [[package]] name = "distlib" version = "0.3.8" @@ -1243,6 +1448,25 @@ doc = ["Sphinx (>=1.6.5,<5)", "jinja2 (>=3.0.0,<3.1.0)", "sphinx-rtd-theme (>=0. lint = ["black (>=22,<23)", "flake8 (==3.7.9)", "isort (>=4.2.15,<5)", "mypy (==0.910)", "pydocstyle (>=5.0.0,<6)"] test = ["coverage", "hypothesis (>=4.18.0,<5)", "pytest (>=6.2.5,<7)", "pytest-xdist", "tox (==3.25.0)"] +[[package]] +name = "eth-bloom" +version = "3.0.1" +description = "A python implementation of the bloom filter used by Ethereum" +optional = false +python-versions = "<4,>=3.8" +files = [ + {file = "eth_bloom-3.0.1-py3-none-any.whl", hash = "sha256:c1eb51cb9f9ec8834b691d67e73c02c4e79e22c81ae8058209971803236ffbb2"}, + {file = "eth_bloom-3.0.1.tar.gz", hash = "sha256:6be3dfa44a597a0bc8d974c381fb9a60bbcadfb56e88e69ab55ba538d90b3256"}, +] + +[package.dependencies] +eth-hash = {version = ">=0.4.0", extras = ["pycryptodome"]} + +[package.extras] +dev = ["build (>=0.9.0)", "bumpversion (>=0.5.3)", "hypothesis (>=3.31.2)", "ipython", "pre-commit (>=3.4.0)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)", "towncrier (>=21,<22)", "tox (>=4.0.0)", "twine", "wheel"] +docs = ["towncrier (>=21,<22)"] +test = ["hypothesis (>=3.31.2)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)"] + [[package]] name = "eth-hash" version = "0.7.0" @@ -1612,6 +1836,57 @@ test-downstream = ["aiobotocore (>=2.5.4,<3.0.0)", "dask-expr", "dask[dataframe, test-full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "cloudpickle", "dask", "distributed", "dropbox", "dropboxdrivefs", "fastparquet", "fusepy", "gcsfs", "jinja2", "kerchunk", "libarchive-c", "lz4", "notebook", "numpy", "ocifs", "pandas", "panel", "paramiko", "pyarrow", "pyarrow (>=1)", "pyftpdlib", "pygit2", "pytest", "pytest-asyncio (!=0.22.0)", "pytest-benchmark", "pytest-cov", "pytest-mock", "pytest-recording", "pytest-rerunfailures", "python-snappy", "requests", "smbprotocol", "tqdm", "urllib3", "zarr", "zstandard"] tqdm = ["tqdm"] +[[package]] +name = "functions-framework" +version = "3.7.0" +description = "An open source FaaS (Function as a service) framework for writing portable Python functions -- brought to you by the Google Cloud Functions team." +optional = false +python-versions = "<4,>=3.5" +files = [ + {file = "functions_framework-3.7.0-py3-none-any.whl", hash = "sha256:bac05bcc30c1b7683213ce1c7eae5bbcb608b78d1f7394cd1b89957020786279"}, + {file = "functions_framework-3.7.0.tar.gz", hash = "sha256:b8844640db2cb2918ad2998875e050b1d0cb43f8981bcac13161a92db05a749b"}, +] + +[package.dependencies] +click = ">=7.0,<9.0" +cloudevents = ">=1.2.0,<2.0.0" +flask = ">=1.0,<4.0" +gunicorn = {version = ">=19.2.0", markers = "platform_system != \"Windows\""} +watchdog = ">=1.0.0" +Werkzeug = ">=0.14,<4.0.0" + +[[package]] +name = "gitdb" +version = "4.0.11" +description = "Git Object Database" +optional = false +python-versions = ">=3.7" +files = [ + {file = "gitdb-4.0.11-py3-none-any.whl", hash = "sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4"}, + {file = "gitdb-4.0.11.tar.gz", hash = "sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b"}, +] + +[package.dependencies] +smmap = ">=3.0.1,<6" + +[[package]] +name = "gitpython" +version = "3.1.43" +description = "GitPython is a Python library used to interact with Git repositories" +optional = false +python-versions = ">=3.7" +files = [ + {file = "GitPython-3.1.43-py3-none-any.whl", hash = "sha256:eec7ec56b92aad751f9912a73404bc02ba212a23adb2c7098ee668417051a1ff"}, + {file = "GitPython-3.1.43.tar.gz", hash = "sha256:35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"}, +] + +[package.dependencies] +gitdb = ">=4.0.1,<5" + +[package.extras] +doc = ["sphinx (==4.3.2)", "sphinx-autodoc-typehints", "sphinx-rtd-theme", "sphinxcontrib-applehelp (>=1.0.2,<=1.0.4)", "sphinxcontrib-devhelp (==1.0.2)", "sphinxcontrib-htmlhelp (>=2.0.0,<=2.0.1)", "sphinxcontrib-qthelp (==1.0.3)", "sphinxcontrib-serializinghtml (==1.1.5)"] +test = ["coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", "pytest (>=7.3.1)", "pytest-cov", "pytest-instafail", "pytest-mock", "pytest-sugar", "typing-extensions"] + [[package]] name = "google-api-core" version = "2.19.0" @@ -1626,6 +1901,14 @@ files = [ [package.dependencies] google-auth = ">=2.14.1,<3.0.dev0" googleapis-common-protos = ">=1.56.2,<2.0.dev0" +grpcio = [ + {version = ">=1.33.2,<2.0dev", optional = true, markers = "python_version < \"3.11\" and extra == \"grpc\""}, + {version = ">=1.49.1,<2.0dev", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}, +] +grpcio-status = [ + {version = ">=1.33.2,<2.0.dev0", optional = true, markers = "python_version < \"3.11\" and extra == \"grpc\""}, + {version = ">=1.49.1,<2.0.dev0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}, +] proto-plus = ">=1.22.3,<2.0.0dev" 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,<5.0.0.dev0" requests = ">=2.18.0,<3.0.0.dev0" @@ -1691,6 +1974,60 @@ files = [ google-auth = "*" httplib2 = ">=0.19.0" +[[package]] +name = "google-cloud-functions" +version = "1.16.3" +description = "Google Cloud Functions API client library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "google-cloud-functions-1.16.3.tar.gz", hash = "sha256:11bde312c37679bdf73247349044c21586ae23e43fe3475e2cff60bfe6dc9dd7"}, + {file = "google_cloud_functions-1.16.3-py2.py3-none-any.whl", hash = "sha256:017e997e59516afdab9b4b5d0328e93462ad7b65f426544e8b4e685e9de1f2fd"}, +] + +[package.dependencies] +google-api-core = {version = ">=1.34.1,<2.0.dev0 || >=2.11.dev0,<3.0.0dev", extras = ["grpc"]} +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 = ">=1.22.3,<2.0.0dev" +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,<5.0.0dev" + +[[package]] +name = "google-cloud-resource-manager" +version = "1.12.3" +description = "Google Cloud Resource Manager API client library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "google-cloud-resource-manager-1.12.3.tar.gz", hash = "sha256:809851824119834e4f2310b2c4f38621c1d16b2bb14d5b9f132e69c79d355e7f"}, + {file = "google_cloud_resource_manager-1.12.3-py2.py3-none-any.whl", hash = "sha256:92be7d6959927b76d90eafc4028985c37975a46ded5466a018f02e8649e113d4"}, +] + +[package.dependencies] +google-api-core = {version = ">=1.34.1,<2.0.dev0 || >=2.11.dev0,<3.0.0dev", extras = ["grpc"]} +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 = ">=1.22.3,<2.0.0dev" +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,<5.0.0dev" + +[[package]] +name = "google-cloud-secret-manager" +version = "2.20.0" +description = "Google Cloud Secret Manager API client library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "google-cloud-secret-manager-2.20.0.tar.gz", hash = "sha256:a086a7413aaf4fffbd1c4fe9229ef0ce9bcf48f5a8df5b449c4a32deb5a2cfde"}, + {file = "google_cloud_secret_manager-2.20.0-py2.py3-none-any.whl", hash = "sha256:c20bf22e59d220c51aa84a1db3411b14b83aa71f788fae8d273c03a4bf3e77ed"}, +] + +[package.dependencies] +google-api-core = {version = ">=1.34.1,<2.0.dev0 || >=2.11.dev0,<3.0.0dev", extras = ["grpc"]} +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 = ">=1.22.3,<2.0.0dev" +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,<5.0.0dev" + [[package]] name = "googleapis-common-protos" version = "1.63.0" @@ -1703,6 +2040,7 @@ files = [ ] [package.dependencies] +grpcio = {version = ">=1.44.0,<2.0.0.dev0", optional = true, markers = "extra == \"grpc\""} protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<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,<5.0.0.dev0" [package.extras] @@ -1832,6 +2170,22 @@ files = [ docs = ["Sphinx", "furo"] test = ["objgraph", "psutil"] +[[package]] +name = "grpc-google-iam-v1" +version = "0.13.0" +description = "IAM API client library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "grpc-google-iam-v1-0.13.0.tar.gz", hash = "sha256:fad318608b9e093258fbf12529180f400d1c44453698a33509cc6ecf005b294e"}, + {file = "grpc_google_iam_v1-0.13.0-py2.py3-none-any.whl", hash = "sha256:53902e2af7de8df8c1bd91373d9be55b0743ec267a7428ea638db3775becae89"}, +] + +[package.dependencies] +googleapis-common-protos = {version = ">=1.56.0,<2.0.0dev", extras = ["grpc"]} +grpcio = ">=1.44.0,<2.0.0dev" +protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<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,<5.0.0dev" + [[package]] name = "grpcio" version = "1.53.0" @@ -1889,6 +2243,43 @@ files = [ [package.extras] protobuf = ["grpcio-tools (>=1.53.0)"] +[[package]] +name = "grpcio-status" +version = "1.53.0" +description = "Status proto mapping for gRPC" +optional = false +python-versions = ">=3.6" +files = [ + {file = "grpcio-status-1.53.0.tar.gz", hash = "sha256:5a46820dc7d94bac48aae5dd97c94cadea09d80a05553aca74a92a2954030420"}, + {file = "grpcio_status-1.53.0-py3-none-any.whl", hash = "sha256:4f4bc140ed718a343d04a573c838c9fff5cb87f40d3cb2aa33b027c55031489d"}, +] + +[package.dependencies] +googleapis-common-protos = ">=1.5.5" +grpcio = ">=1.53.0" +protobuf = ">=4.21.6" + +[[package]] +name = "gunicorn" +version = "22.0.0" +description = "WSGI HTTP Server for UNIX" +optional = false +python-versions = ">=3.7" +files = [ + {file = "gunicorn-22.0.0-py3-none-any.whl", hash = "sha256:350679f91b24062c86e386e198a15438d53a7a8207235a78ba1b53df4c4378d9"}, + {file = "gunicorn-22.0.0.tar.gz", hash = "sha256:4a0b436239ff76fb33f11c07a16482c521a7e09c1ce3cc293c2330afe01bec63"}, +] + +[package.dependencies] +packaging = "*" + +[package.extras] +eventlet = ["eventlet (>=0.24.1,!=0.36.0)"] +gevent = ["gevent (>=1.4.0)"] +setproctitle = ["setproctitle"] +testing = ["coverage", "eventlet", "gevent", "pytest", "pytest-cov"] +tornado = ["tornado (>=0.2)"] + [[package]] name = "h11" version = "0.14.0" @@ -1900,6 +2291,21 @@ files = [ {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, ] +[[package]] +name = "h2" +version = "4.1.0" +description = "HTTP/2 State-Machine based protocol implementation" +optional = false +python-versions = ">=3.6.1" +files = [ + {file = "h2-4.1.0-py3-none-any.whl", hash = "sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d"}, + {file = "h2-4.1.0.tar.gz", hash = "sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb"}, +] + +[package.dependencies] +hpack = ">=4.0,<5" +hyperframe = ">=6.0,<7" + [[package]] name = "hexbytes" version = "0.3.1" @@ -1917,6 +2323,17 @@ doc = ["sphinx (>=5.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)"] lint = ["black (>=22)", "flake8 (==6.0.0)", "flake8-bugbear (==23.3.23)", "isort (>=5.10.1)", "mypy (==0.971)", "pydocstyle (>=5.0.0)"] test = ["eth-utils (>=1.0.1,<3)", "hypothesis (>=3.44.24,<=6.31.6)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)"] +[[package]] +name = "hpack" +version = "4.0.0" +description = "Pure-Python HPACK header compression" +optional = false +python-versions = ">=3.6.1" +files = [ + {file = "hpack-4.0.0-py3-none-any.whl", hash = "sha256:84a076fad3dc9a9f8063ccb8041ef100867b1878b25ef0ee63847a5d53818a6c"}, + {file = "hpack-4.0.0.tar.gz", hash = "sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095"}, +] + [[package]] name = "httpcore" version = "1.0.5" @@ -2002,18 +2419,19 @@ test = ["Cython (>=0.29.24,<0.30.0)"] [[package]] name = "httpx" -version = "0.27.0" +version = "0.25.2" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.0-py3-none-any.whl", hash = "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5"}, - {file = "httpx-0.27.0.tar.gz", hash = "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5"}, + {file = "httpx-0.25.2-py3-none-any.whl", hash = "sha256:a05d3d052d9b2dfce0e3896636467f8a5342fb2b902c819428e1ac65413ca118"}, + {file = "httpx-0.25.2.tar.gz", hash = "sha256:8b8fcaa0c8ea7b05edd69a094e63a2094c4efcb48129fb757361bc423c0ad9e8"}, ] [package.dependencies] anyio = "*" certifi = "*" +h2 = {version = ">=3,<5", optional = true, markers = "extra == \"http2\""} httpcore = "==1.*" idna = "*" sniffio = "*" @@ -2072,6 +2490,17 @@ files = [ [package.dependencies] pyreadline3 = {version = "*", markers = "sys_platform == \"win32\" and python_version >= \"3.8\""} +[[package]] +name = "hyperframe" +version = "6.0.1" +description = "HTTP/2 framing layer for Python" +optional = false +python-versions = ">=3.6.1" +files = [ + {file = "hyperframe-6.0.1-py3-none-any.whl", hash = "sha256:0ec6bafd80d8ad2195c4f03aacba3a8265e57bc4cff261e802bf39970ed02a15"}, + {file = "hyperframe-6.0.1.tar.gz", hash = "sha256:ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914"}, +] + [[package]] name = "hypothesis" version = "6.21.6" @@ -2205,6 +2634,20 @@ files = [ multiaddr = ">=0.0.7" requests = ">=2.11" +[[package]] +name = "isort" +version = "5.13.2" +description = "A Python utility / library to sort Python imports." +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, + {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, +] + +[package.extras] +colors = ["colorama (>=0.4.6)"] + [[package]] name = "itsdangerous" version = "2.2.0" @@ -2426,6 +2869,30 @@ language-data = ">=1.2" build = ["build", "twine"] test = ["pytest", "pytest-cov"] +[[package]] +name = "langfuse" +version = "2.33.0" +description = "A client library for accessing langfuse" +optional = false +python-versions = "<4.0,>=3.8.1" +files = [ + {file = "langfuse-2.33.0-py3-none-any.whl", hash = "sha256:362e3078c5a891df0b7ba3c9ce82f046d1f0274eab3d55337e443fff526f18ad"}, + {file = "langfuse-2.33.0.tar.gz", hash = "sha256:3ca2ef8539a8f28cb80135f4b46b80d5585ce183f8e2035f318be296d09d7d88"}, +] + +[package.dependencies] +backoff = ">=1.10.0" +httpx = ">=0.15.4,<1.0" +idna = ">=3.7,<4.0" +packaging = ">=23.2,<24.0" +pydantic = ">=1.10.7,<3.0" +wrapt = ">=1.14,<2.0" + +[package.extras] +langchain = ["langchain (>=0.0.309)"] +llama-index = ["llama-index (>=0.10.12,<2.0.0)"] +openai = ["openai (>=0.27.8)"] + [[package]] name = "langgraph" version = "0.0.55" @@ -2475,6 +2942,24 @@ marisa-trie = ">=0.7.7" build = ["build", "twine"] test = ["pytest", "pytest-cov"] +[[package]] +name = "loguru" +version = "0.7.2" +description = "Python logging made (stupidly) simple" +optional = false +python-versions = ">=3.5" +files = [ + {file = "loguru-0.7.2-py3-none-any.whl", hash = "sha256:003d71e3d3ed35f0f8984898359d65b79e5b21943f78af86aa5491210429b8eb"}, + {file = "loguru-0.7.2.tar.gz", hash = "sha256:e671a53522515f34fd406340ee968cb9ecafbc4b36c679da03c18fd8d0bd51ac"}, +] + +[package.dependencies] +colorama = {version = ">=0.3.4", markers = "sys_platform == \"win32\""} +win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""} + +[package.extras] +dev = ["Sphinx (==7.2.5)", "colorama (==0.4.5)", "colorama (==0.4.6)", "exceptiongroup (==1.1.3)", "freezegun (==1.1.0)", "freezegun (==1.2.2)", "mypy (==v0.910)", "mypy (==v0.971)", "mypy (==v1.4.1)", "mypy (==v1.5.1)", "pre-commit (==3.4.0)", "pytest (==6.1.2)", "pytest (==7.4.0)", "pytest-cov (==2.12.1)", "pytest-cov (==4.1.0)", "pytest-mypy-plugins (==1.9.3)", "pytest-mypy-plugins (==3.0.0)", "sphinx-autobuild (==2021.3.14)", "sphinx-rtd-theme (==1.3.0)", "tox (==3.27.1)", "tox (==4.11.0)"] + [[package]] name = "lru-dict" version = "1.2.0" @@ -2847,6 +3332,30 @@ setuptools = "*" [package.extras] test = ["hypothesis", "pytest", "readme-renderer"] +[[package]] +name = "markdown-it-py" +version = "3.0.0" +description = "Python port of markdown-it. Markdown parsing, done right!" +optional = false +python-versions = ">=3.8" +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"}, +] + +[package.dependencies] +mdurl = ">=0.1,<1.0" + +[package.extras] +benchmarking = ["psutil", "pytest", "pytest-benchmark"] +code-style = ["pre-commit (>=3.0,<4.0)"] +compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] +linkify = ["linkify-it-py (>=1,<3)"] +plugins = ["mdit-py-plugins"] +profiling = ["gprof2dot"] +rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] + [[package]] name = "markdownify" version = "0.11.6" @@ -2950,6 +3459,17 @@ dev = ["marshmallow[tests]", "pre-commit (>=3.5,<4.0)", "tox"] docs = ["alabaster (==0.7.16)", "autodocsumm (==0.2.12)", "sphinx (==7.3.7)", "sphinx-issues (==4.1.0)", "sphinx-version-warning (==1.1.2)"] tests = ["pytest", "pytz", "simplejson"] +[[package]] +name = "mdurl" +version = "0.1.2" +description = "Markdown URL utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, + {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, +] + [[package]] name = "mech-client" version = "0.2.5" @@ -3583,7 +4103,6 @@ files = [ numpy = [ {version = ">=1.22.4", markers = "python_version < \"3.11\""}, {version = ">=1.23.2", markers = "python_version == \"3.11\""}, - {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, ] python-dateutil = ">=2.8.2" pytz = ">=2020.1" @@ -3733,6 +4252,17 @@ tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "pa typing = ["typing-extensions"] xmp = ["defusedxml"] +[[package]] +name = "pipe" +version = "2.2" +description = "Module enabling a sh like infix syntax (using pipes)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pipe-2.2-py3-none-any.whl", hash = "sha256:0a5c3202ff35122f69a34ccbd40c9658646f033cc941055304fe8bfa7e13376e"}, + {file = "pipe-2.2.tar.gz", hash = "sha256:6a253198e3bc542ffaf0a4222376586bce8583b27a9ddbc2cfbaa554c049230d"}, +] + [[package]] name = "platformdirs" version = "4.2.2" @@ -3787,6 +4317,54 @@ dev = ["black", "flake8", "flake8-print", "isort", "pre-commit"] sentry = ["django", "sentry-sdk"] test = ["coverage", "flake8", "freezegun (==0.3.15)", "mock (>=2.0.0)", "pylint", "pytest", "pytest-timeout"] +[[package]] +name = "prediction-market-agent-tooling" +version = "0.31.0" +description = "Tools to benchmark, deploy and monitor prediction market agents." +optional = false +python-versions = ">=3.10,<3.12" +files = [] +develop = false + +[package.dependencies] +autoflake = "^2.2.1" +cron-validator = "^1.0.8" +eth-account = "*" +eth-typing = "^3.0.0" +functions-framework = "^3.5.0" +google-cloud-functions = "^1.16.0" +google-cloud-resource-manager = "^1.12.0" +google-cloud-secret-manager = "^2.18.2" +isort = "^5.13.2" +langchain-community = ">=0.0.19" +langfuse = "^2.27.1" +loguru = "^0.7.2" +numpy = "^1.26.4" +prompt-toolkit = "^3.0.43" +pydantic = "^2.6.1" +pydantic-settings = "^2.1.0" +safe-cli = "^1.0.0" +safe-eth-py = "^6.0.0b14" +scikit-learn = "^1.3.1" +streamlit = "^1.31.0" +subgrounds = {git = "https://github.com/gabrielfior/subgrounds", branch = "main"} +tabulate = "^0.9.0" +tqdm = "^4.66.2" +typer = "^0.9.0" +types-pytz = "^2024.1.0.20240203" +types-requests = "^2.31.0.0" +web3 = "^6.15.1" + +[package.extras] +google = ["google-api-python-client (==2.95.0)"] +langchain = ["langchain (>=0.1.9,<0.2.0)", "langchain-openai (>=0.0.5,<0.0.6)"] + +[package.source] +type = "git" +url = "https://github.com/gnosis/prediction-market-agent-tooling.git" +reference = "gabriel/olas-deps" +resolved_reference = "931a636d6446ea542ff5826755e7e4c2fcb5f886" + [[package]] name = "preshed" version = "3.0.9" @@ -3847,6 +4425,20 @@ files = [ [package.dependencies] tqdm = "*" +[[package]] +name = "prompt-toolkit" +version = "3.0.45" +description = "Library for building powerful interactive command lines in Python" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "prompt_toolkit-3.0.45-py3-none-any.whl", hash = "sha256:a29b89160e494e3ea8622b09fa5897610b437884dcdcd054fdc1308883326c2a"}, + {file = "prompt_toolkit-3.0.45.tar.gz", hash = "sha256:07c60ee4ab7b7e90824b61afa840c8f5aad2d46b3e2e10acc33d8ecc94a49089"}, +] + +[package.dependencies] +wcwidth = "*" + [[package]] name = "proto-plus" version = "1.23.0" @@ -3966,6 +4558,37 @@ dev = ["bumpversion (>=0.5.3,<1)", "flake8 (==3.5.0)", "mypy (==0.641)", "mypy-e lint = ["flake8 (==3.5.0)", "mypy (==0.641)", "mypy-extensions (>=0.4.1)"] test = ["pytest (==6.2.5)", "pytest-xdist (==1.26.0)"] +[[package]] +name = "py-evm" +version = "0.10.1b1" +description = "Python implementation of the Ethereum Virtual Machine" +optional = false +python-versions = "<4,>=3.8" +files = [ + {file = "py_evm-0.10.1b1-py3-none-any.whl", hash = "sha256:f0fc4a4b904917b40e6a06f87925017dc48ea6582e95f88d28be38f3566e2bae"}, + {file = "py_evm-0.10.1b1.tar.gz", hash = "sha256:aeb889514af12b6a8cb5091fe93008642eadf7c19999859dad3191eaf451647c"}, +] + +[package.dependencies] +cached-property = ">=1.5.1" +ckzg = ">=0.4.3" +eth-bloom = ">=1.0.3" +eth-keys = ">=0.4.0" +eth-typing = ">=3.3.0" +eth-utils = ">=2.0.0" +lru-dict = ">=1.1.6" +py-ecc = ">=1.4.7" +rlp = ">=3.0.0" +trie = ">=2.0.0" + +[package.extras] +benchmark = ["termcolor (>=1.1.0)", "web3 (>=6.0.0)"] +dev = ["build (>=0.9.0)", "bumpversion (>=0.5.3)", "cached-property (>=1.5.1)", "ckzg (>=0.4.3)", "eth-bloom (>=1.0.3)", "eth-keys (>=0.4.0)", "eth-typing (>=3.3.0)", "eth-utils (>=2.0.0)", "factory-boy (>=3.0.0)", "hypothesis (>=6,<7)", "ipython", "lru-dict (>=1.1.6)", "pre-commit (>=3.4.0)", "py-ecc (>=1.4.7)", "py-evm (>=0.8.0b1)", "pytest (>=7.0.0)", "pytest-asyncio (>=0.20.0)", "pytest-cov (>=4.0.0)", "pytest-timeout (>=2.0.0)", "pytest-xdist (>=3.0)", "rlp (>=3.0.0)", "sphinx (>=6.0.0)", "sphinx-rtd-theme (>=1.0.0)", "sphinxcontrib-asyncio (>=0.2.0)", "towncrier (>=21,<22)", "tox (>=4.0.0)", "trie (>=2.0.0)", "twine", "wheel"] +docs = ["py-evm (>=0.8.0b1)", "sphinx (>=6.0.0)", "sphinx-rtd-theme (>=1.0.0)", "sphinxcontrib-asyncio (>=0.2.0)", "towncrier (>=21,<22)"] +eth = ["cached-property (>=1.5.1)", "ckzg (>=0.4.3)", "eth-bloom (>=1.0.3)", "eth-keys (>=0.4.0)", "eth-typing (>=3.3.0)", "eth-utils (>=2.0.0)", "lru-dict (>=1.1.6)", "py-ecc (>=1.4.7)", "rlp (>=3.0.0)", "trie (>=2.0.0)"] +eth-extra = ["blake2b-py (>=0.2.0)", "coincurve (>=18.0.0)"] +test = ["factory-boy (>=3.0.0)", "hypothesis (>=6,<7)", "pytest (>=7.0.0)", "pytest-asyncio (>=0.20.0)", "pytest-cov (>=4.0.0)", "pytest-timeout (>=2.0.0)", "pytest-xdist (>=3.0)"] + [[package]] name = "py-multibase" version = "1.0.3" @@ -3998,6 +4621,54 @@ morphys = ">=1.0,<2.0" six = ">=1.10.0,<2.0" varint = ">=1.0.2,<2.0.0" +[[package]] +name = "pyarrow" +version = "16.1.0" +description = "Python library for Apache Arrow" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pyarrow-16.1.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:17e23b9a65a70cc733d8b738baa6ad3722298fa0c81d88f63ff94bf25eaa77b9"}, + {file = "pyarrow-16.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4740cc41e2ba5d641071d0ab5e9ef9b5e6e8c7611351a5cb7c1d175eaf43674a"}, + {file = "pyarrow-16.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:98100e0268d04e0eec47b73f20b39c45b4006f3c4233719c3848aa27a03c1aef"}, + {file = "pyarrow-16.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f68f409e7b283c085f2da014f9ef81e885d90dcd733bd648cfba3ef265961848"}, + {file = "pyarrow-16.1.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:a8914cd176f448e09746037b0c6b3a9d7688cef451ec5735094055116857580c"}, + {file = "pyarrow-16.1.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:48be160782c0556156d91adbdd5a4a7e719f8d407cb46ae3bb4eaee09b3111bd"}, + {file = "pyarrow-16.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:9cf389d444b0f41d9fe1444b70650fea31e9d52cfcb5f818b7888b91b586efff"}, + {file = "pyarrow-16.1.0-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:d0ebea336b535b37eee9eee31761813086d33ed06de9ab6fc6aaa0bace7b250c"}, + {file = "pyarrow-16.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2e73cfc4a99e796727919c5541c65bb88b973377501e39b9842ea71401ca6c1c"}, + {file = "pyarrow-16.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf9251264247ecfe93e5f5a0cd43b8ae834f1e61d1abca22da55b20c788417f6"}, + {file = "pyarrow-16.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddf5aace92d520d3d2a20031d8b0ec27b4395cab9f74e07cc95edf42a5cc0147"}, + {file = "pyarrow-16.1.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:25233642583bf658f629eb230b9bb79d9af4d9f9229890b3c878699c82f7d11e"}, + {file = "pyarrow-16.1.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:a33a64576fddfbec0a44112eaf844c20853647ca833e9a647bfae0582b2ff94b"}, + {file = "pyarrow-16.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:185d121b50836379fe012753cf15c4ba9638bda9645183ab36246923875f8d1b"}, + {file = "pyarrow-16.1.0-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:2e51ca1d6ed7f2e9d5c3c83decf27b0d17bb207a7dea986e8dc3e24f80ff7d6f"}, + {file = "pyarrow-16.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:06ebccb6f8cb7357de85f60d5da50e83507954af617d7b05f48af1621d331c9a"}, + {file = "pyarrow-16.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b04707f1979815f5e49824ce52d1dceb46e2f12909a48a6a753fe7cafbc44a0c"}, + {file = "pyarrow-16.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d32000693deff8dc5df444b032b5985a48592c0697cb6e3071a5d59888714e2"}, + {file = "pyarrow-16.1.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:8785bb10d5d6fd5e15d718ee1d1f914fe768bf8b4d1e5e9bf253de8a26cb1628"}, + {file = "pyarrow-16.1.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:e1369af39587b794873b8a307cc6623a3b1194e69399af0efd05bb202195a5a7"}, + {file = "pyarrow-16.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:febde33305f1498f6df85e8020bca496d0e9ebf2093bab9e0f65e2b4ae2b3444"}, + {file = "pyarrow-16.1.0-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:b5f5705ab977947a43ac83b52ade3b881eb6e95fcc02d76f501d549a210ba77f"}, + {file = "pyarrow-16.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0d27bf89dfc2576f6206e9cd6cf7a107c9c06dc13d53bbc25b0bd4556f19cf5f"}, + {file = "pyarrow-16.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d07de3ee730647a600037bc1d7b7994067ed64d0eba797ac74b2bc77384f4c2"}, + {file = "pyarrow-16.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fbef391b63f708e103df99fbaa3acf9f671d77a183a07546ba2f2c297b361e83"}, + {file = "pyarrow-16.1.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:19741c4dbbbc986d38856ee7ddfdd6a00fc3b0fc2d928795b95410d38bb97d15"}, + {file = "pyarrow-16.1.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:f2c5fb249caa17b94e2b9278b36a05ce03d3180e6da0c4c3b3ce5b2788f30eed"}, + {file = "pyarrow-16.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:e6b6d3cd35fbb93b70ade1336022cc1147b95ec6af7d36906ca7fe432eb09710"}, + {file = "pyarrow-16.1.0-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:18da9b76a36a954665ccca8aa6bd9f46c1145f79c0bb8f4f244f5f8e799bca55"}, + {file = "pyarrow-16.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:99f7549779b6e434467d2aa43ab2b7224dd9e41bdde486020bae198978c9e05e"}, + {file = "pyarrow-16.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f07fdffe4fd5b15f5ec15c8b64584868d063bc22b86b46c9695624ca3505b7b4"}, + {file = "pyarrow-16.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddfe389a08ea374972bd4065d5f25d14e36b43ebc22fc75f7b951f24378bf0b5"}, + {file = "pyarrow-16.1.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:3b20bd67c94b3a2ea0a749d2a5712fc845a69cb5d52e78e6449bbd295611f3aa"}, + {file = "pyarrow-16.1.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:ba8ac20693c0bb0bf4b238751d4409e62852004a8cf031c73b0e0962b03e45e3"}, + {file = "pyarrow-16.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:31a1851751433d89a986616015841977e0a188662fcffd1a5677453f1df2de0a"}, + {file = "pyarrow-16.1.0.tar.gz", hash = "sha256:15fbb22ea96d11f0b5768504a3f961edab25eaf4197c341720c4a387f6c60315"}, +] + +[package.dependencies] +numpy = ">=1.16.6" + [[package]] name = "pyasn1" version = "0.6.0" @@ -4185,6 +4856,69 @@ files = [ [package.dependencies] typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" +[[package]] +name = "pydantic-settings" +version = "2.2.1" +description = "Settings management using Pydantic" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic_settings-2.2.1-py3-none-any.whl", hash = "sha256:0235391d26db4d2190cb9b31051c4b46882d28a51533f97440867f012d4da091"}, + {file = "pydantic_settings-2.2.1.tar.gz", hash = "sha256:00b9f6a5e95553590434c0fa01ead0b216c3e10bc54ae02e37f359948643c5ed"}, +] + +[package.dependencies] +pydantic = ">=2.3.0" +python-dotenv = ">=0.21.0" + +[package.extras] +toml = ["tomli (>=2.0.1)"] +yaml = ["pyyaml (>=6.0.1)"] + +[[package]] +name = "pydeck" +version = "0.9.1" +description = "Widget for deck.gl maps" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydeck-0.9.1-py2.py3-none-any.whl", hash = "sha256:b3f75ba0d273fc917094fa61224f3f6076ca8752b93d46faf3bcfd9f9d59b038"}, + {file = "pydeck-0.9.1.tar.gz", hash = "sha256:f74475ae637951d63f2ee58326757f8d4f9cd9f2a457cf42950715003e2cb605"}, +] + +[package.dependencies] +jinja2 = ">=2.10.1" +numpy = ">=1.16.4" + +[package.extras] +carto = ["pydeck-carto"] +jupyter = ["ipykernel (>=5.1.2)", "ipython (>=5.8.0)", "ipywidgets (>=7,<8)", "traitlets (>=4.3.2)"] + +[[package]] +name = "pyflakes" +version = "3.2.0" +description = "passive checker of Python programs" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pyflakes-3.2.0-py2.py3-none-any.whl", hash = "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a"}, + {file = "pyflakes-3.2.0.tar.gz", hash = "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f"}, +] + +[[package]] +name = "pygments" +version = "2.18.0" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, + {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, +] + +[package.extras] +windows-terminal = ["colorama (>=0.4.6)"] + [[package]] name = "pymultihash" version = "0.8.2" @@ -4711,6 +5445,24 @@ files = [ [package.dependencies] requests = ">=2.0.1,<3.0.0" +[[package]] +name = "rich" +version = "13.7.1" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "rich-13.7.1-py3-none-any.whl", hash = "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222"}, + {file = "rich-13.7.1.tar.gz", hash = "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432"}, +] + +[package.dependencies] +markdown-it-py = ">=2.2.0" +pygments = ">=2.13.0,<3.0.0" + +[package.extras] +jupyter = ["ipywidgets (>=7.5.1,<9)"] + [[package]] name = "rlp" version = "3.0.0" @@ -4746,6 +5498,61 @@ files = [ [package.dependencies] pyasn1 = ">=0.1.3" +[[package]] +name = "safe-cli" +version = "1.1.0" +description = "Command Line Interface for Safe" +optional = false +python-versions = ">=3.9" +files = [ + {file = "safe_cli-1.1.0-py3-none-any.whl", hash = "sha256:1dfd95d1a363374bed682652ea1335033bc5f856652955b2378e8b03228d6122"}, + {file = "safe_cli-1.1.0.tar.gz", hash = "sha256:a40e3c79b71956cdac13a38aa7d3a885fffd412015ba1a6d9b484c2ed0f498ac"}, +] + +[package.dependencies] +art = ">=6" +colorama = ">=0.4" +prompt-toolkit = ">=3" +pygments = ">=2" +requests = ">=2" +safe-eth-py = "6.0.0b26" +tabulate = ">=0.8" + +[package.extras] +ledger = ["ledgereth (==0.9.1)"] +trezor = ["trezor (==0.13.8)"] + +[[package]] +name = "safe-eth-py" +version = "6.0.0b26" +description = "Safe Ecosystem Foundation utilities for Ethereum projects" +optional = false +python-versions = ">=3.9" +files = [ + {file = "safe_eth_py-6.0.0b26-py3-none-any.whl", hash = "sha256:49e674348b03b6cfd3f3b1960658ac109868318e49948766e41a1e9ea34dfbd4"}, + {file = "safe_eth_py-6.0.0b26.tar.gz", hash = "sha256:140bceb02fd701b55c5c383142deb8307f2de7fbee45cafbaddb945250f5d91b"}, +] + +[package.dependencies] +packaging = "*" +py-evm = ">=0.7.0a1" +requests = ">=2" +safe-pysha3 = ">=1.0.0" +web3 = ">=6.2.0" + +[package.extras] +django = ["django (>=2)", "django-filter (>=2)", "djangorestframework (>=2)"] + +[[package]] +name = "safe-pysha3" +version = "1.0.4" +description = "SHA-3 (Keccak) for Python 3.9 - 3.11" +optional = false +python-versions = "*" +files = [ + {file = "safe-pysha3-1.0.4.tar.gz", hash = "sha256:e429146b1edd198b2ca934a2046a65656c5d31b0ec894bbd6055127f4deaff17"}, +] + [[package]] name = "scikit-learn" version = "1.3.1" @@ -4893,6 +5700,17 @@ ssh = ["paramiko"] test = ["azure-common", "azure-core", "azure-storage-blob", "boto3", "google-cloud-storage (>=2.6.0)", "moto[server]", "paramiko", "pytest", "pytest-rerunfailures", "requests", "responses"] webhdfs = ["requests"] +[[package]] +name = "smmap" +version = "5.0.1" +description = "A pure Python implementation of a sliding window memory map manager" +optional = false +python-versions = ">=3.7" +files = [ + {file = "smmap-5.0.1-py3-none-any.whl", hash = "sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da"}, + {file = "smmap-5.0.1.tar.gz", hash = "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62"}, +] + [[package]] name = "sniffio" version = "1.3.1" @@ -5095,7 +5913,7 @@ files = [ ] [package.dependencies] -greenlet = {version = "!=0.4.17", markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\""} +greenlet = {version = "!=0.4.17", markers = "platform_machine == \"win32\" or platform_machine == \"WIN32\" or platform_machine == \"AMD64\" or platform_machine == \"amd64\" or platform_machine == \"x86_64\" or platform_machine == \"ppc64le\" or platform_machine == \"aarch64\""} typing-extensions = ">=4.6.0" [package.extras] @@ -5186,6 +6004,68 @@ anyio = ">=3.4.0,<5" [package.extras] full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7)", "pyyaml"] +[[package]] +name = "streamlit" +version = "1.35.0" +description = "A faster way to build and share data apps" +optional = false +python-versions = "!=3.9.7,>=3.8" +files = [ + {file = "streamlit-1.35.0-py2.py3-none-any.whl", hash = "sha256:e17d1d86830a0d7687c37faf2fe47bffa752d0c95a306e96d7749bd3faa72a5b"}, + {file = "streamlit-1.35.0.tar.gz", hash = "sha256:679d55bb6189743f606abf0696623df0bfd223a6d0c8d96b8d60678d4891d2d6"}, +] + +[package.dependencies] +altair = ">=4.0,<6" +blinker = ">=1.0.0,<2" +cachetools = ">=4.0,<6" +click = ">=7.0,<9" +gitpython = ">=3.0.7,<3.1.19 || >3.1.19,<4" +numpy = ">=1.19.3,<2" +packaging = ">=16.8,<25" +pandas = ">=1.3.0,<3" +pillow = ">=7.1.0,<11" +protobuf = ">=3.20,<5" +pyarrow = ">=7.0" +pydeck = ">=0.8.0b4,<1" +requests = ">=2.27,<3" +rich = ">=10.14.0,<14" +tenacity = ">=8.1.0,<9" +toml = ">=0.10.1,<2" +tornado = ">=6.0.3,<7" +typing-extensions = ">=4.3.0,<5" +watchdog = {version = ">=2.1.5", markers = "platform_system != \"Darwin\""} + +[package.extras] +snowflake = ["snowflake-connector-python (>=2.8.0)", "snowflake-snowpark-python (>=0.9.0)"] + +[[package]] +name = "subgrounds" +version = "1.8.1" +description = "A Pythonic data access layer for applications querying data from The Graph Network." +optional = false +python-versions = "^3.10" +files = [] +develop = false + +[package.dependencies] +httpx = {version = "^0.25.1", extras = ["http2"]} +pandas = ">=1.4.2, ^2.1" +pipe = "^2.0" +pydantic = "^2.6.1" +pytest-asyncio = "*" + +[package.extras] +all = ["dash (>=2.3.1,<3.0.0)", "plotly (>=5.14.1,<6.0.0)"] +dash = ["dash (>=2.3.1,<3.0.0)"] +plotly = ["plotly (>=5.14.1,<6.0.0)"] + +[package.source] +type = "git" +url = "https://github.com/gabrielfior/subgrounds" +reference = "main" +resolved_reference = "71de9144bc6fcb06917c64f20a14c1a06d79bcf4" + [[package]] name = "sympy" version = "1.12" @@ -5200,6 +6080,20 @@ files = [ [package.dependencies] mpmath = ">=0.19" +[[package]] +name = "tabulate" +version = "0.9.0" +description = "Pretty-print tabular data" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f"}, + {file = "tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c"}, +] + +[package.extras] +widechars = ["wcwidth"] + [[package]] name = "tavily-python" version = "0.3.3" @@ -5573,6 +6467,26 @@ files = [ {file = "toolz-0.12.1.tar.gz", hash = "sha256:ecca342664893f177a13dac0e6b41cbd8ac25a358e5f215316d43e2100224f4d"}, ] +[[package]] +name = "tornado" +version = "6.4" +description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." +optional = false +python-versions = ">= 3.8" +files = [ + {file = "tornado-6.4-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:02ccefc7d8211e5a7f9e8bc3f9e5b0ad6262ba2fbb683a6443ecc804e5224ce0"}, + {file = "tornado-6.4-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:27787de946a9cffd63ce5814c33f734c627a87072ec7eed71f7fc4417bb16263"}, + {file = "tornado-6.4-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7894c581ecdcf91666a0912f18ce5e757213999e183ebfc2c3fdbf4d5bd764e"}, + {file = "tornado-6.4-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e43bc2e5370a6a8e413e1e1cd0c91bedc5bd62a74a532371042a18ef19e10579"}, + {file = "tornado-6.4-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0251554cdd50b4b44362f73ad5ba7126fc5b2c2895cc62b14a1c2d7ea32f212"}, + {file = "tornado-6.4-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fd03192e287fbd0899dd8f81c6fb9cbbc69194d2074b38f384cb6fa72b80e9c2"}, + {file = "tornado-6.4-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:88b84956273fbd73420e6d4b8d5ccbe913c65d31351b4c004ae362eba06e1f78"}, + {file = "tornado-6.4-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:71ddfc23a0e03ef2df1c1397d859868d158c8276a0603b96cf86892bff58149f"}, + {file = "tornado-6.4-cp38-abi3-win32.whl", hash = "sha256:6f8a6c77900f5ae93d8b4ae1196472d0ccc2775cc1dfdc9e7727889145c45052"}, + {file = "tornado-6.4-cp38-abi3-win_amd64.whl", hash = "sha256:10aeaa8006333433da48dec9fe417877f8bcc21f48dda8d661ae79da357b2a63"}, + {file = "tornado-6.4.tar.gz", hash = "sha256:72291fa6e6bc84e626589f1c29d90a5a6d593ef5ae68052ee2ef000dfd273dee"}, +] + [[package]] name = "tox" version = "3.28.0" @@ -5618,6 +6532,29 @@ notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] +[[package]] +name = "trie" +version = "3.0.1" +description = "Python implementation of the Ethereum Trie structure" +optional = false +python-versions = "<4,>=3.8" +files = [ + {file = "trie-3.0.1-py3-none-any.whl", hash = "sha256:fbe90011a28f4fc6597bc83706589c2a74c81c8b1410c5e16eebfae0e9796464"}, + {file = "trie-3.0.1.tar.gz", hash = "sha256:3f53adaa04726eb23cb786b0118e62d1f2fb6ed0a7968be964dc34aba27380ee"}, +] + +[package.dependencies] +eth-hash = ">=0.1.0" +eth-utils = ">=2.0.0" +hexbytes = ">=0.2.3" +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"] +docs = ["towncrier (>=21,<22)"] +test = ["hypothesis (>=6.56.4,<7)", "pycryptodome", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)"] + [[package]] name = "typer" version = "0.9.4" @@ -5639,6 +6576,42 @@ dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "pre-commit (>=2 doc = ["cairosvg (>=2.5.2,<3.0.0)", "mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "pillow (>=9.3.0,<10.0.0)"] test = ["black (>=22.3.0,<23.0.0)", "coverage (>=6.2,<7.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.971)", "pytest (>=4.4.0,<8.0.0)", "pytest-cov (>=2.10.0,<5.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "pytest-xdist (>=1.32.0,<4.0.0)", "rich (>=10.11.0,<14.0.0)", "shellingham (>=1.3.0,<2.0.0)"] +[[package]] +name = "types-pytz" +version = "2024.1.0.20240417" +description = "Typing stubs for pytz" +optional = false +python-versions = ">=3.8" +files = [ + {file = "types-pytz-2024.1.0.20240417.tar.gz", hash = "sha256:6810c8a1f68f21fdf0f4f374a432487c77645a0ac0b31de4bf4690cf21ad3981"}, + {file = "types_pytz-2024.1.0.20240417-py3-none-any.whl", hash = "sha256:8335d443310e2db7b74e007414e74c4f53b67452c0cb0d228ca359ccfba59659"}, +] + +[[package]] +name = "types-requests" +version = "2.31.0.6" +description = "Typing stubs for requests" +optional = false +python-versions = ">=3.7" +files = [ + {file = "types-requests-2.31.0.6.tar.gz", hash = "sha256:cd74ce3b53c461f1228a9b783929ac73a666658f223e28ed29753771477b3bd0"}, + {file = "types_requests-2.31.0.6-py3-none-any.whl", hash = "sha256:a2db9cb228a81da8348b49ad6db3f5519452dd20a9c1e1a868c83c5fe88fd1a9"}, +] + +[package.dependencies] +types-urllib3 = "*" + +[[package]] +name = "types-urllib3" +version = "1.26.25.14" +description = "Typing stubs for urllib3" +optional = false +python-versions = "*" +files = [ + {file = "types-urllib3-1.26.25.14.tar.gz", hash = "sha256:229b7f577c951b8c1b92c1bc2b2fdb0b49847bd2af6d1cc2a2e3dd340f3bda8f"}, + {file = "types_urllib3-1.26.25.14-py3-none-any.whl", hash = "sha256:9683bbb7fb72e32bfe9d2be6e04875fbe1b3eeec3cbb4ea231435aa7fd6b4f0e"}, +] + [[package]] name = "typing-extensions" version = "4.12.0" @@ -5987,6 +6960,17 @@ files = [ [package.dependencies] anyio = ">=3.0.0" +[[package]] +name = "wcwidth" +version = "0.2.13" +description = "Measures the displayed width of unicode strings in a terminal" +optional = false +python-versions = "*" +files = [ + {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, + {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, +] + [[package]] name = "weasel" version = "0.3.4" @@ -6152,6 +7136,99 @@ files = [ [package.extras] watchdog = ["watchdog"] +[[package]] +name = "win32-setctime" +version = "1.1.0" +description = "A small Python utility to set file creation time on Windows" +optional = false +python-versions = ">=3.5" +files = [ + {file = "win32_setctime-1.1.0-py3-none-any.whl", hash = "sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad"}, + {file = "win32_setctime-1.1.0.tar.gz", hash = "sha256:15cf5750465118d6929ae4de4eb46e8edae9a5634350c01ba582df868e932cb2"}, +] + +[package.extras] +dev = ["black (>=19.3b0)", "pytest (>=4.6.2)"] + +[[package]] +name = "wrapt" +version = "1.16.0" +description = "Module for decorators, wrappers and monkey patching." +optional = false +python-versions = ">=3.6" +files = [ + {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, + {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, + {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, + {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, + {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, + {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, + {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, + {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, + {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, + {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, + {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, + {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, + {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, + {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, + {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, + {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, + {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, + {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, +] + [[package]] name = "yarl" version = "1.9.4" @@ -6257,5 +7334,5 @@ multidict = ">=4.0" [metadata] lock-version = "2.0" -python-versions = "^3.10" -content-hash = "e792890e5bd57bf4482a54d44efd5f9c0eb9fefcb193c0377072ca23ff288b4b" +python-versions = ">=3.10,<3.12" +content-hash = "f20a0edbb79f7251216273298bd014a6df97165c596181d9c9f059c0b5ce9770" diff --git a/pyproject.toml b/pyproject.toml index b94a7044..77d6674b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,7 +15,7 @@ classifiers = [ "Environment :: Console", "Environment :: Web Environment", "Dev include = "packages" [tool.poetry.dependencies] -python = "^3.10" +python = ">=3.10,<3.12" open-autonomy = "==0.14.10" openai = "==1.30.2" requests = "==2.28.1" @@ -74,6 +74,7 @@ replicate = "0.15.7" lxml = {extras = ["html-clean"], version = "^5.1.0"} langgraph = "==0.0.55" langchain-community = "==0.2.1" +prediction-market-agent-tooling = {git = "https://github.com/gnosis/prediction-market-agent-tooling.git", rev = "gabriel/olas-deps"} [tool.poetry.group.dev.dependencies] tomte = {version = "==0.2.15", extras = ["cli", "tests"]} From bec95a15236245d92736762f79df5d2af1292f09 Mon Sep 17 00:00:00 2001 From: Gabriel Fior Date: Tue, 4 Jun 2024 16:36:05 -0300 Subject: [PATCH 5/8] Added tests --- .../customs/omen_tools/omen_buy_sell.py | 81 +++++++++++-------- tests/test_tools.py | 53 ++++++++---- 2 files changed, 86 insertions(+), 48 deletions(-) diff --git a/packages/gnosis/customs/omen_tools/omen_buy_sell.py b/packages/gnosis/customs/omen_tools/omen_buy_sell.py index a49fcb3f..10f967ba 100644 --- a/packages/gnosis/customs/omen_tools/omen_buy_sell.py +++ b/packages/gnosis/customs/omen_tools/omen_buy_sell.py @@ -32,6 +32,10 @@ from langchain_openai import ChatOpenAI from openai import OpenAI from prediction_market_agent_tooling.markets.agent_market import AgentMarket +from prediction_market_agent_tooling.markets.omen.data_models import ( + OMEN_TRUE_OUTCOME, + OMEN_FALSE_OUTCOME, +) from prediction_market_agent_tooling.markets.omen.omen import OmenAgentMarket from prediction_market_agent_tooling.markets.omen.omen_contracts import ( OmenFixedProductMarketMakerContract, @@ -41,6 +45,7 @@ from prediction_market_agent_tooling.tools.utils import check_not_none from prediction_market_agent_tooling.tools.web3_utils import ( prepare_tx, + add_fraction, ) from pydantic import BaseModel from web3 import Web3 @@ -79,7 +84,7 @@ class BuyOrSell(BaseModel): def build_params_from_prompt(user_prompt: str) -> BuyOrSell: - model = ChatOpenAI(temperature=0) + model = ChatOpenAI(temperature=0, api_key=client.api_key) parser = PydanticOutputParser(pydantic_object=BuyOrSell) prompt = PromptTemplate( template=BUY_OR_SELL_TOKENS_PROMPT, @@ -169,7 +174,7 @@ def build_buy_tokens_tx_params( market_contract: OmenFixedProductMarketMakerContract = market.get_contract() # Get the index of the outcome we want to buy. - outcome_str = "True" if buy_or_sell.outcome else "False" + outcome_str = OMEN_TRUE_OUTCOME if buy_or_sell.outcome else OMEN_FALSE_OUTCOME outcome_index: int = market.get_outcome_index(outcome_str) # Allow 1% slippage. @@ -178,7 +183,7 @@ def build_buy_tokens_tx_params( # Buy shares using the deposited xDai in the collateral token. tx_params_buy = prepare_tx( web3=w3, - contract_address=market_contract.address, + contract_address=Web3.to_checksum_address(market_contract.address), contract_abi=market_contract.abi, from_address=from_address_checksummed, function_name="buy", @@ -187,6 +192,7 @@ def build_buy_tokens_tx_params( outcome_index, expected_shares, ], + tx_params={"gas": "21000"}, ) return tx_params_buy @@ -194,10 +200,8 @@ def build_buy_tokens_tx_params( def build_sell_tokens_tx_params( buy_or_sell: BuyOrSell, market: AgentMarket, w3: Web3 ) -> TxParams: - from_address_checksummed = Web3.to_checksum_address(buy_or_sell.sender) amount_wei = Web3.to_wei(buy_or_sell.amount_to_buy, "ether") - market_contract: OmenFixedProductMarketMakerContract = market.get_contract() conditional_token_contract = OmenConditionalTokenContract() @@ -207,38 +211,37 @@ def build_sell_tokens_tx_params( f"Market {market.id} uses conditional token that we didn't expect, {market_contract.conditionalTokens()} != {conditional_token_contract.address=}" ) - # Get the index of the outcome we want to buy. - outcome_index: int = market.get_outcome_index(outcome) + # Get the index of the outcome we want to sell. + outcome_str = OMEN_TRUE_OUTCOME if buy_or_sell.outcome else OMEN_FALSE_OUTCOME + outcome_index: int = market.get_outcome_index(outcome_str) - # Calculate the amount of shares we will sell for the given selling amount of xdai. - max_outcome_tokens_to_sell = market_contract.calcSellAmount( - amount_wei, outcome_index, web3=web3 - ) - # Allow 1% slippage. - max_outcome_tokens_to_sell = add_fraction(max_outcome_tokens_to_sell, 0.01) - - # Sell the shares. - tx_params_sell = prepare_tx( - web3=w3, - contract_address=market_contract.address, - contract_abi=market_contract.abi, - from_address=from_address_checksummed, - function_name="sell", - function_params=[ - amount_wei, - outcome_index, - max_outcome_tokens_to_sell, - ], - ) + # Calculate the amount of shares we will sell for the given selling amount of xdai. + max_outcome_tokens_to_sell = market_contract.calcSellAmount( + amount_wei, outcome_index, web3=w3 + ) + # Allow 1% slippage. + max_outcome_tokens_to_sell = add_fraction(max_outcome_tokens_to_sell, 0.01) + + # Sell the shares. + tx_params_sell = prepare_tx( + web3=w3, + contract_address=market_contract.address, + contract_abi=market_contract.abi, + from_address=from_address_checksummed, + function_name="sell", + function_params=[ + amount_wei, + outcome_index, + max_outcome_tokens_to_sell, + ], + tx_params={"gas": 210000}, + ) return tx_params_sell def fetch_params_from_prompt(prompt: str): - tool_prompt = BUY_OR_SELL_TOKENS_PROMPT.format(user_prompt=prompt) - # parse the response to get the transaction object string itself - # parsed_txs = ast.literal_eval(response) - buy_params = build_params_from_prompt(user_prompt=tool_prompt) + buy_params = build_params_from_prompt(user_prompt=prompt) # Calculate the amount of shares we will get for the given investment amount. market: AgentMarket = OmenAgentMarket.get_binary_market(buy_params.market_id) return buy_params, market @@ -347,7 +350,17 @@ def error_response(msg: str) -> Tuple[str, None, None, None]: return msg, None, None, None -AVAILABLE_TOOLS = { +LLM_SETTINGS = { + "gpt-4-0125-preview": { + "default_max_tokens": 500, + "limit_max_tokens": 8192, + "temperature": 0, + }, +} + +ALLOWED_MODELS = list(LLM_SETTINGS.keys()) + +ALLOWED_TOOLS = { "buy_omen": build_buy_tx, # buyYesTokens, buyNoTokens "sell_omen": build_sell_tx, # sellYesTokens, sellNoTokens } @@ -365,10 +378,10 @@ def run(**kwargs) -> Tuple[str, Optional[str], Optional[Dict[str, Any]], Any]: if prompt is None: return error_response("No prompt has been given.") - transaction_builder = AVAILABLE_TOOLS.get(tool) + transaction_builder = ALLOWED_TOOLS.get(tool) if transaction_builder is None: return error_response( - f"Tool {tool!r} is not in supported tools: {tuple(AVAILABLE_TOOLS.keys())}." + f"Tool {tool!r} is not in supported tools: {tuple(ALLOWED_TOOLS.keys())}." ) api_key: str | None = kwargs.get("api_keys", {}).get("openai", None) diff --git a/tests/test_tools.py b/tests/test_tools.py index 61639090..856f2215 100644 --- a/tests/test_tools.py +++ b/tests/test_tools.py @@ -17,18 +17,20 @@ # # ------------------------------------------------------------------------------ """This module contains tool tests.""" - +import os from typing import List, Any -from packages.valory.customs.prediction_request import prediction_request +from packages.gnosis.customs.omen_tools import omen_buy_sell from packages.napthaai.customs.prediction_request_rag import prediction_request_rag +from packages.napthaai.customs.prediction_request_rag_cohere import ( + prediction_request_rag_cohere, +) from packages.napthaai.customs.prediction_request_reasoning import ( prediction_request_reasoning, ) -from packages.napthaai.customs.prediction_request_rag_cohere import prediction_request_rag_cohere from packages.napthaai.customs.prediction_url_cot import prediction_url_cot +from packages.valory.customs.prediction_request import prediction_request from packages.valory.skills.task_execution.utils.apis import KeyChain - from packages.valory.skills.task_execution.utils.benchmarks import TokenCounterCallback from tests.constants import ( OPENAI_SECRET_KEY, @@ -45,16 +47,18 @@ class BaseToolTest: """Base tool test class.""" - keys = KeyChain({ - "openai": [OPENAI_SECRET_KEY], - "stabilityai": [STABILITY_API_KEY], - "google_api_key": [GOOGLE_API_KEY], - "google_engine_id": [GOOGLE_ENGINE_ID], - "anthropic": [CLAUDE_API_KEY], - "replicate": [REPLICATE_API_KEY], - "newsapi": [NEWS_API_KEY], - "openrouter": [OPENROUTER_API_KEY], - }) + keys = KeyChain( + { + "openai": [OPENAI_SECRET_KEY], + "stabilityai": [STABILITY_API_KEY], + "google_api_key": [GOOGLE_API_KEY], + "google_engine_id": [GOOGLE_ENGINE_ID], + "anthropic": [CLAUDE_API_KEY], + "replicate": [REPLICATE_API_KEY], + "newsapi": [NEWS_API_KEY], + "openrouter": [OPENROUTER_API_KEY], + } + ) models: List = [None] tools: List[str] prompts: List[str] @@ -149,3 +153,24 @@ class TestPredictionCOT(BaseToolTest): 'Please take over the role of a Data Scientist to evaluate the given question. With the given question "Will Apple release iPhone 17 by March 2025?" and the `yes` option represented by `Yes` and the `no` option represented by `No`, what are the respective probabilities of `p_yes` and `p_no` occurring?' ] tool_module = prediction_url_cot + + +class TestOmenTransactionBuilder(BaseToolTest): + """Test Prediction COT.""" + + os.environ["GNOSIS_RPC_URL"] = "https://gnosis-rpc.publicnode.com" + + tools = omen_buy_sell.ALLOWED_TOOLS + models = omen_buy_sell.ALLOWED_MODELS + market_id = ( + "0x7323440218011988f0e431e19298d1921e41197f" # to be resolved in 8 years + ) + prompts = [ + f"The sender 0x669F3CD2015eB9298b3feA01FCBb034068FE2D3f wants to buy 0 yes Tokens from market {market_id}." + ] + tool_module = omen_buy_sell + + def _validate_response(self, response: Any) -> None: + super()._validate_response(response) + expected_num_tx_params = 2 + assert len(response[2].keys()) == expected_num_tx_params From c3d7e78ddc09ec534e4b5a1bfc2eec488eef4f92 Mon Sep 17 00:00:00 2001 From: Gabriel Fior Date: Wed, 5 Jun 2024 10:56:31 -0300 Subject: [PATCH 6/8] Added dependencies to more files per PR comments --- packages/valory/agents/mech/aea-config.yaml | 3 +++ tox.ini | 1 + 2 files changed, 4 insertions(+) diff --git a/packages/valory/agents/mech/aea-config.yaml b/packages/valory/agents/mech/aea-config.yaml index 99e12ab4..f29740a6 100644 --- a/packages/valory/agents/mech/aea-config.yaml +++ b/packages/valory/agents/mech/aea-config.yaml @@ -135,6 +135,9 @@ dependencies: version: ==0.0.55 langchain-community: version: ==0.2.1 + prediction-market-agent-tooling: + git: https://github.com/gnosis/prediction-market-agent-tooling + ref: gabriel/olas-deps default_connection: null --- public_id: valory/websocket_client:0.1.0:bafybeiexove4oqyhoae5xmk2hilskthosov5imdp65olpgj3cfrepbouyy diff --git a/tox.ini b/tox.ini index 82fca135..a9fdbfe2 100644 --- a/tox.ini +++ b/tox.ini @@ -69,6 +69,7 @@ deps = lxml-html-clean==0.1.0 moviepy==1.0.3 replicate==0.15.7 + prediction-market-agent-tooling: git+https://github.com/gnosis/prediction-market-agent-tooling.git@gabriel/olas-deps [extra-deps] deps = From 77a92aa8a7ad6819dd3fbcfe5454957e0e23f1b7 Mon Sep 17 00:00:00 2001 From: Gabriel Fior Date: Fri, 7 Jun 2024 14:18:44 -0300 Subject: [PATCH 7/8] Added gnosis_rpc_url to key chain, removed from environ --- .../customs/omen_tools/omen_buy_sell.py | 36 +++++++++---------- tests/constants.py | 2 ++ tests/test_tools.py | 5 ++- 3 files changed, 20 insertions(+), 23 deletions(-) diff --git a/packages/gnosis/customs/omen_tools/omen_buy_sell.py b/packages/gnosis/customs/omen_tools/omen_buy_sell.py index 10f967ba..4d4ab905 100644 --- a/packages/gnosis/customs/omen_tools/omen_buy_sell.py +++ b/packages/gnosis/customs/omen_tools/omen_buy_sell.py @@ -22,7 +22,6 @@ Please note that the gnosis safe parameters are missing from the payload, e.g., `safe_tx_hash`, `safe_tx_gas`, etc. """ import functools -import os import traceback from typing import Any, Dict, Optional, Tuple, Callable @@ -42,7 +41,6 @@ OmenCollateralTokenContract, OmenConditionalTokenContract, ) -from prediction_market_agent_tooling.tools.utils import check_not_none from prediction_market_agent_tooling.tools.web3_utils import ( prepare_tx, add_fraction, @@ -53,12 +51,10 @@ MechResponse = Tuple[str, Optional[str], Optional[Dict[str, Any]], Any, Any] - ENGINE = "gpt-3.5-turbo" MAX_TOKENS = 500 TEMPERATURE = 0.7 - """NOTE: An LLM is used for generating a dict containing interpreted parameters from the response, such as "recipient_address", "market_address", etc. This could also be done if we could somehow publish the parameters needed by the run method and make it discoverable by the caller.""" BUY_OR_SELL_TOKENS_PROMPT = """You are an LLM inside a multi-agent system that takes in a prompt from a user requesting you to produce transaction parameters which @@ -115,7 +111,7 @@ def __exit__(self, exc_type, exc_value, traceback) -> None: def build_approval_for_all_tx_params( - buy_or_sell: BuyOrSell, market: AgentMarket, w3: Web3 + buy_or_sell: BuyOrSell, market: AgentMarket, w3: Web3 ) -> TxParams: """ # Approve the market maker to withdraw our collateral token. @@ -139,7 +135,7 @@ def build_approval_for_all_tx_params( def build_approval_tx_params( - buy_or_sell: BuyOrSell, market: AgentMarket, w3: Web3 + buy_or_sell: BuyOrSell, market: AgentMarket, w3: Web3 ) -> TxParams: """ # Approve the market maker to withdraw our collateral token. @@ -165,9 +161,8 @@ def build_approval_tx_params( def build_buy_tokens_tx_params( - buy_or_sell: BuyOrSell, market: AgentMarket, w3: Web3 + buy_or_sell: BuyOrSell, market: AgentMarket, w3: Web3 ) -> TxParams: - from_address_checksummed = Web3.to_checksum_address(buy_or_sell.sender) amount_wei = Web3.to_wei(buy_or_sell.amount_to_buy, "ether") @@ -198,7 +193,7 @@ def build_buy_tokens_tx_params( def build_sell_tokens_tx_params( - buy_or_sell: BuyOrSell, market: AgentMarket, w3: Web3 + buy_or_sell: BuyOrSell, market: AgentMarket, w3: Web3 ) -> TxParams: from_address_checksummed = Web3.to_checksum_address(buy_or_sell.sender) amount_wei = Web3.to_wei(buy_or_sell.amount_to_buy, "ether") @@ -248,13 +243,13 @@ def fetch_params_from_prompt(prompt: str): def build_buy_tx( - prompt: str, + prompt: str, rpc_url: str ) -> Tuple[str, Optional[str], Optional[Dict[str, Any]], Any]: """Builds buy transaction request.""" try: buy_params, market = fetch_params_from_prompt(prompt) - w3 = get_web3() + w3 = get_web3(rpc_url) tx_params_approve = build_approval_tx_params( buy_or_sell=buy_params, market=market, w3=w3 @@ -271,7 +266,7 @@ def build_buy_tx( def build_return_from_tx_params( - tx_params: list[TxParams], prompt: str + tx_params: list[TxParams], prompt: str ) -> Tuple[str, Optional[str], Optional[Dict[str, Any]], Any]: # We return the transactions_dict below in order to be able to return multiple transactions for later execution instead of just one. transaction_dict = {} @@ -281,21 +276,18 @@ def build_return_from_tx_params( return "", prompt, transaction_dict, None -def get_web3() -> Web3: - GNOSIS_RPC_URL = check_not_none(os.environ["GNOSIS_RPC_URL"]) - if not GNOSIS_RPC_URL: - raise EnvironmentError("GNOSIS_RPC_URL not set. Aborting.") - return Web3(Web3.HTTPProvider(GNOSIS_RPC_URL)) +def get_web3(gnosis_rpc_url: str) -> Web3: + return Web3(Web3.HTTPProvider(gnosis_rpc_url)) def build_sell_tx( - prompt: str, + prompt: str, rpc_url: str ) -> Tuple[str, Optional[str], Optional[Dict[str, Any]], Any]: """Builds sell transaction request.""" try: sell_params, market = fetch_params_from_prompt(prompt) - w3 = get_web3() + w3 = get_web3(rpc_url) tx_params_approve_all = build_approval_for_all_tx_params( buy_or_sell=sell_params, market=market, w3=w3 @@ -388,5 +380,9 @@ def run(**kwargs) -> Tuple[str, Optional[str], Optional[Dict[str, Any]], Any]: if api_key is None: return error_response("No api key has been given.") + gnosis_rpc_url: str | None = kwargs.get("api_keys", {}).get("gnosis_rpc_url", None) + if gnosis_rpc_url is None: + return error_response("No gnosis rpc url has been given.") + with OpenAIClientManager(api_key): - return transaction_builder(prompt) + return transaction_builder(prompt, gnosis_rpc_url) diff --git a/tests/constants.py b/tests/constants.py index 5f5d0636..e4b6ae4c 100644 --- a/tests/constants.py +++ b/tests/constants.py @@ -19,6 +19,7 @@ """This module contains constants.""" import os + from dotenv import load_dotenv load_dotenv() @@ -31,3 +32,4 @@ REPLICATE_API_KEY = os.getenv("REPLICATE_API_KEY") NEWS_API_KEY = os.getenv("NEWS_API_KEY") OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY") +GNOSIS_RPC_URL = os.getenv("GNOSIS_RPC_URL") diff --git a/tests/test_tools.py b/tests/test_tools.py index 856f2215..bd4f660b 100644 --- a/tests/test_tools.py +++ b/tests/test_tools.py @@ -17,7 +17,6 @@ # # ------------------------------------------------------------------------------ """This module contains tool tests.""" -import os from typing import List, Any from packages.gnosis.customs.omen_tools import omen_buy_sell @@ -41,6 +40,7 @@ REPLICATE_API_KEY, NEWS_API_KEY, OPENROUTER_API_KEY, + GNOSIS_RPC_URL, ) @@ -57,6 +57,7 @@ class BaseToolTest: "replicate": [REPLICATE_API_KEY], "newsapi": [NEWS_API_KEY], "openrouter": [OPENROUTER_API_KEY], + "gnosis_rpc_url": [GNOSIS_RPC_URL], } ) models: List = [None] @@ -158,8 +159,6 @@ class TestPredictionCOT(BaseToolTest): class TestOmenTransactionBuilder(BaseToolTest): """Test Prediction COT.""" - os.environ["GNOSIS_RPC_URL"] = "https://gnosis-rpc.publicnode.com" - tools = omen_buy_sell.ALLOWED_TOOLS models = omen_buy_sell.ALLOWED_MODELS market_id = ( From f09951f1df6fd39b4f1a7298d17bfb84b3e6cff2 Mon Sep 17 00:00:00 2001 From: Gabriel Fior Date: Fri, 7 Jun 2024 14:24:59 -0300 Subject: [PATCH 8/8] Added GNOSIS_RPC_URL as secrets to unit tests --- .github/workflows/common_checks.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/common_checks.yaml b/.github/workflows/common_checks.yaml index 1f78c382..adb12530 100644 --- a/.github/workflows/common_checks.yaml +++ b/.github/workflows/common_checks.yaml @@ -190,6 +190,7 @@ jobs: REPLICATE_API_KEY: ${{ secrets.REPLICATE_API_KEY }} NEWS_API_KEY: ${{ secrets.NEWS_API_KEY }} OPENROUTER_API_KEY: ${{ secrets.OPEN_ROUTER_API_KEY }} + GNOSIS_RPC_URL: ${{ secrets.GNOSIS_RPC_URL }} run: | printenv tox -e check-tools \ No newline at end of file