title: Crypto trading bot with Binance, Error from callback > bound method, when I am trying to get historical candles from Binance using the "GET" method
body: <p>The bot takes certain data from www.testnet.binancefuture.com&gt; the information I am getting are bid and ask, historical candles, contracts, balances, place, cancel and order status. The callback methods are on_open, on_error, on_close and on_message + Channel subscription. Here is the code and the error</p>
  <p>class BinanceFuturesClient:</p>
  <pre><code>def __init__(self, public_key, secret_key, testnet):
      if testnet:
          self.base_url = &quot;https://testnet.binancefuture.com&quot;
          self.wss_url = &quot;wss://stream.binancefuture.com/ws&quot;
      else:
          self.base_url = &quot;https://fapi.binance.com&quot;
          self.wss_url = &quot;wss://fstream.binance.com/ws&quot;
  
      self.public_key = public_key
      self.secret_key = secret_key
  
      self.headers = {'X-MBX-APIKEY': self.public_key}
  
      self.prices = dict()
  
      self.id = 1
      self.ws = None
  
      t = threading.Thread(target=self.start_ws)
      t.start()
  
      logger.info(&quot;Binance Futures Client successfully initialized&quot;)
  
  def generate_signature(self, data):
      return hmac.new(self.secret_key.encode(), urlencode(data).encode(), hashlib.sha256).hexdigest()
  
  def make_request(self, method, endpoint, data):
      if method == &quot;GET&quot;:
          response = requests.get(self.base_url + endpoint, params=data, headers=self.headers)
      elif method == 'POST':
          response = requests.post(self.base_url + endpoint, params=data, headers=self.headers)
      elif method == 'DELETE':
          response = requests.delete(self.base_url + endpoint, params=data, headers=self.headers)
      else:
          raise ValueError()
  
      if response.status_code == 200:
          return response.json()
      else:
          logger.error('Error while making %s request to %s: %s(error code %s)',
                       method, endpoint, response.json(), response.status_code)
          return None
  
  def get_contracts(self):
      exchange_info = self.make_request(&quot;GET&quot;, &quot;/fapi/v1/exchangeInfo&quot;, None)
  
      contracts = dict()
  
      if exchange_info is not None:
          for contract_data in exchange_info['symbols']:
              contracts[contract_data['pair']] = contract_data
  
      return contracts
  
  def get_historical_candles(self, symbol, interval):
      data = dict()
      data['symbol'] = symbol
      data['interval'] = interval
      data['limit'] = 1000
  
      raw_candles = self.make_request(&quot;GET&quot;, &quot;/fapi/v1/klines&quot;, data)
  
      candles = []
  
      if raw_candles is not None:
          for c in raw_candles:
              candles.append([c[0], float(c[1]), float(c[2]), float(c[3]), float(c[4]), float(c[5])])
  
      return candles
  
  def get_bid_ask(self, symbol):
      data = dict()
      data['symbol'] = symbol
      ob_data = self.make_request(&quot;GET&quot;, &quot;/fapi/v1/ticker/bookTicker&quot;, data)
  
      if ob_data is not None:
          if symbol not in self.prices:
              self.prices[symbol] = {'bid': float(ob_data['bidPrice']), 'ask': float(ob_data['askPrice'])}
          else:
              self.prices[symbol]['bid'] = float(ob_data['bidPrice'])
              self.prices[symbol]['ask'] = float(ob_data['askPrice'])
  
          return self.prices[symbol]
  
  def get_balances(self):
      data = dict()
      data['timestamp'] = int(time.time() * 1000)
      data['signature'] = self.generate_signature(data)
  
      balances = dict()
  
      account_data = self.make_request(&quot;GET&quot;, &quot;/fapi/v1/account&quot;, data)
  
      if account_data is not None:
          for a in account_data['assets']:
              balances[a['asset']] = a
  
      return balances
  
  def place_order(self, symbol, side, quantity, order_type, price=None, tif=None):
      data = dict()
      data['symbol'] = symbol
      data['side'] = side
      data['quantity'] = quantity
      data['type'] = order_type
  
      if price is not None:
          data['price'] = price
  
      if tif is not None:
          data['timeInForce'] = tif
  
      data['timestamp'] = int(time.time() * 1000)
      data['signature'] = self.generate_signature(data)
  
      order_status = self.make_request(&quot;POST&quot;, &quot;/fapi/v1/order&quot;, data)
  
      return order_status
  
  def cancel_order(self, symbol, order_id):
      data = dict()
      data['symbol'] = symbol
      data['orderId'] = order_id
  
      data['timestamp'] = int(time.time() * 1000)
      data['signature'] = self.generate_signature(data)
  
      order_status = self.make_request(&quot;DELETE&quot;, &quot;/fapi/v1/order&quot;, data)
  
      return order_status
  
  def get_order_status(self, symbol, order_id):
      data = dict()
      data['timestamp'] = int(time.time() * 1000)
      data['symbol'] = symbol
      data['orderId'] = order_id
      data['signature'] = self.generate_signature(data)
  
      order_status = self.make_request(&quot;GET&quot;, &quot;/fapi/v1/order&quot;, data)
  
      return order_status
  
  def start_ws(self):
      ws = websocket.WebSocketApp(self.wss_url, on_open=self.on_open, on_close=self.on_close,
                                  on_error=self.on_error, on_message=self.on_message)
  
      ws.run_forever()
  
  def on_close(self, ws):
      logger.warning(&quot;Binance websocket connection closed&quot;)
  
  def on_error(self, ws, msg):
      logger.error(&quot;Binance connection error: %s&quot;, msg)
  
  def on_open(self, ws):
      logger.info(&quot;Binance connection opened&quot;)
  
      self.subscribe_channel(&quot;BTCUSDT&quot;)
  
  def on_message(self, ws, msg):
      print(msg)
  
  def subscribe_channel(self, symbol):
      data = dict()
      data['method'] = &quot;SUBSCRIBE&quot;
      data['params'] = []
      data['params'].append(symbol.lower() + &quot;@bookTicker&quot;)
      data['id'] = self.id
  
      print(data, type(data))
      print(json.dumps(data), type(json.dumps(data)))
  
      self.ws.send(json.dumps(data))
  
      self.id += 1
  </code></pre>
  <p>The error after data:</p>
  <p>2021-05-04 16:51:55,683 INFO :: Binance Futures Client successfully initialized
  {'method': 'SUBSCRIBE', 'params': ['btcusdt@bookTicker'], 'id': 1} &lt;class 'dict'&gt;
  {&quot;method&quot;: &quot;SUBSCRIBE&quot;, &quot;params&quot;: [&quot;btcusdt@bookTicker&quot;], &quot;id&quot;: 1} &lt;class 'str'&gt;
  2021-05-04 16:51:56,833 INFO :: Binance connection opened
  2021-05-04 16:51:56,834 ERROR :: error from callback &lt;bound method BinanceFuturesClient.on_open of &lt;connectors.binance_futures.BinanceFuturesClient object at 0x000001CAD7F712E0&gt;&gt;: 'NoneType' object has no attribute 'send'</p>