Python | Push To GeckoBoard

I'm doing a python framework which is capable of pushing the data to Geckoboard. Here is a the sample of the code and it handles for "highcharts"(different kinds) and gecko-o-meter.
It can be extended to other charts as well. This is just an template/idea. Here is a sample i made






#!env python -tt
'''
1) Gecko is used for pushing data to Gecko board

----------------------
 Modification History
----------------------
-- 22-Jan-2015| vsubr | created

'''
import sys
import datetime
from collections import OrderedDict
import pprint
import json
import requests

import MySQLdb
from contextlib import closing

import mod.conf.cfg as cfg
import mod.lib.logger as logger
import mod.conf.settings as settings

class Gecko(object):
 ''' "Task" class takes Gecko id as the input and executes that Gecko-task. 
 ''' 
 #-- use this site to check the colors http://html-color-codes.info/
 arr_gecko_colors =[ "#108ec5", #--blue
      "#52b238", #--green
          "#ee5728", #--some what close to orange
         "#ff00aa", #--pink
         "#f52e2e",  #--red
         "#ff8000", #--yellowish -orange
         "e6eb3f",  #--yellow
         "8258fa",  #--hmmmmm.. purple i think
         "2eccfa",  #--cyan
         "#ff2015", #--white 
         "df4ada"  #--different type pink       
       ]
#----------------------------------------------------------------------------------------
 def __init__(self): 
  self.results    = {}
  self._db_conn  = settings.fun_get_db_connection(cfg.AWS_RDS_MYSQL_DB_TAG)
  self._cursor  = self._db_conn.cursor(MySQLdb.cursors.DictCursor)
  self._gecko_params = {}
#---------------------------------------------------------------------------------------
 def __del__(self):  
  logger.log( "gecko__del__fired")
  if self._cursor:
   logger.log( "gecko__del__fired- db cursor and will be closed")
   self._cursor.close()     
#----------------------------------------------------------------------------------------
 def check_for_required_cols(cls, parr_cols, pd_row):

  for x_col in  parr_cols:
   if x_col not in pd_row:
    logger._logger.error("Required column (%s) is not available in the p_data" % x_col)
    sys.exit()
 
#---------------------------------------------------------------------------------------
 def push_to_geckoboard(cls, p_push_url, pj_data):
  
  ret = requests.post( p_push_url, 
        json.dumps( {'api_key' : cfg.GECKO_API_KEY, 
             'data': pj_data } ),
        verify=False
          )

  if not (ret.status_code == 200 and ret.json().get('success') == True):
   raise ValueError(ret.content)
  
#----------------------------------------------------------------------------------------
 def push_gecko_o_meter(cls, pd_rows, p_url, p_title):
  l_template = '{"item":[$$data$$],"min":{"value": [$$min_data$$]},"max":{"value": [$$max_data$$]}}'
  #l_template = '{"item":3, "min":{"value": 1}, "max":{"value": 10}}'

  #--Check if all required columns are there for highcharts
  larr_cols = [ 'data', 'min_data', 'max_data', 'goal_data']
  cls.check_for_required_cols( larr_cols, pd_rows[0])

  l_template = l_template.replace('[$$data$$]'     , str(float(pd_rows[0]['data'])))
  l_template = l_template.replace('[$$min_data$$]' , str(float(pd_rows[0]['min_data'])))
  l_template = l_template.replace('[$$max_data$$]' , str(float(pd_rows[0]['max_data'])))
  l_template = l_template.replace('[$$goal_data$$]', str(float(pd_rows[0]['goal_data'])))

  #-- push the data to Gecko-board
  logger.log("l_template=== %s" % l_template);
  #cls.push_to_geckoboard( p_push_url=p_url, pj_data={"geck-o-meter":l_template})
  cls.push_to_geckoboard( p_push_url = p_url, 
        pj_data    = json.loads(l_template)
         )
#---------------------------------------------------------------------------------------
 def push_highchart(cls, pd_rows, p_url, p_title, p_axis_title="", p_type=None, p_legend=0):
  
  l_template ='{chart:{style: {color: \"#b9bbbb\"},renderTo:\"container\",backgroundColor:\"transparent\",lineColor:\"rgba(35,37,38,100)\",plotShadow: false,},credits:{enabled:false}, \
       title:{style: {color: \"#b9bbbb\"},text:\"[$$gecko_title$$]\"}, \
       xAxis:{categories:[$$x_data$$]},\
       yAxis:{title:{style: {color: \"#b9bbbb\"}, text:\"'+p_axis_title+'\"}}, \
       legend:{enabled: [$$legend$$], itemStyle: {color: \"#b9bbbb\"}, layout:\"horizontal\",align:\"center\",verticalAlign:\"bottom\",borderWidth:0},\
       series:[$$y_data$$]}';
  
  #--Check if all required columns are there for highcharts
  larr_cols = ['x_data', 'y_category', 'y_data']
  cls.check_for_required_cols( larr_cols, pd_rows[0])
  
  #-- now get the DISTINCT y_category and preserver some ORDER
  larr_y_category = list(set([x_row['y_category'] for x_row in pd_rows]))
  ld_y_cat_struct =OrderedDict() 
  for x_cat in larr_y_category:
   ld_y_cat_struct[x_cat] = None
  
  #-- pack each row into pd_rows dictionary ; structure = {x1:{y_cat1:y1,y_cat2:y1},x2:{y_cat1:y2,y_cat2:y2}} 
  ld_data = OrderedDict()  
  for x_row in pd_rows:
   if x_row['x_data'] in ld_data:
    ld_data[x_row['x_data']][x_row['y_category']] = float(x_row['y_data'])
   else: # for the first time
    ld_data[x_row['x_data']] = ld_y_cat_struct.copy()
    ld_data[x_row['x_data']][x_row['y_category']] = float(x_row['y_data'])
   
  logger.log("ld_data==== %s" % ld_data)
  
  #--pack y-data into a dict for easy use; structure {y_cat1:[f(x1), f(x2), f)x3)...], y_cat2:[f(x1), f(x2), f)x3)...]}
  ld_y_data = {}
  for y_each_cat in larr_y_category:
   ld_y_data[y_each_cat] = [ld_data[x_each][y_each_cat] for x_each in ld_data.keys()] # get all Ys conditioned on y_cat i.e y= F(x)| y_category; all X

  #--Get the x and y data for high-charts
  larr_x_data = ld_data.keys()
  larr_y_data = []

  i = 0
  for x_y in larr_y_category:
   ld_y     = {}
   if p_type != None:
    ld_y['type']  = p_type
    
   ld_y['color'] = cls.arr_gecko_colors[i]
   ld_y['name']  = x_y
   ld_y['data']  = ld_y_data[x_y]
   i+=1
    
   larr_y_data.append(ld_y)
   
  pprint.pprint(larr_x_data, width=1)
  pprint.pprint(larr_y_data, width=1)
  
  #-- replace l_template with the data element
  if p_legend == 1:
   l_template = l_template.replace('[$$legend$$]', 'true')
  else:
   l_template = l_template.replace('[$$legend$$]', 'false')
   
  l_template = l_template.replace('[$$gecko_title$$]', p_title)
  l_template = l_template.replace('[$$x_data$$]', json.dumps(larr_x_data))
  l_template = l_template.replace('[$$y_data$$]', json.dumps(larr_y_data))
  
  #-- push the data to Gecko-board
  logger.log("l_template=== %s" % l_template);
  cls.push_to_geckoboard( p_push_url=p_url, pj_data={"highchart":l_template})
  
#-----------------------------------------------------------------------------------------
 def run(self, p_gecko_id):
  
  if self._cursor:
   self._cursor.close()
  self._cursor = self._db_conn.cursor(MySQLdb.cursors.DictCursor)

  try:
   #-- get the gecko board details and parameters. I kept the definition in a table..
   
   
   ld_gecko = []
   ld_gecko['push_url']   = 'https://push.geckoboard.com/v1/send/'
   ld_gecko['gecko_title'] = 'Sometitle'
   ld_gecko['chart_type'] = 'highchart'
   ld_gecko['legend_required'] = 0 # 0 or 1
   ld_gecko['chart_sub_type'] = '' ## can have values like areaspline, bar, line
   ld_gecko['gecko_sql']  = "select 'jan' x_data, 'NYC' y_category, 10 y_data union select 'jan' x_data, 'LA' y_category, 11 y_data union select 'jan' x_data, 'AZ' y_category, 21 y_data"
   #---gecko-o-meter 
   #ld_gecko['chart_type'] = 'gecko-o-meter'
   #ld_gecko['gecko_sql']  = "select 3 data, 1 min_data, 16 max_data,  14 goal_data"
   
   
   
   logger.log( "\n ld_results = %s \n" % ld_gecko)
   
   self._cursor.execute( ld_gecko['gecko_sql'])
   ld_rows = self._cursor.fetchall()
   
   #-- if there are no rows to process then just return
   if ld_rows == None or len(ld_rows) == 0:
    logger._logger.info(" No records to push to Geckoboard")       
   else:
    logger.log( "chart-type is %s" % ld_gecko['chart_type'])
    if ld_gecko['chart_type'] == 'highchart':

     self.push_highchart(pd_rows      =ld_rows, 
          p_url        =ld_gecko['push_url'], 
          p_title      =ld_gecko['gecko_title'], 
          p_axis_title ="some-title",
          p_type       =ld_gecko['chart_sub_type'], 
          p_legend     =ld_gecko['legend_required'])
    elif ld_gecko['chart_type'] == 'gecko-o-meter':

     self.push_gecko_o_meter( pd_rows =ld_rows, 
            p_url   =ld_gecko['push_url'], 
            p_title =ld_gecko['gecko_title'])

  except Exception as e:
   logger._logger.exception( "Exception when processing Gecko_id = %s", p_gecko_id)
   sys.exit()

#------------------------------------------------------------------------------------

Comments

Popular posts from this blog

Tableau - Accessing Tableau's DB

react-bootstrap-table | header column alignment fix

Tableau : Convert ESRI shapes into Tableau Format