python websocket client and with auth header

# import asyncio
import ssl
from socket import socket

import websocket
# import websockets

def on_message(ws, message):
    print ('message received ..')
    print (message)


def on_error(ws, error):
    print ('error happened .. ')
    print (error)


def on_close(ws):
    print ("### closed ###")


def on_open(ws):

    print ('Opening Websocket connection to the server ... ')

    ## This session_key I got, need to be passed over websocket header isntad of ws.send.
    ws.send("testing message here")

websocket.enableTrace(True)

token = "........"
auth = "Authorization: Bearer " + token
ws = websocket.WebSocketApp("wss://APISERVER:8443/api/v1/namespaces/default/services/the-service:8889/proxy/websocket?token=123",
                            on_open = on_open,
                            on_message = on_message,
                            on_error = on_error,
                            on_close = on_close,
                            header = [auth]
                            )

ws.on_open = on_open

##Note: this is for --insecure flag in curl, basically to tell the client not verify the ssl certificate
ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})
# socket.setsockopt

get those APIServer and token using

APISERVER=$(kubectl config view --minify | grep server | cut -f 2- -d ":" | tr -d " ")
SECRET_NAME=$(kubectl get secrets | grep ^default | cut -f1 -d ' ')
TOKEN=$(kubectl describe secret $SECRET_NAME | grep -E '^token' | cut -f2 -d':' | tr -d " ")

curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure

Start a websocket server with tornado

import tornado.ioloop
import tornado.web
import tornado.escape
import tornado.ioloop
import tornado.web
import tornado.websocket
import tornado.options
import time
import logging
import uuid
import sys,os
from tornado.options import define, options



class MainHandler(tornado.web.RequestHandler):
	def get(self):
		self.write("Hello, world")

def make_app():
	return tornado.web.Application([
		(r"/", MainHandler),
	])



define('port', default=8889, help="The tornado server port", type=int)


class WebSocketSever(tornado.websocket.WebSocketHandler):
	bao_cons = set()
	bao_waiters = {}
	global con_key
	global token

	# def initialize(self, my_object):
	# 	self.my_object = my_object

	def open(self):
		sole_id = str(uuid.uuid4()).upper()
		print(sole_id)
		self.con_key = sole_id
		self.token = self.get_argument("token")
		self.bao_waiters["{}".format(sole_id)] = self
		self.bao_cons.add(self)
		# self.write_message({"websocket_sole_id": sole_id})
		self.write_message({"token": self.token})
		logging.info("websocket opened!")
		print(self.bao_cons)

	def on_message(self, message):

		print(type(message))
		if message == "close":
			self.close()
			return
		try:
			parse_data = tornado.escape.json_decode(message)
			if parse_data["user"] and parse_data["content"]:
				user = parse_data["user"]
				content = parse_data["content"]
				if not user or not content:
					logging.info("Date is wrong!")
					return
				else:
					for key in self.bao_waiters.keys():
						if key == user:
							try:
								self.bao_waiters[key].write_message("{}".format(content))
							except Exception as e:
								logging.info(e)
							finally:
								logging.info("process finished!")
		except:
			for con in self.bao_cons:
				con.write_message(message)

	def check_origin(self, origin: str):
		return True

	def allow_draft76(self):
		return True

	def on_close(self):
		self.bao_cons.remove(self)
		# self.bao_waiters.pop(self.con_key)
		self.bao_waiters.pop(self.token)

		logging.info("websocket closed!")
		print(self.bao_cons)


class Application(tornado.web.Application):
	def __init__(self, handlers, setting):
		super(Application, self).__init__(handlers, **setting)


def main():
	options.parse_command_line()
	handlers = [
		(r"/websocket", WebSocketSever),
		(r"/http", MainHandler),
	            ]
	setting = dict(xsrf_cookies=False)
	app = Application(handlers, setting)
	print(options.port)

	app.listen(options.port)
	tornado.ioloop.IOLoop.current().start()


if __name__ == "__main__":
	# app = make_app()
	# app.listen(8889)
	# tornado.ioloop.IOLoop.current().start()
	main()

then to access the websocket server, for example, using javascript

var ws = new WebSocket("ws://127.0.0.1:8080/api/v1/namespaces/default/services/serices:8889/proxy/websocket?token=123");
ws.onopen = function() {
   ws.send("Hello, world");
};
ws.onmessage = function (evt) {
   alert(evt.data);
};

The craziness

def create_multipliers():
multipliers = []

for i in range(5):
def multiplier(x):
return i * x
multipliers.append(multiplier)

return multipliers

for multiplier in create_multipliers():
print(multiplier(2))

print(“=========================”)

def create_multipliers_lambda():
return [lambda x : i * x for i in range(5)]

for multiplier in create_multipliers_lambda():
print(multiplier(2))

print(“=========================”)

def create_multipliers_fix():
return [lambda x, i=i : i * x for i in range(5)]

for multiplier in create_multipliers_fix():
print(multiplier(2))
8
8
8
8
8
=========================
8
8
8
8
8
=========================
0
2
4
6
8

Java being the primary language

it’s not a perfect language, but it’s the one in the lead position and continuously approaching and being the most complete, feature rich and thoughtful language, suitable for most large entreprise grade build out and even with future support, expansion and scaling lookout in mind.

Screenshot 2019-10-24 at 10.50.34 PM

https://www.jetbrains.com/lp/devecosystem-2019/

a peek of python’s state

python is growing popular, personally, mainly due to it’s lower entry barrier. however, the lower entry is in existence partially due to it has historically (“not yet”) never been extremly cautiously designed.
while a lot mature languages has a big community/collective intelligence to form the princeples/guidance before the features/design/establish of implemetations, which secured a robust/stable/scablable language and ecosystem, python is not born nor in existance like that.

it’s easy to start with, but not equally means good to start building on. just a persoanl thought at the momoent.

a peek of the depency mangement state alone(with only two versions of the python at the moment):

python_environment

(i am happy to build on and with python, however, just 2 cents, it’s not yet ready for all entreprise.)

For a starter

convert number to English words

/**
  * @author lwpro
  * @since 10/17/2017
  * @version 1
  */
object NumberTranslator extends App {

  def translateSingle(num: Int): String = {
    num match {
      case 0 => "zero"
      case 1 => "one"
      case 2 => "two"
      case 3 => "three"
      case 4 => "four"
      case 5 => "five"
      case 6 => "six"
      case 7 => "seven"
      case 8 => "eight"
      case 9 => "nine"
    }
  }

    def translateDouble(num: Int): String = {

      num match {
        case 10 => "ten"
        case 11 => "elven"
        case 12 => "twelve"
        case 13 => "thirteen"
        case 14 => "fourteen"
        case 15 => "fifteen"
        case 16 => "sixteen"
        case 17 => "seventeen"
        case 18 => "eighteen"
        case 19 => "nineteen"
        case 20 => "twenty"
        case x if 21 until 30 contains x => "twenty " concat (translateSingle(x - 20))
        case 30 => "thirty"
        case x if 31 until 40 contains x => "thirty " concat (translateSingle(x - 30))
        case 40 => "forty"
        case x if 41 until 50 contains x => "forty " concat (translateSingle(x - 40))
        case 50 => "fifty"
        case x if 51 until 60 contains x => "fifty " concat (translateSingle(x - 50))
        case 60 => "sixty"
        case x if 61 until 70 contains x => "sixty " concat (translateSingle(x - 60))
        case 70 => "seventy"
        case x if 71 until 80 contains x => "seventy " concat (translateSingle(x - 70))
        case 80 => "eighty"
        case x if 81 until 90 contains x => "eightty " concat (translateSingle(x - 80))
        case 90 => "ninety"
        case x if 90 until 100 contains x => "ninety " concat (translateSingle(x - 90))
      }
    }


    def translateBlock(num: Int) = {
      num match {
        case x if 0 until 10 contains x => translateSingle(num)
        case x if 10 until 100 contains x => translateDouble(num)
        case x if (100 until 1000 contains x) && (x %100 == 0) => translateSingle(num / 100) concat " hundred"
        case x if x % 100 < 10 => translateSingle(num / 100) concat " hundred and " concat (translateSingle(num % 100) )
        case _ => translateSingle(num / 100) concat " hundred and " concat (translateDouble(num % 100) )
      }
    }

  for (i <- 0 until 1000)
    println( i.toString concat("::") concat translateBlock(i))


  def translateWhole (num: Int) = {
    num toString() length  match {
      case x if 0 until 3 contains x => translateBlock(num)
      case x if 4 until 6 contains x => translateBlock(num / 1000) concat("thousand and ") concat(translateBlock(num %1000))
      case x if 7 until 9 contains x => translateBlock(num / 1000000) concat("million and ") concat translateBlock(num % 1000 /1000) concat("thousand and ") concat(translateBlock(num %1000 /1000 % 1000))
    }
  }

  }


Another angle of view: imperative/procedural vs functional/declarative

quote
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/functional-programming-vs-imperative-programming
 

Transitioning for OOP Developers
In traditional object-oriented programming (OOP), most developers are accustomed to programming in the imperative/procedural style. To switch to developing in a pure functional style, they have to make a transition in their thinking and their approach to development.
To solve problems, OOP developers design class hierarchies, focus on proper encapsulation, and think in terms of class contracts. The behavior and state of object types are paramount, and language features, such as classes, interfaces, inheritance, and polymorphism, are provided to address these concerns.
In contrast, functional programming approaches computational problems as an exercise in the evaluation of pure functional transformations of data collections. Functional programming avoids state and mutable data, and instead emphasizes the application of functions.

AI for system support

Have tried to build an AI bot since almost 3 years back, finally did a prototype, in case anybody would like to do something similar:

Technologies:

Java, Spring Boot, Spring, SQLlite, PostGre, Scala, Python, Anaconda, Scikit Learn,  EWS, BootStrap, AngularJS/JQuery/HTML/CSS, Symphony API, Cisco API,

Components:

Data Set

  1. I have built a scala web crawler, to download all historical support issues.
  2. at the same time, have manually cleaned up/read through each of the thousand of support issues, put in corresponding resolutions corresponding to each
AI
  1. have leveraged on anaconda & scikit learn, to NLP, to tokenize each support issue (text), remove stop words, stemmed each, remove punctuations
  2. have leveraged on anaconda & scikit learn, bag each token of the text as feature vs class, to feed into linear regression classifier, tried SLDA, so far working at 72% accuracy
AI Exposer
  1. have exposed AI as a service
Issue Feeder
  1. have leveraged EWS to read in all issues, post to AI service
UI
  1. have built a web user interface, on top of HTML5 + JQuery + Bootstrap, to show the support emails + AI responded resolutions
  2. have a option on UI, to provide user feedback to AI, to keep its intelligence updated
Notifier
  1. leverage on Java Mail API, EWS, Chat API, phone API, to post alerts for critical issues

Datetime issue

The nasty datetime format issue seems like is universal. In c# world, depends on the locale, it would format to string and parse to datetime differently and could wrongly as well.

For example, for cultureinfo (“ja-JP”), datetime.tostring() could be yyyy/MM/d format which not recognized by a lot other systems or places.
While for same locale, it would parse 04Apr16 as 2004-04-16.

To solve and avoid the issues, invariantculture should be the cure. Always use invariantculture for parsing and for formating:
Datetime.parseExact(dateString, format, invariantculture).tostring(format, invariantculture).