code: def subscribe(self, dataset=None):
      if dataset is None:
          df_sets = self._list()
          if df_sets.empty:
              print("There are no datasets available yet.")
              return
  
          set_print_settings()
          while True:
              print(df_sets)
              dataset_num = input(
                  "Choose the dataset you want to "
                  "subscribe to [0..{}]: ".format(df_sets.size - 1)
              )
              try:
                  dataset_num = int(dataset_num)
              except ValueError:
                  print(
                      "Enter a number between 0 and {}".format(
                          df_sets.size - 1
                      )
                  )
              else:
                  if dataset_num not in range(0, df_sets.size):
                      print(
                          "Enter a number between 0 and {}".format(
                              df_sets.size - 1
                          )
                      )
                  else:
                      dataset = df_sets.iloc[dataset_num]["dataset"]
                      break
  
      dataset = dataset.lower()
  
      address = self.choose_pubaddr()[0]
      provider_info = self.mkt_contract.functions.getDataProviderInfo(
          Web3.toHex(dataset.encode())
      ).call()
  
      if not provider_info[4]:
          print(
              'The requested "{}" dataset is not registered in '
              "the Data Marketplace.".format(dataset)
          )
          return
  
      grains = provider_info[1]
      price = from_grains(grains)
  
      subscribed = self.mkt_contract.functions.checkAddressSubscription(
          address, Web3.toHex(dataset.encode())
      ).call()
  
      if subscribed[5]:
          print(
              '\nYou are already subscribed to the "{}" dataset.\n'
              "Your subscription started on {} UTC, and is valid until "
              "{} UTC.".format(
                  dataset,
                  pd.to_datetime(subscribed[3], unit="s", utc=True),
                  pd.to_datetime(subscribed[4], unit="s", utc=True),
              )
          )
          return
  
      print(
          "\nThe price for a monthly subscription to this dataset is"
          " {} ENG".format(price)
      )
  
      print(
          "Checking that the ENG balance in {} is greater than {} "
          "ENG... ".format(address, price),
          end="",
      )
  
      wallet_address = address[2:]
      balance = self.web3.eth.call(
          {
              "from": address,
              "to": self.eng_contract_address,
              "data": "0x70a08231000000000000000000000000{}".format(
                  wallet_address
              ),
          }
      )
  
      try:
          balance = Web3.toInt(balance)  # web3 >= 4.0.0b7
      except TypeError:
          balance = Web3.toInt(hexstr=balance)  # web3 <= 4.0.0b6
  
      if balance > grains:
          print("OK.")
      else:
          print(
              "FAIL.\n\nAddress {} balance is {} ENG,\nwhich is lower "
              "than the price of the dataset that you are trying to\n"
              "buy: {} ENG. Get enough ENG to cover the costs of the "
              "monthly\nsubscription for what you are trying to buy, "
              "and try again.".format(
                  address, from_grains(balance), price
              )
          )
          return
  
      while True:
          agree_pay = (
              input(
                  "Please confirm that you agree to pay {} ENG "
                  'for a monthly subscription to the dataset "{}" '
                  "starting today. [default: Y] ".format(price, dataset)
              )
              or "y"
          )
          if agree_pay.lower() not in ("y", "n"):
              print("Please answer Y or N.")
          else:
              if agree_pay.lower() == "y":
                  break
              else:
                  return
  
      print("Ready to subscribe to dataset {}.\n".format(dataset))
      print(
          "In order to execute the subscription, you will need to sign "
          "two different transactions:\n"
          "1. First transaction is to authorize the Marketplace contract "
          "to spend {} ENG on your behalf.\n"
          "2. Second transaction is the actual subscription for the "
          "desired dataset".format(price)
      )
  
      tx = self.eng_contract.functions.approve(
          self.mkt_contract_address,
          grains,
      ).buildTransaction(
          {
              "from": address,
              "nonce": self.web3.eth.getTransactionCount(address),
          }
      )
  
      signed_tx = self.sign_transaction(tx)
      try:
          tx_hash = "0x{}".format(
              bin_hex(self.web3.eth.sendRawTransaction(signed_tx))
          )
          print(
              "\nThis is the TxHash for this transaction: {}".format(
                  tx_hash
              )
          )
  
      except Exception as e:
          print("Unable to subscribe to data source: {}".format(e))
          return
  
      self.check_transaction(tx_hash)
  
      print("Waiting for the first transaction to succeed...")
  
      while True:
          try:
              if self.web3.eth.getTransactionReceipt(tx_hash).status:
                  break
              else:
                  print("\nTransaction failed. Aborting...")
                  return
          except AttributeError:
              pass
          for i in range(0, 10):
              print(".", end="", flush=True)
              time.sleep(1)
  
      print(
          "\nFirst transaction successful!\n"
          "Now processing second transaction."
      )
  
      tx = self.mkt_contract.functions.subscribe(
          Web3.toHex(dataset.encode()),
      ).buildTransaction(
          {
              "from": address,
              "nonce": self.web3.eth.getTransactionCount(address),
          }
      )
  
      signed_tx = self.sign_transaction(tx)
  
      try:
          tx_hash = "0x{}".format(
              bin_hex(self.web3.eth.sendRawTransaction(signed_tx))
          )
          print(
              "\nThis is the TxHash for this transaction: "
              "{}".format(tx_hash)
          )
  
      except Exception as e:
          print("Unable to subscribe to data source: {}".format(e))
          return
  
      self.check_transaction(tx_hash)
  
      print("Waiting for the second transaction to succeed...")
  
      while True:
          try:
              if self.web3.eth.getTransactionReceipt(tx_hash).status:
                  break
              else:
                  print("\nTransaction failed. Aborting...")
                  return
          except AttributeError:
              pass
          for i in range(0, 10):
              print(".", end="", flush=True)
              time.sleep(1)
  
      print(
          "\nSecond transaction successful!\n"
          "You have successfully subscribed to dataset {} with"
          "address {}.\n"
          "You can now ingest this dataset anytime during the "
          "next month by running the following command:\n"
          "catalyst marketplace ingest --dataset={}".format(
              dataset, address, dataset
          )
      )
  
imports: from __future__ import print_function
  import glob
  import json
  import os
  import re
  import shutil
  import sys
  import time
  import webbrowser
  import bcolz
  import logbook
  import pandas
  import requests
  from requests_toolbelt import MultipartDecoder
  from requests_toolbelt.multipart.decoder import NonMultipartContentTypeException
  from catalyst.constants import LOG_LEVEL, AUTH_SERVER, ETH_REMOTE_NODE, MARKETPLACE_CONTRACT, MARKETPLACE_CONTRACT_ABI, ENIGMA_CONTRACT, ENIGMA_CONTRACT_ABI, TERMS_AND_CONDITIONS
  from catalyst.exchange.utils.stats_utils import set_print_settings
  from catalyst.marketplace.marketplace_errors import MarketplaceDatasetNotFound, MarketplaceNoAddressMatch, MarketplaceHTTPRequest, MarketplaceNoCSVFiles, MarketplaceRequiresPython3
  from catalyst.marketplace.utils.auth_utils import get_key_secret, get_signed_headers
  from catalyst.marketplace.utils.eth_utils import bin_hex, from_grains, to_grains
  from catalyst.marketplace.utils.path_utils import get_bundle_folder, get_data_source_folder, get_marketplace_folder, get_user_pubaddr, get_temp_bundles_folder, extract_bundle, save_user_pubaddr
  from catalyst.utils.paths import ensure_directory
label_desc: Use image node_id 8 for calling the Marketplace obj's underlying member method code with example usage: obj.subscribe(dataset) without return types