mech-client 0.8.1__py3-none-any.whl → 0.9.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. mech_client/__init__.py +1 -1
  2. mech_client/cli.py +8 -0
  3. mech_client/marketplace_interact.py +18 -6
  4. {mech_client-0.8.1.dist-info → mech_client-0.9.0.dist-info}/METADATA +11 -1
  5. {mech_client-0.8.1.dist-info → mech_client-0.9.0.dist-info}/RECORD +30 -8
  6. scripts/__init__.py +1 -0
  7. scripts/benchmark.sh +32 -0
  8. scripts/bump.py +316 -0
  9. scripts/deposit_native.py +118 -0
  10. scripts/deposit_token.py +187 -0
  11. scripts/nvm_subscribe.py +51 -0
  12. scripts/nvm_subscription/contracts/agreement_manager.py +44 -0
  13. scripts/nvm_subscription/contracts/base_contract.py +75 -0
  14. scripts/nvm_subscription/contracts/did_registry.py +91 -0
  15. scripts/nvm_subscription/contracts/escrow_payment.py +85 -0
  16. scripts/nvm_subscription/contracts/lock_payment.py +76 -0
  17. scripts/nvm_subscription/contracts/nft.py +47 -0
  18. scripts/nvm_subscription/contracts/nft_sales.py +119 -0
  19. scripts/nvm_subscription/contracts/subscription_provider.py +107 -0
  20. scripts/nvm_subscription/contracts/token.py +87 -0
  21. scripts/nvm_subscription/contracts/transfer_nft.py +81 -0
  22. scripts/nvm_subscription/envs/base.env +10 -0
  23. scripts/nvm_subscription/envs/gnosis.env +10 -0
  24. scripts/nvm_subscription/manager.py +265 -0
  25. scripts/nvm_subscription/resources/networks.json +56 -0
  26. scripts/utils.py +127 -0
  27. scripts/whitelist.py +5 -0
  28. {mech_client-0.8.1.dist-info → mech_client-0.9.0.dist-info}/LICENSE +0 -0
  29. {mech_client-0.8.1.dist-info → mech_client-0.9.0.dist-info}/WHEEL +0 -0
  30. {mech_client-0.8.1.dist-info → mech_client-0.9.0.dist-info}/entry_points.txt +0 -0
mech_client/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """Mech client."""
2
2
 
3
- __version__ = "0.8.1"
3
+ __version__ = "0.9.0"
mech_client/cli.py CHANGED
@@ -19,6 +19,7 @@
19
19
 
20
20
  """Mech client CLI module."""
21
21
  import json
22
+ import os
22
23
  from typing import Any, Dict, List, Optional, Tuple
23
24
 
24
25
  import click
@@ -156,6 +157,12 @@ def interact( # pylint: disable=too-many-arguments,too-many-locals
156
157
  use_offchain = use_offchain or False
157
158
  use_prepaid = use_prepaid or use_offchain
158
159
 
160
+ mech_offchain_url = os.getenv("MECHX_MECH_OFFCHAIN_URL")
161
+ if use_offchain and not mech_offchain_url:
162
+ raise Exception(
163
+ "To use offchain requests, please set MECHX_MECH_OFFCHAIN_URL"
164
+ )
165
+
159
166
  if agent_id is None:
160
167
  if len(prompts) != len(tools):
161
168
  raise ClickException(
@@ -167,6 +174,7 @@ def interact( # pylint: disable=too-many-arguments,too-many-locals
167
174
  priority_mech=priority_mech,
168
175
  use_prepaid=use_prepaid,
169
176
  use_offchain=use_offchain,
177
+ mech_offchain_url=mech_offchain_url,
170
178
  private_key_path=key,
171
179
  tools=tools,
172
180
  extra_attributes=extra_attributes_dict,
@@ -74,6 +74,8 @@ class PaymentType(Enum):
74
74
 
75
75
 
76
76
  IPFS_URL_TEMPLATE = "https://gateway.autonolas.tech/ipfs/f01701220{}"
77
+ MECH_OFFCHAIN_REQUEST_ENDPOINT = "send_signed_requests"
78
+ MECH_OFFCHAIN_DELIVER_ENDPOINT = "fetch_offchain_info"
77
79
  ABI_DIR_PATH = Path(__file__).parent / "abis"
78
80
  IMECH_ABI_PATH = ABI_DIR_PATH / "IMech.json"
79
81
  ITOKEN_ABI_PATH = ABI_DIR_PATH / "IToken.json"
@@ -389,6 +391,7 @@ def send_marketplace_request( # pylint: disable=too-many-arguments,too-many-loc
389
391
  def send_offchain_marketplace_request( # pylint: disable=too-many-arguments,too-many-locals
390
392
  crypto: EthereumCrypto,
391
393
  marketplace_contract: Web3Contract,
394
+ mech_offchain_url: str,
392
395
  prompt: str,
393
396
  tool: str,
394
397
  method_args_data: MechMarketplaceRequestConfig,
@@ -405,6 +408,8 @@ def send_offchain_marketplace_request( # pylint: disable=too-many-arguments,too
405
408
  :type crypto: EthereumCrypto
406
409
  :param marketplace_contract: The mech marketplace contract instance.
407
410
  :type marketplace_contract: Web3Contract
411
+ :param mech_offchain_url: mech url to connect to.
412
+ :type mech_offchain_url: str
408
413
  :param prompt: The request prompt.
409
414
  :type prompt: str
410
415
  :param tool: The requested tool.
@@ -469,9 +474,9 @@ def send_offchain_marketplace_request( # pylint: disable=too-many-arguments,too
469
474
  "nonce": nonce,
470
475
  "ipfs_data": ipfs_data,
471
476
  }
472
- # @todo changed hardcoded url
477
+ url = mech_offchain_url + MECH_OFFCHAIN_REQUEST_ENDPOINT
473
478
  response = requests.post(
474
- "http://localhost:8000/send_signed_requests",
479
+ url=url,
475
480
  data=payload,
476
481
  headers={"Content-Type": "application/json"},
477
482
  ).json()
@@ -562,10 +567,12 @@ def wait_for_marketplace_data_url( # pylint: disable=too-many-arguments, unused
562
567
  return result
563
568
 
564
569
 
565
- def wait_for_offchain_marketplace_data(request_id: str) -> Any:
570
+ def wait_for_offchain_marketplace_data(mech_offchain_url: str, request_id: str) -> Any:
566
571
  """
567
572
  Watches for data off-chain on mech.
568
573
 
574
+ :param mech_offchain_url: mech url to connect to.
575
+ :type mech_offchain_url: str
569
576
  :param request_id: The ID of the request.
570
577
  :type request_id: str
571
578
  :return: The data returned by the mech.
@@ -573,15 +580,15 @@ def wait_for_offchain_marketplace_data(request_id: str) -> Any:
573
580
  """
574
581
  while True:
575
582
  try:
576
- # @todo change hardcoded url
583
+ url = mech_offchain_url + MECH_OFFCHAIN_DELIVER_ENDPOINT
577
584
  response = requests.get(
578
- "http://localhost:8000/fetch_offchain_info",
585
+ url=url,
579
586
  data={"request_id": request_id},
580
587
  ).json()
581
588
  if response:
582
589
  return response
583
590
  except Exception: # pylint: disable=broad-except
584
- time.sleep(1)
591
+ time.sleep(WAIT_SLEEP)
585
592
 
586
593
 
587
594
  def check_prepaid_balances(
@@ -638,6 +645,7 @@ def marketplace_interact( # pylint: disable=too-many-arguments, too-many-locals
638
645
  priority_mech: str,
639
646
  use_prepaid: bool = False,
640
647
  use_offchain: bool = False,
648
+ mech_offchain_url: str = "",
641
649
  tools: tuple = (),
642
650
  extra_attributes: Optional[Dict[str, Any]] = None,
643
651
  private_key_path: Optional[str] = None,
@@ -658,6 +666,8 @@ def marketplace_interact( # pylint: disable=too-many-arguments, too-many-locals
658
666
  :type use_prepaid: bool
659
667
  :param use_offchain: Whether to use offchain model or not.
660
668
  :type use_offchain: bool
669
+ :param mech_offchain_url: mech url to connect to.
670
+ :type mech_offchain_url: str
661
671
  :param tools: The tools to interact with (optional).
662
672
  :type tools: tuple
663
673
  :param extra_attributes: Extra attributes to be included in the request metadata (optional).
@@ -882,6 +892,7 @@ def marketplace_interact( # pylint: disable=too-many-arguments, too-many-locals
882
892
  response = send_offchain_marketplace_request(
883
893
  crypto=crypto,
884
894
  marketplace_contract=mech_marketplace_contract,
895
+ mech_offchain_url=mech_offchain_url,
885
896
  prompt=prompts[0],
886
897
  tool=tools[0],
887
898
  method_args_data=mech_marketplace_request_config,
@@ -910,6 +921,7 @@ def marketplace_interact( # pylint: disable=too-many-arguments, too-many-locals
910
921
 
911
922
  for request_id in request_ids:
912
923
  data = wait_for_offchain_marketplace_data(
924
+ mech_offchain_url=mech_offchain_url,
913
925
  request_id=request_id,
914
926
  )
915
927
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mech-client
3
- Version: 0.8.1
3
+ Version: 0.9.0
4
4
  Summary: Basic client to interact with a mech
5
5
  License: Apache-2.0
6
6
  Author: David Minarsch
@@ -237,6 +237,16 @@ Additionally to other options which are the same as for legacy Mechs, this usage
237
237
 
238
238
  `--use-prepaid <bool>`: use the prepaid method to send requests to a Mech via the Mech Marketplace. Defaults to False. <br>
239
239
  `--use-offchain <bool>`: use the off-chain method to send requests to a Mech via the Mech Marketplace. Defaults to False.
240
+ > To use offchain requests using `--use-offchain` flag, export the `MECHX_MECH_OFFCHAIN_URL` env variable before sending requests. For example if you want to connect to a mech running locally, you can do the following
241
+ ```bash
242
+ export MECHX_MECH_OFFCHAIN_URL="http://localhost:8000/"
243
+ ```
244
+ If you want to use a Valory mech for offchain requests, below is the list of mechs and their address and offchain urls.
245
+
246
+ | Service ID | Priority Mech Address | Offchain URL |
247
+ | :---: | :---: | :---: |
248
+ | 2182 | 0xB3C6319962484602b00d5587e965946890b82101 | https://d19715222af5b940.agent.propel.autonolas.tech/ |
249
+
240
250
 
241
251
  The Mech Client can also be used to send batch requests. There are couple of different ways to achieve this:
242
252
 
@@ -1,4 +1,4 @@
1
- mech_client/__init__.py,sha256=H6mfUy3jsvO3gznDqhbjyAY9Uu4NeCw-M2QfB2WThRc,42
1
+ mech_client/__init__.py,sha256=Ed2swOIv8MmttDlcU_lXntd4MDQZ75GbLzEVhuhi_3o,42
2
2
  mech_client/abis/AgentMech.json,sha256=IEbs_xBGunBu5h-uT5DvIty8Zw412QoPI46S_DUMYNw,18082
3
3
  mech_client/abis/AgentRegistry.json,sha256=2qmXeFINZWz9pyOma6Bq67kMDSUI1lD7WvgHLwuETD8,24723
4
4
  mech_client/abis/AgreementStoreManager.base.json,sha256=_ljdIZcfFGmFzBHUTfhA4X0382ZHHpkdr_CziTwUETo,34360
@@ -30,7 +30,7 @@ mech_client/abis/SubscriptionToken.base.json,sha256=5StPEyfRvDMTqtQPO-KakXXZqobX
30
30
  mech_client/abis/TransferNFTCondition.base.json,sha256=71O_3itHBz9qPtoTLev8_a7KxlcQfIZSfxK2562lkqw,42540
31
31
  mech_client/abis/TransferNFTCondition.gnosis.json,sha256=-huhxV54eoNY8mR9WtQdmSgQDgaKiUi0PULJ4HEshWw,42540
32
32
  mech_client/acn.py,sha256=Rj_jLPvJ5loDQfGbu3a_O24cJC4SwIErLceSz_zVYS8,5356
33
- mech_client/cli.py,sha256=XezX27Y0VdnUq8HmHF6HxyhPmsC91YuLSuqAoi41UrE,17655
33
+ mech_client/cli.py,sha256=CgpembCl3JTubCgUYw7-one6cuge8YlUTHfoIkhbZu4,17957
34
34
  mech_client/configs/mechs.json,sha256=Zv8JrY6yvNsSxTP7RchvR1yz2k3yjYUZkuSILnPbWzg,5445
35
35
  mech_client/fetch_ipfs_hash.py,sha256=tg_hYVf4deXl89x3SOBrGFUthaSeN_Vg_OHDtfjdbp4,2752
36
36
  mech_client/helpers/__init__.py,sha256=nmQig1EqBQ9EMOpgdykP3a6_2NWcoVH3-lnyHP5n0ws,1196
@@ -62,7 +62,7 @@ mech_client/helpers/p2p_libp2p_client/__init__.py,sha256=-GOP3D_JnmXTDomrMLCbnRk
62
62
  mech_client/helpers/p2p_libp2p_client/connection.py,sha256=b5jfcUeSoNrUw8DOSTCbK4DTi-N8bf2_pdogUOz0ep0,28606
63
63
  mech_client/helpers/p2p_libp2p_client/connection.yaml,sha256=nMiHnU_dv9EFjVNqZ-0SAnoATfadJSad-JsbDvk97Mk,1790
64
64
  mech_client/interact.py,sha256=52UW5NysSTIC--APLpJde8VvrruWeYFCFzO02uRQpwc,21288
65
- mech_client/marketplace_interact.py,sha256=rRIHYLzuaXYW7vh4fvNh9KBbUY4tgoavmMxFaPg0Rkw,33045
65
+ mech_client/marketplace_interact.py,sha256=7K-xb4Bg9UrWs3U_xXIRibnfBjCaRG4XZyeAi-nO6BU,33591
66
66
  mech_client/mech_marketplace_tool_management.py,sha256=q_cXyJGI1rLXKB_Ds21eQLCzUhTYE9BHN48wqIw0w6g,7341
67
67
  mech_client/mech_tool_management.py,sha256=NQFmVzzGZsIkeHokDPWXGHwa8u-pyQIMPR1Q5H81bKw,7806
68
68
  mech_client/prompt_to_ipfs.py,sha256=XqSIBko15MEkpWOQNT97fRI6jNxMF5EDBDEPOJFdhyk,2533
@@ -70,8 +70,30 @@ mech_client/push_to_ipfs.py,sha256=IfvgaPU79N_ZmCPF9d7sPCYz2uduZH0KjT_HQ2LHXoQ,2
70
70
  mech_client/subgraph.py,sha256=MiyWiLPkqtXS9qayT75xYM6tz2pxd2Q6iE92yZxDugw,4700
71
71
  mech_client/to_png.py,sha256=pjUcFJ63MJj_r73eqnfqCWMtlpsrj6H4ZmgvIEmRcFw,2581
72
72
  mech_client/wss.py,sha256=N38eprKqwHyQpqGa6XZ9ZUwJ_YO50wlBJqJ5D1QCIj4,9888
73
- mech_client-0.8.1.dist-info/LICENSE,sha256=mdBDB-mWKV5Cz4ejBzBiKqan6Z8zVLAh9xwM64O2FW4,11339
74
- mech_client-0.8.1.dist-info/METADATA,sha256=7FyF1UwwIe5-EmE1vYk16-wz94fA1IHycPPY5xd8Oo4,25165
75
- mech_client-0.8.1.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
76
- mech_client-0.8.1.dist-info/entry_points.txt,sha256=SbRMRsayzD8XfNXhgwPuXEqQsdZ5Bw9XDPnUuaDExyY,45
77
- mech_client-0.8.1.dist-info/RECORD,,
73
+ scripts/__init__.py,sha256=I8VcZ7sjlAw171Er7B6mumpMLfrynrWie4YoeJIayno,26
74
+ scripts/benchmark.sh,sha256=qgfYEI5u8Qd-vqaD3xZktuubXyz0sdHE1_9qg6stEzs,935
75
+ scripts/bump.py,sha256=2o4MsFGG_ix4UXscekfX7dqpM-q-T4mTwkHw_KtA8mk,9503
76
+ scripts/deposit_native.py,sha256=A66o74w7Mg9VS7uh3xWGg6gu3x6iE9tyHUbhl1usmjw,3902
77
+ scripts/deposit_token.py,sha256=PGJszulGTk4utrKIhqtaiP_yKzs8nV9inNAHSUdvxtM,6067
78
+ scripts/nvm_subscribe.py,sha256=N3I9r9ugTf_HMfQSAGeKq0TcInJsWI8rYQVF57AmmFM,1473
79
+ scripts/nvm_subscription/contracts/agreement_manager.py,sha256=JFP5YJTbo_1liZTBmnkvHtRm-0Dfmp-gyRkXHPdzPG8,1466
80
+ scripts/nvm_subscription/contracts/base_contract.py,sha256=DR_GfPZo9i47o3AYAxGR6hjc0KhHQY1dJ2yRXJ8I9DE,2868
81
+ scripts/nvm_subscription/contracts/did_registry.py,sha256=yoWp2V29qFozgGsndKiExpF-yQ13TfCZmGGWb1DRmS8,3108
82
+ scripts/nvm_subscription/contracts/escrow_payment.py,sha256=7B-TdZYq9ELj58jWhD-2RcdGg-pYWYxuRnhQXx6K9TA,2856
83
+ scripts/nvm_subscription/contracts/lock_payment.py,sha256=_nRRkjnHgThSqAQ91bIwGq18yvWVPItAY2JfEz8aWOk,2556
84
+ scripts/nvm_subscription/contracts/nft.py,sha256=NOOCNcPd0fP7gtShH1fECpSR_hUBcihIcoEaEj8tZN4,1287
85
+ scripts/nvm_subscription/contracts/nft_sales.py,sha256=pjCrAgebDL7pet3gxL5TjkPRUwZGu1S95SGILJ2wiKk,4700
86
+ scripts/nvm_subscription/contracts/subscription_provider.py,sha256=cVjoZ4yEKR8mJOFYrlsKrVD_A18i6qplGgvw3cKwh5E,3981
87
+ scripts/nvm_subscription/contracts/token.py,sha256=NrVnxlcP2J0QyiuPbVIoeSEPHEEUU0IXTmC6AYc1i7w,2728
88
+ scripts/nvm_subscription/contracts/transfer_nft.py,sha256=Z3IlfBYVQLT4WhI5cszruHCKBrwQGTBuZrlQQcuEN3s,2681
89
+ scripts/nvm_subscription/envs/base.env,sha256=mI2loQ5Dt-rkZzuzmgyNiV-fUutwN89kOsEmygG4K78,528
90
+ scripts/nvm_subscription/envs/gnosis.env,sha256=mDCb1wEY4fRQYJQuyqg2b4qTFQtHHopRaKYCXTCeACM,554
91
+ scripts/nvm_subscription/manager.py,sha256=y0Qh0aVAmOPB4Ytt93alIarSvhrQpC-lRYNAY09GRZ0,10054
92
+ scripts/nvm_subscription/resources/networks.json,sha256=xH0P3YkgkMTkQdahVKO0kI9m6ybJ67iwHApstUlfRmw,2359
93
+ scripts/utils.py,sha256=lXjY3s1HvNHT2fXm2fBpZtVvlQaqW288Y2S-s3rpSDM,3248
94
+ scripts/whitelist.py,sha256=-TF4fcojBmF6a7fXleBk96DvJ-xWkNGoN0s_8r8J20Q,289
95
+ mech_client-0.9.0.dist-info/LICENSE,sha256=mdBDB-mWKV5Cz4ejBzBiKqan6Z8zVLAh9xwM64O2FW4,11339
96
+ mech_client-0.9.0.dist-info/METADATA,sha256=S5aSBEHrmFl-Az-VGwdqRQEtp2OQ2DN8jPPOXvYsYfM,25935
97
+ mech_client-0.9.0.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
98
+ mech_client-0.9.0.dist-info/entry_points.txt,sha256=SbRMRsayzD8XfNXhgwPuXEqQsdZ5Bw9XDPnUuaDExyY,45
99
+ mech_client-0.9.0.dist-info/RECORD,,
scripts/__init__.py ADDED
@@ -0,0 +1 @@
1
+ """Mech client scripts"""
scripts/benchmark.sh ADDED
@@ -0,0 +1,32 @@
1
+ #!/bin/bash
2
+
3
+ export MANUAL_GAS_LIMIT=150000
4
+ export WEBSOCKET_ENDPOINT=wss://rpc.eu-central-2.gateway.fm/ws/v4/gnosis/non-archival/mainnet
5
+ iterations=2
6
+
7
+ mechx --version
8
+
9
+ echo $WEBSOCKET_ENDPOINT
10
+
11
+ start_time=$(date +%s.%N)
12
+
13
+ # Execute the command for the specified number of iterations
14
+ for ((i=1; i<=$iterations; i++)); do
15
+ echo "- Iteration $i"
16
+
17
+ prompt="($i) Will arsenal win the Premier League in 2024"
18
+ mechx interact "$prompt" 6 --tool prediction-offline --confirm on-chain --extra-attribute key1=value1 --extra-attribute key2=value2
19
+
20
+ if [ $? -ne 0 ]; then
21
+ echo "Error: Command execution failed."
22
+ exit 1
23
+ fi
24
+
25
+ echo ""
26
+ done
27
+
28
+ end_time=$(date +%s.%N)
29
+ elapsed_time=$(echo "$end_time - $start_time" | bc)
30
+ seconds_per_iteration=$(echo "$elapsed_time / $iterations" | bc)
31
+
32
+ echo "Overall execution time for $iterations iterations: $elapsed_time seconds (rate of $seconds_per_iteration seconds/iteration)."
scripts/bump.py ADDED
@@ -0,0 +1,316 @@
1
+ # -*- coding: utf-8 -*-
2
+ # ------------------------------------------------------------------------------
3
+ #
4
+ # Copyright 2023 Valory AG
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ # ------------------------------------------------------------------------------
19
+
20
+ """
21
+ Script for bumping core dependencies.
22
+
23
+ This script
24
+
25
+ - Fetches the latest core dependency versions from github
26
+ - Updates the tox.ini, packages and Pipfile/pyproject.toml files
27
+ - Performs the packages sync
28
+ """
29
+
30
+ import os
31
+ import re
32
+ import typing as t
33
+ from pathlib import Path
34
+
35
+ import click
36
+ import requests
37
+ from aea.cli.utils.click_utils import PackagesSource, PyPiDependency
38
+ from aea.configurations.constants import PACKAGES, PACKAGE_TYPE_TO_CONFIG_FILE
39
+ from aea.configurations.data_types import Dependency
40
+ from aea.helpers.logging import setup_logger
41
+ from aea.helpers.yaml_utils import yaml_dump, yaml_dump_all, yaml_load, yaml_load_all
42
+ from aea.package_manager.v1 import PackageManagerV1
43
+
44
+ from autonomy.cli.helpers.ipfs_hash import load_configuration
45
+
46
+
47
+ BUMP_BRANCH = "chore/bump"
48
+ PIPFILE = Path.cwd() / "Pipfile"
49
+ PYPROJECT_TOML = Path.cwd() / "pyproject.toml"
50
+ TOX_INI = Path.cwd() / "tox.ini"
51
+
52
+ TAGS_URL = "https://api.github.com/repos/{repo}/tags"
53
+ FILE_URL = "https://raw.githubusercontent.com/{repo}/{tag}/{file}"
54
+
55
+ VERISON_RE = re.compile(r"(__version__|version)( )?=( )?\"(?P<version>[0-9a-z\.]+)\"")
56
+
57
+ OPEN_AEA_REPO = "valory-xyz/open-aea"
58
+ OPEN_AUTONOMY_REPO = "valory-xyz/open-autonomy"
59
+
60
+ DEPENDENCY_SPECS = {
61
+ "open-aea": {
62
+ "repo": OPEN_AEA_REPO,
63
+ "file": "aea/__version__.py",
64
+ },
65
+ "open-aea-ledger-ethereum": {
66
+ "repo": OPEN_AEA_REPO,
67
+ "file": "plugins/aea-ledger-ethereum/setup.py",
68
+ },
69
+ "open-aea-ledger-ethereum-flashbots": {
70
+ "repo": OPEN_AEA_REPO,
71
+ "file": "plugins/aea-ledger-ethereum-flashbots/setup.py",
72
+ },
73
+ "open-aea-ledger-ethereum-hwi": {
74
+ "repo": OPEN_AEA_REPO,
75
+ "file": "plugins/aea-ledger-ethereum-hwi/setup.py",
76
+ },
77
+ "open-aea-ledger-cosmos": {
78
+ "repo": OPEN_AEA_REPO,
79
+ "file": "plugins/aea-ledger-cosmos/setup.py",
80
+ },
81
+ "open-aea-ledger-solana": {
82
+ "repo": OPEN_AEA_REPO,
83
+ "file": "plugins/aea-ledger-solana/setup.py",
84
+ },
85
+ "open-aea-cli-ipfs": {
86
+ "repo": OPEN_AEA_REPO,
87
+ "file": "plugins/aea-cli-ipfs/setup.py",
88
+ },
89
+ "open-autonomy": {
90
+ "repo": OPEN_AUTONOMY_REPO,
91
+ "file": "autonomy/__version__.py",
92
+ },
93
+ "open-aea-test-autonomy": {
94
+ "repo": OPEN_AUTONOMY_REPO,
95
+ "file": "plugins/aea-test-autonomy/setup.py",
96
+ },
97
+ }
98
+
99
+ _cache_file = Path.home() / ".aea" / ".gitcache"
100
+ _version_cache = {}
101
+ _logger = setup_logger("bump")
102
+
103
+
104
+ def load_git_cache() -> None:
105
+ """Load versions cache."""
106
+ if not _cache_file.exists():
107
+ return
108
+ with _cache_file.open("r", encoding="utf-8") as stream:
109
+ _version_cache.update(yaml_load(stream=stream))
110
+
111
+
112
+ def dump_git_cache() -> None:
113
+ """Dump versions cache."""
114
+ with _cache_file.open("w", encoding="utf-8") as stream:
115
+ yaml_dump(data=_version_cache, stream=stream)
116
+
117
+
118
+ def make_git_request(url: str) -> requests.Response:
119
+ """Make git request"""
120
+ auth = os.environ.get("GITHUB_AUTH")
121
+ if auth is None:
122
+ return requests.get(url=url)
123
+ return requests.get(url=url, headers={"Authorization": f"Bearer {auth}"})
124
+
125
+
126
+ def get_latest_tag(repo: str) -> str:
127
+ """Fetch latest git tag."""
128
+ if repo in _version_cache:
129
+ return _version_cache[repo]
130
+
131
+ response = make_git_request(url=TAGS_URL.format(repo=repo))
132
+ if response.status_code != 200:
133
+ raise ValueError(
134
+ f"Fetching tags from `{repo}` failed with message '"
135
+ + response.json()["message"]
136
+ + "'"
137
+ )
138
+ latest_tag_data, *_ = response.json()
139
+ _version_cache[repo] = latest_tag_data["name"]
140
+ return _version_cache[repo]
141
+
142
+
143
+ def get_dependency_version(repo: str, file: str) -> str:
144
+ """Get version spec ."""
145
+ response = make_git_request(
146
+ FILE_URL.format(
147
+ repo=repo,
148
+ tag=get_latest_tag(repo=repo),
149
+ file=file,
150
+ )
151
+ )
152
+ if response.status_code != 200:
153
+ raise ValueError(
154
+ f"Fetching packages from `{repo}` failed with message '"
155
+ + response.text
156
+ + "'"
157
+ )
158
+ ((*_, version),) = VERISON_RE.findall(response.content.decode())
159
+ return f"=={version}"
160
+
161
+
162
+ def get_dependencies() -> t.Dict:
163
+ """Get dependency->version mapping."""
164
+ dependencies = {}
165
+ for dependency, specs in DEPENDENCY_SPECS.items():
166
+ version = _version_cache.get(
167
+ dependency,
168
+ get_dependency_version(
169
+ repo=specs["repo"],
170
+ file=specs["file"],
171
+ ),
172
+ )
173
+ dependencies[dependency] = version
174
+ _version_cache.update(dependencies)
175
+ return dependencies
176
+
177
+
178
+ def bump_pipfile_or_pyproject(file: Path, dependencies: t.Dict[str, str]) -> None:
179
+ """Bump Pipfile."""
180
+ if not file.exists():
181
+ return
182
+
183
+ _logger.info(f"Updating {file.name}")
184
+ updated = ""
185
+ content = file.read_text(encoding="utf-8")
186
+ for line in content.split("\n"):
187
+ try:
188
+ spec = Dependency.from_pipfile_string(line)
189
+ update = dependencies.get(spec.name)
190
+ if update is None:
191
+ updated += line + "\n"
192
+ continue
193
+ spec = Dependency(
194
+ name=spec.name,
195
+ version=update,
196
+ extras=spec.extras,
197
+ )
198
+ updated += spec.to_pipfile_string() + "\n"
199
+ except ValueError:
200
+ updated += line + "\n"
201
+ file.write_text(updated[:-1], encoding="utf-8")
202
+
203
+
204
+ def bump_tox(dependencies: t.Dict[str, str]) -> None:
205
+ """Bump tox file."""
206
+ if not TOX_INI.exists():
207
+ return
208
+
209
+ _logger.info("Updating tox.ini")
210
+ updated = ""
211
+ content = TOX_INI.read_text(encoding="utf-8")
212
+ for line in content.split("\n"):
213
+ try:
214
+ spec = Dependency.from_string(line.lstrip().rstrip())
215
+ update = dependencies.get(spec.name)
216
+ if update is None:
217
+ updated += line + "\n"
218
+ continue
219
+ spec = Dependency(
220
+ name=spec.name,
221
+ version=update,
222
+ extras=spec.extras,
223
+ )
224
+ updated += " " + spec.to_pip_string() + "\n"
225
+ except ValueError:
226
+ updated += line + "\n"
227
+ TOX_INI.write_text(updated[:-1], encoding="utf-8")
228
+
229
+
230
+ def bump_packages(dependencies: t.Dict[str, str]) -> None:
231
+ """Bump packages."""
232
+ _logger.info("Updating packages")
233
+ manager = PackageManagerV1.from_dir(Path(PACKAGES))
234
+ for package_id in manager.dev_packages:
235
+ path = (
236
+ manager.package_path_from_package_id(
237
+ package_id=package_id,
238
+ )
239
+ / PACKAGE_TYPE_TO_CONFIG_FILE[package_id.package_type.value]
240
+ )
241
+ with path.open("r", encoding="utf-8") as stream:
242
+ config, *extra = yaml_load_all(stream=stream)
243
+
244
+ for name in config.get("dependencies", {}):
245
+ update = dependencies.get(name)
246
+ if update is None:
247
+ continue
248
+ config["dependencies"][name]["version"] = update
249
+
250
+ with path.open("w", encoding="utf-8") as stream:
251
+ yaml_dump_all([config, *extra], stream=stream)
252
+
253
+
254
+ @click.command(name="bump")
255
+ @click.option(
256
+ "-d",
257
+ "--dependency",
258
+ "extra",
259
+ type=PyPiDependency(),
260
+ multiple=True,
261
+ help="Specify extra dependency.",
262
+ )
263
+ @click.option(
264
+ "-s",
265
+ "--source",
266
+ "sources",
267
+ type=PackagesSource(),
268
+ multiple=True,
269
+ help="Specify extra sources.",
270
+ )
271
+ @click.option("--sync", is_flag=True, help="Perform sync.")
272
+ @click.option(
273
+ "--no-cache",
274
+ is_flag=True,
275
+ default=False,
276
+ help="Avoid using cache to bump.",
277
+ )
278
+ def main(
279
+ extra: t.Tuple[Dependency, ...],
280
+ sources: t.Tuple[str, ...],
281
+ sync: bool,
282
+ no_cache: bool,
283
+ ) -> None:
284
+ """Run the bump script."""
285
+
286
+ if not no_cache:
287
+ load_git_cache()
288
+
289
+ dependencies = {}
290
+ dependencies.update(get_dependencies())
291
+ dependencies.update({dep.name: dep.version for dep in extra or []})
292
+
293
+ bump_pipfile_or_pyproject(PIPFILE, dependencies=dependencies)
294
+ bump_pipfile_or_pyproject(PYPROJECT_TOML, dependencies=dependencies)
295
+ bump_tox(dependencies=dependencies)
296
+ bump_packages(dependencies=dependencies)
297
+ dump_git_cache()
298
+
299
+ if sync:
300
+ pm = PackageManagerV1.from_dir(
301
+ Path.cwd() / PACKAGES, config_loader=load_configuration
302
+ )
303
+ pm.sync(
304
+ sources=[
305
+ f"{OPEN_AEA_REPO}:{_version_cache[OPEN_AEA_REPO]}",
306
+ f"{OPEN_AUTONOMY_REPO}:{_version_cache[OPEN_AUTONOMY_REPO]}",
307
+ *sources,
308
+ ],
309
+ update_packages=True,
310
+ )
311
+ pm.update_package_hashes()
312
+ pm.dump()
313
+
314
+
315
+ if __name__ == "__main__":
316
+ main() # pylint: disable=no-value-for-parameter