Package: typhoon-web
================================================
    _____            _ 
   |_   _|   _ _ __ | |__  based on Tornado
     | || | | | '_ \| '_ \ / _ \ / _ \| '_ \ 
     | || |_| | |_) | | | | (_) | (_) | | | |
     |_| \__, | .__/|_| |_|\___/ \___/|_| |_|
         |___/|_|
================================================Typhoon is a wrapper around theTornadoweb framework. It offers the ability to attach log records with a trace id, which is used to trace individual HTTP requests. By default Typhoon obtains trace id from the request's headerX-TRACEID. To change this behavior, subclasstyphoon.web.Applicationand overwrite theget_trace_idmethod.Requirementstornado >= 5.1InstallationUse pip:pip install typhoon-web
pip install typhoon-web --upgradeClone repository and install with:python setup.py installHello, worldHere is a simple “Hello, world” example web app for Typhoon:importloggingimporttimeimporttornado.ioloopimporttyphoon.webimporttyphoon.logclassMainHandler(typhoon.web.RequestHandler):@typhoon.web.run_in_executordefprocess(self):logging.info('go to sleep')time.sleep(3)logging.info('wake up')return'Hello, world'asyncdefget(self):result=awaitself.process()self.write(result)# Native coroutine (using async def and await) was introduced in Python 3.5.# For previous version, use generator-based coroutine.# For example:## @tornado.gen.coroutine# def get(self):#     result = yield self.process()#     self.write(result)defmake_app():returntyphoon.web.Application([(r'/',MainHandler),])if__name__=='__main__':typhoon.log.configure(log_path='/home/logs')app=make_app()app.listen(8888)tornado.ioloop.IOLoop.current().start()In this example, three different log files will be generated in the log_path:access.logrecords summaries of each http request.stats.logrecords messages for statistics and analysis.app.logcontains all logs that are neither access logs nor stats logs.To log to stats.log, use an instance oftyphoon.log.StatsLogger:importtyphoon.logstats_log=typhoon.log.StatsLogger()stats_log.info({'user_count':100})stats_log.info({'job_register':20},topic='register')Notice that logging methods ofStatsLoggeronly accept adictobject as message.Trace idBy default trace id is automatically obtained and handled by Typhoon only when the client sends a request with a headerX-TRACEID: some-value:$curl-H"X-TRACEID: ceon1haa6cau1dung1"http://127.0.0.1:8888To customize the way trace id is passed, subclasstyphoon.web.Applicationand overwrite theget_trace_idmethod.importtyphoon.webclassMyApplication(typhoon.web.Application):defget_trace_id(self,handler):# obtain trace id from URL Parameter.returnhandler.get_argument('traceId','-')In the above example, trace id is passed through an URL parameter:$curlhttp://127.0.0.1:8888?traceId=ceon1haa6cau1dung1You may have to call another service and pass down the trace id. In this case, usetyphoon.log.TRACE_ID()to obtain current trace id:importrequestsimporttyphoon.webimporttyphoon.logclassMainHandler(typhoon.web.RequestHandler):@typhoon.web.run_in_executordefprocess(self):# call another service and pass down current trace id.r=request.get('http://127.0.0.1:9990/hello',header={'X-TRACEID':typhoon.log.TRACE_ID()})ifr.status_code==200:return'Hello, world'else:return'oops!'asyncdefget(self):result=awaitself.process()self.write(result)[new]High-Level APIFor those who are not familiar with Tornado, Typhoon provides high-level api since v1.0.2.NeitherRequestHandler, norApplication. Just subclasstyphoon.rest.RestControler, and decorated method withtyphoon.rest.routedecorator.Here is a “Hello, world” example.fromtyphoon.restimportRestController,RestResult,route,start_serverfromtyphoon.statusimportOKclassController(RestController):@route(uri=r'/hello',method='get')defgreet(self,user=None):ifuserisnotNone:content=f'Hello,{user}'else:content='Hello, world'returnRestResult(status=OK,content=content)if__name__=='__main__':start_server(controller=Controller(),port=8888)