pytonapi 0.3.6__tar.gz → 0.3.7__tar.gz

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 (115) hide show
  1. pytonapi-0.3.7/PKG-INFO +134 -0
  2. pytonapi-0.3.7/README.md +114 -0
  3. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/async_tonapi/__init__.py +21 -8
  4. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/async_tonapi/client.py +65 -25
  5. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/async_tonapi/methods/__init__.py +4 -0
  6. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/async_tonapi/methods/accounts.py +13 -32
  7. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/async_tonapi/methods/blockchain.py +2 -14
  8. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/async_tonapi/methods/dns.py +2 -2
  9. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/async_tonapi/methods/emulate.py +2 -2
  10. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/async_tonapi/methods/events.py +4 -4
  11. pytonapi-0.3.7/pytonapi/async_tonapi/methods/gasless.py +56 -0
  12. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/async_tonapi/methods/inscriptions.py +3 -3
  13. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/async_tonapi/methods/jettons.py +3 -3
  14. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/async_tonapi/methods/liteserver.py +2 -2
  15. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/async_tonapi/methods/nft.py +4 -8
  16. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/async_tonapi/methods/rates.py +17 -6
  17. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/async_tonapi/methods/sse.py +12 -12
  18. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/async_tonapi/methods/staking.py +2 -2
  19. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/async_tonapi/methods/storage.py +2 -2
  20. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/async_tonapi/methods/tonconnect.py +2 -2
  21. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/async_tonapi/methods/traces.py +4 -4
  22. pytonapi-0.3.7/pytonapi/async_tonapi/methods/utilites.py +28 -0
  23. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/async_tonapi/methods/wallet.py +2 -2
  24. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/async_tonapi/methods/websocket.py +2 -2
  25. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/exceptions.py +1 -1
  26. pytonapi-0.3.7/pytonapi/logger_config.py +25 -0
  27. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/schema/__init__.py +2 -0
  28. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/schema/_address.py +5 -10
  29. pytonapi-0.3.7/pytonapi/schema/_balance.py +31 -0
  30. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/schema/accounts.py +14 -26
  31. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/schema/blockchain.py +24 -29
  32. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/schema/dns.py +4 -4
  33. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/schema/domains.py +3 -3
  34. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/schema/events.py +49 -49
  35. pytonapi-0.3.7/pytonapi/schema/gasless.py +27 -0
  36. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/schema/inscriptions.py +1 -1
  37. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/schema/jettons.py +8 -7
  38. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/schema/liteserver.py +1 -1
  39. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/schema/nft.py +11 -11
  40. pytonapi-0.3.7/pytonapi/schema/rates.py +28 -0
  41. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/schema/staking.py +2 -2
  42. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/schema/storage.py +1 -1
  43. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/schema/tonconnect.py +1 -1
  44. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/schema/traces.py +26 -26
  45. pytonapi-0.3.7/pytonapi/schema/utilites.py +20 -0
  46. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/tonapi/__init__.py +36 -22
  47. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/tonapi/client.py +64 -23
  48. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/tonapi/methods/__init__.py +4 -0
  49. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/tonapi/methods/accounts.py +14 -33
  50. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/tonapi/methods/blockchain.py +2 -14
  51. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/tonapi/methods/dns.py +2 -2
  52. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/tonapi/methods/emulate.py +2 -2
  53. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/tonapi/methods/events.py +4 -4
  54. pytonapi-0.3.7/pytonapi/tonapi/methods/gasless.py +56 -0
  55. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/tonapi/methods/inscriptions.py +3 -3
  56. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/tonapi/methods/jettons.py +3 -4
  57. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/tonapi/methods/liteserver.py +2 -2
  58. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/tonapi/methods/nft.py +33 -29
  59. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/tonapi/methods/rates.py +18 -6
  60. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/tonapi/methods/sse.py +13 -13
  61. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/tonapi/methods/staking.py +2 -2
  62. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/tonapi/methods/storage.py +2 -2
  63. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/tonapi/methods/tonconnect.py +2 -2
  64. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/tonapi/methods/traces.py +4 -5
  65. pytonapi-0.3.7/pytonapi/tonapi/methods/utilites.py +28 -0
  66. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/tonapi/methods/wallet.py +2 -2
  67. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/utils.py +17 -15
  68. pytonapi-0.3.7/pytonapi.egg-info/PKG-INFO +134 -0
  69. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi.egg-info/SOURCES.txt +41 -1
  70. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi.egg-info/top_level.txt +1 -0
  71. {pytonapi-0.3.6 → pytonapi-0.3.7}/setup.py +1 -1
  72. pytonapi-0.3.7/tests/async_tonapi/__init__.py +11 -0
  73. pytonapi-0.3.7/tests/async_tonapi/test_accounts_methods.py +86 -0
  74. pytonapi-0.3.7/tests/async_tonapi/test_blockchain_methods.py +81 -0
  75. pytonapi-0.3.7/tests/async_tonapi/test_dns_methods.py +23 -0
  76. pytonapi-0.3.7/tests/async_tonapi/test_events_methods.py +16 -0
  77. pytonapi-0.3.7/tests/async_tonapi/test_inscriptions_methods.py +25 -0
  78. pytonapi-0.3.7/tests/async_tonapi/test_jettons_methods.py +28 -0
  79. pytonapi-0.3.7/tests/async_tonapi/test_liteserver_methods.py +11 -0
  80. pytonapi-0.3.7/tests/async_tonapi/test_nft_methods.py +41 -0
  81. pytonapi-0.3.7/tests/async_tonapi/test_rates_methods.py +21 -0
  82. pytonapi-0.3.7/tests/async_tonapi/test_sse_methods.py +25 -0
  83. pytonapi-0.3.7/tests/async_tonapi/test_staking_methods.py +24 -0
  84. pytonapi-0.3.7/tests/async_tonapi/test_storage_methods.py +9 -0
  85. pytonapi-0.3.7/tests/async_tonapi/test_tonconnect_methods.py +11 -0
  86. pytonapi-0.3.7/tests/async_tonapi/test_traces_methods.py +15 -0
  87. pytonapi-0.3.7/tests/async_tonapi/test_utilities_methods.py +15 -0
  88. pytonapi-0.3.7/tests/async_tonapi/test_websocket_methods.py +22 -0
  89. pytonapi-0.3.7/tests/tonapi/__init__.py +11 -0
  90. pytonapi-0.3.7/tests/tonapi/test_accounts_methods.py +86 -0
  91. pytonapi-0.3.7/tests/tonapi/test_blockchain_methods.py +81 -0
  92. pytonapi-0.3.7/tests/tonapi/test_dns_methods.py +23 -0
  93. pytonapi-0.3.7/tests/tonapi/test_events_methods.py +16 -0
  94. pytonapi-0.3.7/tests/tonapi/test_inscriptions_methods.py +25 -0
  95. pytonapi-0.3.7/tests/tonapi/test_jettons_methods.py +28 -0
  96. pytonapi-0.3.7/tests/tonapi/test_liteserver_methods.py +11 -0
  97. pytonapi-0.3.7/tests/tonapi/test_nft_methods.py +42 -0
  98. pytonapi-0.3.7/tests/tonapi/test_rates_methods.py +21 -0
  99. pytonapi-0.3.7/tests/tonapi/test_sse_methods.py +25 -0
  100. pytonapi-0.3.7/tests/tonapi/test_staking_methods.py +24 -0
  101. pytonapi-0.3.7/tests/tonapi/test_storage_methods.py +9 -0
  102. pytonapi-0.3.7/tests/tonapi/test_tonconnect_methods.py +11 -0
  103. pytonapi-0.3.7/tests/tonapi/test_traces_methods.py +15 -0
  104. pytonapi-0.3.7/tests/tonapi/test_utilities_methods.py +15 -0
  105. pytonapi-0.3.6/PKG-INFO +0 -168
  106. pytonapi-0.3.6/README.md +0 -148
  107. pytonapi-0.3.6/pytonapi/schema/_balance.py +0 -33
  108. pytonapi-0.3.6/pytonapi/schema/rates.py +0 -18
  109. pytonapi-0.3.6/pytonapi.egg-info/PKG-INFO +0 -168
  110. {pytonapi-0.3.6 → pytonapi-0.3.7}/LICENSE +0 -0
  111. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/__init__.py +0 -0
  112. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi/py.typed +0 -0
  113. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi.egg-info/dependency_links.txt +0 -0
  114. {pytonapi-0.3.6 → pytonapi-0.3.7}/pytonapi.egg-info/requires.txt +0 -0
  115. {pytonapi-0.3.6 → pytonapi-0.3.7}/setup.cfg +0 -0
@@ -0,0 +1,134 @@
1
+ Metadata-Version: 2.1
2
+ Name: pytonapi
3
+ Version: 0.3.7
4
+ Summary: Provide access to indexed TON blockchain.
5
+ Home-page: https://github.com/tonkeeper/pytonapi/
6
+ Author: nessshon
7
+ Classifier: Programming Language :: Python :: 3.7
8
+ Classifier: Programming Language :: Python :: 3.8
9
+ Classifier: Programming Language :: Python :: 3.9
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+ Requires-Dist: httpx>=0.26.0
18
+ Requires-Dist: websockets>=12.0
19
+ Requires-Dist: pydantic==2.*
20
+
21
+ # 📦 PyTONAPI
22
+
23
+ [![TON](https://img.shields.io/badge/TON-grey?logo=TON&logoColor=40AEF0)](https://ton.org)
24
+ [![PyPI](https://img.shields.io/pypi/v/pytonapi.svg?color=FFE873&labelColor=3776AB)](https://pypi.python.org/pypi/pytonapi)
25
+ ![Python Versions](https://img.shields.io/badge/Python-3.7%20--%203.12-black?color=FFE873&labelColor=3776AB)
26
+ [![License](https://img.shields.io/github/license/tonkeeper/pytonapi)](https://github.com/tonkeeper/pytonapi/blob/main/LICENSE)
27
+
28
+ ![Image](https://telegra.ph//file/f88bcf9051073973edbd6.jpg)
29
+
30
+ ![Downloads](https://pepy.tech/badge/pytonapi)
31
+ ![Downloads](https://pepy.tech/badge/pytonapi/month)
32
+ ![Downloads](https://pepy.tech/badge/pytonapi/week)
33
+
34
+ Python SDK for [tonapi.io](https://tonapi.io).\
35
+ Information about the API can be found in the [documentation](https://docs.tonconsole.com/tonapi/api-v2).\
36
+ To use the API **you need an API key**, you can get it here [tonconsole.com](https://tonconsole.com/).
37
+
38
+ <blockquote>
39
+ For creating wallets, transferring TON, Jetton, NFTs, and other operations, recommend using <a href="https://github.com/nessshon/tonutils">tonutils</a> in combination with <code>TonapiClient</code>. For more information, refer to the library documentation.
40
+ </blockquote>
41
+
42
+ ## Usage
43
+
44
+ ### Installation
45
+
46
+ ```bash
47
+ pip install pytonapi
48
+ ```
49
+
50
+ ### Examples
51
+
52
+ * **Asynchronous**
53
+
54
+ ```python
55
+ from pytonapi import AsyncTonapi
56
+
57
+
58
+ # Declare an asynchronous function for using await
59
+ async def main():
60
+ # Create a new Tonapi object with the provided API key
61
+ tonapi = AsyncTonapi(api_key="Your API key")
62
+
63
+ # Specify the account ID
64
+ account_id = "EQC-3ilVr-W0Uc3pLrGJElwSaFxvhXXfkiQA3EwdVBHNNess" # noqa
65
+
66
+ # Retrieve account information asynchronously
67
+ account = await tonapi.accounts.get_info(account_id=account_id)
68
+
69
+ # Print account details
70
+ print(f"Account Address (raw): {account.address.to_raw()}")
71
+ print(f"Account Address (userfriendly): {account.address.to_userfriendly(is_bounceable=True)}")
72
+ print(f"Account Balance (nanoton): {account.balance.to_nano()}")
73
+ print(f"Account Balance (amount): {account.balance.to_amount()}")
74
+
75
+
76
+ if __name__ == '__main__':
77
+ import asyncio
78
+
79
+ # Run the asynchronous function
80
+ asyncio.run(main())
81
+
82
+ ```
83
+
84
+ * **Synchronous**
85
+
86
+ ```python
87
+ from pytonapi import Tonapi
88
+
89
+
90
+ def main():
91
+ # Create a new Tonapi object with the provided API key
92
+ tonapi = Tonapi(api_key="Your API key")
93
+
94
+ # Specify the account ID
95
+ account_id = "EQC-3ilVr-W0Uc3pLrGJElwSaFxvhXXfkiQA3EwdVBHNNess" # noqa
96
+
97
+ # Retrieve account information
98
+ account = tonapi.accounts.get_info(account_id=account_id)
99
+
100
+ # Print account details
101
+ print(f"Account Address (raw): {account.address.to_raw()}")
102
+ print(f"Account Address (userfriendly): {account.address.to_userfriendly(is_bounceable=True)}")
103
+ print(f"Account Balance (nanoton): {account.balance.to_nano()}")
104
+ print(f"Account Balance (amount): {account.balance.to_amount()}")
105
+
106
+
107
+ if __name__ == '__main__':
108
+ main()
109
+ ```
110
+
111
+ * **Additional examples** can be found [examples](https://github.com/tonkeeper/pytonapi/tree/main/examples) folder.
112
+
113
+ ## Donations
114
+
115
+ **TON** - `EQC-3ilVr-W0Uc3pLrGJElwSaFxvhXXfkiQA3EwdVBHNNess`
116
+
117
+ **USDT** (TRC-20) - `TJjADKFT2i7jqNJAxkgeRm5o9uarcoLUeR`
118
+
119
+ ## Contribution
120
+
121
+ We welcome your contributions! If you have ideas for improvement or have identified a bug, please create an issue or
122
+ submit a pull request.
123
+
124
+ ## Support
125
+
126
+ Supported by [TONAPI](https://tonapi.io) and [TON Society](https://github.com/ton-society/grants-and-bounties) (Grants
127
+ and Bounties program).
128
+
129
+ ## License
130
+
131
+ This repository is distributed under the [MIT License](https://github.com/tonkeeper/pytonapi/blob/main/LICENSE). Feel
132
+ free to use, modify, and distribute the code in accordance
133
+ with the terms of the license.
134
+
@@ -0,0 +1,114 @@
1
+ # 📦 PyTONAPI
2
+
3
+ [![TON](https://img.shields.io/badge/TON-grey?logo=TON&logoColor=40AEF0)](https://ton.org)
4
+ [![PyPI](https://img.shields.io/pypi/v/pytonapi.svg?color=FFE873&labelColor=3776AB)](https://pypi.python.org/pypi/pytonapi)
5
+ ![Python Versions](https://img.shields.io/badge/Python-3.7%20--%203.12-black?color=FFE873&labelColor=3776AB)
6
+ [![License](https://img.shields.io/github/license/tonkeeper/pytonapi)](https://github.com/tonkeeper/pytonapi/blob/main/LICENSE)
7
+
8
+ ![Image](https://telegra.ph//file/f88bcf9051073973edbd6.jpg)
9
+
10
+ ![Downloads](https://pepy.tech/badge/pytonapi)
11
+ ![Downloads](https://pepy.tech/badge/pytonapi/month)
12
+ ![Downloads](https://pepy.tech/badge/pytonapi/week)
13
+
14
+ Python SDK for [tonapi.io](https://tonapi.io).\
15
+ Information about the API can be found in the [documentation](https://docs.tonconsole.com/tonapi/api-v2).\
16
+ To use the API **you need an API key**, you can get it here [tonconsole.com](https://tonconsole.com/).
17
+
18
+ <blockquote>
19
+ For creating wallets, transferring TON, Jetton, NFTs, and other operations, recommend using <a href="https://github.com/nessshon/tonutils">tonutils</a> in combination with <code>TonapiClient</code>. For more information, refer to the library documentation.
20
+ </blockquote>
21
+
22
+ ## Usage
23
+
24
+ ### Installation
25
+
26
+ ```bash
27
+ pip install pytonapi
28
+ ```
29
+
30
+ ### Examples
31
+
32
+ * **Asynchronous**
33
+
34
+ ```python
35
+ from pytonapi import AsyncTonapi
36
+
37
+
38
+ # Declare an asynchronous function for using await
39
+ async def main():
40
+ # Create a new Tonapi object with the provided API key
41
+ tonapi = AsyncTonapi(api_key="Your API key")
42
+
43
+ # Specify the account ID
44
+ account_id = "EQC-3ilVr-W0Uc3pLrGJElwSaFxvhXXfkiQA3EwdVBHNNess" # noqa
45
+
46
+ # Retrieve account information asynchronously
47
+ account = await tonapi.accounts.get_info(account_id=account_id)
48
+
49
+ # Print account details
50
+ print(f"Account Address (raw): {account.address.to_raw()}")
51
+ print(f"Account Address (userfriendly): {account.address.to_userfriendly(is_bounceable=True)}")
52
+ print(f"Account Balance (nanoton): {account.balance.to_nano()}")
53
+ print(f"Account Balance (amount): {account.balance.to_amount()}")
54
+
55
+
56
+ if __name__ == '__main__':
57
+ import asyncio
58
+
59
+ # Run the asynchronous function
60
+ asyncio.run(main())
61
+
62
+ ```
63
+
64
+ * **Synchronous**
65
+
66
+ ```python
67
+ from pytonapi import Tonapi
68
+
69
+
70
+ def main():
71
+ # Create a new Tonapi object with the provided API key
72
+ tonapi = Tonapi(api_key="Your API key")
73
+
74
+ # Specify the account ID
75
+ account_id = "EQC-3ilVr-W0Uc3pLrGJElwSaFxvhXXfkiQA3EwdVBHNNess" # noqa
76
+
77
+ # Retrieve account information
78
+ account = tonapi.accounts.get_info(account_id=account_id)
79
+
80
+ # Print account details
81
+ print(f"Account Address (raw): {account.address.to_raw()}")
82
+ print(f"Account Address (userfriendly): {account.address.to_userfriendly(is_bounceable=True)}")
83
+ print(f"Account Balance (nanoton): {account.balance.to_nano()}")
84
+ print(f"Account Balance (amount): {account.balance.to_amount()}")
85
+
86
+
87
+ if __name__ == '__main__':
88
+ main()
89
+ ```
90
+
91
+ * **Additional examples** can be found [examples](https://github.com/tonkeeper/pytonapi/tree/main/examples) folder.
92
+
93
+ ## Donations
94
+
95
+ **TON** - `EQC-3ilVr-W0Uc3pLrGJElwSaFxvhXXfkiQA3EwdVBHNNess`
96
+
97
+ **USDT** (TRC-20) - `TJjADKFT2i7jqNJAxkgeRm5o9uarcoLUeR`
98
+
99
+ ## Contribution
100
+
101
+ We welcome your contributions! If you have ideas for improvement or have identified a bug, please create an issue or
102
+ submit a pull request.
103
+
104
+ ## Support
105
+
106
+ Supported by [TONAPI](https://tonapi.io) and [TON Society](https://github.com/ton-society/grants-and-bounties) (Grants
107
+ and Bounties program).
108
+
109
+ ## License
110
+
111
+ This repository is distributed under the [MIT License](https://github.com/tonkeeper/pytonapi/blob/main/LICENSE). Feel
112
+ free to use, modify, and distribute the code in accordance
113
+ with the terms of the license.
114
+
@@ -1,36 +1,39 @@
1
1
  from typing import Any, Dict, Optional
2
2
 
3
3
  from pytonapi.async_tonapi import methods
4
- from pytonapi.async_tonapi.client import AsyncTonapiClient
4
+ from pytonapi.async_tonapi.client import AsyncTonapiClientBase
5
5
 
6
6
  __all__ = [
7
7
  "AsyncTonapi",
8
- "AsyncTonapiClient",
8
+ "AsyncTonapiClientBase",
9
9
  ]
10
10
 
11
11
 
12
- class AsyncTonapi(AsyncTonapiClient):
12
+ class AsyncTonapi(AsyncTonapiClientBase):
13
13
 
14
14
  def __init__(
15
15
  self,
16
16
  api_key: str,
17
- is_testnet: Optional[bool] = False,
18
- max_retries: Optional[int] = None,
17
+ is_testnet: bool = False,
18
+ max_retries: int = 0,
19
19
  base_url: Optional[str] = None,
20
20
  websocket_url: Optional[str] = None,
21
21
  headers: Optional[Dict[str, Any]] = None,
22
22
  timeout: Optional[float] = None,
23
+ debug: bool = False,
24
+ **kwargs,
23
25
  ) -> None:
24
26
  """
25
27
  Initialize the AsyncTonapiClient.
26
28
 
27
29
  :param api_key: The API key.
30
+ :param is_testnet: Use True if using the testnet.
31
+ :param max_retries: Maximum number of retries per request if rate limit is reached.
28
32
  :param base_url: The base URL for the API.
29
33
  :param websocket_url: The URL for the WebSocket server.
30
- :param is_testnet: Use True if using the testnet.
31
- :param timeout: Request timeout in seconds.
32
34
  :param headers: Additional headers to include in requests.
33
- :param max_retries: Maximum number of retries per request if rate limit is reached.
35
+ :param timeout: Request timeout in seconds.
36
+ :param debug: Enable debug mode.
34
37
  """
35
38
  super().__init__(
36
39
  api_key=api_key,
@@ -40,6 +43,8 @@ class AsyncTonapi(AsyncTonapiClient):
40
43
  websocket_url=websocket_url,
41
44
  headers=headers,
42
45
  timeout=timeout,
46
+ debug=debug,
47
+ **kwargs,
43
48
  )
44
49
 
45
50
  @property
@@ -70,6 +75,10 @@ class AsyncTonapi(AsyncTonapiClient):
70
75
  def events(self) -> methods.EventsMethod:
71
76
  return methods.EventsMethod(**self.__dict__)
72
77
 
78
+ @property
79
+ def gasless(self) -> methods.GaslessMethod:
80
+ return methods.GaslessMethod(**self.__dict__)
81
+
73
82
  @property
74
83
  def inscriptions(self) -> methods.InscriptionsMethod:
75
84
  return methods.InscriptionsMethod(**self.__dict__)
@@ -102,6 +111,10 @@ class AsyncTonapi(AsyncTonapiClient):
102
111
  def traces(self) -> methods.TracesMethod:
103
112
  return methods.TracesMethod(**self.__dict__)
104
113
 
114
+ @property
115
+ def utilities(self) -> methods.UtilitiesMethod:
116
+ return methods.UtilitiesMethod(**self.__dict__)
117
+
105
118
  @property
106
119
  def wallet(self) -> methods.WalletMethod:
107
120
  return methods.WalletMethod(**self.__dict__)
@@ -1,10 +1,10 @@
1
1
  import asyncio
2
2
  import json
3
- import logging
4
3
  from typing import Any, Dict, Optional, AsyncGenerator
5
4
 
6
5
  import httpx
7
6
  import websockets
7
+ from httpx import URL, QueryParams
8
8
 
9
9
  from pytonapi.exceptions import (
10
10
  TONAPIBadRequestError,
@@ -16,9 +16,10 @@ from pytonapi.exceptions import (
16
16
  TONAPINotImplementedError,
17
17
  TONAPISSEError,
18
18
  )
19
+ from pytonapi.logger_config import setup_logging
19
20
 
20
21
 
21
- class AsyncTonapiClient:
22
+ class AsyncTonapiClientBase:
22
23
  """
23
24
  Asynchronous TON API Client.
24
25
  """
@@ -26,23 +27,26 @@ class AsyncTonapiClient:
26
27
  def __init__(
27
28
  self,
28
29
  api_key: str,
29
- is_testnet: Optional[bool] = False,
30
- max_retries: Optional[int] = None,
30
+ is_testnet: bool = False,
31
+ max_retries: int = 0,
31
32
  base_url: Optional[str] = None,
32
33
  websocket_url: Optional[str] = None,
33
34
  headers: Optional[Dict[str, Any]] = None,
34
35
  timeout: Optional[float] = None,
36
+ debug: bool = False,
37
+ **kwargs,
35
38
  ) -> None:
36
39
  """
37
40
  Initialize the AsyncTonapiClient.
38
41
 
39
42
  :param api_key: The API key.
43
+ :param is_testnet: Use True if using the testnet.
44
+ :param max_retries: Maximum number of retries per request if rate limit is reached.
40
45
  :param base_url: The base URL for the API.
41
46
  :param websocket_url: The URL for the WebSocket server.
42
- :param is_testnet: Use True if using the testnet.
43
- :param timeout: Request timeout in seconds.
44
47
  :param headers: Additional headers to include in requests.
45
- :param max_retries: Maximum number of retries per request if rate limit is reached.
48
+ :param timeout: Request timeout in seconds.
49
+ :param debug: Enable debug mode.
46
50
  """
47
51
  self.api_key = api_key
48
52
  self.is_testnet = is_testnet
@@ -53,6 +57,9 @@ class AsyncTonapiClient:
53
57
  self.websocket_url = websocket_url or "wss://tonapi.io/v2/websocket"
54
58
  self.headers = headers or {"Authorization": f"Bearer {api_key}"}
55
59
 
60
+ self.debug = debug
61
+ self.logger = setup_logging(self.debug)
62
+
56
63
  @staticmethod
57
64
  async def __read_content(response: httpx.Response) -> Any:
58
65
  """
@@ -97,15 +104,18 @@ class AsyncTonapiClient:
97
104
  501: TONAPINotImplementedError,
98
105
  }
99
106
  error_class = error_map.get(response.status_code, TONAPIError)
100
- error_message = content.get("error") if isinstance(content, dict) else content
101
- raise error_class(error_message)
107
+
108
+ if isinstance(content, dict):
109
+ content = content.get("error") or content.get("Error")
110
+ self.logger.error(f"Error response received: {content}")
111
+ raise error_class(content)
102
112
 
103
113
  return content
104
114
 
105
115
  async def _subscribe(
106
116
  self,
107
117
  method: str,
108
- params: Optional[Dict[str, Any]],
118
+ params: Dict[str, Any],
109
119
  ) -> AsyncGenerator[str, None]:
110
120
  """
111
121
  Subscribe to an SSE event stream.
@@ -115,26 +125,36 @@ class AsyncTonapiClient:
115
125
  """
116
126
  url = self.base_url + method
117
127
  timeout = httpx.Timeout(timeout=self.timeout)
118
- data = {"headers": self.headers, "params": params, "timeout": timeout}
119
128
 
129
+ self.logger.debug(f"Subscribing to SSE with URL: {url} and params: {params}")
120
130
  async with httpx.AsyncClient() as client:
121
131
  try:
122
- async with client.stream("GET", url=url, **data) as response:
123
- response: httpx.Response
132
+ async with client.stream(
133
+ method="GET",
134
+ url=url,
135
+ headers=self.headers,
136
+ params=params or {},
137
+ timeout=timeout,
138
+ ) as response:
124
139
  response.raise_for_status()
125
140
 
126
141
  async for line in response.aiter_lines():
127
142
  try:
128
143
  key, value = line.split(": ", 1)
129
144
  except ValueError:
145
+ self.logger.debug(f"Skipped line due to ValueError: {line}")
130
146
  continue
131
147
  if value == "heartbeat":
148
+ self.logger.debug("Received heartbeat")
132
149
  continue
133
150
  if key == "data":
151
+ self.logger.debug(f"Received SSE data: {value}")
134
152
  yield value
135
153
  except httpx.LocalProtocolError:
154
+ self.logger.error("Local protocol error during SSE subscription.")
136
155
  raise TONAPIUnauthorizedError
137
156
  except httpx.HTTPStatusError as e:
157
+ self.logger.error(f"HTTP status error during SSE subscription: {e}")
138
158
  raise TONAPISSEError(e)
139
159
 
140
160
  async def _subscribe_websocket(
@@ -155,6 +175,7 @@ class AsyncTonapiClient:
155
175
  "method": method,
156
176
  "params": params,
157
177
  }
178
+ self.logger.debug("Subscribing to WebSocket with payload: {payload}")
158
179
  async with websockets.connect(self.websocket_url) as websocket:
159
180
  try:
160
181
  await websocket.send(json.dumps(payload))
@@ -163,9 +184,11 @@ class AsyncTonapiClient:
163
184
  message_json = json.loads(message)
164
185
  if "params" in message_json:
165
186
  value = message_json["params"]
187
+ self.logger.debug(f"Received WebSocket message: {value}")
166
188
  yield value
167
- except websockets.exceptions.ConnectionClosed:
168
- raise
189
+ except websockets.exceptions.ConnectionClosed as e:
190
+ self.logger.error(f"WebSocket connection closed unexpectedly: {e}")
191
+ raise TONAPIError(e)
169
192
 
170
193
  async def _request(
171
194
  self,
@@ -188,14 +211,33 @@ class AsyncTonapiClient:
188
211
  url = self.base_url + path
189
212
  self.headers.update(headers or {})
190
213
  timeout = httpx.Timeout(timeout=self.timeout)
214
+
215
+ self.logger.debug(f"Request {method}: {URL(url).copy_merge_params(QueryParams(params))}")
216
+ self.logger.debug(f"Request headers: {self.headers}")
217
+ if params:
218
+ self.logger.debug(f"Request params: {params}")
219
+ if body:
220
+ self.logger.debug(f"Request body: {body}")
191
221
  try:
192
222
  async with httpx.AsyncClient(headers=self.headers, timeout=timeout) as session:
193
- session: httpx.AsyncClient
194
- data = {"params": params or {}, "json": body or {}}
195
- response = await session.request(method=method, url=url, **data)
196
- return await self.__process_response(response)
223
+ response = await session.request(
224
+ method=method,
225
+ url=url,
226
+ params=params or {},
227
+ json=body or {},
228
+ )
229
+ response_content = await self.__process_response(response)
230
+ self.logger.debug(f"Response received - Status code: {response.status_code}")
231
+ self.logger.debug(f"Response headers: {response.headers}")
232
+ self.logger.debug(f"Response content: {response_content}")
233
+ return response_content
234
+
197
235
  except httpx.LocalProtocolError:
236
+ self.logger.error("Local protocol error occurred during request.")
198
237
  raise TONAPIUnauthorizedError
238
+ except httpx.HTTPStatusError as e:
239
+ self.logger.error(f"HTTP status error during request: {e}")
240
+ raise TONAPIError(e)
199
241
 
200
242
  async def _request_retries(
201
243
  self,
@@ -225,12 +267,10 @@ class AsyncTonapiClient:
225
267
  body=body,
226
268
  )
227
269
  except TONAPITooManyRequestsError:
228
- logging.warning(
229
- f"Rate limit exceeded. "
230
- f"Retrying {i + 1}/{self.max_retries} is in progress."
231
- )
270
+ self.logger.warning(f"Rate limit exceeded. Retrying {i + 1}/{self.max_retries} in 1 second.")
232
271
  await asyncio.sleep(1)
233
272
 
273
+ self.logger.error("Max retries exceeded while making request")
234
274
  raise TONAPITooManyRequestsError
235
275
 
236
276
  async def _get(
@@ -248,7 +288,7 @@ class AsyncTonapiClient:
248
288
  :return: The response content as a dictionary.
249
289
  """
250
290
  request = self._request
251
- if self.max_retries:
291
+ if self.max_retries > 0:
252
292
  request = self._request_retries
253
293
  return await request("GET", method, headers, params=params)
254
294
 
@@ -268,6 +308,6 @@ class AsyncTonapiClient:
268
308
  :return: The response content as a dictionary.
269
309
  """
270
310
  request = self._request
271
- if self.max_retries:
311
+ if self.max_retries > 0:
272
312
  request = self._request_retries
273
313
  return await request("POST", method, headers, params=params, body=body)
@@ -3,6 +3,7 @@ from .blockchain import BlockchainMethod
3
3
  from .dns import DnsMethod
4
4
  from .emulate import EmulateMethod
5
5
  from .events import EventsMethod
6
+ from .gasless import GaslessMethod
6
7
  from .inscriptions import InscriptionsMethod
7
8
  from .jettons import JettonsMethod
8
9
  from .liteserver import LiteserverMethod
@@ -13,6 +14,7 @@ from .staking import StakingMethod
13
14
  from .storage import StorageMethod
14
15
  from .tonconnect import TonconnectMethod
15
16
  from .traces import TracesMethod
17
+ from .utilites import UtilitiesMethod
16
18
  from .wallet import WalletMethod
17
19
  from .websocket import WebSocketMethod
18
20
 
@@ -22,6 +24,7 @@ __all__ = [
22
24
  "DnsMethod",
23
25
  "EmulateMethod",
24
26
  "EventsMethod",
27
+ "GaslessMethod",
25
28
  "InscriptionsMethod",
26
29
  "JettonsMethod",
27
30
  "LiteserverMethod",
@@ -32,6 +35,7 @@ __all__ = [
32
35
  "StorageMethod",
33
36
  "TonconnectMethod",
34
37
  "TracesMethod",
38
+ "UtilitiesMethod",
35
39
  "WalletMethod",
36
40
  "WebSocketMethod",
37
41
  ]