text: import requests
  import pandas as pd
  import io
  from json import loads
  import json
  from pandas.io.json import json_normalize
  import os
  from keys import asset_keys, order_keys, event_keys, coll_keys,\
      bundle_keys, map_dic, stats_keys, user_keys, urls, map_replace_dic, contract_keys
  api_key = os.getenv('API_KEY')
  
  
  def create_df(dic_in, cols, input_type):
      """
      Convert JSON output from OpenSea API to pandas DataFrame
      :param dic_in: JSON output from OpenSea API
      :param cols: Keys in JSON output from OpenSea API
      :param input_type: <TBD> save the columns with dictionaries as entries seperately
      :return: Cleaned DataFrame
      """
      # First pass create dataframe where some of the values are a dictionary with multiple values
      df = pd.DataFrame(columns=cols)
      for col in cols:
          data = []
          for row in dic_in:
              data.append(row.get(col))
          df[col] = data
      # Second Pass get rid of columns with dictionaries, for now just forgetting about dictionary
      df_2 = df.copy()
      if input_type == 'collections':
          for col in df_2.columns:
              if col in map_dic:
                  embed_dic_type = map_dic[col]
                  df_2.at[col] = map_replace_dic[embed_dic_type]
                  if embed_dic_type == 'stats':
                      stats_df_i = pd.DataFrame(columns=stats_keys)
                      for df_index, df_row in df.iterrows():
                          dic_in_2 = df_row['stats']
                          for row_2 in dic_in_2:
                              stats_df_i.at[df_index, row_2] = dic_in_2[row_2]
  
      return df_2, stats_df_i
  
  
  def get_default_query_header(input_type):
      """
      Get Default query string to OpenSea API, used for initialization
      :param input_type: 'assets', 'orders', 'asset_events', 'collections'
      :return: query and header input to OpenSea API
      """
      querystring = {}
      headers = {}
      if input_type == 'assets':
          querystring = {"order_direction": "desc", "offset": "0", "limit": "10000"}
          headers = {"X-API-KEY": api_key}
  
      elif input_type == 'collections':
          querystring = {"offset": "0", "limit": "100000"}
          headers = {"X-API-KEY": api_key}
  
      elif input_type == 'bundles':
          querystring = {"limit": "100000", "offset": "0"}
          headers = {"X-API-KEY": api_key}
  
      elif input_type == 'asset_events':
          querystring = {"only_opensea": "false", "offset": "0", "limit": "10000"}
          headers = {"Accept": "application/json", "X-API-KEY": api_key}
  
      elif input_type == 'orders':
          querystring = {"bundled": "false", "include_bundled": "false", "include_invalid": "false", "limit": "10000",
                         "offset": "0", "order_by": "created_date", "order_direction": "desc"}
          headers = {"Accept": "application/json", "X-API-KEY": api_key}
  
      return querystring, headers
  
  
  def read_data(input_type, query_in):
      """
      Read OpenSea API
      :param input_type: 'assets', 'orders', 'asset_events', 'collections'
      :param query_in:
      :return: dataframe associated with query
      """
      # If query_in provided use that, or use default:
      querystring, headers = get_default_query_header(input_type)
      if query_in:
          querystring = query_in
      url = urls[input_type]
  
      # API call -- JSON returned
      try:
          response = requests.request("GET", url, headers=headers, params=querystring)
          j = response.json()
          # Convert JSON to python DataFrame (after command it is still in dic like format)
          df = pd.DataFrame.from_dict(j)
          dic = df[input_type]
          keys = list(dic[0].keys())
          df_1, df_2 = create_df(dic, keys, input_type)
          if input_type == 'events':
              df = df.rename(columns={'payment_token': 'payment_token_event'})
      except:
          df_1 = pd.DataFrame()
          df_2 = pd.DataFrame()
  
      return df_1, df_2
  
  
  def read_default():
      """
      Run OpenSea API call with default query
      :return: default DataFrame for assets, orders, collections, events, and bundles
      """
      df_assets = pd.DataFrame()
      df_orders = pd.DataFrame()
      df_asset_events = pd.DataFrame()
      df_collections = pd.DataFrame()
      df_bundles = pd.DataFrame()
      types_list = ['assets', 'orders', 'asset_events', 'collections', 'bundles']
      for type_i in types_list:
          if type_i == 'orders':
              df_orders = read_data(type_i, None)
          elif type_i == 'assets':
              df_assets = read_data(type_i, None)
          elif type_i == 'asset_events':
              df_asset_events = read_data(type_i, None)
          elif type_i == 'collections':
              df_collections = read_data(type_i, None)
          elif type_i == 'bundles':
              df_bundles = read_data(type_i, None)
  
      return df_assets, df_orders, df_asset_events, df_collections, df_bundles
  
  
  
  