async def ws_writer(websocket, path): print("ws-test-server: ws_writer: started") global pending_requests i = 1 while True: # message = await producer() ## ## THIS IS JUST FOR TESTING - SEND A GET REQUEST... ## message = json.dumps({ 'message': { 'messageId': i, 'messageType': 'REST:REQUEST', 'requiresResponse': True, 'method': 'GET', 'path': '/micronets/v1/dhcp/subnets' } }) print("ws-test-client: > sending client message: ", message) await websocket.send(message) print("ws-test-client: > sent client message #", i) message_future = asyncio.get_event_loop().create_future() pending_requests[i] = message_future print("ws-test-client: Waiting for future #", i) response = await message_future message = json.loads(response) print(f"ws-test-client: Got a response from future #{i}: ", json.dumps(message, indent=2)) print(f"ws-test-client: Sleeping...") await asyncio.sleep(30) i += 1
def custom_response(res, status_code): """ Custom Response Function """ return Response(mimetype="application/json", response=json.dumps(res), status=status_code)
async def send_dpp_onboard_event(self, micronet, device, event_name, reason=None): ws_connector = get_ws_connector() if not ws_connector: return f"No websocket connector configured", 500 if not ws_connector.is_ready(): ws_uri = ws_connector.get_connect_uri() logger.info( f"DPPHandler.send_dpp_onboard_event: websocket not connected (ws uri: {ws_uri})" ) return f"The websocket connection to {ws_uri} is not connected/ready", 500 dev_mac_field = device['macAddress']['eui48'] dpp_onboarding_complete_event = { event_name: { 'micronetId': micronet['micronetId'], 'deviceId': device['deviceId'], 'macAddress': dev_mac_field } } if reason: dpp_onboarding_complete_event[event_name]['reason'] = reason logger.info(f"DPPHandler.send_dpp_onboard_event: sending:") logger.info(json.dumps(dpp_onboarding_complete_event, indent=4)) await ws_connector.send_event_message("DPP", event_name, dpp_onboarding_complete_event)
async def handle_message(self, raw_message): message = json.loads(raw_message) if (not message): raise Exception(f"message does not appear to be json") logger.debug("WSConnector: handle_message:") logger.debug(json.dumps(message, indent=2)) check_json_field(message, 'message', dict, True) message = message['message'] # Drill down check_json_field(message, 'messageId', int, True) check_json_field(message, 'messageType', str, True) check_json_field(message, 'requiresResponse', bool, True) message_type = message['messageType'] message_type_prefix = message_type[:message_type.find(":")] logger.debug( f"ws_connector: handle_message: message type prefix: {message_type_prefix}" ) if message_type_prefix == "REST": await self.handle_rest_message(message) elif message_type_prefix == "EVENT:": await self.handle_event_message(message) else: if message_type_prefix not in self.handler_table: raise Exception( f"unknown message type prefix {message_type_prefix}") type_handler = self.handler_table[message_type_prefix] await type_handler.handle_ws_message(message)
async def handle_rest_message(self, message): received_message_id = message['messageId'] method = check_json_field(message, 'method', str, True) path = check_json_field(message, 'path', str, True) queries = check_json_field(message, 'queryStrings', list, False) headers = check_json_field(message, 'headers', list, False) data_format = check_json_field(message, 'dataFormat', str, False) message_body = check_json_field(message, 'messageBody', (str, dict), False) header_dict = multidict.CIMultiDict() if (data_format): header_dict.add("Content-Type", data_format) if (headers): for header in headers: header_dict.add(header['name'], header['value']) if (queries): for query in queries: path += f"&{query['name']}={query['value']}" query_part = b'' request = Request(method, "http", path, query_part, header_dict) if ('messageBody' in message): if isinstance(message_body, dict): request.body.set_result( json.dumps(message_body).encode('utf-8')) else: request.body.set_result(message_body.encode('utf-8')) header_dict.add('Content-Length', len(message_body)) else: request.body.set_result(b'') response = await asyncio.ensure_future(app.handle_request(request)) await self.handle_rest_response(received_message_id, response)
async def get_messages(): data = await request.get_json() if data.get("to_user") and data.get("from_user"): msgs = await get_all_messages(to_user=data.get("to_user"), from_user=data.get("from_user")) return Response(status=200, response=json.dumps(msgs)) elif data.get("user") and data.get("limit"): msgs = await get_all_messages(me=data.get("user"), limit=data.get("limit")) return Response(status=200, response=json.dumps(msgs)) resp = { "status": "failed", "message": "You will need at least a user and limit to be able to get messages. " } return Response(status=400, response=json.dumps(resp))
async def fetch(): await client.connect() msgs = await client.messages(limit=500) return Response(status=200, response=json.dumps({ "status": "success", "message": "{} messages pulled".format(msgs) }))
async def handle_request(self, req: request) -> str: header_signature = req.headers.get('X-Hub-Signature') if header_signature is None: logger.warning( f'Request for GitHub repo \'{self.repo.name}\' did not have X-Hub-Signature header!' ) abort(403) sha_name, signature = header_signature.split('=') if sha_name != 'sha1': logger.warning( f'Request for GitHub repo \'{self.repo.name}\' was not signed with SHA1 function!' ) abort(501) if not self.is_data_signed_correctly(await req.data, signature): logger.warning( f'Request for GitHub repo \'{self.repo.name}\' did not have valid signature!' ) abort(403) # Ping-Pong messages event = req.headers.get('X-GitHub-Event', 'ping') if event == 'ping': return dumps({'msg': 'pong'}) if event != 'push': logger.warning( f'Request for GitHub repo \'{self.repo.name}\' was not result of push event!' ) abort(501) if self.repo.branch: if request.is_json: data = await request.get_json() else: data = await request.form expected_ref = f'refs/heads/{self.repo.branch}' if data['ref'] != expected_ref: logger.debug( f'Received push-event for \'{self.repo.name}\', but for branch \'{data["ref"]}\' ' f'instead of expected \'{expected_ref}\' - ignoring the event' ) abort( 204, 'Everything OK, but not following this branch. Build skipped.' ) loop = asyncio.get_event_loop() # noinspection PyAsyncCall loop.run_in_executor(None, self.repo.publish_repo) return 'OK'
async def get_latest_speeches(): """ GET request: curl -X GET "http://127.0.0.1:8080/latest-speeches/?anftyp=Nej&sz=10" """ """ Clients can input the number of speeches required by them. Result will be a merged data of speeches with members. """ anftyp = request.args["anftyp"] size = request.args["sz"] speeches = await get_speeches(anftyp, size) return json.dumps(speeches)
async def relay_messages_to_peer (self): try: logger.debug (f"ws_client {id (self)}: relay_messages_to_peer: sending cached hello to client {id (self.peer_client)}") logger.debug (" %s", self.hello_message) await self.peer_client.send_message (json.dumps (self.hello_message)) logger.info (f"ws_client {id (self)}: relay_messages_to_peer: Routing all messages to {id (self.peer_client)}") while True: message = await self.websocket.recv () logger.info (f"ws_client {id (self)}: relay_messages_to_peer: Copying message to client {id (self.peer_client)}") logger.debug (message) await self.peer_client.send_message (message) finally: logger.info(f"ws_client {id (self)}: relay_messages_to_peer: terminating")
async def handle_exception(e): if isinstance(e, HTTPException): response = e.get_response() response.data = json.dumps({ "code": e.code, "name": e.name, "description": e.description, }) response.content_type = "application/json" app.logger.error("HTTP Error 500") return response app.logger.error(e) return await render_template("500_generic.html", e=e)
async def send_message(self, message, must_be_ready=True): if not self.is_connected(): raise Exception( f"Websocket not connected (to {self.get_connect_uri()})") if must_be_ready and not self.is_ready(): raise Exception( f"Websocket not ready (connected to {self.get_connect_uri()})") message_id = self.message_id self.message_id += 1 message['messageId'] = message_id message_json = json.dumps({'message': message}) logger.debug(f"ws_connector: > sending event message: {message}") await self.websocket.send(message_json) return message_id
async def recommendations(): limit = g.config.api.v1.recommendations.default_limit limit = int(request.args.get('limit', limit)) if limit < 1: # TODO: Or return an error code? limit = 1 since_id = request.args.get('since_id') since_id = int(since_id) if since_id and int(since_id) >= 0 else None # TODO: Raise a request error if max_id < since_id which doesn't make sense max_id = request.args.get('max_id') max_id = int(max_id) if max_id and int(max_id) >= 0 else None user_id = g.auth['user_id'] # Request the recsystems # TODO: User assignment is not implemented yet so just selecting a # single recsystem at random if (recsystems_manager is None or not recsystems_manager.recsystem_rpc_clients): return (json.dumps({'error': 'no recsystems are available'}), HTTPStatus.SERVICE_UNAVAILABLE) recsystem_id = random.choice(list( recsystems_manager.recsystem_rpc_clients)) response = await recsystems_manager.rpc(recsystem_id, 'recommend', user_id=user_id, limit=limit, since_id=since_id, max_id=max_id) article_ids = response.data.result timestamp = datetime.utcnow() if article_ids: g.db.articles.events.insert_many([{ 'user_id': user_id, 'article_id': article_id, 'recommended_by': [recsystem_id], 'timestamp': timestamp } for article_id in article_ids]) return get_articles({'article_id': {'$in': article_ids}}, limit=limit) else: return jsonify([])
async def handle_rest_request(websocket, message_json): global message_id print( f"handle_rest_request: {message_json ['method']} for {message_json ['path']}" ) if ('dataFormat' in message_json): print( f"handle_rest_request: message_body ({message_json [dataFormat]}):\n{message_json [messageBody]}" ) response = json.dumps({ 'message': { 'messageId': message_id, 'messageType': 'REST:RESPONSE', 'requiresResponse': False, 'inResponseTo': message_json['messageId'], 'statusCode': 200, 'reasonPhrase': "OK" } }) message_id = message_id + 1 print(f"handle_rest_request: sending response:", response) await websocket.send(response)
def _generate_etag(etag_data, etag_schema=None, extra_data=None): """Generate an ETag from data etag_data: Data to use to compute ETag etag_schema: Schema to dump data with before hashing extra_data: Extra data to add before hashing Typically, extra_data is used to add pagination metadata to the hash. It is not dumped through the Schema. """ if etag_schema is None: raw_data = etag_data else: if isinstance(etag_schema, type): etag_schema = etag_schema() raw_data = etag_schema.dump(etag_data) if MARSHMALLOW_VERSION_MAJOR < 3: raw_data = raw_data.data if extra_data: raw_data = (raw_data, extra_data) # flask's json.dumps is needed here # as vanilla json.dumps chokes on lazy_strings data = json.dumps(raw_data, sort_keys=True) return hashlib.sha1(bytes(data, 'utf-8')).hexdigest()
def dumps(self, value: Any) -> str: return dumps(self.tag(value), separators=(",", ":"))
async def test_ascii_dumps(as_ascii: bool, expected: str) -> None: app = Quart(__name__) async with app.app_context(): app.config["JSON_AS_ASCII"] = as_ascii assert dumps("🎊") == expected
async def me(): mee = await client.get_me() return Response(status=200, response=json.dumps(mee.to_dict()))
async def handle_hostapd_ready(self): logger.info(f"DPPHandler.handle_hostapd_ready()") self.ssid = self.hostapd_adapter.get_status_var('ssid')[0] logger.info(f"DPPHandler.handle_hostapd_ready: SSID: {self.ssid}") self.freq = self.hostapd_adapter.get_status_var('freq') logger.info(f"DPPHandler.handle_hostapd_ready: FREQ: {self.freq}") if self.dpp_config_key_file.exists(): try: dpp_config_key = self.dpp_config_key_file.read_text() logger.info( f"DPPHandler.handle_hostapd_ready: Loaded DPP configurator key from {self.dpp_config_key_file}" ) except Exception as ex: logger.warning( f"DPPHandler: handle_hostapd_ready: Caught exception reading {self.dpp_config_key_file}: {ex}" ) return else: # Create a prime256v1 key dpp_config_key = ecdsa.SigningKey.generate( curve=ecdsa.NIST256p).to_der().hex() self.dpp_config_key_file.write_text(dpp_config_key) logger.info( f"DPPHandler.handle_hostapd_ready: Saved new configurator key to {self.dpp_config_key_file}" ) add_configurator_cmd = HostapdAdapter.DPPAddConfiguratorCLICommand( curve="prime256v1", key=dpp_config_key) await self.hostapd_adapter.send_command(add_configurator_cmd) self.dpp_configurator_id = await add_configurator_cmd.get_configurator_id( ) logger.info( f"DPPHandler.handle_hostapd_ready: DPP Configurator ID: {self.dpp_configurator_id}" ) try: if self.dpp_ap_connector_file.exists(): self.dpp_ap_connector = json.loads( self.dpp_ap_connector_file.read_text()) logger.info( f"DPPHandler.handle_hostapd_ready: Loaded AP Connector from {self.dpp_ap_connector_file}" ) else: # Create the AP's connector and persist it logger.info( f"DPPHandler: handle_hostapd_ready: Creating a DPP Connector for the AP" ) dpp_config_sign_cmd = HostapdAdapter.DPPConfiguratorDPPSignCLICommand( self.dpp_configurator_id, self.ssid) await self.hostapd_adapter.send_command(dpp_config_sign_cmd) dpp_connector = await dpp_config_sign_cmd.get_connector() logger.info( f"DPPHandler: handle_hostapd_ready: Connector: {dpp_connector}" ) dpp_c_sign_key = await dpp_config_sign_cmd.get_c_sign_key() logger.info( f"DPPHandler: handle_hostapd_ready: DPP c-sign-key: {dpp_c_sign_key}" ) dpp_net_access_key = await dpp_config_sign_cmd.get_net_access_key( ) logger.info( f"DPPHandler: handle_hostapd_ready: Net access key: {dpp_net_access_key}" ) self.dpp_ap_connector = { "dpp_connector": dpp_connector, "dpp_csign": dpp_c_sign_key, "dpp_netaccesskey": dpp_net_access_key } dpp_ap_connector_json = json.dumps(self.dpp_ap_connector, indent=3) + "\n" self.dpp_ap_connector_file.write_text(dpp_ap_connector_json) await self.hostapd_adapter.send_command( HostapdAdapter.SetCLICommand( "dpp_connector", self.dpp_ap_connector['dpp_connector'])) await self.hostapd_adapter.send_command( HostapdAdapter.SetCLICommand( "dpp_csign", self.dpp_ap_connector['dpp_csign'])) await self.hostapd_adapter.send_command( HostapdAdapter.SetCLICommand( "dpp_netaccesskey", self.dpp_ap_connector['dpp_netaccesskey'])) except Exception as ex: logger.warning( f"DPPHandler: handle_hostapd_ready: Caught exception processing DPP AP connector {self.dpp_ap_connector_file}: {ex}", exc_info=True) return
async def ws_connected (websocket, path): try: new_client = None peer_client = None client_list = None remote_address = websocket.remote_address logger.info (f"ws_connected: from {remote_address}, {path}") if (not path.startswith (proxy_service_prefix)): logger.warning (f"ws_connected: Unsupported path: {proxy_service_prefix} - CLOSING!") return meetup_id = path [len (proxy_service_prefix):] if (not meetup_id in meetup_table): client_list = [] meetup_table [meetup_id] = client_list else: client_list = meetup_table [meetup_id] if (len (client_list) >= 2): logger.warning (f"ws_connected: client {id (new_client)}: meetup ID {meetup_id} " f"already has {len (client_list)} clients - CLOSING connection from {remote_address}.") return new_client = WSClient (meetup_id, websocket) client_list.append (new_client) perform_connection_report () logger.debug (f"ws_connected: client {id (new_client)}: (meetup_id: {meetup_id})") logger.debug (f"ws_connected: client {id (new_client)}: Waiting for HELLO message...") hello_message = await new_client.recv_hello_message () logger.info (f"ws_connected: client {id (new_client)}: Received HELLO message:") logger.info (json.dumps (hello_message, indent=2)) # Here's where we'd add any accept criteria based on the HELLO message if (len (client_list) == 1): logger.info (f"ws_connected: client {id (new_client)} is the first connected to {path}") perform_connection_report () peer_client = await new_client.wait_for_peer () else: logger.info (f"ws_connected: client {id (new_client)} is the second connected to {path}") peer_client = client_list [0] new_client.set_peer (peer_client) peer_client.set_peer (new_client) perform_connection_report () # Will just relay data between the clients until someone disconnects... await new_client.communicate_with_peer () logger.info (f"ws_connected: client {id (new_client)} relay_messages_to_peer() returned") except websockets.ConnectionClosed as cce: logger.info (f"ws_connected: client {id (new_client)} disconnected normally") except Exception as Ex: logger.info (f"ws_connected: client {id (new_client)}: Caught an exception from ws_reader: {Ex}") finally: logger.info (f"ws_connected: client {id (new_client)}: Cleaning up...") if (new_client in client_list): client_list.remove (new_client) if len(client_list) == 0: meetup_table.pop (meetup_id) perform_connection_report() if (new_client): new_client.cleanup_before_close () if (peer_client): await peer_client.peer_disconnected (new_client)
def dumps(self, value: Any) -> str: return dumps(self.tag(value), separators=(',', ':'))