coinex-api 0.0.12__py3-none-any.whl → 0.0.14__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 (289) hide show
  1. coinex/__init__.py +7 -0
  2. coinex/ccxt/__init__.py +101 -0
  3. coinex/ccxt/abstract/coinex.py +237 -0
  4. coinex/ccxt/async_support/__init__.py +80 -0
  5. coinex/ccxt/async_support/base/__init__.py +1 -0
  6. coinex/ccxt/async_support/base/exchange.py +2100 -0
  7. coinex/ccxt/async_support/base/throttler.py +50 -0
  8. coinex/ccxt/async_support/base/ws/__init__.py +38 -0
  9. coinex/ccxt/async_support/base/ws/aiohttp_client.py +147 -0
  10. coinex/ccxt/async_support/base/ws/cache.py +213 -0
  11. coinex/ccxt/async_support/base/ws/client.py +214 -0
  12. coinex/ccxt/async_support/base/ws/fast_client.py +97 -0
  13. coinex/ccxt/async_support/base/ws/functions.py +59 -0
  14. coinex/ccxt/async_support/base/ws/future.py +69 -0
  15. coinex/ccxt/async_support/base/ws/order_book.py +78 -0
  16. coinex/ccxt/async_support/base/ws/order_book_side.py +174 -0
  17. coinex/ccxt/async_support/coinex.py +5833 -0
  18. coinex/ccxt/base/__init__.py +27 -0
  19. coinex/ccxt/base/decimal_to_precision.py +174 -0
  20. coinex/ccxt/base/errors.py +267 -0
  21. coinex/ccxt/base/exchange.py +6769 -0
  22. coinex/ccxt/base/precise.py +297 -0
  23. coinex/ccxt/base/types.py +577 -0
  24. coinex/ccxt/coinex.py +5832 -0
  25. coinex/ccxt/pro/__init__.py +21 -0
  26. coinex/ccxt/pro/coinex.py +1366 -0
  27. coinex/ccxt/static_dependencies/README.md +1 -0
  28. coinex/ccxt/static_dependencies/__init__.py +1 -0
  29. coinex/ccxt/static_dependencies/ecdsa/__init__.py +14 -0
  30. coinex/ccxt/static_dependencies/ecdsa/_version.py +520 -0
  31. coinex/ccxt/static_dependencies/ecdsa/curves.py +56 -0
  32. coinex/ccxt/static_dependencies/ecdsa/der.py +221 -0
  33. coinex/ccxt/static_dependencies/ecdsa/ecdsa.py +310 -0
  34. coinex/ccxt/static_dependencies/ecdsa/ellipticcurve.py +197 -0
  35. coinex/ccxt/static_dependencies/ecdsa/keys.py +332 -0
  36. coinex/ccxt/static_dependencies/ecdsa/numbertheory.py +531 -0
  37. coinex/ccxt/static_dependencies/ecdsa/rfc6979.py +100 -0
  38. coinex/ccxt/static_dependencies/ecdsa/util.py +266 -0
  39. coinex/ccxt/static_dependencies/ethereum/__init__.py +7 -0
  40. coinex/ccxt/static_dependencies/ethereum/abi/__init__.py +16 -0
  41. coinex/ccxt/static_dependencies/ethereum/abi/abi.py +19 -0
  42. coinex/ccxt/static_dependencies/ethereum/abi/base.py +152 -0
  43. coinex/ccxt/static_dependencies/ethereum/abi/codec.py +217 -0
  44. coinex/ccxt/static_dependencies/ethereum/abi/constants.py +3 -0
  45. coinex/ccxt/static_dependencies/ethereum/abi/decoding.py +565 -0
  46. coinex/ccxt/static_dependencies/ethereum/abi/encoding.py +720 -0
  47. coinex/ccxt/static_dependencies/ethereum/abi/exceptions.py +139 -0
  48. coinex/ccxt/static_dependencies/ethereum/abi/grammar.py +443 -0
  49. coinex/ccxt/static_dependencies/ethereum/abi/packed.py +13 -0
  50. coinex/ccxt/static_dependencies/ethereum/abi/py.typed +0 -0
  51. coinex/ccxt/static_dependencies/ethereum/abi/registry.py +643 -0
  52. coinex/ccxt/static_dependencies/ethereum/abi/tools/__init__.py +3 -0
  53. coinex/ccxt/static_dependencies/ethereum/abi/tools/_strategies.py +230 -0
  54. coinex/ccxt/static_dependencies/ethereum/abi/utils/__init__.py +0 -0
  55. coinex/ccxt/static_dependencies/ethereum/abi/utils/numeric.py +83 -0
  56. coinex/ccxt/static_dependencies/ethereum/abi/utils/padding.py +27 -0
  57. coinex/ccxt/static_dependencies/ethereum/abi/utils/string.py +19 -0
  58. coinex/ccxt/static_dependencies/ethereum/account/__init__.py +3 -0
  59. coinex/ccxt/static_dependencies/ethereum/account/encode_typed_data/__init__.py +4 -0
  60. coinex/ccxt/static_dependencies/ethereum/account/encode_typed_data/encoding_and_hashing.py +239 -0
  61. coinex/ccxt/static_dependencies/ethereum/account/encode_typed_data/helpers.py +40 -0
  62. coinex/ccxt/static_dependencies/ethereum/account/messages.py +263 -0
  63. coinex/ccxt/static_dependencies/ethereum/account/py.typed +0 -0
  64. coinex/ccxt/static_dependencies/ethereum/hexbytes/__init__.py +5 -0
  65. coinex/ccxt/static_dependencies/ethereum/hexbytes/_utils.py +54 -0
  66. coinex/ccxt/static_dependencies/ethereum/hexbytes/main.py +65 -0
  67. coinex/ccxt/static_dependencies/ethereum/hexbytes/py.typed +0 -0
  68. coinex/ccxt/static_dependencies/ethereum/typing/__init__.py +63 -0
  69. coinex/ccxt/static_dependencies/ethereum/typing/abi.py +6 -0
  70. coinex/ccxt/static_dependencies/ethereum/typing/bls.py +7 -0
  71. coinex/ccxt/static_dependencies/ethereum/typing/discovery.py +5 -0
  72. coinex/ccxt/static_dependencies/ethereum/typing/encoding.py +7 -0
  73. coinex/ccxt/static_dependencies/ethereum/typing/enums.py +17 -0
  74. coinex/ccxt/static_dependencies/ethereum/typing/ethpm.py +9 -0
  75. coinex/ccxt/static_dependencies/ethereum/typing/evm.py +20 -0
  76. coinex/ccxt/static_dependencies/ethereum/typing/networks.py +1122 -0
  77. coinex/ccxt/static_dependencies/ethereum/typing/py.typed +0 -0
  78. coinex/ccxt/static_dependencies/ethereum/utils/__init__.py +115 -0
  79. coinex/ccxt/static_dependencies/ethereum/utils/abi.py +72 -0
  80. coinex/ccxt/static_dependencies/ethereum/utils/address.py +171 -0
  81. coinex/ccxt/static_dependencies/ethereum/utils/applicators.py +151 -0
  82. coinex/ccxt/static_dependencies/ethereum/utils/conversions.py +190 -0
  83. coinex/ccxt/static_dependencies/ethereum/utils/currency.py +107 -0
  84. coinex/ccxt/static_dependencies/ethereum/utils/curried/__init__.py +269 -0
  85. coinex/ccxt/static_dependencies/ethereum/utils/debug.py +20 -0
  86. coinex/ccxt/static_dependencies/ethereum/utils/decorators.py +132 -0
  87. coinex/ccxt/static_dependencies/ethereum/utils/encoding.py +6 -0
  88. coinex/ccxt/static_dependencies/ethereum/utils/exceptions.py +4 -0
  89. coinex/ccxt/static_dependencies/ethereum/utils/functional.py +75 -0
  90. coinex/ccxt/static_dependencies/ethereum/utils/hexadecimal.py +74 -0
  91. coinex/ccxt/static_dependencies/ethereum/utils/humanize.py +188 -0
  92. coinex/ccxt/static_dependencies/ethereum/utils/logging.py +159 -0
  93. coinex/ccxt/static_dependencies/ethereum/utils/module_loading.py +31 -0
  94. coinex/ccxt/static_dependencies/ethereum/utils/numeric.py +43 -0
  95. coinex/ccxt/static_dependencies/ethereum/utils/py.typed +0 -0
  96. coinex/ccxt/static_dependencies/ethereum/utils/toolz.py +76 -0
  97. coinex/ccxt/static_dependencies/ethereum/utils/types.py +54 -0
  98. coinex/ccxt/static_dependencies/ethereum/utils/typing/__init__.py +18 -0
  99. coinex/ccxt/static_dependencies/ethereum/utils/typing/misc.py +14 -0
  100. coinex/ccxt/static_dependencies/ethereum/utils/units.py +31 -0
  101. coinex/ccxt/static_dependencies/keccak/__init__.py +3 -0
  102. coinex/ccxt/static_dependencies/keccak/keccak.py +197 -0
  103. coinex/ccxt/static_dependencies/lark/__init__.py +38 -0
  104. coinex/ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
  105. coinex/ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
  106. coinex/ccxt/static_dependencies/lark/ast_utils.py +59 -0
  107. coinex/ccxt/static_dependencies/lark/common.py +86 -0
  108. coinex/ccxt/static_dependencies/lark/exceptions.py +292 -0
  109. coinex/ccxt/static_dependencies/lark/grammar.py +130 -0
  110. coinex/ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
  111. coinex/ccxt/static_dependencies/lark/grammars/common.lark +59 -0
  112. coinex/ccxt/static_dependencies/lark/grammars/lark.lark +62 -0
  113. coinex/ccxt/static_dependencies/lark/grammars/python.lark +302 -0
  114. coinex/ccxt/static_dependencies/lark/grammars/unicode.lark +7 -0
  115. coinex/ccxt/static_dependencies/lark/indenter.py +143 -0
  116. coinex/ccxt/static_dependencies/lark/lark.py +658 -0
  117. coinex/ccxt/static_dependencies/lark/lexer.py +678 -0
  118. coinex/ccxt/static_dependencies/lark/load_grammar.py +1428 -0
  119. coinex/ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
  120. coinex/ccxt/static_dependencies/lark/parser_frontends.py +257 -0
  121. coinex/ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
  122. coinex/ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
  123. coinex/ccxt/static_dependencies/lark/parsers/earley.py +314 -0
  124. coinex/ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
  125. coinex/ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
  126. coinex/ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
  127. coinex/ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
  128. coinex/ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
  129. coinex/ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
  130. coinex/ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
  131. coinex/ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
  132. coinex/ccxt/static_dependencies/lark/py.typed +0 -0
  133. coinex/ccxt/static_dependencies/lark/reconstruct.py +107 -0
  134. coinex/ccxt/static_dependencies/lark/tools/__init__.py +70 -0
  135. coinex/ccxt/static_dependencies/lark/tools/nearley.py +202 -0
  136. coinex/ccxt/static_dependencies/lark/tools/serialize.py +32 -0
  137. coinex/ccxt/static_dependencies/lark/tools/standalone.py +196 -0
  138. coinex/ccxt/static_dependencies/lark/tree.py +267 -0
  139. coinex/ccxt/static_dependencies/lark/tree_matcher.py +186 -0
  140. coinex/ccxt/static_dependencies/lark/tree_templates.py +180 -0
  141. coinex/ccxt/static_dependencies/lark/utils.py +343 -0
  142. coinex/ccxt/static_dependencies/lark/visitors.py +596 -0
  143. coinex/ccxt/static_dependencies/marshmallow/__init__.py +81 -0
  144. coinex/ccxt/static_dependencies/marshmallow/base.py +65 -0
  145. coinex/ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
  146. coinex/ccxt/static_dependencies/marshmallow/decorators.py +231 -0
  147. coinex/ccxt/static_dependencies/marshmallow/error_store.py +60 -0
  148. coinex/ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
  149. coinex/ccxt/static_dependencies/marshmallow/fields.py +2114 -0
  150. coinex/ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
  151. coinex/ccxt/static_dependencies/marshmallow/py.typed +0 -0
  152. coinex/ccxt/static_dependencies/marshmallow/schema.py +1228 -0
  153. coinex/ccxt/static_dependencies/marshmallow/types.py +12 -0
  154. coinex/ccxt/static_dependencies/marshmallow/utils.py +378 -0
  155. coinex/ccxt/static_dependencies/marshmallow/validate.py +678 -0
  156. coinex/ccxt/static_dependencies/marshmallow/warnings.py +2 -0
  157. coinex/ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
  158. coinex/ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
  159. coinex/ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
  160. coinex/ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
  161. coinex/ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
  162. coinex/ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
  163. coinex/ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
  164. coinex/ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
  165. coinex/ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
  166. coinex/ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
  167. coinex/ccxt/static_dependencies/msgpack/__init__.py +55 -0
  168. coinex/ccxt/static_dependencies/msgpack/_cmsgpack.pyx +11 -0
  169. coinex/ccxt/static_dependencies/msgpack/_packer.pyx +374 -0
  170. coinex/ccxt/static_dependencies/msgpack/_unpacker.pyx +547 -0
  171. coinex/ccxt/static_dependencies/msgpack/buff_converter.h +8 -0
  172. coinex/ccxt/static_dependencies/msgpack/exceptions.py +48 -0
  173. coinex/ccxt/static_dependencies/msgpack/ext.py +168 -0
  174. coinex/ccxt/static_dependencies/msgpack/fallback.py +951 -0
  175. coinex/ccxt/static_dependencies/msgpack/pack.h +89 -0
  176. coinex/ccxt/static_dependencies/msgpack/pack_template.h +820 -0
  177. coinex/ccxt/static_dependencies/msgpack/sysdep.h +194 -0
  178. coinex/ccxt/static_dependencies/msgpack/unpack.h +391 -0
  179. coinex/ccxt/static_dependencies/msgpack/unpack_define.h +95 -0
  180. coinex/ccxt/static_dependencies/msgpack/unpack_template.h +464 -0
  181. coinex/ccxt/static_dependencies/parsimonious/__init__.py +10 -0
  182. coinex/ccxt/static_dependencies/parsimonious/exceptions.py +105 -0
  183. coinex/ccxt/static_dependencies/parsimonious/expressions.py +479 -0
  184. coinex/ccxt/static_dependencies/parsimonious/grammar.py +487 -0
  185. coinex/ccxt/static_dependencies/parsimonious/nodes.py +325 -0
  186. coinex/ccxt/static_dependencies/parsimonious/utils.py +40 -0
  187. coinex/ccxt/static_dependencies/starknet/__init__.py +0 -0
  188. coinex/ccxt/static_dependencies/starknet/abi/v0/__init__.py +2 -0
  189. coinex/ccxt/static_dependencies/starknet/abi/v0/model.py +44 -0
  190. coinex/ccxt/static_dependencies/starknet/abi/v0/parser.py +216 -0
  191. coinex/ccxt/static_dependencies/starknet/abi/v0/schemas.py +72 -0
  192. coinex/ccxt/static_dependencies/starknet/abi/v0/shape.py +63 -0
  193. coinex/ccxt/static_dependencies/starknet/abi/v1/__init__.py +2 -0
  194. coinex/ccxt/static_dependencies/starknet/abi/v1/core_structures.json +14 -0
  195. coinex/ccxt/static_dependencies/starknet/abi/v1/model.py +39 -0
  196. coinex/ccxt/static_dependencies/starknet/abi/v1/parser.py +220 -0
  197. coinex/ccxt/static_dependencies/starknet/abi/v1/parser_transformer.py +179 -0
  198. coinex/ccxt/static_dependencies/starknet/abi/v1/schemas.py +66 -0
  199. coinex/ccxt/static_dependencies/starknet/abi/v1/shape.py +47 -0
  200. coinex/ccxt/static_dependencies/starknet/abi/v2/__init__.py +2 -0
  201. coinex/ccxt/static_dependencies/starknet/abi/v2/model.py +89 -0
  202. coinex/ccxt/static_dependencies/starknet/abi/v2/parser.py +293 -0
  203. coinex/ccxt/static_dependencies/starknet/abi/v2/parser_transformer.py +192 -0
  204. coinex/ccxt/static_dependencies/starknet/abi/v2/schemas.py +132 -0
  205. coinex/ccxt/static_dependencies/starknet/abi/v2/shape.py +107 -0
  206. coinex/ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
  207. coinex/ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
  208. coinex/ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
  209. coinex/ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
  210. coinex/ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
  211. coinex/ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
  212. coinex/ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
  213. coinex/ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
  214. coinex/ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
  215. coinex/ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
  216. coinex/ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
  217. coinex/ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
  218. coinex/ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
  219. coinex/ccxt/static_dependencies/starknet/common.py +15 -0
  220. coinex/ccxt/static_dependencies/starknet/constants.py +39 -0
  221. coinex/ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
  222. coinex/ccxt/static_dependencies/starknet/hash/address.py +79 -0
  223. coinex/ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
  224. coinex/ccxt/static_dependencies/starknet/hash/selector.py +16 -0
  225. coinex/ccxt/static_dependencies/starknet/hash/storage.py +12 -0
  226. coinex/ccxt/static_dependencies/starknet/hash/utils.py +78 -0
  227. coinex/ccxt/static_dependencies/starknet/models/__init__.py +0 -0
  228. coinex/ccxt/static_dependencies/starknet/models/typed_data.py +45 -0
  229. coinex/ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
  230. coinex/ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
  231. coinex/ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
  232. coinex/ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
  233. coinex/ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
  234. coinex/ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
  235. coinex/ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
  236. coinex/ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
  237. coinex/ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
  238. coinex/ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
  239. coinex/ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
  240. coinex/ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
  241. coinex/ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
  242. coinex/ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
  243. coinex/ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
  244. coinex/ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
  245. coinex/ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
  246. coinex/ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
  247. coinex/ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
  248. coinex/ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
  249. coinex/ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
  250. coinex/ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
  251. coinex/ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
  252. coinex/ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
  253. coinex/ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
  254. coinex/ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
  255. coinex/ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
  256. coinex/ccxt/static_dependencies/starknet/utils/schema.py +13 -0
  257. coinex/ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
  258. coinex/ccxt/static_dependencies/starkware/__init__.py +0 -0
  259. coinex/ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
  260. coinex/ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +50 -0
  261. coinex/ccxt/static_dependencies/starkware/crypto/math_utils.py +78 -0
  262. coinex/ccxt/static_dependencies/starkware/crypto/signature.py +2344 -0
  263. coinex/ccxt/static_dependencies/starkware/crypto/utils.py +63 -0
  264. coinex/ccxt/static_dependencies/sympy/__init__.py +0 -0
  265. coinex/ccxt/static_dependencies/sympy/core/__init__.py +0 -0
  266. coinex/ccxt/static_dependencies/sympy/core/intfunc.py +35 -0
  267. coinex/ccxt/static_dependencies/sympy/external/__init__.py +0 -0
  268. coinex/ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
  269. coinex/ccxt/static_dependencies/sympy/external/importtools.py +187 -0
  270. coinex/ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
  271. coinex/ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
  272. coinex/ccxt/static_dependencies/toolz/__init__.py +26 -0
  273. coinex/ccxt/static_dependencies/toolz/_signatures.py +784 -0
  274. coinex/ccxt/static_dependencies/toolz/_version.py +520 -0
  275. coinex/ccxt/static_dependencies/toolz/compatibility.py +30 -0
  276. coinex/ccxt/static_dependencies/toolz/curried/__init__.py +101 -0
  277. coinex/ccxt/static_dependencies/toolz/curried/exceptions.py +22 -0
  278. coinex/ccxt/static_dependencies/toolz/curried/operator.py +22 -0
  279. coinex/ccxt/static_dependencies/toolz/dicttoolz.py +339 -0
  280. coinex/ccxt/static_dependencies/toolz/functoolz.py +1049 -0
  281. coinex/ccxt/static_dependencies/toolz/itertoolz.py +1057 -0
  282. coinex/ccxt/static_dependencies/toolz/recipes.py +46 -0
  283. coinex/ccxt/static_dependencies/toolz/utils.py +9 -0
  284. coinex/ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
  285. coinex/ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
  286. {coinex_api-0.0.12.dist-info → coinex_api-0.0.14.dist-info}/METADATA +1 -1
  287. coinex_api-0.0.14.dist-info/RECORD +288 -0
  288. coinex_api-0.0.12.dist-info/RECORD +0 -3
  289. {coinex_api-0.0.12.dist-info → coinex_api-0.0.14.dist-info}/WHEEL +0 -0
@@ -0,0 +1,50 @@
1
+ import asyncio
2
+ import collections
3
+ from time import time
4
+
5
+
6
+ class Throttler:
7
+ def __init__(self, config, loop=None):
8
+ self.loop = loop
9
+ self.config = {
10
+ 'refillRate': 1.0,
11
+ 'delay': 0.001,
12
+ 'cost': 1.0,
13
+ 'tokens': 0,
14
+ 'maxCapacity': 2000,
15
+ 'capacity': 1.0,
16
+ }
17
+ self.config.update(config)
18
+ self.queue = collections.deque()
19
+ self.running = False
20
+
21
+ async def looper(self):
22
+ last_timestamp = time() * 1000
23
+ while self.running:
24
+ future, cost = self.queue[0]
25
+ cost = self.config['cost'] if cost is None else cost
26
+ if self.config['tokens'] >= 0:
27
+ self.config['tokens'] -= cost
28
+ if not future.done():
29
+ future.set_result(None)
30
+ self.queue.popleft()
31
+ # context switch
32
+ await asyncio.sleep(0)
33
+ if len(self.queue) == 0:
34
+ self.running = False
35
+ else:
36
+ await asyncio.sleep(self.config['delay'])
37
+ now = time() * 1000
38
+ elapsed = now - last_timestamp
39
+ last_timestamp = now
40
+ self.config['tokens'] = min(self.config['tokens'] + elapsed * self.config['refillRate'], self.config['capacity'])
41
+
42
+ def __call__(self, cost=None):
43
+ future = asyncio.Future()
44
+ if len(self.queue) > self.config['maxCapacity']:
45
+ raise RuntimeError('throttle queue is over maxCapacity (' + str(int(self.config['maxCapacity'])) + '), see https://github.com/ccxt/ccxt/issues/11645#issuecomment-1195695526')
46
+ self.queue.append((future, cost))
47
+ if not self.running:
48
+ self.running = True
49
+ asyncio.ensure_future(self.looper(), loop=self.loop)
50
+ return future
@@ -0,0 +1,38 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ from ccxt.base import errors
4
+
5
+ # -----------------------------------------------------------------------------
6
+
7
+ from ccxt.base import decimal_to_precision
8
+
9
+ from ccxt import BaseError # noqa: F401
10
+ from ccxt import ExchangeError # noqa: F401
11
+ from ccxt import NotSupported # noqa: F401
12
+ from ccxt import AuthenticationError # noqa: F401
13
+ from ccxt import PermissionDenied # noqa: F401
14
+ from ccxt import AccountSuspended # noqa: F401
15
+ from ccxt import InvalidNonce # noqa: F401
16
+ from ccxt import InsufficientFunds # noqa: F401
17
+ from ccxt import InvalidOrder # noqa: F401
18
+ from ccxt import OrderNotFound # noqa: F401
19
+ from ccxt import OrderNotCached # noqa: F401
20
+ from ccxt import DuplicateOrderId # noqa: F401
21
+ from ccxt import CancelPending # noqa: F401
22
+ from ccxt import NetworkError # noqa: F401
23
+ from ccxt import DDoSProtection # noqa: F401
24
+ from ccxt import RateLimitExceeded # noqa: F401
25
+ from ccxt import RequestTimeout # noqa: F401
26
+ from ccxt import ExchangeNotAvailable # noqa: F401
27
+ from ccxt import OnMaintenance # noqa: F401
28
+ from ccxt import InvalidAddress # noqa: F401
29
+ from ccxt import AddressPending # noqa: F401
30
+ from ccxt import ArgumentsRequired # noqa: F401
31
+ from ccxt import BadRequest # noqa: F401
32
+ from ccxt import BadResponse # noqa: F401
33
+ from ccxt import NullResponse # noqa: F401
34
+ from ccxt import OrderImmediatelyFillable # noqa: F401
35
+ from ccxt import OrderNotFillable # noqa: F401
36
+
37
+
38
+ __all__ = decimal_to_precision.__all__ + errors.__all__ # noqa: F405
@@ -0,0 +1,147 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ orjson = None
4
+ try:
5
+ import orjson as orjson
6
+ except ImportError:
7
+ pass
8
+
9
+ import json
10
+ from asyncio import sleep, ensure_future
11
+ from aiohttp import WSMsgType
12
+ from .functions import milliseconds, iso8601, is_json_encoded_object
13
+ from ccxt.async_support.base.ws.client import Client
14
+ from ccxt.async_support.base.ws.functions import gunzip, inflate
15
+ from ccxt import NetworkError, RequestTimeout, ExchangeClosedByUser
16
+
17
+
18
+ class AiohttpClient(Client):
19
+
20
+ proxy = None
21
+
22
+ def closed(self):
23
+ return (self.connection is None) or self.connection.closed
24
+
25
+ def receive(self):
26
+ return self.connection.receive()
27
+
28
+ # helper method for binary and text messages
29
+ def handle_text_or_binary_message(self, data):
30
+ if self.verbose:
31
+ self.log(iso8601(milliseconds()), 'message', data)
32
+ if isinstance(data, bytes):
33
+ data = data.decode()
34
+ # decoded = json.loads(data) if is_json_encoded_object(data) else data
35
+ decode = None
36
+ if is_json_encoded_object(data):
37
+ if orjson is None:
38
+ decode = json.loads(data)
39
+ else:
40
+ decode = orjson.loads(data)
41
+ else:
42
+ decode = data
43
+ self.on_message_callback(self, decode)
44
+
45
+ def handle_message(self, message):
46
+ # self.log(iso8601(milliseconds()), message)
47
+ if message.type == WSMsgType.TEXT:
48
+ self.handle_text_or_binary_message(message.data)
49
+ elif message.type == WSMsgType.BINARY:
50
+ data = message.data
51
+ if self.gunzip:
52
+ data = gunzip(data)
53
+ elif self.inflate:
54
+ data = inflate(data)
55
+ self.handle_text_or_binary_message(data)
56
+ # autoping is responsible for automatically replying with pong
57
+ # to a ping incoming from a server, we have to disable autoping
58
+ # with aiohttp's websockets and respond with pong manually
59
+ # otherwise aiohttp's websockets client won't trigger WSMsgType.PONG
60
+ elif message.type == WSMsgType.PING:
61
+ if self.verbose:
62
+ self.log(iso8601(milliseconds()), 'ping', message)
63
+ ensure_future(self.connection.pong(message.data), loop=self.asyncio_loop)
64
+ elif message.type == WSMsgType.PONG:
65
+ self.lastPong = milliseconds()
66
+ if self.verbose:
67
+ self.log(iso8601(milliseconds()), 'pong', message)
68
+ pass
69
+ elif message.type == WSMsgType.CLOSE:
70
+ if self.verbose:
71
+ self.log(iso8601(milliseconds()), 'close', self.closed(), message)
72
+ self.on_close(message.data)
73
+ elif message.type == WSMsgType.CLOSED:
74
+ if self.verbose:
75
+ self.log(iso8601(milliseconds()), 'closed', self.closed(), message)
76
+ self.on_close(1000)
77
+ elif message.type == WSMsgType.ERROR:
78
+ if self.verbose:
79
+ self.log(iso8601(milliseconds()), 'error', message)
80
+ error = NetworkError(str(message))
81
+ self.on_error(error)
82
+
83
+ def create_connection(self, session):
84
+ # autoping is responsible for automatically replying with pong
85
+ # to a ping incoming from a server, we have to disable autoping
86
+ # with aiohttp's websockets and respond with pong manually
87
+ # otherwise aiohttp's websockets client won't trigger WSMsgType.PONG
88
+ # call aenter here to simulate async with otherwise we get the error "await not called with future"
89
+ # if connecting to a non-existent endpoint
90
+ if (self.proxy):
91
+ return session.ws_connect(self.url, autoping=False, autoclose=False, headers=self.options.get('headers'), proxy=self.proxy, max_msg_size=10485760).__aenter__()
92
+ return session.ws_connect(self.url, autoping=False, autoclose=False, headers=self.options.get('headers'), max_msg_size=10485760).__aenter__()
93
+
94
+ async def send(self, message):
95
+ if self.verbose:
96
+ self.log(iso8601(milliseconds()), 'sending', message)
97
+ send_msg = None
98
+ if isinstance(message, str):
99
+ send_msg = message
100
+ else:
101
+ if orjson is None:
102
+ send_msg = json.dumps(message, separators=(',', ':'))
103
+ else:
104
+ send_msg = orjson.dumps(message).decode('utf-8')
105
+ return await self.connection.send_str(send_msg)
106
+
107
+ async def close(self, code=1000):
108
+ if self.verbose:
109
+ self.log(iso8601(milliseconds()), 'closing', code)
110
+ if not self.closed():
111
+ await self.connection.close()
112
+ # these will end automatically once self.closed() = True
113
+ # so we don't need to cancel them
114
+ if self.ping_looper:
115
+ self.ping_looper.cancel()
116
+ if self.receive_looper:
117
+ self.receive_looper.cancel() # cancel all pending futures stored in self.futures
118
+ for key in self.futures:
119
+ future = self.futures[key]
120
+ if not future.done():
121
+ if future.is_race_future:
122
+ future.cancel() # this is an "internal" future so we want to cancel it silently
123
+ else:
124
+ future.reject(ExchangeClosedByUser('Connection closed by the user'))
125
+
126
+
127
+ async def ping_loop(self):
128
+ if self.verbose:
129
+ self.log(iso8601(milliseconds()), 'ping loop')
130
+ while self.keepAlive and not self.closed():
131
+ now = milliseconds()
132
+ self.lastPong = now if self.lastPong is None else self.lastPong
133
+ if (self.lastPong + self.keepAlive * self.maxPingPongMisses) < now:
134
+ self.on_error(RequestTimeout('Connection to ' + self.url + ' timed out due to a ping-pong keepalive missing on time'))
135
+ # the following ping-clause is not necessary with aiohttp's built-in ws
136
+ # since it has a heartbeat option (see create_connection above)
137
+ # however some exchanges require a text-type ping message
138
+ # therefore we need this clause anyway
139
+ else:
140
+ if self.ping:
141
+ try:
142
+ await self.send(self.ping(self))
143
+ except Exception as e:
144
+ self.on_error(e)
145
+ else:
146
+ await self.connection.ping()
147
+ await sleep(self.keepAlive / 1000)
@@ -0,0 +1,213 @@
1
+ import collections
2
+
3
+
4
+ class Delegate:
5
+ def __init__(self, name, delegated):
6
+ self.name = name
7
+ self.delegated = delegated
8
+
9
+ def __get__(self, instance, owner):
10
+ deque = getattr(instance, self.delegated)
11
+ return getattr(deque, self.name)
12
+
13
+
14
+ class BaseCache(list):
15
+ # implicitly called magic methods don't invoke __getattribute__
16
+ # https://docs.python.org/3/reference/datamodel.html#special-method-lookup
17
+ # all method lookups obey the descriptor protocol
18
+ # this is how the implicit api is defined in ccxt
19
+ __iter__ = Delegate('__iter__', '_deque')
20
+ __setitem__ = Delegate('__setitem__', '_deque')
21
+ __delitem__ = Delegate('__delitem__', '_deque')
22
+ __len__ = Delegate('__len__', '_deque')
23
+ __contains__ = Delegate('__contains__', '_deque')
24
+ __reversed__ = Delegate('__reversed__', '_deque')
25
+ clear = Delegate('clear', '_deque')
26
+ pop = Delegate('pop', '_deque')
27
+
28
+ def __init__(self, max_size=None):
29
+ super(BaseCache, self).__init__()
30
+ self.max_size = max_size
31
+ self._deque = collections.deque([], max_size)
32
+
33
+ def __eq__(self, other):
34
+ return list(self) == other
35
+
36
+ def __repr__(self):
37
+ return str(list(self))
38
+
39
+ def __add__(self, other):
40
+ return list(self) + other
41
+
42
+ def __getitem__(self, item):
43
+ # deque doesn't support slicing
44
+ deque = super(list, self).__getattribute__('_deque')
45
+ if isinstance(item, slice):
46
+ start, stop, step = item.indices(len(deque))
47
+ return [deque[i] for i in range(start, stop, step)]
48
+ else:
49
+ return deque[item]
50
+
51
+ # to be overriden
52
+ def getLimit(self, symbol, limit):
53
+ pass
54
+
55
+ # support transpiled snake_case calls
56
+ def get_limit(self, symbol, limit):
57
+ return self.getLimit(symbol, limit)
58
+
59
+
60
+ class ArrayCache(BaseCache):
61
+ def __init__(self, max_size=None):
62
+ super(ArrayCache, self).__init__(max_size)
63
+ self._nested_new_updates_by_symbol = False
64
+ self._new_updates_by_symbol = {}
65
+ self._clear_updates_by_symbol = {}
66
+ self._all_new_updates = 0
67
+ self._clear_all_updates = False
68
+
69
+ def getLimit(self, symbol, limit):
70
+ if symbol is None:
71
+ new_updates_value = self._all_new_updates
72
+ self._clear_all_updates = True
73
+ else:
74
+ new_updates_value = self._new_updates_by_symbol.get(symbol)
75
+ if new_updates_value is not None and self._nested_new_updates_by_symbol:
76
+ new_updates_value = len(new_updates_value)
77
+ self._clear_updates_by_symbol[symbol] = True
78
+
79
+ if new_updates_value is None:
80
+ return limit
81
+ elif limit is not None:
82
+ return min(new_updates_value, limit)
83
+ else:
84
+ return new_updates_value
85
+
86
+ def append(self, item):
87
+ self._deque.append(item)
88
+ if self._clear_all_updates:
89
+ self._clear_all_updates = False
90
+ self._clear_updates_by_symbol.clear()
91
+ self._all_new_updates = 0
92
+ self._new_updates_by_symbol.clear()
93
+ if self._clear_updates_by_symbol.get(item['symbol']):
94
+ self._clear_updates_by_symbol[item['symbol']] = False
95
+ self._new_updates_by_symbol[item['symbol']] = 0
96
+ self._new_updates_by_symbol[item['symbol']] = self._new_updates_by_symbol.get(item['symbol'], 0) + 1
97
+ self._all_new_updates = (self._all_new_updates or 0) + 1
98
+
99
+
100
+ class ArrayCacheByTimestamp(BaseCache):
101
+ def __init__(self, max_size=None):
102
+ super(ArrayCacheByTimestamp, self).__init__(max_size)
103
+ self.hashmap = {}
104
+ self._size_tracker = set()
105
+ self._new_updates = 0
106
+ self._clear_updates = False
107
+
108
+ def getLimit(self, symbol, limit):
109
+ self._clear_updates = True
110
+ if limit is None:
111
+ return self._new_updates
112
+ return min(self._new_updates, limit)
113
+
114
+ def append(self, item):
115
+ if item[0] in self.hashmap:
116
+ reference = self.hashmap[item[0]]
117
+ if reference != item:
118
+ reference[0:len(item)] = item
119
+ else:
120
+ self.hashmap[item[0]] = item
121
+ if len(self._deque) == self._deque.maxlen:
122
+ delete_reference = self._deque.popleft()
123
+ del self.hashmap[delete_reference[0]]
124
+ self._deque.append(item)
125
+ if self._clear_updates:
126
+ self._clear_updates = False
127
+ self._size_tracker.clear()
128
+ self._size_tracker.add(item[0])
129
+ self._new_updates = len(self._size_tracker)
130
+
131
+
132
+ class ArrayCacheBySymbolById(ArrayCache):
133
+ def __init__(self, max_size=None):
134
+ super(ArrayCacheBySymbolById, self).__init__(max_size)
135
+ self._nested_new_updates_by_symbol = True
136
+ self.hashmap = {}
137
+ self._index = collections.deque([], max_size)
138
+
139
+ def append(self, item):
140
+ by_id = self.hashmap.setdefault(item['symbol'], {})
141
+ if item['id'] in by_id:
142
+ reference = by_id[item['id']]
143
+ if reference != item:
144
+ reference.update(item)
145
+ item = reference
146
+ index = self._index.index(item['id'])
147
+ del self._deque[index]
148
+ del self._index[index]
149
+ else:
150
+ by_id[item['id']] = item
151
+ if len(self._deque) == self._deque.maxlen:
152
+ delete_item = self._deque.popleft()
153
+ self._index.popleft()
154
+ del self.hashmap[delete_item['symbol']][delete_item['id']]
155
+ self._deque.append(item)
156
+ self._index.append(item['id'])
157
+ if self._clear_all_updates:
158
+ self._clear_all_updates = False
159
+ self._clear_updates_by_symbol.clear()
160
+ self._all_new_updates = 0
161
+ self._new_updates_by_symbol.clear()
162
+ if item['symbol'] not in self._new_updates_by_symbol:
163
+ self._new_updates_by_symbol[item['symbol']] = set()
164
+ if self._clear_updates_by_symbol.get(item['symbol']):
165
+ self._clear_updates_by_symbol[item['symbol']] = False
166
+ self._new_updates_by_symbol[item['symbol']].clear()
167
+ id_set = self._new_updates_by_symbol[item['symbol']]
168
+ before_length = len(id_set)
169
+ id_set.add(item['id'])
170
+ after_length = len(id_set)
171
+ self._all_new_updates = (self._all_new_updates or 0) + (after_length - before_length)
172
+
173
+
174
+ class ArrayCacheBySymbolBySide(ArrayCache):
175
+ def __init__(self, max_size=None):
176
+ super(ArrayCacheBySymbolBySide, self).__init__(max_size)
177
+ self._nested_new_updates_by_symbol = True
178
+ self.hashmap = {}
179
+ self._index = collections.deque([], max_size)
180
+
181
+ def append(self, item):
182
+ by_side = self.hashmap.setdefault(item['symbol'], {})
183
+ if item['side'] in by_side:
184
+ reference = by_side[item['side']]
185
+ if reference != item:
186
+ reference.update(item)
187
+ item = reference
188
+ index = self._index.index(item['symbol'] + item['side'])
189
+ del self._deque[index]
190
+ del self._index[index]
191
+ else:
192
+ by_side[item['side']] = item
193
+ if len(self._deque) == self._deque.maxlen:
194
+ delete_item = self._deque.popleft()
195
+ self._index.popleft()
196
+ del self.hashmap[delete_item['symbol']][delete_item['side']]
197
+ self._deque.append(item)
198
+ self._index.append(item['symbol'] + item['side'])
199
+ if self._clear_all_updates:
200
+ self._clear_all_updates = False
201
+ self._clear_updates_by_symbol.clear()
202
+ self._all_new_updates = 0
203
+ self._new_updates_by_symbol.clear()
204
+ if item['symbol'] not in self._new_updates_by_symbol:
205
+ self._new_updates_by_symbol[item['symbol']] = set()
206
+ if self._clear_updates_by_symbol.get(item['symbol']):
207
+ self._clear_updates_by_symbol[item['symbol']] = False
208
+ self._new_updates_by_symbol[item['symbol']].clear()
209
+ side_set = self._new_updates_by_symbol[item['symbol']]
210
+ before_length = len(side_set)
211
+ side_set.add(item['side'])
212
+ after_length = len(side_set)
213
+ self._all_new_updates = (self._all_new_updates or 0) + (after_length - before_length)
@@ -0,0 +1,214 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ from asyncio import sleep, ensure_future, wait_for, TimeoutError
4
+ from .functions import milliseconds, iso8601, deep_extend
5
+ from ccxt import NetworkError, RequestTimeout, NotSupported
6
+ from ccxt.async_support.base.ws.future import Future
7
+ from collections import deque
8
+
9
+ class Client(object):
10
+
11
+ url = None
12
+ ws = None
13
+ futures = {}
14
+ options = {} # ws-specific options
15
+ subscriptions = {}
16
+ rejections = {}
17
+ message_queue = {}
18
+ useMessageQueue = False
19
+ on_message_callback = None
20
+ on_error_callback = None
21
+ on_close_callback = None
22
+ on_connected_callback = None
23
+ connectionStarted = None
24
+ connectionEstablished = None
25
+ isConnected = False
26
+ connectionTimeout = 10000 # ms, false to disable
27
+ connection = None
28
+ error = None # low-level networking exception, if any
29
+ connected = None # connection-related Future
30
+ keepAlive = 5000
31
+ heartbeat = True
32
+ maxPingPongMisses = 2.0 # how many missed pongs to raise a timeout
33
+ lastPong = None
34
+ ping = None # ping-function if defined
35
+ verbose = False # verbose output
36
+ gunzip = False
37
+ inflate = False
38
+ throttle = None
39
+ connecting = False
40
+ asyncio_loop = None
41
+ ping_looper = None
42
+ receive_looper = None
43
+
44
+ def __init__(self, url, on_message_callback, on_error_callback, on_close_callback, on_connected_callback, config={}):
45
+ defaults = {
46
+ 'url': url,
47
+ 'futures': {},
48
+ 'subscriptions': {},
49
+ 'rejections': {},
50
+ 'on_message_callback': on_message_callback,
51
+ 'on_error_callback': on_error_callback,
52
+ 'on_close_callback': on_close_callback,
53
+ 'on_connected_callback': on_connected_callback,
54
+ }
55
+ settings = {}
56
+ settings.update(defaults)
57
+ settings.update(config)
58
+ for key in settings:
59
+ if hasattr(self, key) and isinstance(getattr(self, key), dict):
60
+ setattr(self, key, deep_extend(getattr(self, key), settings[key]))
61
+ else:
62
+ setattr(self, key, settings[key])
63
+ # connection-related Future
64
+ self.connected = Future()
65
+
66
+ def future(self, message_hash):
67
+ if message_hash not in self.futures or self.futures[message_hash].cancelled():
68
+ self.futures[message_hash] = Future()
69
+ future = self.futures[message_hash]
70
+ if message_hash in self.rejections:
71
+ future.reject(self.rejections[message_hash])
72
+ del self.rejections[message_hash]
73
+ del self.message_queue[message_hash]
74
+ return future
75
+ if self.useMessageQueue and message_hash in self.message_queue:
76
+ queue = self.message_queue[message_hash]
77
+ if len(queue):
78
+ future.resolve(queue.popleft())
79
+ del self.futures[message_hash]
80
+ return future
81
+
82
+ def resolve(self, result, message_hash):
83
+ if self.verbose and message_hash is None:
84
+ self.log(iso8601(milliseconds()), 'resolve received None messageHash')
85
+
86
+ if self.useMessageQueue:
87
+ if message_hash not in self.message_queue:
88
+ self.message_queue[message_hash] = deque(maxlen=10)
89
+ queue = self.message_queue[message_hash]
90
+ queue.append(result)
91
+ if message_hash in self.futures:
92
+ future = self.futures[message_hash]
93
+ future.resolve(queue.popleft())
94
+ del self.futures[message_hash]
95
+ else:
96
+ if message_hash in self.futures:
97
+ future = self.futures[message_hash]
98
+ future.resolve(result)
99
+ del self.futures[message_hash]
100
+ return result
101
+
102
+ def reject(self, result, message_hash=None):
103
+ if message_hash:
104
+ if message_hash in self.futures:
105
+ future = self.futures[message_hash]
106
+ future.reject(result)
107
+ del self.futures[message_hash]
108
+ else:
109
+ self.rejections[message_hash] = result
110
+ else:
111
+ message_hashes = list(self.futures.keys())
112
+ for message_hash in message_hashes:
113
+ self.reject(result, message_hash)
114
+ return result
115
+
116
+ async def receive_loop(self):
117
+ if self.verbose:
118
+ self.log(iso8601(milliseconds()), 'receive loop')
119
+ while not self.closed():
120
+ try:
121
+ message = await self.receive()
122
+ # self.log(iso8601(milliseconds()), 'received', message)
123
+ self.handle_message(message)
124
+ except Exception as e:
125
+ error = NetworkError(str(e))
126
+ if self.verbose:
127
+ self.log(iso8601(milliseconds()), 'receive_loop', 'Exception', error)
128
+ self.reset(error)
129
+
130
+ async def open(self, session, backoff_delay=0):
131
+ # exponential backoff for consequent connections if necessary
132
+ if backoff_delay:
133
+ await sleep(backoff_delay)
134
+ if self.verbose:
135
+ self.log(iso8601(milliseconds()), 'connecting to', self.url, 'with timeout', self.connectionTimeout, 'ms')
136
+ self.connectionStarted = milliseconds()
137
+ try:
138
+ coroutine = self.create_connection(session)
139
+ self.connection = await wait_for(coroutine, timeout=int(self.connectionTimeout / 1000))
140
+ self.connecting = False
141
+ self.connectionEstablished = milliseconds()
142
+ self.isConnected = True
143
+ if self.verbose:
144
+ self.log(iso8601(milliseconds()), 'connected')
145
+ self.connected.resolve(self.url)
146
+ self.on_connected_callback(self)
147
+ # run both loops forever
148
+ self.ping_looper = ensure_future(self.ping_loop(), loop=self.asyncio_loop)
149
+ self.receive_looper = ensure_future(self.receive_loop(), loop=self.asyncio_loop)
150
+ except TimeoutError:
151
+ # connection timeout
152
+ error = RequestTimeout('Connection timeout')
153
+ if self.verbose:
154
+ self.log(iso8601(milliseconds()), 'RequestTimeout', error)
155
+ self.on_error(error)
156
+ except Exception as e:
157
+ # connection failed or rejected (ConnectionRefusedError, ClientConnectorError)
158
+ error = NetworkError(e)
159
+ if self.verbose:
160
+ self.log(iso8601(milliseconds()), 'NetworkError', error)
161
+ self.on_error(error)
162
+
163
+ def connect(self, session, backoff_delay=0):
164
+ if not self.connection and not self.connecting:
165
+ self.connecting = True
166
+ ensure_future(self.open(session, backoff_delay), loop=self.asyncio_loop)
167
+ return self.connected
168
+
169
+ def on_error(self, error):
170
+ if self.verbose:
171
+ self.log(iso8601(milliseconds()), 'on_error', error)
172
+ self.error = error
173
+ self.reset(error)
174
+ self.on_error_callback(self, error)
175
+ if not self.closed():
176
+ ensure_future(self.close(1006), loop=self.asyncio_loop)
177
+
178
+ def on_close(self, code):
179
+ if self.verbose:
180
+ self.log(iso8601(milliseconds()), 'on_close', code)
181
+ if not self.error:
182
+ self.reset(NetworkError('Connection closed by remote server, closing code ' + str(code)))
183
+ self.on_close_callback(self, code)
184
+ if not self.closed():
185
+ ensure_future(self.close(code), loop=self.asyncio_loop)
186
+
187
+ def reset(self, error):
188
+ self.message_queue = {}
189
+ self.reject(error)
190
+
191
+ async def ping_loop(self):
192
+ if self.verbose:
193
+ self.log(iso8601(milliseconds()), 'ping loop')
194
+
195
+ def receive(self):
196
+ raise NotSupported('receive() not implemented')
197
+
198
+ def handle_message(self, message):
199
+ raise NotSupported('handle_message() not implemented')
200
+
201
+ def closed(self):
202
+ raise NotSupported('closed() not implemented')
203
+
204
+ async def send(self, message):
205
+ raise NotSupported('send() not implemented')
206
+
207
+ async def close(self, code=1000):
208
+ raise NotSupported('close() not implemented')
209
+
210
+ def create_connection(self, session):
211
+ raise NotSupported('create_connection() not implemented')
212
+
213
+ def log(self, *args):
214
+ print(*args)