hunk.code_window:                 http_response = await response.text()
                   http_status_code = response.status
                   http_status_text = response.reason
                   json_response = self.parse_json(http_response)
                   raw_response = response.content
                   headers = response.headers
                   if self.enableLastHttpResponse:
                       self.last_http_response = http_response
  
hunk.labels: keep keep keep keep replace keep keep keep
hunk.file_path: python/ccxt/async_support/base/exchange.py
hunk.type: replace
file: # -*- coding: utf-8 -*-
  
  # -----------------------------------------------------------------------------
  
  __version__ = '1.18.1086'
  
  # -----------------------------------------------------------------------------
  
  import asyncio
  import concurrent
  import socket
  import time
  import math
  import random
  import certifi
  import aiohttp
  import ssl
  import sys
  import yarl
  
  # -----------------------------------------------------------------------------
  
  from ccxt.async_support.base.throttle import throttle
  
  # -----------------------------------------------------------------------------
  
  from ccxt.base.errors import ExchangeError
  from ccxt.base.errors import ExchangeNotAvailable
  from ccxt.base.errors import RequestTimeout
  from ccxt.base.errors import NotSupported
  
  # -----------------------------------------------------------------------------
  
  from ccxt.base.exchange import Exchange as BaseExchange
  
  # -----------------------------------------------------------------------------
  
  __all__ = [
      'BaseExchange',
      'Exchange',
  ]
  
  # -----------------------------------------------------------------------------
  
  
  class Exchange(BaseExchange):
  
      def __init__(self, config={}):
          if 'asyncio_loop' in config:
              self.asyncio_loop = config['asyncio_loop']
          self.asyncio_loop = self.asyncio_loop or asyncio.get_event_loop()
          self.aiohttp_trust_env = config.get('aiohttp_trust_env', self.aiohttp_trust_env)
          self.verify = config.get('verify', self.verify)
          self.own_session = 'session' not in config
          self.cafile = config.get('cafile', certifi.where())
          self.open()
          super(Exchange, self).__init__(config)
          self.init_rest_rate_limiter()
  
      def init_rest_rate_limiter(self):
          self.throttle = throttle(self.extend({
              'loop': self.asyncio_loop,
          }, self.tokenBucket))
  
      def __del__(self):
          if self.session is not None:
              self.logger.warning(self.id + " requires to release all resources with an explicit call to the .close() coroutine. If you are using the exchange instance with async coroutines, add exchange.close() to your code into a place when you're done with the exchange and don't need the exchange instance anymore (at the end of your async coroutine).")
  
      if sys.version_info >= (3, 5):
          async def __aenter__(self):
              self.open()
              return self
  
          async def __aexit__(self, exc_type, exc, tb):
              await self.close()
  
      def open(self):
          if self.own_session and self.session is None:
              # Create our SSL context object with our CA cert file
              context = ssl.create_default_context(cafile=self.cafile) if self.verify else self.verify
              # Pass this SSL context to aiohttp and create a TCPConnector
              connector = aiohttp.TCPConnector(ssl=context, loop=self.asyncio_loop)
              self.session = aiohttp.ClientSession(loop=self.asyncio_loop, connector=connector, trust_env=self.aiohttp_trust_env)
  
      async def close(self):
          if self.session is not None:
              if self.own_session:
                  await self.session.close()
              self.session = None
  
      async def wait_for_token(self):
          while self.rateLimitTokens <= 1:
              # if self.verbose:
              #     print('Waiting for tokens: Exchange: {0}'.format(self.id))
              self.add_new_tokens()
              seconds_delays = [0.001, 0.005, 0.022, 0.106, 0.5]
              delay = random.choice(seconds_delays)
              await asyncio.sleep(delay)
          self.rateLimitTokens -= 1
  
      def add_new_tokens(self):
          # if self.verbose:
          #     print('Adding new tokens: Exchange: {0}'.format(self.id))
          now = time.monotonic()
          time_since_update = now - self.rateLimitUpdateTime
          new_tokens = math.floor((0.8 * 1000.0 * time_since_update) / self.rateLimit)
          if new_tokens > 1:
              self.rateLimitTokens = min(self.rateLimitTokens + new_tokens, self.rateLimitMaxTokens)
              self.rateLimitUpdateTime = now
  
      async def fetch2(self, path, api='public', method='GET', params={}, headers=None, body=None):
          """A better wrapper over request for deferred signing"""
          if self.enableRateLimit:
              await self.throttle()
          self.lastRestRequestTimestamp = self.milliseconds()
          request = self.sign(path, api, method, params, headers, body)
          return await self.fetch(request['url'], request['method'], request['headers'], request['body'])
  
      async def fetch(self, url, method='GET', headers=None, body=None):
          """Perform a HTTP request and return decoded JSON data"""
          request_headers = self.prepare_request_headers(headers)
          url = self.proxy + url
  
          if self.verbose:
              print("\nRequest:", method, url, headers, body)
          self.logger.debug("%s %s, Request: %s %s", method, url, headers, body)
  
          encoded_body = body.encode() if body else None
          session_method = getattr(self.session, method.lower())
  
          http_response = None
          http_status_code = None
          http_status_text = None
          json_response = None
          try:
              async with session_method(yarl.URL(url, encoded=True),
                                        data=encoded_body,
                                        headers=request_headers,
                                        timeout=(self.timeout / 1000),
                                        proxy=self.aiohttp_proxy) as response:
                  http_response = await response.text()
                  http_status_code = response.status
                  http_status_text = response.reason
                  json_response = self.parse_json(http_response)
                  raw_response = response.content
                  headers = response.headers
                  if self.enableLastHttpResponse:
                      self.last_http_response = http_response
                  if self.enableLastResponseHeaders:
                      self.last_response_headers = headers
                  if self.enableLastJsonResponse:
                      self.last_json_response = json_response
                  if self.enableLastRawResponse:
                      self.last_raw_response = raw_response
                  if self.verbose:
                      print("\nResponse:", method, url, http_status_code, headers, http_response)
                  self.logger.debug("%s %s, Response: %s %s %s", method, url, http_status_code, headers, http_response)
  
          except socket.gaierror as e:
              raise ExchangeNotAvailable(method + ' ' + url)
  
          except concurrent.futures._base.TimeoutError as e:
              raise RequestTimeout(method + ' ' + url)
  
          except aiohttp.client_exceptions.ClientConnectionError as e:
              raise ExchangeNotAvailable(method + ' ' + url)
  
          except aiohttp.client_exceptions.ClientError as e:  # base exception class
              raise ExchangeError(method + ' ' + url)
  
          self.handle_errors(http_status_code, http_status_text, url, method, headers, http_response, json_response)
          self.handle_rest_errors(http_status_code, http_status_text, http_response, url, method)
          self.handle_rest_response(http_response, json_response, url, method)
          if json_response is not None:
              return json_response
          return http_response
  
      async def load_markets(self, reload=False, params={}):
          if not reload:
              if self.markets:
                  if not self.markets_by_id:
                      return self.set_markets(self.markets)
                  return self.markets
          currencies = None
          if self.has['fetchCurrencies']:
              currencies = await self.fetch_currencies()
          markets = await self.fetch_markets(params)
          return self.set_markets(markets, currencies)
  
      async def fetch_fees(self):
          trading = {}
          funding = {}
          if self.has['fetchTradingFees']:
              trading = await self.fetch_trading_fees()
          if self.has['fetchFundingFees']:
              funding = await self.fetch_funding_fees()
          return {
              'trading': trading,
              'funding': funding,
          }
  
      async def load_fees(self, reload=False):
          if not reload:
              if self.loaded_fees != Exchange.loaded_fees:
                  return self.loaded_fees
          self.loaded_fees = self.deep_extend(self.loaded_fees, await self.fetch_fees())
          return self.loaded_fees
  
      async def fetch_markets(self, params={}):
          # markets are returned as a list
          # currencies are returned as a dict
          # this is for historical reasons
          # and may be changed for consistency later
          return self.to_array(self.markets)
  
      async def fetch_currencies(self, params={}):
          # markets are returned as a list
          # currencies are returned as a dict
          # this is for historical reasons
          # and may be changed for consistency later
          return self.currencies
  
      async def fetch_status(self, params={}):
          if self.has['fetchTime']:
              updated = await self.fetch_time(params)
              self.status['updated'] = updated
          return self.status
  
      async def fetch_order_status(self, id, symbol=None, params={}):
          order = await self.fetch_order(id, symbol, params)
          return order['status']
  
      async def fetch_partial_balance(self, part, params={}):
          balance = await self.fetch_balance(params)
          return balance[part]
  
      async def fetch_l2_order_book(self, symbol, limit=None, params={}):
          orderbook = await self.fetch_order_book(symbol, limit, params)
          return self.extend(orderbook, {
              'bids': self.sort_by(self.aggregate(orderbook['bids']), 0, True),
              'asks': self.sort_by(self.aggregate(orderbook['asks']), 0),
          })
  
      async def perform_order_book_request(self, market, limit=None, params={}):
          raise NotSupported(self.id + ' performOrderBookRequest not supported yet')
  
      async def fetch_order_book(self, symbol, limit=None, params={}):
          await self.load_markets()
          market = self.market(symbol)
          orderbook = await self.perform_order_book_request(market, limit, params)
          return self.parse_order_book(orderbook, market, limit, params)
  
      async def fetch_ohlcv(self, symbol, timeframe='1m', since=None, limit=None, params={}):
          if not self.has['fetchTrades']:
              raise NotSupported('fetch_ohlcv() not implemented yet')
          await self.load_markets()
          trades = await self.fetch_trades(symbol, since, limit, params)
          return self.build_ohlcv(trades, timeframe, since, limit)
  
      async def fetchOHLCV(self, symbol, timeframe='1m', since=None, limit=None, params={}):
          return await self.fetch_ohlcv(symbol, timeframe, since, limit, params)
  
      async def fetch_full_tickers(self, symbols=None, params={}):
          return await self.fetch_tickers(symbols, params)
  
      async def edit_order(self, id, symbol, *args):
          if not self.enableRateLimit:
              raise ExchangeError('updateOrder() requires enableRateLimit = true')
          await self.cancel_order(id, symbol)
          return await self.create_order(symbol, *args)
  
      async def fetch_trading_fees(self, params={}):
          raise NotSupported('fetch_trading_fees() not supported yet')
  
      async def fetch_trading_fee(self, symbol, params={}):
          if not self.has['fetchTradingFees']:
              raise NotSupported('fetch_trading_fee() not supported yet')
          return await self.fetch_trading_fees(params)
  
      async def load_trading_limits(self, symbols=None, reload=False, params={}):
          if self.has['fetchTradingLimits']:
              if reload or not('limitsLoaded' in list(self.options.keys())):
                  response = await self.fetch_trading_limits(symbols)
                  for i in range(0, len(symbols)):
                      symbol = symbols[i]
                      self.markets[symbol] = self.deep_extend(self.markets[symbol], response[symbol])
                  self.options['limitsLoaded'] = self.milliseconds()
          return self.markets
  
      async def load_accounts(self, reload=False, params={}):
          if reload:
              self.accounts = await self.fetch_accounts(params)
          else:
              if self.accounts:
                  return self.accounts
              else:
                  self.accounts = await self.fetch_accounts(params)
          self.accountsById = self.index_by(self.accounts, 'id')
          return self.accounts
  
      async def fetch_ticker(self, symbol, params={}):
          raise NotSupported('fetch_ticker() not supported yet')
  