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

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.