def test_procurementSecurity(self) -> None: """ Once a session is negotiated, it should be the identical object to avoid duplicate work - unless we are using forceInsecure to retrieve the insecure session from a secure request, in which case the result should not be cached. """ sessions = [] mss = MemorySessionStore() router = Klein() @router.route("/") @inlineCallbacks def route(request: IRequest) -> Deferred: sproc = SessionProcurer(mss) sessions.append((yield sproc.procureSession(request))) sessions.append((yield sproc.procureSession(request))) sessions.append((yield sproc.procureSession(request, forceInsecure=True))) returnValue(b"sessioned") treq = StubTreq(router.resource()) self.successResultOf(treq.get("http://unittest.example.com/")) self.assertIs(sessions[0], sessions[1]) self.assertIs(sessions[0], sessions[2]) self.successResultOf(treq.get("https://unittest.example.com/")) self.assertIs(sessions[3], sessions[4]) self.assertIsNot(sessions[3], sessions[5])
def test_resource(self, mock_kr): """ L{Klien.resource} returns a L{KleinResource}. """ app = Klein() resource = app.resource() mock_kr.assert_called_with(app) self.assertEqual(mock_kr.return_value, resource)
def test_resource(self, mock_kr): """ L{Klien.resource} returns a L{KleinResource}. """ app = Klein() resource = app.resource() mock_kr.assert_called_with(app) self.assertEqual(mock_kr.return_value, resource)
def simpleSessionRouter(): # type: () -> Tuple[sessions, errors, str, str, StubTreq] """ Construct a simple router. """ sessions = [] exceptions = [] mss = MemorySessionStore.fromAuthorizers([memoryAuthorizer]) router = Klein() token = "X-Test-Session-Token" cookie = "X-Test-Session-Cookie" sproc = SessionProcurer( mss, secureTokenHeader=b"X-Test-Session-Token", secureCookie=b"X-Test-Session-Cookie", ) @router.route("/") @inlineCallbacks def route(request): # type: (IRequest) -> Deferred try: sessions.append((yield sproc.procureSession(request))) except NoSuchSession as nss: exceptions.append(nss) returnValue(b"ok") requirer = Requirer() @requirer.prerequisite([ISession]) def procure(request): # type: (IRequest) -> Deferred return sproc.procureSession(request) @requirer.require(router.route("/test"), simple=Authorization(ISimpleTest)) def testRoute(simple): # type: (SimpleTest) -> str return "ok: " + str(simple.doTest() + 4) @requirer.require(router.route("/denied"), nope=Authorization(IDenyMe)) def testDenied(nope): # type: (IDenyMe) -> str return "bad" treq = StubTreq(router.resource()) return sessions, exceptions, token, cookie, treq
def webserver_for_test(test, url_path, response_content): """ Create a webserver that serves ``response_content`` from ``url_path``. """ app = Klein() @app.route(url_path) def _respond(request): return response_content factory = Site(app.resource()) endpoint = serverFromString(reactor, b"tcp:0") listening = endpoint.listen(factory) def stop_port(port): test.addCleanup(port.stopListening) return port listening.addCallback(stop_port) return listening
def test_cookiesTurnedOff(self) -> None: """ If cookies can't be set, then C{procureSession} raises L{NoSuchSession}. """ mss = MemorySessionStore() router = Klein() @router.route("/") @inlineCallbacks def route(request: IRequest) -> Deferred: sproc = SessionProcurer(mss, setCookieOnGET=False) with self.assertRaises(NoSuchSession): yield sproc.procureSession(request) returnValue(b"no session") treq = StubTreq(router.resource()) result = self.successResultOf(treq.get("http://unittest.example.com/")) self.assertEqual(self.successResultOf(result.content()), b"no session")
def webserver_for_test(test, url_path, response_content): """ Create a webserver that serves ``response_content`` from ``url_path``. """ app = Klein() @app.route(url_path) def _respond(request): return response_content factory = Site(app.resource()) endpoint = serverFromString(reactor, b"tcp:0") listening = endpoint.listen(factory) def stop_port(port): test.addCleanup(port.stopListening) return port listening.addCallback(stop_port) return listening
def test_procuredTooLate(self) -> None: """ If you start writing stuff to the response before procuring the session, when cookies need to be set, you will get a comprehensible error. """ mss = MemorySessionStore() router = Klein() @router.route("/") @inlineCallbacks def route(request: IRequest) -> Deferred: sproc = SessionProcurer(mss) request.write(b"oops...") with self.assertRaises(TooLateForCookies): yield sproc.procureSession(request) request.write(b"bye") request.finish() treq = StubTreq(router.resource()) result = self.successResultOf(treq.get("http://unittest.example.com/")) self.assertEqual(self.successResultOf(result.content()), b"oops...bye")
def main(reactor): component = Component( transports=u"ws://localhost:8080/ws", realm=u"crossbardemo", ) app = Klein() webapp = WebApplication(app, component) # have our Web site listen on 8090 site = Site(app.resource()) server_ep = TCP4ServerEndpoint(reactor, 8090) port = yield server_ep.listen(site) print("Web application on {}".format(port)) # we don't *have* to hand over control of the reactor to # component.run -- if we don't want to, we call .start() # The Deferred it returns fires when the component is "completed" # (or errbacks on any problems). comp_d = component.start(reactor) # When not using run() we also must start logging ourselves. import txaio txaio.start_logging(level='info') # If the Component raises an exception we want to exit. Note that # things like failing to connect will be swallowed by the # re-connection mechanisms already so won't reach here. def _failed(f): print("Component failed: {}".format(f)) done.errback(f) comp_d.addErrback(_failed) # wait forever (unless the Component raises an error) done = Deferred() yield done
def main(reactor): component = Component( transports=u"ws://localhost:8080/ws", realm=u"crossbardemo", ) app = Klein() webapp = WebApplication(app, component) # have our Web site listen on 8090 site = Site(app.resource()) server_ep = TCP4ServerEndpoint(reactor, 8090) port = yield server_ep.listen(site) print("Web application on {}".format(port)) # we don't *have* to hand over control of the reactor to # component.run -- if we don't want to, we call .start() # The Deferred it returns fires when the component is "completed" # (or errbacks on any problems). comp_d = component.start(reactor) # When not using run() we also must start logging ourselves. import txaio txaio.start_logging(level='info') # If the Component raises an exception we want to exit. Note that # things like failing to connect will be swallowed by the # re-connection mechanisms already so won't reach here. def _failed(f): print("Component failed: {}".format(f)) done.errback(f) comp_d.addErrback(_failed) # wait forever (unless the Component raises an error) done = Deferred() yield done
if capability_hash is not None: capability_url = append_segments(get_url_root(), api, "execute", capability_version, capability_hash, '') links.append({"href": capability_url, "rel": "capability"}) return links else: return url def transaction_id(request): """ Extract the transaction id from the given request. :param IRequest request: The request we are trying to get the transaction id for. :returns: A string transaction id. """ return request.responseHeaders.getRawHeaders('X-Response-Id')[0] app = Klein() app.route = partial(app.route, strict_slashes=False) root = Resource() root.putChild('v1.0', app.resource()) root.putChild('', Data('', 'text/plain'))
class PlatingTests(TestCase): """ Tests for L{Plating}. """ def setUp(self): """ Create an app and a resource wrapping that app for this test. """ self.app = Klein() self.kr = self.app.resource() def get(self, uri): """ Issue a virtual GET request to the given path that is expected to succeed synchronously, and return the generated request object and written bytes. """ request = requestMock(uri) d = _render(self.kr, request) self.successResultOf(d) return request, request.getWrittenData() def test_template_html(self): """ Rendering a L{Plating.routed} decorated route results in templated HTML. """ @page.routed(self.app.route("/"), tags.span(slot("ok"))) def plateMe(request): return {"ok": "test-data-present"} request, written = self.get(b"/") self.assertIn(b'<span>test-data-present</span>', written) self.assertIn(b'<title>default title unchanged</title>', written) def test_template_json(self): """ Rendering a L{Plating.routed} decorated route with a query parameter asking for JSON will yield JSON instead. """ @page.routed(self.app.route("/"), tags.span(slot("ok"))) def plateMe(request): return {"ok": "an-plating-test"} request, written = self.get(b"/?json=true") self.assertEqual( request.responseHeaders.getRawHeaders(b'content-type')[0], b'text/json; charset=utf-8' ) self.assertEquals({"ok": "an-plating-test", "title": "default title unchanged"}, json.loads(written.decode('utf-8'))) def test_template_numbers(self): """ Data returned from a plated method may include numeric types (integers, floats, and possibly longs), which although they are not normally serializable by twisted.web.template, will be converted by plating into their decimal representation. """ @page.routed(self.app.route("/"), tags.div(tags.span(slot("anInteger")), tags.i(slot("anFloat")), tags.b(slot("anLong")), )) def plateMe(result): return {"anInteger": 7, "anFloat": 3.2, "anLong": 0x10000000000000001} request, written = self.get(b"/") self.assertIn(b"<span>7</span>", written) self.assertIn(b"<i>3.2</i>", written) self.assertIn(b"<b>18446744073709551617</b>", written) def test_render_list(self): """ The C{:list} renderer suffix will render the slot named by the renderer as a list, filling each slot. """ @page.routed(self.app.route("/"), tags.ul(tags.li(slot("item"), render="subplating:list"))) def rsrc(request): return {"subplating": [1, 2, 3]} request, written = self.get(b"/") self.assertIn(b'<ul><li>1</li><li>2</li><li>3</li></ul>', written) self.assertIn(b'<title>default title unchanged</title>', written) def test_widget_html(self): """ When L{Plating.widgeted} is applied as a decorator, it gives the decorated function a C{widget} attribute which is a version of the function with a modified return type that turns it into a renderable HTML sub-element that may fill a slot. """ @page.routed(self.app.route("/"), tags.div(slot("widget"))) def rsrc(request): return {"widget": enwidget.widget(3, 4)} request, written = self.get(b"/") self.assertIn(b"<span>a: 3</span>", written) self.assertIn(b"<span>b: 4</span>", written) def test_widget_json(self): """ When L{Plating.widgeted} is applied as a decorator, and the result is serialized to JSON, it appears the same as the returned value despite the HTML-friendly wrapping described above. """ @page.routed(self.app.route("/"), tags.div(slot("widget"))) def rsrc(request): return {"widget": enwidget.widget(3, 4)} request, written = self.get(b"/?json=1") self.assertEqual(json.loads(written.decode('utf-8')), {"widget": {"a": 3, "b": 4}, "title": "default title unchanged"}) def test_prime_directive_return(self): """ Nothing within these Articles Of Federation shall authorize the United Federation of Planets to alter the return value of a callable by applying a decorator to it... """ exact_result = {"ok": "some nonsense value"} @page.routed(self.app.route("/"), tags.span(slot("ok"))) def plateMe(request): return exact_result self.assertIdentical(plateMe(None), exact_result) def test_prime_directive_arguments(self): """ ... or shall require the function to modify its signature under these Articles Of Federation. """ @page.routed(self.app.route("/"), tags.span(slot("ok"))) def plateMe(request, one, two, three): return (one, two, three) exact_one = {"one": "and"} exact_two = {"two": "and"} exact_three = {"three": "and"} result_one, result_two, result_three = plateMe( None, exact_one, exact_two, three=exact_three ) self.assertIdentical(result_one, exact_one) self.assertIdentical(result_two, exact_two) self.assertIdentical(result_three, exact_three) def test_presentation_only_json(self): """ Slots marked as "presentation only" will not be reflected in the output. """ plating = Plating(tags=tags.span(slot("title")), presentation_slots={"title"}) @plating.routed(self.app.route("/"), tags.span(slot("data"))) def justJson(request): return {"title": "uninteresting", "data": "interesting"} request, written = self.get(b"/?json=1") self.assertEqual(json.loads(written.decode("utf-8")), {"data": "interesting"}) def test_missing_renderer(self): """ Missing renderers will result in an exception during rendering. """ def test(missing): plating = Plating(tags=tags.span(slot(Plating.CONTENT))) @plating.routed(self.app.route("/"), tags.span(tags.span(render=missing))) def no(request): return {} self.get(b"/") [fe] = self.flushLoggedErrors(FlattenerError) self.assertIsInstance(fe.value.args[0], MissingRenderMethod) test("garbage") test("garbage:missing") def test_json_serialize_unknown_type(self): """ The JSON serializer will raise a L{TypeError} when it can't find an appropriate type. """ from klein._plating import json_serialize class reprish(object): def __repr__(self): return '<blub>' te = self.assertRaises(TypeError, json_serialize, {"an": reprish()}) self.assertIn("<blub>", str(te))
api, "execute", capability_version, capability_hash, '') links.append({"href": capability_url, "rel": "capability"}) return links else: return url def transaction_id(request): """ Extract the transaction id from the given request. :param IRequest request: The request we are trying to get the transaction id for. :returns: A string transaction id. """ return request.responseHeaders.getRawHeaders('X-Response-Id')[0] app = Klein() app.route = partial(app.route, strict_slashes=False) root = Resource() root.putChild('v1.0', app.resource()) root.putChild('', Data('', 'text/plain'))
@app.route("/bot/start", methods=['POST']) def bot_start(request): body = json.loads(request.content.read()) world[body['u_id']] = world['base'].clone() world[body['u_id']].set_agents( [base_agents[0].clone(), base_agents[1].clone()]) # world.new_user(body['u_id']) pprint(world) return body['u_id'] world = {} world['base'] = Interactive.main( # world = Interactive.main( model_file='zoo:blender/blender_90M/model', # single_turn=True, ) base_agents = world['base'].get_agents() reactor.suggestThreadPoolSize(20) # this way reactor logs only print calls web_server = endpoints.serverFromString(reactor, "tcp:8999") web_server.listen(Site(app.resource())) reactor.run() # python ../../second_pjt/pythonProject/main.py
class WebInterface(YomboLibrary, FrontendMixin, LoadRoutesMixin, RenderMixin, WebServerMixin): """ Web interface framework. """ starting: ClassVar[bool] = True already_starting_web_servers: ClassVar[bool] = False hook_listeners: ClassVar[dict] = { } # special way to toss hook calls to routes. generic_router_list: ClassVar[dict] = {"libraries": {}, "modules": {}} @inlineCallbacks def _init_(self, **kwargs): setup_webinterface_reference( self) # Sets a reference to this library in auth.py self.webapp = Klein() self.webapp.webinterface = self self.api_key = self._Configs.get("frontend.api_key", random_string(length=75)) self.frontend_building: bool = False self.web_interface_fully_started: bool = False self.enabled = self._Configs.get("webinterface.enabled", True) self.fqdn = self._Configs.get("dns.fqdn", None, False, instance=True) self.enabled = self._Configs.get("core.enabled", True) if not self.enabled: return self.file_cache = ExpiringDict( max_len=100, max_age_seconds=120 ) # used to load a few static files into memory that are commonly used. self.translators = {} self.idempotence = self._Cache.ttl(name="lib.webinterface.idempotence", ttl=300) self.wi_dir = "/lib/webinterface" self.misc_wi_data = {} self.wi_port_nonsecure = self._Configs.get( "webinterface.nonsecure_port", 8080, instance=True) self.wi_port_secure = self._Configs.get("webinterface.secure_port", 8443, instance=True) self.webapp.templates = jinja2.Environment( loader=jinja2.FileSystemLoader(f"{self._app_dir}/yombo"), extensions=["jinja2.ext.loopcontrols"]) self.setup_basic_filters() self.web_interface_listener = None self.web_interface_ssl_listener = None self.api_stream_spectators = { } # Tracks all the spectators connected. An alternative to MQTT listening. if self._Configs.get("webinterface.enable_default_routes", default=True, create=False): yield self.webinterface_load_routes() # Loads all the routes. self.npm_build_results = None self.temp_data = ExpiringDict(max_age_seconds=1800) self.web_server_started = False self.web_server_ssl_started = False self.setup_wizard_map_js = None self.web_factory = None self.user_login_tokens = self._Cache.ttl(name="lib.users.cache", ttl=300) @property def operating_mode(self): return self._Loader.operating_mode @inlineCallbacks def _load_(self, **kwargs): if not self.enabled: return yield self._Notifications.new( notice_id="webinterface:starting", title="System still starting", message="Still starting up. Please wait.", request_context=self._FullName, priority="high", always_show=True, always_show_allow_clear=False) if self._Configs.get("webinterface.enable_frontend", True, False): self.build_dist() # Makes the Vue application frontend. self.module_config_links = {} # self.web_factory = YomboSite(self.webapp.resource(), None, logPath="/dev/null") self.web_factory = YomboSite(self, self.webapp.resource(), None, logPath=None) self.web_factory.noisy = False # turn off Starting/stopping message self.displayTracebacks = False self._display_how_to_access_at = 0 # When the display notice for how to access the web was shown. self.misc_wi_data["gateway_label"] = self._Configs.get("core.label", "Yombo Gateway", False, instance=True) self.misc_wi_data["operating_mode"] = self._Loader.operating_mode self.misc_wi_data["notifications"] = self._Notifications self.misc_wi_data[ "notification_priority_map_css"] = NOTIFICATION_PRIORITY_MAP_CSS self.misc_wi_data["breadcrumb"] = [] self.webapp.templates.globals["yombo"] = self self.webapp.templates.globals["_local_gateway"] = self._Gateways.local self.webapp.templates.globals["py_time"] = time self.webapp.templates.globals["misc_wi_data"] = self.misc_wi_data self.webapp.templates.globals["webinterface"] = self self.webapp.templates.globals["bg_image_id"] = lambda: int(time( ) / 300) % 6 # Used to select a background. # self.webapp.templates.globals["get_alerts"] = self.get_alerts self._refresh_jinja2_globals_() self.starting = False yield self.start_web_servers() self.clean_idempotence_ids_loop = LoopingCall( self.clean_idempotence_ids) self.clean_idempotence_ids_loop.start(1806, False) def _refresh_jinja2_globals_(self, **kwargs): """ Update various globals for the Jinja2 template. :return: """ if self._Loader.operating_mode != "run": return self.webapp.templates.globals[ "_location_id"] = self._Locations.location_id self.webapp.templates.globals["_area_id"] = self._Locations.area_id self.webapp.templates.globals["_location"] = self._Locations.location self.webapp.templates.globals["_area"] = self._Locations.area @inlineCallbacks def _start_(self, **kwargs): self.webapp.templates.globals["_"] = _ # i18n if self._gateway_id == "local": results = yield self._Requests.request("get", "https://yg2.in/9id39") self.setup_wizard_map_js = results.content.strip() def _started_(self, **kwargs): """ Perform a couple of small tasks after everything has started. """ self.web_interface_fully_started = True self.display_how_to_access() self._Notifications.delete("webinterface:starting") self.send_hook_listeners_ping_loop = LoopingCall( self.send_hook_listeners_ping_loop) self.send_hook_listeners_ping_loop.start(55, True) @inlineCallbacks def _unload_(self, **kwargs): if hasattr(self, "web_factory"): if self.web_factory is not None: yield self.web_factory.save_log_queue() def clean_idempotence_ids(self): """ Removes older idempotence keys. :return: """ delete_time = int(time()) - 1800 for key in self.idempotence.keys(): if self.idempotence[key] < delete_time: del self.idempotence[key] def send_hook_listeners_ping_loop(self): web_broadcast(self, "ping", int(time())) def register_hook(self, name, thecallback): if name not in self.hook_listeners: self.hook_listeners[name] = [] self.hook_listeners[name].append(thecallback) @inlineCallbacks def _yombo_universal_hook_(self, hook_name=None, **kwargs): """ Implements the universal hook. :param kwargs: :return: """ if hook_name in self.hook_listeners: for a_callback in self.hook_listeners[hook_name]: d = Deferred() d.addCallback(lambda ignored: maybeDeferred( a_callback, self, hook_name=hook_name, **kwargs)) d.addErrback(self.yombo_universal_hook_failure, hook_name, a_callback) d.callback(1) yield d def yombo_universal_hook_failure(self, failure, hook_name, acallback): logger.warn( "---==(failure WI:universal hook for hook ({hook_name})==----", hook_name=hook_name) logger.warn("--------------------------------------------------------") logger.warn("{acallback}", acallback=acallback) logger.warn("{failure}", failure=failure) logger.warn("--------------------------------------------------------") raise RuntimeError(f"failure during module invoke for hook: {failure}") def check_have_required_nodes(self): try: node = yield self._Nodes.get("main_page", "webinterface_page") except KeyError as e: pass # add base node... def _configs_set_(self, arguments, **kwargs): """ Need to monitor if the web interface port has changed. This will restart the webinterface server if needed. :param arguments: section, option(key), value :return: """ section = arguments["section"] option = arguments["option"] value = arguments["value"] if self.starting is True: return if section == "webinterface": if option == "nonsecure_port": self.change_ports(port_nonsecure=value) elif option == "secure_port": self.change_ports(port_secure=value) @property def internal_url(self): """ Returns the starting portion of the URL to this host. https://i.exmaple.yombo.net :return: """ if self.fqdn.value is None: internal_hostname = self._Configs.get( "networking.localipaddress.v4") return f"http://{internal_hostname}:{self.wi_port_nonsecure.value}" else: return f"https://i.{self.fqdn.value}:{self.wi_port_secure.value}" @property def external_url(self): """ Returns the starting portion of the URL to this host. https://e.exmaple.yombo.net :return: """ if self.fqdn.value is None: external_hostname = self._Configs.get( "networking.externalipaddress.v4") return f"https://{external_hostname}:{self.wi_port_secure.value}" else: return f"https://e.{self.fqdn.value}:{self.wi_port_secure.value}" def add_alert(self, session, message, level="info", display_once=True, deletable=True, id=None): """ Add an alert to the stack. :param level: info, warning, error :param message: :return: """ id = session.add_alert(message, level, display_once, deletable, id) return id def get_alerts(self, session, autodelete=None): """ Retrieve a list of alerts for display. """ if session is None: return {} return session.get_alerts(autodelete) def redirect(self, request, redirect_path): return request.redirect(redirect_path) def _get_parms(self, request): return parse_qs(urlparse(request.uri).query) def request_get_default(self, request, name, default, offset=None): if offset == None: offset = 0 try: return request.args.get(name)[offset] except: return default def home_breadcrumb(self, request): self.add_breadcrumb(request, "/", "Home") def add_breadcrumb(self, request, url=None, text=None, show=None, style=None, data=None): if hasattr(request, "breadcrumb") is False: request.breadcrumb = [] self.misc_wi_data["breadcrumb"] = request.breadcrumb if show is None: show = True if style is None: style = "link" elif style == "select_groups": items = {} for option_label, option_data in data.items(): items[option_label] = [] for select_text, select_url in option_data.items(): selected = "" option_style = "None" if select_url.startswith("$"): selected = "selected" select_url = select_url[1:] elif select_url.startswith("#"): option_style = "divider" items[option_label].append({ "option_style": option_style, "text": select_text, "url": select_url, "selected": selected, }) data = items elif style == "select": items = [] for select_text, select_url in data.items(): selected = "" option_style = "None" if select_url.startswith("$"): selected = "selected" select_url = select_url[1:] elif select_url.startswith("#"): option_style = "divider" items.append({ "option_style": option_style, "text": select_text, "url": select_url, "selected": selected, }) data = items hash = sha256( str( str(url) + str(text) + str(show) + str(style) + json.dumps(data)).encode()).hexdigest() breadcrumb = { "hash": hash, "url": url, "text": text, "show": show, "style": style, "data": data, } request.breadcrumb.append(breadcrumb) def setup_basic_filters(self): self.webapp.templates.filters["yes_no"] = yombo.utils.is_yes_no self.webapp.templates.filters["true_false"] = yombo.utils.is_true_false self.webapp.templates.filters["excerpt"] = yombo.utils.excerpt self.webapp.templates.filters["make_link"] = yombo.utils.make_link self.webapp.templates.filters[ "status_to_string"] = converters.status_to_string self.webapp.templates.filters[ "public_to_string"] = converters.public_to_string self.webapp.templates.filters[ "epoch_to_string"] = converters.epoch_to_string self.webapp.templates.filters[ "epoch_get_age"] = dt_util.get_age # yesterday, 5 minutes ago, etc. self.webapp.templates.filters[ "epoch_get_age_exact"] = dt_util.get_age_exact # yesterday, 5 minutes ago, etc. self.webapp.templates.filters[ "format_markdown"] = yombo.utils.format_markdown self.webapp.templates.filters[ "hide_none"] = yombo.utils.display_hide_none self.webapp.templates.filters[ "display_temperature"] = self._Localize.display_temperature self.webapp.templates.filters["yombo"] = self def restart(self, request, message=None, redirect=None): """ Restart the gateway. Called by various routes that need to restart the gateway. This will return the restarting html with message and redirect to injected into it. :param request: :param message: :param redirect: :return: """ if message is None: message = "" if redirect is None: redirect = "/" def do_restart(): try: raise YomboRestart("Web Interface setup wizard complete.") except: pass reactor.callLater(0.3, do_restart) return self.render_template( request, self.wi_dir + "/pages/misc/restarting.html", message=message, redirect=redirect, ) def shutdown(self, request, message=None, redirect=None): """ Shutdown the gateway. Called by various routes that need to shutdownthe gateway. This will return the shutting down html with the optional message injected into it. :param request: :param message: :param redirect: :return: """ def do_shutdown(): raise YomboQuit("Requested gateway shutdown from webinterface.") reactor.callLater(0.3, do_shutdown) return self.render_template( request, self.wi_dir + "/pages/misc/shutting_down.html")
"Processed cache on server start in %s seconds. " % round(time.time() - start_time)) if configuration["ENABLE_HTTPS"] == "Y": endpoint_description = ( "ssl:" + str(configuration["DASHBOARD_WEB_PORT"]) + ":interface=" + configuration["NETWORK_INTERFACE"] + ":privateKey=" + configuration["PRIVATE_KEY"]) else: endpoint_description = ( "tcp:port=" + str(configuration["DASHBOARD_WEB_PORT"]) + ":interface=" + configuration["NETWORK_INTERFACE"]) endpoint = endpoints.serverFromString(reactor, endpoint_description) endpoint.listen(Site(nserv.resource())) syslog_cache_processor_task = task.LoopingCall( syslog_cache_processor, redis_syslog_cache, redis_main_db) main_server_processor_loop = syslog_cache_processor_task.start( configuration["SYSLOG_CACHE_PROCESS_INTERVAL"]) main_server_processor_loop.addErrback(main_server_loop_failed) # reactor.suggestThreadPoolSize(30) reactor.run() except (IOError, SystemExit): raise
class Master: def __init__(self): self.config_path: str = '' self.main_path: str = '' self.root: Union[PBRoot, None] = None self.web_root: Union[Klein, None] = None def config(self, config_path: str, main_path: str) -> None: """ :param config_path: :param main_path: :return: """ self.config_path = config_path self.main_path = main_path def master_app(self): with open(self.config_path, 'r') as f: GO.json_config = config = json.loads(f.read()) # config master_cnf = config.get('master') root_port = master_cnf.get('root_port') web_port = master_cnf.get('web_port') master_log = master_cnf.get('log') self.root = PBRoot() root_service = services.Service("root_service") self.root.add_service_channel(root_service) GO.root = self.root # import learn_twist.master.rootapp self.web_root = Klein() GO.web_root = self.web_root # import learn_twist.master.webapp if master_log: log.addObserver(LogObj(master_log)) log.startLogging(sys.stdout) reactor.listenTCP(web_port, DelaySite(self.web_root.resource())) reactor.listenTCP(root_port, BilateralFactory(self.root)) def start(self): sys_args = sys.argv if len(sys_args) > 2 and sys_args[1] == "single": server_name = sys_args[2] if server_name == "master": mode = MASTER_SERVER_MODE else: mode = SINGLE_SERVER_MODE else: mode = MULTI_SERVER_MODE server_name = "" if mode == MULTI_SERVER_MODE: self.master_app() with open(self.config_path, 'r') as f: config = json.loads(f.read()) servers_conf = config.get('servers') log.msg(servers_conf) for server_name in servers_conf.keys(): cmd = 'python %s %s %s' % (self.main_path, server_name, self.config_path) log.msg('cmd:', cmd) subprocess.Popen(cmd, shell=True) reactor.run() elif mode == SINGLE_SERVER_MODE: sername = server_name cmds = 'python %s %s %s' % (self.main_path, sername, self.config_path) subprocess.Popen(cmds, shell=True) else: self.master_app() reactor.run()
## See the License for the specific language governing permissions and ## limitations under the License. ## ############################################################################### from twisted.internet.defer import inlineCallbacks, returnValue from klein import Klein from autobahn.twisted.wamp import Application app = Klein() wampapp = Application() @app.route('/square/submit', methods=['POST']) @inlineCallbacks def square_submit(request): x = int(request.args.get('x', [0])[0]) res = yield wampapp.session.call('com.example.square', x) returnValue("{} squared is {}".format(x, res)) if __name__ == "__main__": import sys from twisted.python import log from twisted.web.server import Site from twisted.internet import reactor log.startLogging(sys.stdout) reactor.listenTCP(8080, Site(app.resource())) wampapp.run("ws://localhost:9000", "realm1", standalone=False)
print("unlock: %s" % (imei, )) dev = devices.get(imei) if dev is None: raise NotFound() request.setHeader('Content-Type', 'application/json') dev.sendUnlock() # FIXME: async, get confirmation from lock data = {"success": True, "status": "pending"} print(jsons.dumps(data)) return jsons.dumps(data) @http.route('/<imei>') def lock(request, imei): dev = devices.get(imei) if dev is None: raise NotFound() return 'Hi %s!' % (imei, ) bl10endpoint = endpoints.TCP4ServerEndpoint(reactor, LOCK_PORT, interface=LOCK_HOST) bl10endpoint.listen(BL10Factory()) print("Listening for Lock Traffic on %s:%d" % (LOCK_HOST, LOCK_PORT)) httpendpoint = endpoints.TCP4ServerEndpoint(reactor, PORT, interface=HOST) httpendpoint.listen(Site(http.resource())) print("Listening for HTTP on %s:%d" % (HOST, PORT)) reactor.run()
def main(reactor): # Because we're using a self-signed certificate, we need to tell Twisted # that it is OK to trust it. cert_fname = (".crossbar/server_cert.pem") cert = crypto.load_certificate(crypto.FILETYPE_PEM, six.u(open(cert_fname, 'r').read())) opt = ssl.CertificateOptions(\ trustRoot=OpenSSLCertificateAuthorities([cert])) # Set up our sisock component. component = Component( transports=[{ u"type": u"websocket", u"url": sisock.base.WAMP_URI, u"endpoint": { u"type": u"tcp", u"host": sisock.base.SISOCK_HOST, u"port": sisock.base.SISOCK_PORT, u"tls": opt } }], authentication={ u"wampcra": { u"authid": u"simonsobs", u"secret": u"yW4V2T^bPD&rGFwy" } }, realm=sisock.base.REALM, ) # Create our klein webserver, and then our datasource (which also connects # our component to the WAMP server). app = Klein() GrafanaSisockDatasrc(app, component) # Have our webserver listen for Grafana requests. # TODO: use SSL and authentication. site = Site(app.resource()) #server_ep = SSL4ServerEndpoint(reactor, klein_port, opt) server_ep = TCP4ServerEndpoint(reactor, klein_port) port = yield server_ep.listen(site) print("Web application on {}".format(port)) # We don't *have* to hand over control of the reactor to # component.run -- if we don't want to, we call .start() # The Deferred it returns fires when the component is "completed" # (or errbacks on any problems). comp_d = component.start(reactor) # When not using run() we also must start logging ourselves. txaio.start_logging(level=environ.get("LOGLEVEL", "info")) # If the Component raises an exception we want to exit. Note that # things like failing to connect will be swallowed by the # re-connection mechanisms already so won't reach here. def _failed(f): print("Component failed: {}".format(f)) done.errback(f) comp_d.addErrback(_failed) # Wait forever (unless the Component raises an error). done = Deferred() yield done
# coding=utf-8 import os from klein import Klein from twisted.internet import reactor from twisted.web.resource import Resource, ForbiddenResource from twisted.web.server import Site from twisted.web.static import File from server.app import App class FileNoDir(File): def directoryListing(self): return ForbiddenResource() if __name__ == '__main__': client_side_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'client_side')) server = Klein() app = App(server, client_side_dir) root = server.resource() site = Site(root) """ root.putChild("static", FileNoDir(os.path.join(client_side_dir, 'static'))) root.putChild("app", FileNoDir(os.path.join(client_side_dir, 'app'))) root.putChild("", File(os.path.join(client_side_dir, 'templates', 'index.html'))) root.putChild("templates", File(os.path.join(client_side_dir, 'templates'))) """ reactor.listenTCP(8888, site) reactor.run()
webapp.visits += 1 wampapp.session.publish(u'com.example.onvisit', visits=webapp.visits) page = webapp.templates.get_template('index.html') return page.render(visits=webapp.visits) @webapp.route('/square/<int:x>') @inlineCallbacks def square(request, x): result = yield wampapp.session.call(u'com.example.square', x) page = webapp.templates.get_template('result.html') content = page.render(x=x, result=result) returnValue(content) @webapp.route('/square/submit', methods=['POST']) def square_submit(request): x = int(request.args.get('x', [0])[0]) return square(request, x) if __name__ == "__main__": import sys from twisted.python import log from twisted.web.server import Site from twisted.internet import reactor log.startLogging(sys.stdout) reactor.listenTCP(8080, Site(webapp.resource())) wampapp.run(u"ws://127.0.0.1:9000", u"realm1", standalone=True)
webapp = Klein() @webapp.route('/', methods=['POST']) def index(request: Request): content = json.loads(request.content.read()) try: new_state = GameState(**content) except Exception as e: print(content) print(e) return "wew" wamp_component.state = new_state print(wamp_component.state.map.game_state) return "ok" if __name__ == "__main__": from twisted.web.server import Site from twisted.internet import reactor, task import sys print(sys.path) reactor.listenTCP(8016, Site(webapp.resource())) run([wamp_component])
action="store", help="Config file (default. %s)" % PROTOCOL_CONFIG, default=PROTOCOL_CONFIG) args = parser.parse_args() settings.setup(args.config) logger.info("Starting api.py") logger.debug("Config: %s", args.config) logger.debug("Network: %s", settings.net_name) # Enable Twisted logging (see also http://twistedmatrix.com/documents/12.0.0/core/howto/logging.html) log.startLogging(sys.stdout) # # Get the blockchain up and running # blockchain = LevelDBBlockchain(settings.LEVELDB_PATH) # Blockchain.RegisterBlockchain(blockchain) # reactor.suggestThreadPoolSize(15) # NodeLeader.Instance().Start() # dbloop = task.LoopingCall(Blockchain.Default().PersistBlocks) # dbloop.start(.1) # Blockchain.Default().PersistBlocks() # Hook up Klein API to Twisted reactor endpoint_description = "tcp:port=%s:interface=localhost" % API_PORT endpoint = endpoints.serverFromString(reactor, endpoint_description) endpoint.listen(Site(app.resource())) reactor.run()
else: self.message('NONE') elif command == 'ZAP': pos0,_ = self.currentState() if self.ammo == 0: self. message('NO AMMO') else: self.ammo -= 1 for client in self.factory.arena.bots.store: if client == self or client is None: continue pos1,_ = client.currentState() dist = numpy.sqrt(numpy.dot(pos1-pos0,pos1-pos0)) if dist <= 0.05: client.battery -= 1.0 elif dist <= 0.1: client.battery -= (0.1 - dist) * 20 client.checkBattery() self.message('OK') elif command == 'BYE': self.leave() else: raise Exception('Not understood') except Exception as e: g_trace.debug(self.ip + ':' + self.port + ' | ' + self.name + ' | error: ' + str(e)) self.message('NOT UNDERSTOOD') def message(self, message): self.transport.write(message.encode('ascii') + b'\r\n') factory = protocol.ServerFactory() factory.protocol = Bot factory.arena = Arena(len(colours)) endpoints.serverFromString(reactor, "tcp:8000").listen(Site(app.resource())) reactor.listenTCP(8888,factory) reactor.run()
class PlatingTests(TestCase): """ Tests for L{Plating}. """ def setUp(self): """ Create an app and a resource wrapping that app for this test. """ self.app = Klein() self.kr = self.app.resource() def get(self, uri): """ Issue a virtual GET request to the given path that is expected to succeed synchronously, and return the generated request object and written bytes. """ request = requestMock(uri) d = _render(self.kr, request) self.successResultOf(d) return request, request.getWrittenData() def test_template_html(self): """ Rendering a L{Plating.routed} decorated route results in templated HTML. """ @page.routed(self.app.route("/"), tags.span(slot("ok"))) def plateMe(request): return {"ok": "test-data-present"} request, written = self.get(b"/") self.assertIn(b'<span>test-data-present</span>', written) self.assertIn(b'<title>default title unchanged</title>', written) def test_template_json(self): """ Rendering a L{Plating.routed} decorated route with a query parameter asking for JSON will yield JSON instead. """ @page.routed(self.app.route("/"), tags.span(slot("ok"))) def plateMe(request): return {"ok": "an-plating-test"} request, written = self.get(b"/?json=true") self.assertEqual( request.responseHeaders.getRawHeaders(b'content-type')[0], b'text/json; charset=utf-8') self.assertEquals( { "ok": "an-plating-test", "title": "default title unchanged" }, json.loads(written.decode('utf-8'))) def test_template_numbers(self): """ Data returned from a plated method may include numeric types (integers, floats, and possibly longs), which although they are not normally serializable by twisted.web.template, will be converted by plating into their decimal representation. """ @page.routed(self.app.route("/"), tags.div( tags.span(slot("anInteger")), tags.i(slot("anFloat")), tags.b(slot("anLong")), )) def plateMe(result): return { "anInteger": 7, "anFloat": 3.2, "anLong": 0x10000000000000001 } request, written = self.get(b"/") self.assertIn(b"<span>7</span>", written) self.assertIn(b"<i>3.2</i>", written) self.assertIn(b"<b>18446744073709551617</b>", written) def test_render_list(self): """ The C{:list} renderer suffix will render the slot named by the renderer as a list, filling each slot. """ @page.routed(self.app.route("/"), tags.ul(tags.li(slot("item"), render="subplating:list"))) def rsrc(request): return {"subplating": [1, 2, 3]} request, written = self.get(b"/") self.assertIn(b'<ul><li>1</li><li>2</li><li>3</li></ul>', written) self.assertIn(b'<title>default title unchanged</title>', written) def test_widget_html(self): """ When L{Plating.widgeted} is applied as a decorator, it gives the decorated function a C{widget} attribute which is a version of the function with a modified return type that turns it into a renderable HTML sub-element that may fill a slot. """ @page.routed(self.app.route("/"), tags.div(slot("widget"))) def rsrc(request): return {"widget": enwidget.widget(3, 4)} request, written = self.get(b"/") self.assertIn(b"<span>a: 3</span>", written) self.assertIn(b"<span>b: 4</span>", written) def test_widget_json(self): """ When L{Plating.widgeted} is applied as a decorator, and the result is serialized to JSON, it appears the same as the returned value despite the HTML-friendly wrapping described above. """ @page.routed(self.app.route("/"), tags.div(slot("widget"))) def rsrc(request): return {"widget": enwidget.widget(3, 4)} request, written = self.get(b"/?json=1") self.assertEqual(json.loads(written.decode('utf-8')), { "widget": { "a": 3, "b": 4 }, "title": "default title unchanged" }) def test_prime_directive_return(self): """ Nothing within these Articles Of Federation shall authorize the United Federation of Planets to alter the return value of a callable by applying a decorator to it... """ exact_result = {"ok": "some nonsense value"} @page.routed(self.app.route("/"), tags.span(slot("ok"))) def plateMe(request): return exact_result self.assertIdentical(plateMe(None), exact_result) def test_prime_directive_arguments(self): """ ... or shall require the function to modify its signature under these Articles Of Federation. """ @page.routed(self.app.route("/"), tags.span(slot("ok"))) def plateMe(request, one, two, three): return (one, two, three) exact_one = {"one": "and"} exact_two = {"two": "and"} exact_three = {"three": "and"} result_one, result_two, result_three = plateMe(None, exact_one, exact_two, three=exact_three) self.assertIdentical(result_one, exact_one) self.assertIdentical(result_two, exact_two) self.assertIdentical(result_three, exact_three) def test_presentation_only_json(self): """ Slots marked as "presentation only" will not be reflected in the output. """ plating = Plating(tags=tags.span(slot("title")), presentation_slots={"title"}) @plating.routed(self.app.route("/"), tags.span(slot("data"))) def justJson(request): return {"title": "uninteresting", "data": "interesting"} request, written = self.get(b"/?json=1") self.assertEqual(json.loads(written.decode("utf-8")), {"data": "interesting"}) def test_missing_renderer(self): """ Missing renderers will result in an exception during rendering. """ def test(missing): plating = Plating(tags=tags.span(slot(Plating.CONTENT))) @plating.routed(self.app.route("/"), tags.span(tags.span(render=missing))) def no(request): return {} self.get(b"/") [fe] = self.flushLoggedErrors(FlattenerError) self.assertIsInstance(fe.value.args[0], MissingRenderMethod) test("garbage") test("garbage:missing") def test_json_serialize_unknown_type(self): """ The JSON serializer will raise a L{TypeError} when it can't find an appropriate type. """ from klein._plating import json_serialize class reprish(object): def __repr__(self): return '<blub>' te = self.assertRaises(TypeError, json_serialize, {"an": reprish()}) self.assertIn("<blub>", str(te))
pass @webapp.route('/msg', methods=['POST']) def do_post(request): content = json.loads(request.content.read()) token = request.requestHeaders.getRawHeaders('authorization') webapp.msgs.append( dict( text=content["msg"] ) ) wampapp.session.publish('com.example.msg', webapp.msgs ) response = json.dumps(dict(the_data=content), indent=4) return response @webapp.route('/') def home(request): webapp.visits += 1 wampapp.session.publish('com.example.msg', webapp.msgs) page = webapp.templates.get_template('index.html') return page.render(visits=webapp.visits) if __name__ == "__main__": import sys from twisted.python import log from twisted.web.server import Site from twisted.internet import reactor log.startLogging(sys.stdout) reactor.listenTCP(5000, Site(webapp.resource())) wampapp.run("ws://crossbar:8080/ws", "realm1")