async def get_order_book_data(
            trading_pair: str,
            throttler: Optional[AsyncThrottler] = None) -> Dict[str, any]:
        """
        Retrieves the JSON order book data of the specified trading pair using the exchange's REST API.
        :param trading_pair: Specified trading pair.
        :param throttler: Optional AsyncThrottler used to throttle the API request.
        """
        throttler = throttler or CryptoComAPIOrderBookDataSource._get_throttler_instance(
        )
        async with aiohttp.ClientSession() as client:
            async with throttler.execute_task(
                    CONSTANTS.GET_ORDER_BOOK_PATH_URL):
                url = crypto_com_utils.get_rest_url(
                    CONSTANTS.GET_ORDER_BOOK_PATH_URL)
                params = {
                    "depth":
                    150,
                    "instrument_name":
                    crypto_com_utils.convert_to_exchange_trading_pair(
                        trading_pair),
                }
                orderbook_response = await client.get(url=url, params=params)

                if orderbook_response.status != 200:
                    raise IOError(
                        f"Error fetching OrderBook for {trading_pair} at {CONSTANTS.EXCHANGE_NAME}. "
                        f"HTTP status is {orderbook_response.status}.")

                orderbook_data: List[Dict[str, Any]] = await safe_gather(
                    orderbook_response.json())
                orderbook_data = orderbook_data[0]["result"]["data"][0]

            return orderbook_data
 async def fetch_trading_pairs(
         throttler: Optional[AsyncThrottler] = None) -> List[str]:
     """
     Retrieves active trading pairs using the exchange's REST API.
     :param throttler: Optional AsyncThrottler used to throttle the API request
     """
     throttler = throttler or CryptoComAPIOrderBookDataSource._get_throttler_instance(
     )
     async with aiohttp.ClientSession() as client:
         async with throttler.execute_task(CONSTANTS.GET_TICKER_PATH_URL):
             url = crypto_com_utils.get_rest_url(
                 path_url=CONSTANTS.GET_TICKER_PATH_URL)
             async with client.get(url=url, timeout=10) as response:
                 if response.status == 200:
                     try:
                         data: Dict[str, Any] = await response.json()
                         return [
                             crypto_com_utils.
                             convert_from_exchange_trading_pair(item["i"])
                             for item in data["result"]["data"]
                         ]
                     except Exception:
                         pass
                         # Do nothing if the request fails -- there will be no autocomplete for kucoin trading pairs
                 return []
    def test_get_last_trade_prices(self, mock_api):
        url = crypto_com_utils.get_rest_url(
            path_url=CONSTANTS.GET_TICKER_PATH_URL)
        regex_url = re.compile(f"^{url}")

        expected_last_traded_price = 1.0

        mock_responses = {
            "code": 0,
            "method": "public/get-ticker",
            "result": {
                "data": [
                    {  # Truncated Response
                        "i": self.ex_trading_pair,
                        "a": expected_last_traded_price,
                    }
                ]
            },
        }
        mock_api.get(regex_url, body=ujson.dumps(mock_responses))

        result = self.async_run_with_timeout(
            self.data_source.get_last_traded_prices(
                trading_pairs=[self.trading_pair]))

        self.assertEqual(result[self.trading_pair], expected_last_traded_price)
    def test_get_new_order_book(self, mock_api):
        url = crypto_com_utils.get_rest_url(
            path_url=CONSTANTS.GET_ORDER_BOOK_PATH_URL)
        regex_url = re.compile(f"^{url}")

        snapshot_timestamp = 1634731570152
        mock_response = {
            "code": 0,
            "method": "public/get-book",
            "result": {
                "instrument_name":
                self.ex_trading_pair,
                "depth":
                150,
                "data": [{
                    "bids": [
                        [999.00, 1.0, 1],
                    ],
                    "asks": [
                        [1000.00, 1.0, 1],
                    ],
                    "t": snapshot_timestamp,
                }],
            },
        }

        mock_api.get(regex_url, body=ujson.dumps(mock_response))

        result = self.async_run_with_timeout(
            self.data_source.get_new_order_book(self.trading_pair))

        self.assertIsInstance(result, OrderBook)
        self.assertEqual(snapshot_timestamp, result.snapshot_uid)
Exemple #5
0
    async def _api_request(self,
                           method: str,
                           path_url: str,
                           params: Dict[str, Any] = {},
                           is_auth_required: bool = False) -> Dict[str, Any]:
        """
        Sends an aiohttp request and waits for a response.
        :param method: The HTTP method, e.g. get or post
        :param path_url: The path url or the API end point
        :param is_auth_required: Whether an authentication is required, when True the function will add encrypted
        signature to the request.
        :returns A response in json format.
        """
        async with self._throttler.execute_task(path_url):
            url = crypto_com_utils.get_rest_url(path_url)
            client = await self._http_client()
            if is_auth_required:
                request_id = crypto_com_utils.RequestId.generate_request_id()
                data = {"params": params}
                params = self._crypto_com_auth.generate_auth_dict(
                    path_url, request_id, crypto_com_utils.get_ms_timestamp(),
                    data)
                headers = self._crypto_com_auth.get_headers()
            else:
                headers = {"Content-Type": "application/json"}

            if method == "get":
                response = await client.get(url, headers=headers)
            elif method == "post":
                post_json = json.dumps(params)
                response = await client.post(url,
                                             data=post_json,
                                             headers=headers)
            else:
                raise NotImplementedError

            try:
                parsed_response = json.loads(await response.text())
            except Exception as e:
                raise IOError(
                    f"Error parsing data from {url}. Error: {str(e)}")
            if response.status != 200:
                raise IOError(
                    f"Error fetching data from {url}. HTTP status is {response.status}. "
                    f"Message: {parsed_response}")
            if parsed_response["code"] != 0:
                raise IOError(
                    f"{url} API call failed, response: {parsed_response}")
            return parsed_response
    def test_listen_for_order_book_snapshots_successful(self, mock_api):
        url = crypto_com_utils.get_rest_url(
            path_url=CONSTANTS.GET_ORDER_BOOK_PATH_URL)
        regex_url = re.compile(f"^{url}")

        mock_response = {
            "code": 0,
            "method": "public/get-book",
            "result": {
                "instrument_name":
                self.ex_trading_pair,
                "depth":
                150,
                "data": [{
                    "bids": [
                        [999.00, 1.0, 1],
                    ],
                    "asks": [
                        [1000.00, 1.0, 1],
                    ],
                    "t": 1634731570152,
                }],
            },
        }

        mock_api.get(regex_url, body=ujson.dumps(mock_response))

        order_book_messages = asyncio.Queue()

        self.async_task = self.ev_loop.create_task(
            self.data_source.listen_for_order_book_snapshots(
                ev_loop=self.ev_loop, output=order_book_messages))

        order_book_message = self.async_run_with_timeout(
            order_book_messages.get())

        self.assertTrue(order_book_messages.empty())
        self.assertEqual(1634731570152, order_book_message.update_id)
        self.assertEqual(1634731570152, order_book_message.timestamp)
        self.assertEqual(999.00, order_book_message.bids[0].price)
        self.assertEqual(1000.00, order_book_message.asks[0].price)
 async def get_last_traded_prices(
         cls,
         trading_pairs: List[str],
         throttler: Optional[AsyncThrottler] = None) -> Dict[str, float]:
     result = {}
     throttler = throttler or cls._get_throttler_instance()
     async with aiohttp.ClientSession() as client:
         async with throttler.execute_task(CONSTANTS.GET_TICKER_PATH_URL):
             resp = await client.get(
                 crypto_com_utils.get_rest_url(
                     path_url=CONSTANTS.GET_TICKER_PATH_URL))
             resp_json = await resp.json()
             for t_pair in trading_pairs:
                 last_trade = [
                     o["a"] for o in resp_json["result"]["data"]
                     if o["i"] == crypto_com_utils.
                     convert_to_exchange_trading_pair(t_pair)
                 ]
                 if last_trade and last_trade[0] is not None:
                     result[t_pair] = last_trade[0]
     return result
    def test_fetch_trading_pairs(self, mock_api):
        url = crypto_com_utils.get_rest_url(
            path_url=CONSTANTS.GET_TICKER_PATH_URL)
        regex_url = re.compile(f"^{url}")

        mock_response = {
            "code": 0,
            "method": "public/get-ticker",
            "result": {
                "data": [
                    {  # Truncated Response
                        "i": self.ex_trading_pair,
                        "a": 1.0,
                    }
                ]
            },
        }

        mock_api.get(regex_url, body=ujson.dumps(mock_response))

        result = self.async_run_with_timeout(
            self.data_source.fetch_trading_pairs())

        self.assertTrue(self.trading_pair in result)