blob: af8c6c52debc30a7cdfac7ead030fd2cd17b9ef1 [file] [log] [blame]
Zsolt Haraszti034db372016-10-03 22:26:41 -07001#!/usr/bin/env python
2#
3# Copyright 2016 the original author or authors.
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17
18import os
19
20from klein import Klein
21from simplejson import dumps, load
22from structlog import get_logger
23from twisted.internet import reactor, endpoints
24from twisted.internet.defer import inlineCallbacks, returnValue
25from twisted.internet.tcp import Port
26from twisted.web.server import Site
27from twisted.web.static import File
28
29log = get_logger()
30
Zsolt Haraszti034db372016-10-03 22:26:41 -070031
32class WebServer(object):
33
34 app = Klein()
35
36 def __init__(self, port, work_dir, grpc_client):
37 self.port = port
38 self.site = None
39 self.work_dir = work_dir
40 self.grpc_client = grpc_client
41
42 self.swagger_ui_root_dir = os.path.abspath(
43 os.path.join(os.path.dirname(__file__), '../swagger_ui'))
44
45 self.tcp_port = None
46
47 @inlineCallbacks
48 def run(self):
49 yield self._open_endpoint()
50 yield self._load_generated_routes()
51 returnValue(self)
52
53 def _load_generated_routes(self):
54 for fname in os.listdir(self.work_dir):
55 if fname.endswith('_gw.py'):
56 module_name = fname.replace('.py', '')
57 print 'module_name', module_name
58 m = __import__(module_name)
59 print dir(m)
60 assert hasattr(m, 'add_routes')
61 m.add_routes(self.app, self.grpc_client)
62
63 @inlineCallbacks
64 def _open_endpoint(self):
65 endpoint = endpoints.TCP4ServerEndpoint(reactor, self.port)
66 self.site = Site(self.app.resource())
67 self.tcp_port = yield endpoint.listen(self.site)
68 log.info('web-server-started', port=self.port)
69 self.endpoint = endpoint
70
71 @inlineCallbacks
72 def shutdown(self):
73 if self.tcp_porte is not None:
74 assert isinstance(self.tcp_port, Port)
75 yield self.tcp_port.socket.close()
76
77 # static swagger_ui website as landing page (for now)
78
79 @app.route('/', branch=True)
80 def static(self, request):
81 try:
82 log.debug(request=request)
83 return File(self.swagger_ui_root_dir)
84 except Exception, e:
85 log.exception('file-not-found', request=request)
86
87 # static swagger.json file to serve the schema
88
89 @app.route('/v1/swagger.json')
90 def swagger_json(self, request):
91 try:
92 return File(os.path.join(self.work_dir, 'swagger.json'))
93 except Exception, e:
94 log.exception('file-not-found', request=request)