Python socket server with selection - python

How do I make socket server(made in node js) with node selection like the one shown below in node.js in python3 ?
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
io.on('connection', function(socket){
socket.on('pose', function(pose){
io.emit('pose', pose);
console.log(pose);
});
});
http.listen(3000, function () {
console.log('Socket.io Running');
});

Found what I needed to do, here's the sample code with reference:
from flask import Flask, render_template
from flask_socketio import SocketIO, emit
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
#socketio.on('my event')
def test_message(message):
emit('my response', {'data': 'got it!'})
if __name__ == '__main__':
socketio.run(app, port = 3000)

Related

"opaque" response from FLASK API

So currently I am developing a very minimal front-end using react. I am very much a beginner with react. I created a dummy API at using FLASK which was returning json string. The problem is that I recieve the response on front-end. But the type is "opaque". I am currently in development mode and the connection is not secure obv. So I believe the issue is with security. Is there any workout for this in dev mode?
I am attaching screenshot of response and code of front-end and backend as reference.
Thank you for help in advance.
I tried: FLASK CORS method as mentioned in the code.
I was expecting to catch JSON at frontend but it gives error. The error is in response.json() line in js code. error
from flask import Flask, request, jsonify
from flask_cors import CORS
import os
import base64
from PIL import Image
import numpy as np
from flask import send_file
app = Flask(__name__)
cors=CORS(app, origins=["http://example.com", "http://147.46.246.106:3000"])
#app.route('/skinai', methods=['POST'])
def v1_launch():
response = jsonify({"recieved": "Tsdce"})
return response
if __name__ == '__main__':
#data={"some":"dummy"}
app.run(host='0.0.0.0', port=3336)
Frontend code:
fetch(host+'/skinai', {
method: 'POST',
body: formData,
mode: 'no-cors',
})
.then(response => {
console.log(response);
return response.json();
})
.catch(error => {
console.error('Error:', error);
});
};

python service access to ajax call , CORS error

I'm getting lost with this problem,
i have a service written in python that i need to access from a web page with an ajax call
the python code is as follows:
import flask
from flask import request, jsonify, make_response
from flask_cors import CORS, cross_origin
from datetime import datetime, timedelta
app = flask.Flask(__name__)
app.run(host='0.0.0.0', port=5000)
cors = CORS(app)
app.config['CORS_HEADERS'] = 'Content-Type'
#app.route('/api/v1/resources/device/all', methods=['GET'])
#cross_origin()
def api_all():
[...]
response = jsonify(result)
response.headers.add("Access-Control-Allow-Origin", "*")
return response,status_code
and the ajax call is:
$.ajax({
type: 'get',
crossDomain: true,
dataType: "json",
url: AddressWS + '/api/v1/resources/device/all?type=A',
success: function (result) {
//.,...
}
});
The error is ever
... has been blocked by CORS policy: No 'Access-Control-Allow-Origin'
header is present on the requested resource.
the web application is under IIS .
the question is :
if I set 0.0.0.0 as address in python script, which address should I call in the web application ?
i try to machine ipv4 address but don't run.
how i fix the cors problem, i seem to have correctly included the flask libraries.
Thanks everyone for the kind replies
CORS is not configured properly in your code. Please find below the code with the correct CORS configuration.
import flask
from flask import request, jsonify, make_response
from flask_cors import CORS
from flask_restful import Api
from datetime import datetime, timedelta
app = flask.Flask(__name__)
api = Api(app)
CORS(app)
#app.route('/api/v1/resources/device/all', methods=['GET'])
def api_all():
[...]
response = jsonify(result)
status_code = 'some code'
return response,status_code
if __name__ == '__main__':
app.run()
Try this in my case it works ,
$.ajax({
type: 'get',
dataType: 'json',
url: AddressWS + '/api/v1/resources/device/all?type=A',
cors: true,
contentType: 'application/json;charset=UTF-8',
secure: true,
headers: {
'Access-Control-Allow-Origin': '*',
},
success: function (result) {
//.,...
},
error: function (errorMessage) {
console.log('error');
}
});

Post request from react to flask

I am trying to send a post request from react to flask using the following code:
function App() {
const [currentTime, setCurrentTime] = useState(0);
const [accessToken, setAccessToken] = useState(null);
const clicked = 'clicked';
useEffect(() => {
fetch('/time').then(res => res.json()).then(data => {
setCurrentTime(data.time);
});
}, []);
useEffect(() => {
// POST request using fetch inside useEffect React hook
const requestOptions = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ title: 'React Hooks POST Request Example',action: 'clicked' })
};
var myParams = {
data: requestOptions
}
fetch('http://127.0.0.1:5000/login', myParams)
.then(response => response.json())
.then(data => setAccessToken(data.access_token));
// empty dependency array means this effect will only run once (like componentDidMount in classes)
}, []);
return (
<div className="App">
<div className="leftPane">
<div className="joyStick" >
<Joystick size={300} baseColor="gray" stickColor="black" ></Joystick>
</div>
<p>The current time is {currentTime}.</p>
<p>The access token is {accessToken}.</p>
</div>
And the flask code is
from __future__ import print_function
from flask import Flask, jsonify, request
from flask_cors import CORS
import time
from flask import Flask
import sys
robotIP="10.7.4.109"
PORT=9559
app = Flask(__name__)
access_token='a'
action="d"
#app.route('/time')
def get_current_time():
return {'time': time.time()}
#app.route('/login', methods=['POST'])
def nao():
nao_json = request.get_json()
if not nao_json:
return jsonify({'msg': 'Missing JSON'}), 400
action = nao_json.get('action')
access_token= action+'s'
print(access_token, file=sys.stderr)
return jsonify({'access_token': access_token}), 200
But every time I run both them both, I get the 'msg': 'Missing JSON' message I have defined and the data from react is never available in flask,even though the get request works.I am not sure what I am doing wrong here.
The problem actually is that this is a cross origin request which must be allowed by the server.
Place this function on your Python code:
#app.after_request
def set_headers(response):
response.headers["Access-Control-Allow-Origin"] = "*"
response.headers["Access-Control-Allow-Headers"] = "*"
response.headers["Access-Control-Allow-Methods"] = "*"
return response
Note:
If react is served from the same server this won't be necessary.
You should set the value of these headers to be as strict as possible on production. The above example is too permissive.
You could serve your React aplication from Flask, thus not requiring these headers to be set. You could use something like this to serve the main react file:
#app.route('/', defaults={'path': ''})
#app.route('/<string:path>')
#app.route('/<path:path>')
def index(path: str):
current_app.logger.debug(path)
return bp_main.send_static_file('path/to/dist/index.html')
Where path/to/dist/index.html would be on the static folder.
See more at:
MDN Web docs
Stackoverflow: How to enable CORS in flask
Stackoverflow: Catch all routes for Flask

Flask Socket.io doesn't work when emitting from thread

Description
The client side has 2 buttons:
One makes the server to send periodic messages
The other, stops the sending of periodic messages
This problem is a proxy of the real problem I am trying to solve.
I build the app, and in the server side it seems to work, but the client doesn't receive the server push, but is able to start the push and kill it!
What I tried
Server Side
import random
from threading import Thread
from time import sleep
from flask import Flask
from flask_socketio import SocketIO
SOCKET_NAMESPACE = '/test'
is_pushing = False
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!!'
socketio = SocketIO(app)
def server_push(fps):
dt = 1 / fps
global is_pushing
while is_pushing:
with app.test_request_context('/'):
sent = f"Server Pushed!! {random.random()}"
print(sent)
socketio.emit("serverResponse", sent, namespace=SOCKET_NAMESPACE)
sleep(dt)
#socketio.on('connect', namespace=SOCKET_NAMESPACE)
def on_connect():
print("connected server!!")
socketio.emit("serverResponse", "First Push", namespace=SOCKET_NAMESPACE)
#socketio.on('disconnect', namespace=SOCKET_NAMESPACE)
def on_disconnect():
print("disconnected server!!")
#socketio.on('startServerPush', namespace=SOCKET_NAMESPACE)
def on_start_server_push(fps=1):
print("Sever push start!!")
global is_pushing
is_pushing = True
socketio.emit("serverResponse", "Start Push", namespace=SOCKET_NAMESPACE)
Thread(target=lambda: server_push(fps)).start()
#socketio.on("killServerPush", namespace=SOCKET_NAMESPACE)
def on_kill_server_push():
print("Server push stop!!")
global is_pushing
is_pushing = False
socketio.emit("serverResponse", "Kill Push", namespace=SOCKET_NAMESPACE)
def main():
socketio.run(app, port=8082, debug=True)
if __name__ == '__main__':
main()
Client Side
import openSocket from 'socket.io-client';
import React, { Component } from 'react';
class Test extends Component {
state = {
pushedFromServer: [],
socket: null
};
componentDidMount() {
const url = 'localhost:8082/test';
const socket = openSocket(url);
socket.on('connect', () => console.log('Test connected!!'));
socket.on('disconnect', () => console.log('Test disconnected!!'));
socket.on('serverResponse', response => {
console.log(response);
const pushedFromServer = [...this.state.pushedFromServer];
pushedFromServer.push(response);
this.setState({ pushedFromServer });
});
this.setState({ socket });
}
killServerPush = () => {
this.state.socket.emit('killServerPush');
};
startServerPush = () => {
this.state.socket.emit('startServerPush');
};
render() {
return (
<div>
<button onClick={this.startServerPush}>
<h3>Start push from server</h3>
</button>
<button onClick={this.killServerPush}>
<h3>Kill push from server</h3>
</button>
<ul>
{this.state.pushedFromServer.map(value => (
<li>{value}</li>
))}
</ul>
</div>
);
}
}
export default Test;
Final Notes
In the client, I could receive the First Push, and the Start Push, I am also able to stop the periodic process from the client and restart it. I am not able to receive the periodic messages on the client.
Thanks
By looking at https://github.com/miguelgrinberg/python-socketio/issues/99, I found a solution to the issue.
Just need to change the server side.
Change line:
Thread(target=lambda: server_push(fps)).start()
to
socketio.start_background_task(target=lambda: server_push(fps))
And instead of using python sleep, use:
socketio.sleep(dt)

WebSocket with angular 6 gets destroyed

I'm trying to learn how to use WebSocket with a python backend and an Angular 6 front end.
It looks like the WebSocket connection gets destroy as the updates does only work when I put a breakpoint on the following line:
ngOnInit() {
this.sub = this.socketService.getQuotes()
.subscribe(quote => {
console.log('got price: ' + quote);
this.price = quote;
});
} // breakpoint
The backend is pretty simple:
def send_market_price():
threading.Timer(5.0, send_market_price).start()
print('sending price ws')
socketio.emit('market', market.update_market())
if __name__ == '__main__':
send_market_price()
print('starting')
socketio.run(app)
the service is basic too:
#Injectable()
export class SocketService {
public socket;
public observer: Observer<number>;
getQuotes(): Observable<number> {
this.socket = socketio(SERVER_URL);
this.socket.on('market', (res) => {
this.observer.next(res);
});
return this.createObservable();
}
createObservable(): Observable<number> {
return new Observable(observer => {
this.observer = observer;
});
}
Is there anything wrong in my code to do this basic feature?
EDIT
after some tests, it looks like that the backend is bugged. I did the same thing getting a Node.js code and it works great.
What is wrong with this python code:
import threading
from flask import Flask, jsonify
from flask_cors import CORS
from flask_socketio import SocketIO
from market_engine import market
from market_engine.market import RandomMarket
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
CORS(app)
market = RandomMarket()
#socketio.on('connect')
def connect():
print('Client connected')
#socketio.on('disconnect')
def disconnect():
print('Client disconnected')
def send_market_price():
threading.Timer(5.0, send_market_price).start()
print('sending price ws')
socketio.emit('market', market.update_market())
if __name__ == '__main__':
send_market_price()
print('starting')
socketio.run(app)

Categories