Publish to specific channel/Group - python

I am looking into the swampdragon chat_example. In the router.py as per documentation get_subscription_channel gives channel name.
When I tried to change the retrun value it still works.
How can I limit the messages to specific group/channel. What things I need to do in the front end.
from swampdragon import route_handler
from swampdragon.route_handler import BaseRouter
class ChatRouter(BaseRouter):
route_name = 'chat-route'
valid_verbs = ['chat', 'subscribe']
def get_subscription_channels(self, **kwargs):
return ['chatrm']
def chat(self, *args, **kwargs):
errors = {}
if errors:
self.send_error(errors)
else:
self.send({'status': 'ok'})
self.publish(self.get_subscription_channels(), kwargs)
route_handler.register(ChatRouter)
Here is the subscription method.
function subscribe () {
swampdragon.subscribe('chat-route', 'local-channel', null, function (context, data) {
// any thing that happens after successfully subscribing
}, function (context, data) {
// any thing that happens if subscribing failed
});
}

I also came across the same issue. Here the problem is that you are not publishing data to the channel that you have subscribed . You subscribed for channel named 'local-channel' but in your router.py you are publishing or routing data another channel named 'chatrm'. Thats why you are not getting any notification. There are two ways you can fix it.
1. You need to change the get_subscription_channels method in router.py as shown below.
def get_subscription_channels(self, **kwargs):
return ['local-channel']
OR
2. Change the subscription method like the one below:
function subscribe () {
swampdragon.subscribe('chat-route', 'chatrm', null, function (context, data) {
// any thing that happens after successfully subscribing
}, function (context, data) {
// any thing that happens if subscribing failed
});
}

Related

Not able to bind Flask's Server-Sent Event's data in Angular

I am using Flask for backend and Angular for frontend. I am implementing Server-Sent Events (SSE) for some task. Unfortunately, I am not able to receive any data from the SSE.
Banckend:
#app.route('/stream')
def stream():
def event_stream():
while True:
time.sleep(1)
yield 'data: some data\n\n'
return Response(event_stream(), mimetype='text/event-stream')
Frontend:
ngOnInit(): void {
var eventSource = new EventSource('http://127.0.0.1:5000/stream')
eventSource.onmessage = (e) => {
console.log(e.data); // Not working
this.eventData = e.data; // Not working
}
}
The issue with this code is the if I am commenting time.sleep(1) line in the backend, then I am able to see the response in the Chrome's dev tools, but not able to bind it in the HTML file. So, if I keep it like that, then I am not able to see either of them.
I am facing one more issue, when I am terminating the backend (by killing the command promt), I am able to see that the failed calls are still being continuously made from the browser to the event stream. I believe, SSEs are always sent from the server/backend, but in this case the client/browser is requesting for the event. Is my understanding wrong?
I have attached an image for reference.
Use eventSource's addEventListener method:
eventSource.addEventListener('message', (e) => {
this.eventData = e.data;
});
eventSource.addEventListener('error', (e) => { // This will properly close the stream, when it ends.
eventSource.close();
});

Saving Longitude and Latitude to a user profile in Django

I was looking for a way to use HTML5 (and possibly JS) to save visitor/user Longitudnal & Latitudnal data to a database. I do not wish to use packages out there as they seem a bit outdated and may break my code in future considerting their own reliance on other APIs.
I know there is a way around using AJAX, but I clearly dont know and understand it well enough to implement it.
My ask of the learned Lords is - 1. Get Loc data 2. Send it to Python in dict or json or string format from where it can be further processed and saved.
Why you may ask - Good question. I would use it for displaying weather on the homepage and local twitter trends on a 'logged-in' page.
Any assistance would be appreciated.
Cheers!
My JS code is below:
// Set up global variable
var result;
function showPosition() {
// Store the element where the page displays the result
result = document.getElementById("result");
// If geolocation is available, try to get the visitor's position
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(successCallback, errorCallback);
result.innerHTML = "Getting the position information...";
} else {
alert("Sorry, your browser does not support HTML5 geolocation.");
}
};
// Define callback function for successful attempt
function successCallback(position) {
result.innerHTML = [position.coords.latitude, position.coords.longitude];
}
// Define callback function for failed attempt
function errorCallback(error) {
if (error.code == 1) {
result.innerHTML = "You've decided not to share your position, but it's OK. We won't ask you again.";
} else if (error.code == 2) {
result.innerHTML = "The network is down or the positioning service can't be reached.";
} else if (error.code == 3) {
result.innerHTML = "The attempt timed out before it could get the location data.";
} else {
result.innerHTML = "Geolocation failed due to unknown error.";
}
}
window.onload = showPosition;
what works for me:
First I recommend you to use models.PointField on your model.
When I obtain the long/lat data on FE, I send it as form-data in the following format eg:
"{\"type\":\"Point\",\"coordinates\":[14.215641,50.0100000001]}"
Then I map it to the model field and save it. It saves well and later I am able to query google geocoder or anything with it.
In your JS code:
function successCallback(position) {
result.innerHTML = [position.coords.latitude, position.coords.longitude];
$.post('your-python-endpoint-url', {
latitude: position.coords.latitude,
longitude: position.coords.longitude
});
}
In your python:
def index(request):
if request.is_ajax():
if request.method == 'POST':
print 'Raw Data: "%s"' % request.body
return HttpResponse("OK")
Change the method name and body according to your needs and don't forget to define a route in django.

How to check in CAPL if message is receiving in simulation or not?

I want check in CAPL if the message is receiving or not in the simulation and if it is not coming in the trace, i want send new message. I have tried using functions like. I want to check particular message is receving or not?
TestWaitForPDU();TestWaitFormessage(msg,2000) etc but in simple configuration these are not working.
I have also tried using istimerActive() or istimerunning(), but these function will not check if message has stopped receiving or transmitting.
I am working in generic node.and i have tried something like this
on timer tslpack
{
int sleepack;
long Systemtime[9];
sleepack= isTimerActive(tslpack);
//write("Bus Active");
// write("Running Status %d",tslpack.isRunning());
if(sleepack==1)
{
write("timer cancelled");
cancelTimer(tslpack);
Settimer(tslpack,100);
}
else
{
result=1;
if(result ==1)
{
write("Bus Sleep");
sleeptime=timeNow();
result = 0;
}
}
You have mentioned that you are not writing the code in Test Node and you want to do it in Simulation Node. Clearly the functions TestWaitForPDU();TestWaitFormessage(msg,2000) are supposed to be used in tests as the name of the function shows.
I suppose you are waiting for a CAN message and so I am giving you a sample code for it.
variables
{
msTimer TimerToCheckMessage;
message CAN1.0x123 TxMsg; //Message which you want to send
}
on start
{
setTimer(TimerToCheckMessage,103);
TxMsg.dlc = 4;
}
on message CAN1.0x1 //Message which you want to check
{
setTimer(TimerToCheckMessage,103);
}
on timer TimerToCheckMessage
{
output(TxMsg);
setTimer(TimerToCheckMessage,103);
}

Is it possible to return custom errors in python gRPC server?

I have a .proto file:
// Protocol Buffers Language version
syntax = "proto3";
package my_package;
// -----------------Cart service-----------------
service CartService {
rpc AddItem(AddItemRequest) returns (AddItemResponse) {}
}
message CartItem {
string product_id = 1;
int32 quantity = 2;
}
message AddItemRequest {
string user_id = 1;
CartItem item = 2;
}
message AddItemResponse {
string user_id = 1;
}
In my AddItem method I want to return a custom error like cart_not_found:
class CartService(my_package_pb2_grpc.CartServiceServicer):
def AddItem(self, request, context):
context.set_code(StatusCode.CART_NOT_FOUND)
context.set_details('Cart Not Found!')
return context
The above code does not work as gRPC status codes are limited to some basic list. How can I return custom errors in gRPC?
EDIT-1:
I've seen examples that set machine readable code in details like below:
context.set_code(grpc.StatusCode.INTERNAL)
context.set_details('cart_not_found')
return context
But this has its own limitation and I cannot set description for the error or any other custom key.
The other method is to return error in every message you have like below:
message AddItemResponse {
string user_id = 1;
Error error = 2;
}
message Error {
string code = 1;
string message = 2;
}
This implementation has one drawback that services need to check for error existence and then handle the error otherwise process the response.
You can return custom KV pairs in trailing metadata.
Example from unit test: https://github.com/grpc/grpc/blob/master/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py#L430
There is an example for returning custom error at https://github.com/grpc/grpc/tree/master/examples/python/errors.

How do I correctly make consecutive calls to a child process in Node.js?

I have a Node.js application which is currently a web-based API. For one of my API functions, I make a call to a short Python script that I've written to achieve some extra functionality.
After reading up on communicating between Node and Python using the child_process module, I gave it a try and achieved my desired results. I call my Node function that takes in an email address, sends it to Python through std.in, my Python script performs the necessary external API call using the provided e-mail, and writes the output of the external API call to std.out and sends it back to my Node function.
Everything works properly until I fire off several requests consecutively. Despite Python correctly logging the changed e-mail address and also making the request to the external API with the updated e-mail address, after the first request I make to my API (returning the correct data), I keep receiving the same old data again and again.
My initial guess was that Python's input stream wasn't being flushed, but after testing the Python script I saw that I was correctly updating the e-mail address being received from Node and receiving the proper query results.
I think there's some underlying workings of the child_process module that I may not be understanding... since I'm fairly certain that the corresponding data is being correctly passed back and forth.
Below is the Node function:
exports.callPythonScript = (email)=>
{
let getPythonData = new Promise(function(success,fail){
const spawn = require('child_process').spawn;
const pythonProcess = spawn('python',['./util/emailage_query.py']);
pythonProcess.stdout.on('data', (data) =>{
let dataString = singleToDoubleQuote(data.toString());
let emailageResponse = JSON.parse(dataString);
success(emailageResponse);
})
pythonProcess.stdout.on('end', function(){
console.log("python script done");
})
pythonProcess.stderr.on('data', (data) => {
fail(data);
})
pythonProcess.stdin.write(email);
pythonProcess.stdin.end();
})
return getPythonData;
}
And here is the Python script:
import sys
from emailage.client import EmailageClient
def read_in():
lines = sys.stdin.readlines()
return lines[0]
def main():
client = EmailageClient('key','auth')
email = read_in()
json_response = client.query(email,user_email='authemail#mail.com')
print(json_response)
sys.stdout.flush()
if __name__ == '__main__':
main()
Again, upon making a single call to callPythonScript everything is returned perfectly. It is only upon making multiple calls that I'm stuck returning the same output over and over.
I'm hitting a wall here and any and all help would be appreciated. Thanks all!
I've used a Mutex lock for this kind of example. I can't seem to find the question the code comes from though, as I found it on SO when I had the same kind of issue:
class Lock {
constructor() {
this._locked = false;
this._waiting = [];
}
lock() {
const unlock = () => {
let nextResolve;
if (this._waiting.length > 0) {
nextResolve = this._waiting.pop(0);
nextResolve(unlock);
} else {
this._locked = false;
}
};
if (this._locked) {
return new Promise((resolve) => {
this._waiting.push(resolve);
});
} else {
this._locked = true;
return new Promise((resolve) => {
resolve(unlock);
});
}
}
}
module.exports = Lock;
Where I then call would implement it like this, with your code:
class Email {
constructor(Lock) {
this._lock = new Lock();
}
async callPythonScript(email) {
const unlock = await this._lock.lock();
let getPythonData = new Promise(function(success,fail){
const spawn = require('child_process').spawn;
const pythonProcess = spawn('python',['./util/emailage_query.py']);
pythonProcess.stdout.on('data', (data) =>{
let dataString = singleToDoubleQuote(data.toString());
let emailageResponse = JSON.parse(dataString);
success(emailageResponse);
})
pythonProcess.stdout.on('end', function(){
console.log("python script done");
})
pythonProcess.stderr.on('data', (data) => {
fail(data);
})
pythonProcess.stdin.write(email);
pythonProcess.stdin.end();
})
await unlock();
return getPythonData;
}
}
I haven't tested this code, and i've implemented where i'm dealing with arrays and each array value calling python... but this should at least give you a good start.

Categories

Resources