diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml deleted file mode 100644 index 9cbd9b7ac..000000000 --- a/.github/workflows/e2e.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: "Test Operate Installation E2E" -on: - push: - branches: - - develop - - main - pull_request: -jobs: - test: - continue-on-error: False - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, macos-12, macos-14] - timeout-minutes: 30 - steps: - - uses: actions/checkout@v2 - - name: Setup Node.js - uses: actions/setup-node@v3 - with: - node-version: "20.11" - - name: Setup - run: | - yarn - # Uninstall brew - sudo bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/uninstall.sh)" - - name: Run Test - run: | - node electron/test.js diff --git a/electron/install.js b/electron/install.js index 158918c40..47271e408 100644 --- a/electron/install.js +++ b/electron/install.js @@ -16,7 +16,7 @@ const { BrewScript } = require('./scripts'); * - use "" (nothing as a suffix) for latest release candidate, for example "0.1.0rc26" * - use "alpha" for alpha release, for example "0.1.0rc26-alpha" */ -const OlasMiddlewareVersion = '0.1.0rc50'; +const OlasMiddlewareVersion = '0.1.0rc54'; const OperateDirectory = `${os.homedir()}/.operate`; const VenvDir = `${OperateDirectory}/venv`; const TempDir = `${OperateDirectory}/temp`; diff --git a/frontend/constants/serviceTemplates.ts b/frontend/constants/serviceTemplates.ts index 249fe95a7..b8cc8f742 100644 --- a/frontend/constants/serviceTemplates.ts +++ b/frontend/constants/serviceTemplates.ts @@ -3,7 +3,7 @@ import { ServiceTemplate } from '@/client'; export const SERVICE_TEMPLATES: ServiceTemplate[] = [ { name: 'Trader Agent', - hash: 'bafybeieg45wcjcwd5znuwpjcp5scfhgdqwpfq43pzaare6nwvmy5bb56cm', + hash: 'bafybeicihxhw2djlsuoy2eji3g2tmasipfqe3rwsfvzbd2j3tvphqvp7aa', description: 'Trader agent for omen prediction markets', image: 'https://operate.olas.network/_next/image?url=%2Fimages%2Fprediction-agent.png&w=3840&q=75', diff --git a/operate/cli.py b/operate/cli.py index 64a7bfd21..e31ea9ef1 100644 --- a/operate/cli.py +++ b/operate/cli.py @@ -145,6 +145,7 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st logger = setup_logger(name="operate") operate = OperateApp(home=home, logger=logger) funding_jobs: t.Dict[str, asyncio.Task] = {} + healthcheck_jobs: t.Dict[str, asyncio.Task] = {} # Create shutdown endpoint shutdown_endpoint = uuid.uuid4().hex @@ -171,6 +172,22 @@ def schedule_funding_job( ) ) + def schedule_healthcheck_job( + service: str, + ) -> None: + """Schedule a healthcheck job.""" + logger.info(f"Starting healthcheck job for {service}") + if service in healthcheck_jobs: + logger.info(f"Cancelling existing healthcheck_jobs job for {service}") + cancel_healthcheck_job(service=service) + + loop = asyncio.get_running_loop() + healthcheck_jobs[service] = loop.create_task( + operate.service_manager().healthcheck_job( + hash=service, + ) + ) + def cancel_funding_job(service: str) -> None: """Cancel funding job.""" if service not in funding_jobs: @@ -179,11 +196,11 @@ def cancel_funding_job(service: str) -> None: if not status: logger.info(f"Funding job cancellation for {service} failed") - def pause_all_services_on_startup(): - logger.info(f"stopping services on startup") - services = [i["hash"] for i in operate.service_manager().json] + def pause_all_services_on_startup() -> None: + logger.info("Stopping services on startup...") + service_hashes = [i["hash"] for i in operate.service_manager().json] - for service in services: + for service in service_hashes: if not operate.service_manager().exists(service=service): continue deployment = operate.service_manager().create_or_load(service).deployment @@ -193,7 +210,15 @@ def pause_all_services_on_startup(): deployment.stop(force=True) logger.info(f"Cancelling funding job for {service}") cancel_funding_job(service=service) - logger.info(f"stopping services on startup: done") + logger.info("Stopping services on startup done.") + + def cancel_healthcheck_job(service: str) -> None: + """Cancel healthcheck job.""" + if service not in healthcheck_jobs: + return + status = healthcheck_jobs[service].cancel() + if not status: + logger.info(f"Healthcheck job cancellation for {service} failed") # on backend app started we assume there are now started agents, so we force to pause all pause_all_services_on_startup() @@ -525,6 +550,7 @@ async def _create_services(request: Request) -> JSONResponse: manager.fund_service(hash=service.hash) manager.deploy_service_locally(hash=service.hash) schedule_funding_job(service=service.hash) + schedule_healthcheck_job(service=service.hash) return JSONResponse( content=operate.service_manager().create_or_load(hash=service.hash).json @@ -548,6 +574,7 @@ async def _update_services(request: Request) -> JSONResponse: manager.fund_service(hash=service.hash) manager.deploy_service_locally(hash=service.hash) schedule_funding_job(service=service.hash) + schedule_healthcheck_job(service=service.hash) return JSONResponse(content=service.json) @@ -657,6 +684,7 @@ async def _start_service_locally(request: Request) -> JSONResponse: manager.fund_service(hash=service) manager.deploy_service_locally(hash=service, force=True) schedule_funding_job(service=service) + schedule_healthcheck_job(service=service.hash) return JSONResponse(content=manager.create_or_load(service).deployment) @app.post("/api/services/{service}/deployment/stop") diff --git a/operate/services/manage.py b/operate/services/manage.py index e4b67430c..2014e6afe 100644 --- a/operate/services/manage.py +++ b/operate/services/manage.py @@ -26,6 +26,7 @@ from concurrent.futures import ThreadPoolExecutor from pathlib import Path +import aiohttp # type: ignore from aea.helpers.base import IPFSHash from aea.helpers.logging import setup_logger from autonomy.chain.base import registry_contracts @@ -56,6 +57,18 @@ KEYS_JSON = "keys.json" DOCKER_COMPOSE_YAML = "docker-compose.yaml" SERVICE_YAML = "service.yaml" +HTTP_OK = 200 + + +async def check_service_health() -> bool: + """Check the service health""" + async with aiohttp.ClientSession() as session: + async with session.get("http://localhost:8716/healthcheck") as resp: + status = resp.status + response_json = await resp.json() + return status == HTTP_OK and response_json.get( + "is_transitioning_fast", False + ) class ServiceManager: @@ -901,6 +914,32 @@ async def funding_job( ) await asyncio.sleep(60) + async def healthcheck_job( + self, + hash: str, + ) -> None: + """Start a background funding job.""" + failed_health_checks = 0 + + while True: + try: + # Check the service health + healthy = await check_service_health() + # Restart the service if the health failed 5 times in a row + if not healthy: + failed_health_checks += 1 + else: + failed_health_checks = 0 + if failed_health_checks >= 4: + self.stop_service_locally(hash=hash) + self.deploy_service_locally(hash=hash) + + except Exception: # pylint: disable=broad-except + logging.info( + f"Error occured while checking the service health\n{traceback.format_exc()}" + ) + await asyncio.sleep(30) + def deploy_service_locally(self, hash: str, force: bool = True) -> Deployment: """ Deploy service locally diff --git a/operate/services/protocol.py b/operate/services/protocol.py index 349b3b7b1..f6d8acf46 100644 --- a/operate/services/protocol.py +++ b/operate/services/protocol.py @@ -679,7 +679,7 @@ def swap( # pylint: disable=too-many-arguments,too-many-locals key_file = Path(temp_dir, "key.txt") key_file.write_text(owner_key, encoding="utf-8") owner_crypto = EthereumCrypto(private_key_path=str(key_file)) - owner_cryptos: list[EthereumCrypto] = [owner_crypto] + owner_cryptos: t.List[EthereumCrypto] = [owner_crypto] owners = [ manager.ledger_api.api.to_checksum_address(owner_crypto.address) for owner_crypto in owner_cryptos diff --git a/operate/services/service.py b/operate/services/service.py index 2f05c6d9e..b7b224b98 100644 --- a/operate/services/service.py +++ b/operate/services/service.py @@ -822,7 +822,7 @@ def start(self, use_docker: bool = False) -> None: self.status = DeploymentStatus.DEPLOYED self.store() - def stop(self, use_docker: bool = False, force: bool=False) -> None: + def stop(self, use_docker: bool = False, force: bool = False) -> None: """Stop the deployment.""" if self.status != DeploymentStatus.DEPLOYED and not force: return diff --git a/package.json b/package.json index 7a22390d0..bdabdbb4c 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "main": "electron/main.js", "name": "olas-operate-app", "productName": "Pearl", - "version": "0.1.0-rc50", + "version": "0.1.0-rc54", "dependencies": { "@ant-design/cssinjs": "^1.18.4", "@ant-design/icons": "^5.3.0", diff --git a/poetry.lock b/poetry.lock index 545b014ac..172cfc64f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,9 +1,10 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.4.0 and should not be changed by hand. [[package]] name = "aiohttp" version = "3.9.5" description = "Async http client/server framework (asyncio)" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -100,6 +101,7 @@ speedups = ["Brotli", "aiodns", "brotlicffi"] name = "aiosignal" version = "1.3.1" description = "aiosignal: a list of registered asynchronous callbacks" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -114,6 +116,7 @@ frozenlist = ">=1.1.0" name = "annotated-types" version = "0.7.0" description = "Reusable constraint types to use with typing.Annotated" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -128,6 +131,7 @@ typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.9\""} name = "anyio" version = "4.4.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -150,6 +154,7 @@ trio = ["trio (>=0.23)"] name = "async-timeout" version = "4.0.3" description = "Timeout context manager for asyncio programs" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -161,6 +166,7 @@ files = [ name = "attrs" version = "23.2.0" description = "Classes Without Boilerplate" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -180,6 +186,7 @@ tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "p name = "backoff" version = "2.2.1" description = "Function decoration for backoff and retry" +category = "main" optional = false python-versions = ">=3.7,<4.0" files = [ @@ -191,6 +198,7 @@ files = [ name = "base58" version = "2.1.1" description = "Base58 and Base58Check implementation." +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -205,6 +213,7 @@ tests = ["PyHamcrest (>=2.0.2)", "mypy", "pytest (>=4.6)", "pytest-benchmark", " name = "bcrypt" version = "4.1.3" description = "Modern password hashing for your software and your servers" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -245,6 +254,7 @@ typecheck = ["mypy"] name = "bitarray" version = "2.9.2" description = "efficient arrays of booleans -- C extension" +category = "main" optional = false python-versions = "*" files = [ @@ -376,6 +386,7 @@ files = [ name = "certifi" version = "2024.6.2" description = "Python package for providing Mozilla's CA Bundle." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -387,6 +398,7 @@ files = [ name = "cffi" version = "1.16.0" description = "Foreign Function Interface for Python calling C code." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -451,6 +463,7 @@ pycparser = "*" name = "charset-normalizer" version = "2.1.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +category = "main" optional = false python-versions = ">=3.6.0" files = [ @@ -465,6 +478,7 @@ unicode-backport = ["unicodedata2"] name = "clea" version = "0.1.0rc4" description = "Framework for writing CLI application quickly" +category = "main" optional = false python-versions = ">=3.8,<4.0" files = [ @@ -479,6 +493,7 @@ typing-extensions = ">=4.7.1,<5.0.0" name = "click" version = "8.0.2" description = "Composable command line interface toolkit" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -493,6 +508,7 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -504,6 +520,7 @@ files = [ name = "coverage" version = "7.5.3" description = "Code coverage measurement for Python" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -568,6 +585,7 @@ toml = ["tomli"] name = "cryptography" version = "42.0.8" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -622,6 +640,7 @@ test-randomorder = ["pytest-randomly"] name = "cytoolz" version = "0.12.3" description = "Cython implementation of Toolz: High performance functional utilities" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -737,10 +756,23 @@ toolz = ">=0.8.0" [package.extras] cython = ["cython"] +[[package]] +name = "distlib" +version = "0.3.8" +description = "Distribution utilities" +category = "dev" +optional = false +python-versions = "*" +files = [ + {file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"}, + {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"}, +] + [[package]] name = "distro" version = "1.9.0" description = "Distro - an OS platform information API" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -752,6 +784,7 @@ files = [ name = "docker" version = "6.1.2" description = "A Python library for the Docker Engine API." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -774,6 +807,7 @@ ssh = ["paramiko (>=2.4.3)"] name = "dockerpty" version = "0.4.1" description = "Python library to use the pseudo-tty of a docker container" +category = "main" optional = false python-versions = "*" files = [ @@ -787,6 +821,7 @@ six = ">=1.3.0" name = "docopt" version = "0.6.2" description = "Pythonic argument parser, that will make you smile" +category = "main" optional = false python-versions = "*" files = [ @@ -797,6 +832,7 @@ files = [ name = "ecdsa" version = "0.16.1" description = "ECDSA cryptographic signature library (pure python)" +category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -815,6 +851,7 @@ gmpy2 = ["gmpy2"] name = "eth-abi" version = "5.1.0" description = "eth_abi: Python utilities for working with Ethereum ABI definitions, especially encoding and decoding" +category = "main" optional = false python-versions = "<4,>=3.8" files = [ @@ -837,6 +874,7 @@ tools = ["hypothesis (>=4.18.2,<5.0.0)"] name = "eth-account" version = "0.8.0" description = "eth-account: Sign Ethereum transactions and messages with local private keys" +category = "main" optional = false python-versions = ">=3.6, <4" files = [ @@ -864,6 +902,7 @@ test = ["coverage", "hypothesis (>=4.18.0,<5)", "pytest (>=6.2.5,<7)", "pytest-x name = "eth-hash" version = "0.7.0" description = "eth-hash: The Ethereum hashing function, keccak256, sometimes (erroneously) called sha3" +category = "main" optional = false python-versions = ">=3.8, <4" files = [ @@ -885,6 +924,7 @@ test = ["pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)"] name = "eth-keyfile" version = "0.6.1" description = "A library for handling the encrypted keyfiles used to store ethereum private keys." +category = "main" optional = false python-versions = "*" files = [ @@ -907,6 +947,7 @@ test = ["pytest (>=6.2.5,<7)"] name = "eth-keys" version = "0.4.0" description = "Common API for Ethereum key operations." +category = "main" optional = false python-versions = "*" files = [ @@ -929,6 +970,7 @@ test = ["asn1tools (>=0.146.2,<0.147)", "eth-hash[pycryptodome]", "eth-hash[pysh name = "eth-rlp" version = "0.3.0" description = "eth-rlp: RLP definitions for common Ethereum objects in Python" +category = "main" optional = false python-versions = ">=3.7, <4" files = [ @@ -951,6 +993,7 @@ test = ["eth-hash[pycryptodome]", "pytest (>=6.2.5,<7)", "pytest-xdist", "tox (= name = "eth-typing" version = "3.5.2" description = "eth-typing: Common type annotations for ethereum python packages" +category = "main" optional = false python-versions = ">=3.7.2, <4" files = [ @@ -971,6 +1014,7 @@ test = ["pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)"] name = "eth-utils" version = "2.3.1" description = "eth-utils: Common utility functions for python code that interacts with Ethereum" +category = "main" optional = false python-versions = ">=3.7,<4" files = [ @@ -994,6 +1038,7 @@ test = ["hypothesis (>=4.43.0)", "mypy (==0.971)", "pytest (>=7.0.0)", "pytest-x name = "exceptiongroup" version = "1.2.1" description = "Backport of PEP 654 (exception groups)" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1008,6 +1053,7 @@ test = ["pytest (>=6)"] name = "fastapi" version = "0.110.0" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1023,10 +1069,28 @@ typing-extensions = ">=4.8.0" [package.extras] all = ["email-validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.7)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] +[[package]] +name = "filelock" +version = "3.14.0" +description = "A platform independent file lock." +category = "dev" +optional = false +python-versions = ">=3.8" +files = [ + {file = "filelock-3.14.0-py3-none-any.whl", hash = "sha256:43339835842f110ca7ae60f1e1c160714c5a6afd15a2873419ab185334975c0f"}, + {file = "filelock-3.14.0.tar.gz", hash = "sha256:6ea72da3be9b8c82afd3edcf99f2fffbb5076335a5ae4d03248bb5b6c3eae78a"}, +] + +[package.extras] +docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] +typing = ["typing-extensions (>=4.8)"] + [[package]] name = "flask" version = "2.1.3" description = "A simple framework for building complex web applications." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1049,6 +1113,7 @@ dotenv = ["python-dotenv"] name = "frozenlist" version = "1.4.1" description = "A list-like structure which implements collections.abc.MutableSequence" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1135,6 +1200,7 @@ files = [ name = "gql" version = "3.5.0" description = "GraphQL client for Python" +category = "main" optional = false python-versions = "*" files = [ @@ -1163,6 +1229,7 @@ websockets = ["websockets (>=10,<12)"] name = "graphql-core" version = "3.2.3" description = "GraphQL implementation for Python, a port of GraphQL.js, the JavaScript reference implementation for GraphQL." +category = "main" optional = false python-versions = ">=3.6,<4" files = [ @@ -1174,6 +1241,7 @@ files = [ name = "h11" version = "0.14.0" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1185,6 +1253,7 @@ files = [ name = "hexbytes" version = "0.3.1" description = "hexbytes: Python `bytes` subclass that decodes hex, with a readable console output" +category = "main" optional = false python-versions = ">=3.7, <4" files = [ @@ -1202,6 +1271,7 @@ test = ["eth-utils (>=1.0.1,<3)", "hypothesis (>=3.44.24,<=6.31.6)", "pytest (>= name = "idna" version = "3.7" description = "Internationalized Domain Names in Applications (IDNA)" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1213,6 +1283,7 @@ files = [ name = "importlib-metadata" version = "7.1.0" description = "Read metadata from Python packages" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1232,6 +1303,7 @@ testing = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", name = "importlib-resources" version = "6.4.0" description = "Read resources from Python packages" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1250,6 +1322,7 @@ testing = ["jaraco.test (>=5.4)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "p name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1261,6 +1334,7 @@ files = [ name = "ipfshttpclient" version = "0.8.0a2" description = "Python IPFS HTTP CLIENT library" +category = "main" optional = false python-versions = ">=3.6.2,!=3.7.0,!=3.7.1" files = [ @@ -1276,6 +1350,7 @@ requests = ">=2.11" name = "itsdangerous" version = "2.2.0" description = "Safely pass data to untrusted environments and back." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1287,6 +1362,7 @@ files = [ name = "jinja2" version = "3.1.4" description = "A very fast and expressive template engine." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1304,6 +1380,7 @@ i18n = ["Babel (>=2.7)"] name = "jsonschema" version = "4.3.3" description = "An implementation of JSON Schema validation for Python" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1324,6 +1401,7 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339- name = "lru-dict" version = "1.3.0" description = "An Dict like LRU container." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1417,6 +1495,7 @@ test = ["pytest"] name = "markupsafe" version = "2.1.5" description = "Safely add untrusted strings to HTML/XML markup." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1486,6 +1565,7 @@ files = [ name = "morphys" version = "1.0" description = "Smart conversions between unicode and bytes types for common cases" +category = "main" optional = false python-versions = "*" files = [ @@ -1496,6 +1576,7 @@ files = [ name = "multiaddr" version = "0.0.9" description = "Python implementation of jbenet's multiaddr" +category = "main" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" files = [ @@ -1513,6 +1594,7 @@ varint = "*" name = "multidict" version = "6.0.5" description = "multidict implementation" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1612,6 +1694,7 @@ files = [ name = "netaddr" version = "1.3.0" description = "A network address manipulation library for Python" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1626,6 +1709,7 @@ nicer-shell = ["ipython"] name = "open-aea" version = "1.51.0" description = "Open Autonomous Economic Agent framework (without vendor lock-in)" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1665,6 +1749,7 @@ test-tools = ["click (==8.0.2)", "coverage (>=6.4.4,<8.0.0)", "jsonschema (>=4.3 name = "open-aea-cli-ipfs" version = "1.51.0" description = "CLI extension for open AEA framework wrapping IPFS functionality." +category = "main" optional = false python-versions = "*" files = [ @@ -1681,6 +1766,7 @@ pytest = ">=7.0.0,<7.3.0" name = "open-aea-ledger-ethereum" version = "1.51.0" description = "Python package wrapping the public and private key cryptography and ledger api of Ethereum." +category = "main" optional = false python-versions = "*" files = [ @@ -1698,6 +1784,7 @@ web3 = ">=6.0.0,<7" name = "open-autonomy" version = "0.14.11.post1" description = "A framework for the creation of autonomous agent services." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1734,6 +1821,7 @@ cli = ["click (==8.0.2)", "coverage (>=6.4.4,<8.0.0)", "open-aea-cli-ipfs (==1.5 name = "packaging" version = "23.2" description = "Core utilities for Python packages" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1745,6 +1833,7 @@ files = [ name = "paramiko" version = "3.4.0" description = "SSH2 protocol library" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1766,6 +1855,7 @@ invoke = ["invoke (>=2.0)"] name = "parsimonious" version = "0.10.0" description = "(Soon to be) the fastest pure-Python PEG parser I could muster" +category = "main" optional = false python-versions = "*" files = [ @@ -1776,10 +1866,28 @@ files = [ [package.dependencies] regex = ">=2022.3.15" +[[package]] +name = "platformdirs" +version = "4.2.2" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." +category = "dev" +optional = false +python-versions = ">=3.8" +files = [ + {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, + {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, +] + +[package.extras] +docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] +type = ["mypy (>=1.8)"] + [[package]] name = "pluggy" version = "1.5.0" description = "plugin and hook calling mechanisms for python" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1795,6 +1903,7 @@ testing = ["pytest", "pytest-benchmark"] name = "protobuf" version = "4.24.4" description = "" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1817,6 +1926,7 @@ files = [ name = "psutil" version = "5.9.8" description = "Cross-platform lib for process and system monitoring in Python." +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ @@ -1841,10 +1951,23 @@ files = [ [package.extras] test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] +[[package]] +name = "py" +version = "1.11.0" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, + {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, +] + [[package]] name = "py-multibase" version = "1.0.3" description = "Multibase implementation for Python" +category = "main" optional = false python-versions = "*" files = [ @@ -1861,6 +1984,7 @@ six = ">=1.10.0,<2.0" name = "py-multicodec" version = "0.2.1" description = "Multicodec implementation in Python" +category = "main" optional = false python-versions = "*" files = [ @@ -1877,6 +2001,7 @@ varint = ">=1.0.2,<2.0.0" name = "pycparser" version = "2.22" description = "C parser in Python" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1888,6 +2013,7 @@ files = [ name = "pycryptodome" version = "3.20.0" description = "Cryptographic library for Python" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -1929,6 +2055,7 @@ files = [ name = "pydantic" version = "2.7.3" description = "Data validation using Python type hints" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1948,6 +2075,7 @@ email = ["email-validator (>=2.0.0)"] name = "pydantic-core" version = "2.18.4" description = "Core functionality for Pydantic validation and serialization" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2039,6 +2167,7 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" name = "pymultihash" version = "0.8.2" description = "Python implementation of the multihash specification" +category = "main" optional = false python-versions = "*" files = [ @@ -2054,6 +2183,7 @@ sha3 = ["pysha3"] name = "pynacl" version = "1.5.0" description = "Python binding to the Networking and Cryptography (NaCl) library" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2080,6 +2210,7 @@ tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"] name = "pyrsistent" version = "0.20.0" description = "Persistent/Functional/Immutable data structures" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2121,6 +2252,7 @@ files = [ name = "pytest" version = "7.2.1" description = "pytest: simple powerful testing with Python" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2144,6 +2276,7 @@ testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2. name = "python-baseconv" version = "1.2.2" description = "Convert numbers from base 10 integers to base X strings and back again." +category = "main" optional = false python-versions = "*" files = [ @@ -2154,6 +2287,7 @@ files = [ name = "python-dotenv" version = "0.21.1" description = "Read key-value pairs from a .env file and set them as environment variables" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2168,6 +2302,7 @@ cli = ["click (>=5.0)"] name = "pywin32" version = "306" description = "Python for Window Extensions" +category = "main" optional = false python-versions = "*" files = [ @@ -2191,6 +2326,7 @@ files = [ name = "pyyaml" version = "6.0.1" description = "YAML parser and emitter for Python" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2240,6 +2376,7 @@ files = [ name = "regex" version = "2024.5.15" description = "Alternative regular expression module, to replace re." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2328,6 +2465,7 @@ files = [ name = "requests" version = "2.28.1" description = "Python HTTP for Humans." +category = "main" optional = false python-versions = ">=3.7, <4" files = [ @@ -2349,6 +2487,7 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "requests-toolbelt" version = "1.0.0" description = "A utility belt for advanced users of python-requests" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -2363,6 +2502,7 @@ requests = ">=2.0.1,<3.0.0" name = "rlp" version = "3.0.0" description = "A package for Recursive Length Prefix encoding and decoding" +category = "main" optional = false python-versions = "*" files = [ @@ -2384,6 +2524,7 @@ test = ["hypothesis (==5.19.0)", "pytest (>=6.2.5,<7)", "tox (>=2.9.1,<3)"] name = "semver" version = "2.13.0" description = "Python helper for Semantic Versioning (http://semver.org/)" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -2395,6 +2536,7 @@ files = [ name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -2406,6 +2548,7 @@ files = [ name = "sniffio" version = "1.3.1" description = "Sniff out which async library your code is running under" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2417,6 +2560,7 @@ files = [ name = "starlette" version = "0.36.3" description = "The little ASGI library that shines." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2435,6 +2579,7 @@ full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7 name = "texttable" version = "1.6.7" description = "module to create simple ASCII tables" +category = "main" optional = false python-versions = "*" files = [ @@ -2446,6 +2591,7 @@ files = [ name = "tomli" version = "2.0.1" description = "A lil' TOML parser" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2453,10 +2599,44 @@ files = [ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] +[[package]] +name = "tomte" +version = "0.2.15" +description = "A library that wraps many useful tools (linters, analysers, etc) to keep Python code clean, secure, well-documented and optimised." +category = "dev" +optional = false +python-versions = ">=3.8,<4" +files = [ + {file = "tomte-0.2.15-py3-none-any.whl", hash = "sha256:c1ec71bdb919290e42671d83098232bf7cf46cddf1a736c5d1c9f12ab1308c34"}, + {file = "tomte-0.2.15.tar.gz", hash = "sha256:662f3cdd616347969c3fea557c47545b555f5f82798b978e78ade3d23d43c92d"}, +] + +[package.dependencies] +click = {version = "8.0.2", optional = true, markers = "extra == \"black\" or extra == \"cli\" or extra == \"docs\""} +requests = {version = "2.28.1", optional = true, markers = "extra == \"cli\""} +tox = {version = "3.28.0", optional = true, markers = "extra == \"cli\" or extra == \"tox\""} + +[package.extras] +bandit = ["bandit (==1.7.4)"] +black = ["black (==23.1.0)", "click (==8.0.2)"] +cli = ["click (==8.0.2)", "requests (==2.28.1)", "tox (==3.28.0)"] +darglint = ["darglint (==1.8.1)"] +docs = ["Markdown (==3.3.7)", "Pygments (>=2.16,<3.0)", "bs4 (==0.0.1)", "click (==8.0.2)", "markdown-include (==0.8.0)", "mkdocs (>=1.5.3,<2.0)", "mkdocs-macros-plugin (==0.7.0)", "mkdocs-material (==9.4.10)", "mkdocs-material-extensions (==1.3)", "mkdocs-redirects (==1.2.0)", "pydoc-markdown (==4.8.2)", "pydocstyle (==6.2.3)", "pymdown-extensions (>=10.2,<11.0)"] +flake8 = ["flake8 (==3.9.2)", "flake8-bugbear (==23.1.14)", "flake8-docstrings (==1.6.0)", "flake8-eradicate (==1.4.0)", "flake8-isort (==6.0.0)", "pydocstyle (==6.2.3)"] +isort = ["isort (==5.11.4)"] +liccheck = ["liccheck (==0.8.3)"] +mypy = ["mypy (==0.991)"] +pylint = ["pylint (==2.13.9)"] +safety = ["safety (==2.4.0b1)"] +tests = ["pytest (==7.2.1)", "pytest-asyncio (==0.20.3)", "pytest-cov (==4.0.0)", "pytest-randomly (==3.12.0)", "pytest-rerunfailures (==11.0)"] +tox = ["tox (==3.28.0)"] +vulture = ["vulture (==2.7)"] + [[package]] name = "toolz" version = "0.12.1" description = "List processing tools and functional utilities" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2464,10 +2644,37 @@ files = [ {file = "toolz-0.12.1.tar.gz", hash = "sha256:ecca342664893f177a13dac0e6b41cbd8ac25a358e5f215316d43e2100224f4d"}, ] +[[package]] +name = "tox" +version = "3.28.0" +description = "tox is a generic virtualenv management and test command line tool" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +files = [ + {file = "tox-3.28.0-py2.py3-none-any.whl", hash = "sha256:57b5ab7e8bb3074edc3c0c0b4b192a4f3799d3723b2c5b76f1fa9f2d40316eea"}, + {file = "tox-3.28.0.tar.gz", hash = "sha256:d0d28f3fe6d6d7195c27f8b054c3e99d5451952b54abdae673b71609a581f640"}, +] + +[package.dependencies] +colorama = {version = ">=0.4.1", markers = "platform_system == \"Windows\""} +filelock = ">=3.0.0" +packaging = ">=14" +pluggy = ">=0.12.0" +py = ">=1.4.17" +six = ">=1.14.0" +tomli = {version = ">=2.0.1", markers = "python_version >= \"3.7\" and python_version < \"3.11\""} +virtualenv = ">=16.0.0,<20.0.0 || >20.0.0,<20.0.1 || >20.0.1,<20.0.2 || >20.0.2,<20.0.3 || >20.0.3,<20.0.4 || >20.0.4,<20.0.5 || >20.0.5,<20.0.6 || >20.0.6,<20.0.7 || >20.0.7" + +[package.extras] +docs = ["pygments-github-lexers (>=0.0.5)", "sphinx (>=2.0.0)", "sphinxcontrib-autoprogram (>=0.1.5)", "towncrier (>=18.5.0)"] +testing = ["flaky (>=3.4.0)", "freezegun (>=0.3.11)", "pathlib2 (>=2.3.3)", "psutil (>=5.6.1)", "pytest (>=4.0.0)", "pytest-cov (>=2.5.1)", "pytest-mock (>=1.10.0)", "pytest-randomly (>=1.0.0)"] + [[package]] name = "typing-extensions" version = "4.12.1" description = "Backported and Experimental Type Hints for Python 3.8+" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2479,6 +2686,7 @@ files = [ name = "urllib3" version = "1.26.18" description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ @@ -2495,6 +2703,7 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] name = "uvicorn" version = "0.27.0" description = "The lightning-fast ASGI server." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2514,6 +2723,7 @@ standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", name = "valory-docker-compose" version = "1.29.3" description = "Multi-container orchestration for Docker" +category = "main" optional = false python-versions = ">=3.4" files = [ @@ -2542,16 +2752,39 @@ tests = ["ddt (>=1.2.2,<2)", "pytest (<6)"] name = "varint" version = "1.0.2" description = "Simple python varint implementation" +category = "main" optional = false python-versions = "*" files = [ {file = "varint-1.0.2.tar.gz", hash = "sha256:a6ecc02377ac5ee9d65a6a8ad45c9ff1dac8ccee19400a5950fb51d594214ca5"}, ] +[[package]] +name = "virtualenv" +version = "20.26.2" +description = "Virtual Python Environment builder" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "virtualenv-20.26.2-py3-none-any.whl", hash = "sha256:a624db5e94f01ad993d476b9ee5346fdf7b9de43ccaee0e0197012dc838a0e9b"}, + {file = "virtualenv-20.26.2.tar.gz", hash = "sha256:82bf0f4eebbb78d36ddaee0283d43fe5736b53880b8a8cdcd37390a07ac3741c"}, +] + +[package.dependencies] +distlib = ">=0.3.7,<1" +filelock = ">=3.12.2,<4" +platformdirs = ">=3.9.1,<5" + +[package.extras] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] +test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] + [[package]] name = "watchdog" version = "4.0.1" description = "Filesystem events monitoring" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2596,6 +2829,7 @@ watchmedo = ["PyYAML (>=3.10)"] name = "web3" version = "6.1.0" description = "web3.py" +category = "main" optional = false python-versions = ">=3.7.2" files = [ @@ -2629,6 +2863,7 @@ tester = ["eth-tester[py-evm] (==v0.8.0-b.3)", "py-geth (>=3.11.0)"] name = "websocket-client" version = "0.59.0" description = "WebSocket client for Python with low level API options" +category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -2643,6 +2878,7 @@ six = "*" name = "websockets" version = "12.0" description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2724,6 +2960,7 @@ files = [ name = "werkzeug" version = "2.0.3" description = "The comprehensive WSGI web application library." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2738,6 +2975,7 @@ watchdog = ["watchdog"] name = "yarl" version = "1.9.4" description = "Yet another URL library" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2841,6 +3079,7 @@ multidict = ">=4.0" name = "zipp" version = "3.19.2" description = "Backport of pathlib-compatible object wrapper for zip files" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2855,4 +3094,4 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", [metadata] lock-version = "2.0" python-versions = "<4.0,>=3.8" -content-hash = "5fa061baee21213f2d471e79e7c00fd6f4bca217f7d53bd74c29e0637d447bd3" +content-hash = "51ac5f8bc9fc8ab317875066cb565858ec7184c5215f7b536944ea52d0eb1749" diff --git a/pyproject.toml b/pyproject.toml index b4c266b81..60f52a792 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "olas-operate-middleware" -version = "0.1.0-rc50" +version = "0.1.0-rc54" description = "" authors = ["David Vilela ", "Viraj Patel "] readme = "README.md" @@ -44,6 +44,10 @@ starlette = "==0.36.3" uvicorn = "==0.27.0" web3 = "==6.1.0" psutil = "^5.9.8" +aiohttp = "3.9.5" + +[tool.poetry.group.development.dependencies] +tomte = {version = "0.2.15", extras = ["cli"]} [build-system] requires = ["poetry-core"] diff --git a/templates/trader.yaml b/templates/trader.yaml index 5be1fa187..d85460c97 100644 --- a/templates/trader.yaml +++ b/templates/trader.yaml @@ -1,6 +1,6 @@ name: "Trader Agent" description: "Trader agent for omen prediction markets" -hash: bafybeieg45wcjcwd5znuwpjcp5scfhgdqwpfq43pzaare6nwvmy5bb56cm +hash: bafybeicihxhw2djlsuoy2eji3g2tmasipfqe3rwsfvzbd2j3tvphqvp7aa image: https://operate.olas.network/_next/image?url=%2Fimages%2Fprediction-agent.png&w=3840&q=75 configuration: nft: bafybeig64atqaladigoc3ds4arltdu63wkdrk3gesjfvnfdmz35amv7faq