text: import requests as r
  import pandas as pd
  from datetime import datetime
  import json, time, base64
  
  class MeshClient():
      def __init__(self,username=None,password=None):
          if not username:
              print("[ERROR] Username required")
          elif not password:
              print("[Error] Password required")
          else:
              encoded_auth = base64.b64encode(f"{username}:{password}".encode())
              self.auth = f"Basic {encoded_auth.decode()}"
              self.rest_url = "https://api.merfi.xyz/api/"
              self.graphql_url = "https://api.merfi.xyz/graphql"
              self.search_query = '''
              query search($search_str: String!) {
                search(searchStr: $search_str) {
                  ...on basicToken {
                    symbol
                    name
                    address
                  }
                  ...on optionToken {
                    premium {
                      symbol
                    }
                    name
                    address
                  }
                  ...on virtualToken {
                    symbol
                    name
                  }
                  ...on uniswapPair {
                    name
                    address
                    token0Price {
                      symbol
                    }
                  }
                  ...on aggregatePair {
                    name
                  }
                }
              }
              '''
      
      def engine(self,mesh_string,time_start=None,time_end=None,unit="MINUTE",number=15,display='raw'):
  
          if time_start is None:
              time_start = int((datetime.now().timestamp() - 3*86400))
          if time_end is None:
              time_end = int(datetime.now().timestamp())
  
          headers = {
            "Authorization":self.auth,
            "Content-Type":"application/json"
          }
  
          params = {
              "expr":mesh_string,
              "range":{"tstart":time_start,"tend":time_end},
              "interval":{"unit": unit,"n":number}
          }
  
          identifier = r.post(self.rest_url + "engine",json=params,headers=headers)
  
          result = None
          while not result:
              status = r.get(self.rest_url + "status",params={"id":identifier.content.decode()},headers=headers)
              #print(status.content.decode())
              if status.content.decode() != 'DONE':
                  time.sleep(4)
              else:
                  result = r.get(self.rest_url + "fetch", params={"id":identifier.content.decode()},headers=headers).json()
  
          if display == "raw":
              df = result
          elif display == "dataframe":
              if result[0] == 'DSLScalar':
                  df = result['engine']['value']
              else:
                  df = pd.DataFrame.from_records(result["DSLTimeseries"]["values"])
                  df["timestamp"] = pd.to_datetime(df["timestamp"],unit="s")
          else:
              df = None
  
          return df
  
      
      
      def search(self,search_string):
          if search_string == "":
              return None
          else:
              return r.post(self.graphql_url,json={"query":self.search_query,"variables":{"search_str":search_string}})
          