socket.io client doens't catch the events from flask-socketio server - flask

I have a very basic setup
flask-socketio app
from flask import Flask, render_template, request
from flask_socketio import SocketIO
logger = logging.getLogger('mainLogger')
level = logging.DEBUG
logger.setLevel(level)
app = Flask(__name__)
socketio = SocketIO(app, manage_session=True, cors_allowed_origins="*")
#app.route('/')
def homepage():
return render_template(
"test.html"
)
# Tfrom flask import Flask, render_template, request
from flask_socketio import SocketIO
app = Flask(__name__)
socketio = SocketIO(app, manage_session=True, cors_allowed_origins="*")
#app.route('/')
def homepage():
return render_template(
"test.html"
)
#app.route('/testMessages', methods=['GET'])
def testMessages():
_session = request.args.get('session')
print(_session)
socketio.emit('message', {'session': _session})
return "OK"est function to validate multiple concurrent calls
#app.route('/testMessages', methods=['GET'])
def testMessages():
_session = request.args.get('session')
print(_session)
socketio.emit('message', {'session': _session})
return "OK"
if __name__ == '__main__':
socketio.run(app)
and the test html with socket.io client
<button id="testMessage" class="float-right btn btn-wok my-2 my-sm-0 btn-sm ml-1 mt-2" type="submit" >Run Test</button>
<footer>
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/3.0.4/socket.io.js"></script>
</footer>
<script>
var url=document.URL, shortUrl=url.substring(0,url.lastIndexOf("/"));
var sessionId = "1234567890";
function testMessages(){
console.log('TESTMESSAGES')
$.getJSON(
shortUrl + '/testMessages?session=' + sessionId, {}, function(data) {
console.log('WOW')
console.log(data)
}
);
return false;
}
$(function() {
$('#testMessage').on('click', function() {
testMessages();
});
});
$(document).ready(function(){
console.log('DOCUMENT READY')
const socket = io("http://localhost:5000/socket.io");
socket.on("connect", () => {
console.log(socket.disconnected); // false
});
socket.on("disconnect", (reason) => {console.log(`disconnect ${reason}`)})
socket.on('message', function(message) {
console.log("Received message: " + message);
});
console.log(socket);
});
</script>
it's just the button that hits /testMessages endpoint.
What I see:
when I connect to the http://127.0.0.1:5000/ socket says it's properly connected.
'connect' event is properly captured.
when click on the button, that function on server is successfully called.
The issue is that calling socketio.emit(, ) is not seen on the website like at all.
When server is shut down the 'disconnect' event is properly captured.
I'm struggling to understand what is not working
[UPDATE] Server side logs.
127.0.0.1 - - [11/Apr/2021 20:18:49] "POST /socket.io/?EIO=4&transport=polling&t=NZ2A64b&sid=HkWPPEUTctR_6I7TAAAA HTTP/1.1" 200 -
127.0.0.1 - - [11/Apr/2021 20:18:49] "GET /socket.io/?EIO=4&transport=polling&t=NZ2A64c&sid=HkWPPEUTctR_6I7TAAAA HTTP/1.1" 200 -
127.0.0.1 - - [11/Apr/2021 20:18:52] "GET /socket.io/?EIO=4&transport=polling&t=NZ2A6tn HTTP/1.1" 200 -
127.0.0.1 - - [11/Apr/2021 20:18:52] "POST /socket.io/?EIO=4&transport=polling&t=NZ2A6vW&sid=PtEmmdsmPR908dcrAAAC HTTP/1.1" 200 -
127.0.0.1 - - [11/Apr/2021 20:18:52] "GET /socket.io/?EIO=4&transport=polling&t=NZ2A6vY&sid=PtEmmdsmPR908dcrAAAC HTTP/1.1" 200 -
127.0.0.1 - - [11/Apr/2021 20:18:54] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [11/Apr/2021 20:18:55] "GET /socket.io/?EIO=4&transport=polling&t=NZ2A7Q- HTTP/1.1" 200 -
127.0.0.1 - - [11/Apr/2021 20:18:55] "POST /socket.io/?EIO=4&transport=polling&t=NZ2A7SR&sid=IdQeK-qNbpEyBLx7AAAE HTTP/1.1" 200 -
127.0.0.1 - - [11/Apr/2021 20:18:55] "GET /socket.io/?EIO=4&transport=polling&t=NZ2A7SS&sid=IdQeK-qNbpEyBLx7AAAE HTTP/1.1" 200 -
1234567890
message was received!
emitting event "message" to all [/]
client side logs in the browser console
(index):35 DOCUMENT READY
(index):44 Socket {ids: 0, acks: {…}, receiveBuffer: Array(0), sendBuffer: Array(0), flags: {…}, …}
(index):19 TESTMESSAGES

Related

Flask REST API very slow on simple endpoint

I'm using a Flask REST API for my application and I've noticed that when I send requests from outside my own network, it's sometimes very, very slow. Most calls get completed within 150ms, but some take 8 seconds. The database connection is to a MySQL database using DBUtils.PersistentDB
The code for the endpoint:
#app.route("/name", methods=["POST"])
#jwt_refresh_token_required
def get_name_and_company():
user = get_jwt_identity()
response_object = server_functions.get_name_and_company(user)
return response_object
The function it uses:
def get_name_and_company(user):
sql = "SELECT fysios.firstname, fysios.lastname, companies.name FROM
fysios " +\
"INNER JOIN companies ON fysios.companyID = companies.id WHERE fysios.email = %s"
cursor = flask_server.get_db().cursor()
cursor.execute(sql, user)
data = cursor.fetchall()
first_name = data[0]['firstname']
last_name = data[0]['lastname']
company = data[0]['name']
response_object = name_and_company(first_name, last_name, company)
return make_response(jsonify(response_object)), 200
Here are the timestamps on the Flask server (it is the internal dev server, but I am running it with threaded=True):
[08/Mar/2019 22:16:54] "OPTIONS /login HTTP/1.1" 200 -
[08/Mar/2019 22:16:55] "POST /login HTTP/1.1" 200 -
[08/Mar/2019 22:16:55] "OPTIONS /clients HTTP/1.1" 200 -
[08/Mar/2019 22:16:55] "OPTIONS /verifyLogin HTTP/1.1" 200 -
[08/Mar/2019 22:16:55] "POST /clients HTTP/1.1" 200 -
[08/Mar/2019 22:16:57] "POST /verifyLogin HTTP/1.1" 200 -
[08/Mar/2019 22:16:57] "OPTIONS /name HTTP/1.1" 200 -
[08/Mar/2019 22:16:58] "POST /clients HTTP/1.1" 200 -
[08/Mar/2019 22:17:05] "POST /name HTTP/1.1" 200 -
As you can see, /name takes a total of 8 seconds and I can't find out why. This call to /name is just an example, it can happen on any of the calls. Is there a way to find out where the Flask application is actually stuck on?
Deploying to AWS Beanstalk solved the problem. I don't know if the limitations of the build-in dev server is to blame, but that's what did it for me.

Random HTTP 500 error Django

I've been having an issue with a HTTP 500 error. It doesn't seem to cause any real problems until a few hours after the error has been shown. After the error shows up the script begins to act abnormally, giving hangups on controlling a relay and degrading in response time.
I checked my logs both in the pi and the server side and below is what I found but I can't figure out what my issue is since it seems so random, the HTTP request typically returns a 200 status and runs fine.
On the pi:
tail applocation/errors.log
2018-03-05 06:38:33 [HTTP Error] While sending data to remote Server: HTTP Error 500: Internal Server Error
2018-03-05 09:08:50 [HTTP Error] While sending data to remote Server: HTTP Error 500: Internal Server Error
on the server:
This is where it gets weird because most of the time it returns 200 but like I said every so often it gives a 500 error.
cat /var/log/ngnix/access.log | grep 9:0
47.176.12.130 - - [05/Mar/2018:09:08:29 -0800] "POST /api/1.0/access/add/ HTTP/1.1" 200 43 "-" "Python-urllib/3.4"
47.176.12.130 - - [05/Mar/2018:09:08:50 -0800] "POST /api/1.0/access/add/ HTTP/1.1" 500 38 "-" "Python-urllib/3.4"
47.176.12.130 - - [05/Mar/2018:09:09:28 -0800] "POST /api/1.0/access/add/ HTTP/1.1" 200 43 "-" "Python-urllib/3.4"
cat /var/log/ngnix/access.log | grep 500
raspberry.pi.ip - - [05/Mar/2018:06:38:33 -0800] "POST /api/1.0/access/add/ HTTP/1.1" 500 38 "-" "Python-urllib/3.4"
raspberry.pi.ip - - [05/Mar/2018:09:08:50 -0800] "POST /api/1.0/access/add/ HTTP/1.1" 500 38 "-" "Python-urllib/3.4"
in my urls.py inside my API:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^1.0/access/add/$', views.access_add, name='access_add'),
url(r'^1.0/employees/active/$', views.employees_active, name='employees_active'),
]
in my views.py inside my API:
#csrf_exempt
def access_add(request):
context = {
'status': 'error',
'msg' : ''
}
if request.method != 'POST':
context["msg"] = "This method only supports POST"
return JsonResponse(context)
try:
content = json.loads(request.body.decode('utf-8'))
except Exception as e:
context['msg'] = "Failed to load JSON parameters."
return JsonResponse(context)
key = content.get('key')
gate = content.get('gate')
code = content.get('code')
if key != KEY:
context['msg'] = "Please provide a valid API key."
return JsonResponse(context)
if gate not in ['entry','exit']:
context['msg'] = "Please provide a valid gate name."
return JsonResponse(context)
gate = 1 if gate == "entry" else 2
if not code:
context['msg'] = "Please provide an access code."
return JsonResponse(context)
context['status'] = "success"
try:
employee = Employee.objects.get(code=code)
Eventlog.objects.create(event=gate, employee=employee, status=True)
except Employee.DoesNotExist:
try:
Eventlog.objects.create(event=gate, status=False)
except:
pass
return JsonResponse(context)

Google and Twitter return empty user data on Flask

I don't understand what is wrong?
callback uri:
google - http://127.0.0.1:5000/auth/google/
twitter - http://127.0.0.1:5000/auth/tw/
config:
from authomatic.providers import oauth2, oauth1
SECRET_KEY = '####'
AUTH_CONFIG = {
'google': {
'class_': oauth2.Google,
'consumer_key': '####',
'consumer_secret': ####',
'scope': ['email',],
},
'tw': {
'class_': oauth1.Twitter,
'consumer_key': '####',
'consumer_secret': '####',
},
}
controller:
from authomatic.adapters import WerkzeugAdapter
from authomatic import Authomatic
from app import app, db
from app.models.users import User
authomatic = Authomatic(
app.config.get('AUTH_CONFIG'),
app.config.get('SECRET_KEY'),
report_errors=True
)
#app.route('/auth/<provider>/', methods=['GET', 'POST'])
def auth(provider):
print "REQUEST: ", request.args
response = make_response()
result = authomatic.login(WerkzeugAdapter(request, response), provider)
if result:
if result.user:
result.user.update()
if result.user.email:
user = User.query.filter(User.email == result.user.email).first()
if user is None:
user = User(nickname=result.user.name, email=result.user.email)
db.session.add(user)
db.session.commit()
flash('A new user profile has been created for you.')
return redirect(url_for('index'))
flash('Your provider return empty data, try again later.')
return redirect(url_for('index'))
return response
and after I accept access to app in google or twitter, I have redirected to index.html page with flash massage "Your provider return empty data, try again later"
in console I see:
google:
127.0.0.1 - - [29/Nov/2014 00:41:26] "GET /login/ HTTP/1.1" 200 -
REQUEST: ImmutableMultiDict([])
127.0.0.1 - - [29/Nov/2014 00:41:27] "GET /auth/google/ HTTP/1.1" 302 -
REQUEST: ImmutableMultiDict([('state', u'bbee8547ff97e001sdss61e6'), ('code', u'4/ZJRhjCqEzAVep9UL2epaTzYI')])
127.0.0.1 - - [29/Nov/2014 00:41:30] "GET /auth/google/?state=bbee8547ff97e001d3d77161e6&code=4/ZJRhjCqEzAVep9UL2epaTzYI HTTP/1.1" 302 -
127.0.0.1 - - [29/Nov/2014 00:41:30] "GET / HTTP/1.1" 200 -
twitter:
127.0.0.1 - - [29/Nov/2014 00:43:38] "GET /login/ HTTP/1.1" 200 -
REQUEST: ImmutableMultiDict([])
127.0.0.1 - - [29/Nov/2014 00:43:42] "GET /auth/tw/ HTTP/1.1" 302 -
REQUEST: ImmutableMultiDict([('oauth_token', u'KmF9L1m5CYUY9O6joIh0'), ('oauth_verifier', u'95sGsiRz5sTxZua88G')])
127.0.0.1 - - [29/Nov/2014 00:43:44] "GET /auth/tw/?oauth_token=KmF9L1m5CYUY9O6joIh0&oauth_verifier=95sGsiRz5sTxZua88G HTTP/1.1" 302 -
127.0.0.1 - - [29/Nov/2014 00:43:44] "GET / HTTP/1.1" 200 -
May be some thing wrong if i get 302 - on response???
Please help me!
I believe this is a setup issue on the Google Developer Console.
Under the APIs & auth settings of your project you need to authorize the API's you want access to, otherwise nothing will be returned in the results var.
If you inspect it you will see an error message from Google telling you to authorize API's.
Add the following API's from here: APIs & auth > APIs, select Google+ API, this will return the result dictionary with the values you are looking for.
from authomatic.providers import openid, oauth2
CONFIG = {
'oi': {
# OpenID provider dependent on the python-openid package.
'class_': openid.OpenID,
},
'google' : {
'class_': oauth2.Google,
'consumer_key': 'GOOGLE DEVELOPER CLIENT ID',
'consumer_secret': 'GOOGLE DEVELOPER CLIENT SECRET',
'scope': ['profile', 'email']
}
}
on your index.html you will want to trigger the call like:
Sign In With Google
That should trigger the call to the google oauth login.
#app.route('/login/<provider_name>/', methods=['GET', 'POST'])
def login(provider_name):
"""
Login handler, must accept both GET and POST to be able to use OpenID.
"""
# We need response object for the WerkzeugAdapter.
response = make_response()
# Log the user in, pass it the adapter and the provider name.
result = authomatic.login(WerkzeugAdapter(request, response), provider_name)
# If there is no LoginResult object, the login procedure is still pending.
if result:
if result.user:
# We need to update the user to get more info.
result.user.update()
# The rest happens inside the template.
#result.user.data.x will return further user data
return render_template('login.html', email=result.user.email, name=result.user.name)
# Don't forget to return the response.
return response

Trouble with Django + Bootstrap3 + typeahead.js remote fetching

I'm new to django and bootstrap3 and I've been trying to implement the typeahead by twitter.
my urls.py
url(r'^name_autocomplete/?q=$', 'home.views.name_autocomplete'),
my script:
<script type="text/javascript">
$(document).ready(function() {
$("#navPersonSearch").typeahead({
name: 'people',
remote: 'name_autocomplete/?q=%QUERY'
});
});
my view
def name_autocomplete(request):
query = request.GET.get('query','')
if(len(query) > 0):
print "hello"
results = Person.objects.filter(short__istartswith=query)
result_list = []
for item in results:
result_list.append(item.short)
else:
result_list = []
response_text = json.dumps(result_list, separators=(',',':'))
return HttpResponse(response_text, content_type="application/json")
The requests seem to be getting through from the console output:
[05/Oct/2013 01:34:12] "GET / HTTP/1.1" 200 2007
[05/Oct/2013 01:34:12] "GET /static/bootstrap/css/bootstrap.min.css HTTP/1.1" 304 0
[05/Oct/2013 01:34:12] "GET /static/bootstrap/css/typeahead.js-bootstrap.css HTTP/1.1" 304 0
[05/Oct/2013 01:34:12] "GET /static/bootstrap/js/typeahead.js HTTP/1.1" 304 0
[05/Oct/2013 01:34:15] "GET /name_autocomplete/?q=J HTTP/1.1" 200 2
[05/Oct/2013 01:34:30] "GET /name_autocomplete/?q=Jac HTTP/1.1" 200 2
But the typeahead isn't working.
Replace the urlpattern as follow (you should not specify query string part):
url(r'^name_autocomplete/$', 'home.views.name_autocomplete'),
And in the view, you get query, while the javascript send query string as q=; so replace the following line:
query = request.GET.get('query','')
with
query = request.GET.get('q','')

No handlers could be found for logger "stomp.py"

I'm trying to get Orbited running as per instructions on http://mischneider.net/?p=125
Here's a copy of the error:
Validating models...
0 errors found
Django version 1.3, using settings 'comet.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
[28/May/2011 11:43:36] "GET /comet/ HTTP/1.1" 200 2952
[28/May/2011 11:43:36] "GET /site_media/Orbited.js HTTP/1.1" 304 0
[28/May/2011 11:43:37] "GET /site_media/stomp.js HTTP/1.1" 304 0
[28/May/2011 11:44:18] "POST /addMessage/ HTTP/1.1" 403 2332
[28/May/2011 11:44:21] "POST /addMessage/ HTTP/1.1" 403 2332
[28/May/2011 11:44:40] "GET /comet/ HTTP/1.1" 200 2952
[28/May/2011 11:44:41] "GET /site_media/Orbited.js HTTP/1.1" 304 0
[28/May/2011 11:44:41] "GET /site_media/stomp.js HTTP/1.1" 304 0
No handlers could be found for logger "stomp.py"
[28/May/2011 12:00:36] "GET /comet/ HTTP/1.1" 200 2952
Also, when I load the page it gives me an error. Here's a selection of some of my files.
index.html:
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Django, Orbited, Stomp and Co.</title>
<script src="http://www.json.org/json2.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
<script src="/site_media/Orbited.js"></script>
<script>
// set the orbited settings and port
Orbited.settings.port = 9000;
Orbited.settings.hostname = "127.0.0.1";
//Orbited.settings.streaming = false;
TCPSocket = Orbited.TCPSocket
</script>
<script> document.domain = document.domain; </script>
<script src="/site_media/stomp.js"></script>
<script type="text/javascript" charset="utf-8">
function add_message(msg) {
$("<p>" + msg["user"] + ": " + msg["message"] + " at " + msg["time"] + "</p>").appendTo("#messages")
};
$(document).ready(function() {
stomp = new STOMPClient();
stomp.onopen = function(){
//console.log("opening stomp client");
};
stomp.onclose = function(c){
alert('Lost Connection, Code: ' + c);
};
stomp.onerror = function(error){
alert("Error: " + error);
};
stomp.onerrorframe = function(frame){
alert("Error: " + frame.body);
};
stomp.onconnectedframe = function(){
console.log("Connected. Subscribing");
//alert("subscribing");
stomp.subscribe("/messages");
};
stomp.onmessageframe = function(frame){
// Presumably we should only receive message frames with the
// destination "/topic/message" because that's the only destination
// to which we've subscribed. To handle multiple destinations we
// would have to check frame.headers.destination.
add_message(JSON.parse(frame.body));
};
stomp.connect('localhost', 61613);
$("#send").click(function(data) {
var message = $("#message").val()
var user = $("#user").val()
$.post("/addMessage/", {"message":message, "user":user});
})
});
</script>
</head>
<body id="index">
<div id="messages">
{% for message in messages %}
<p>{{message.user}}: {{message.body}} at {{message.time|date:"H:i-d/m/Y"}}</p>
{% endfor %}
</div>
<div id="new_message">
Text: <input type="text" name="message" value="" id="message"> Name: <input type="text" name="user" value="" id="user">
<p><button type="text" id="send" value="Submit a message">Submit a message</button><p>
</div>
</body>
orbited.cnf
[listen]
http://:9000
stomp://:61613
[access]
* -> localhost:61613
[global]
session.ping_interval = 300
# new logging configuration using the python stdlib logging.fileConfig
[loggers]
keys = root,orbited,orbited_TCPConnectionResource
[handlers]
keys = console,errors,connections
[formatters]
keys = generic
[logger_root]
level = INFO
handlers = console
[logger_orbited]
level = INFO
handlers = errors
qualname = orbited
[logger_orbited_TCPConnectionResource]
level = DEBUG
handlers = connections
qualname = orbited.cometsession.TCPConnectionResource
[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = INFO
formatter = generic
[handler_errors]
class = FileHandler
args = ('error.log', 'w')
level = INFO
formatter = generic
[handler_connections]
class = FileHandler
level = DEBUG
formatter = generic
args = ('connections.log', 'w')
[formatter_generic]
format = %(asctime)s,%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
urls:
from django.conf.urls.defaults import patterns, include, url
# Uncomment the next two lines to enable the admin:
# from django.contrib import admin
# admin.autodiscover()
from django.conf.urls.defaults import *
from stompapp.views import *
urlpatterns = patterns('',
(r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': 'C:/Users/Hunter/DjangoBackup/comet/static'}),
(r'^comet/', index),
(r'^addMessage/', addMessage),
(r'^site_media/(.*)$', 'django.views.static.serve', {'document_root': 'PATH_TO_YOUR_STATIC_FOLDER'}),
)
I hope my problem is somewhere in there? Thanks for the help :D
Also, when I load the page it gives me an error.
What exactly error? I guess you are talking something else than "No handlers could be found for logger "stomp.py"" message?