-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.py
108 lines (85 loc) · 3.45 KB
/
server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import os.path
import time
from thrift.protocol import TJSONProtocol, TBinaryProtocol
from thrift.transport.TTransport import TTransportBase
from werkzeug.serving import run_simple
from werkzeug.wrappers import Request, Response
from api.test import BulletinBoard
from api.test.ttypes import Message, MessageExistsException
class Service(object):
_instance = None
def __init__(self, *args, **kwargs):
self.__class__._instance = self
@classmethod
def Get(cls, *args, **kwargs):
"""Service Factory that returns a singleton instance"""
if not cls._instance:
cls._instance = cls(*args, **kwargs)
return cls._instance
class BulletinBoardService(Service, BulletinBoard.Iface):
"""Implments the BulletinBoard Service"""
messages = []
def add(self, message):
time.sleep(10)
if message in self.messages:
raise MessageExistsException("This message exists")
self.messages.append(message)
def get(self):
return self.messages
class TIOStreamTransport(TTransportBase):
"""Creates a Thrift Transport from a stream-like object"""
def __init__(self, input_stream, output_stream):
self.input_stream = input_stream
self.output_stream = output_stream
def isOpen(self):
return True
def close(self):
pass
def read(self, sz):
s = self.input_stream.read(sz)
print s.encode('hex_codec'),
return s
def write(self, buf):
self.output_stream.write(buf)
def flush(self):
pass
class ThriftMiddleware(object):
"""Implements a WSGI middleware for handling Thrift services.
Initialize with a WSGI application (such as a Flask or Django app) and
a dict of Path -> Handler mappings. ThriftMiddleware will use the
content-type of the request to determine the thrift protocol
to use (ie. JSON or Binary).
"""
def __init__(self, app):
# TODO: implement a map of path to handler/processors
self.app = app
self.bb_handler = BulletinBoardService.Get()
self.bb_processor = BulletinBoard.Processor(self.bb_handler)
def __call__(self, environ, start_response):
path = environ.get('PATH_INFO') or '/'
method = environ.get('REQUEST_METHOD')
request = Request(environ)
response = Response()
if method == 'POST': # trap all post requests for example
content_type_header = request.headers.get('Content-Type')
if not content_type_header:
response.status_code = 405
return response(environ, start_response)
transport = TIOStreamTransport(request.stream, response.stream)
if 'application/x-thrift' in content_type_header:
protocol = TBinaryProtocol.TBinaryProtocol(transport)
elif 'application/json' in content_type_header:
protocol = TJSONProtocol.TJSONProtocol(transport)
else:
response.status_code = 405
return response(environ, start_response)
self.bb_processor.process(protocol, protocol)
return response(environ, start_response)
else:
return self.app(environ, start_response)
def test_app(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/plain')])
return ['Hello World!']
if __name__ == '__main__':
application = ThriftMiddleware(test_app)
run_simple('127.0.0.1', 5000, application)