Exception has occurred: NotImplementedError - python-3.x

Executed this for the first time and getting exception at app.listen(port)
import tornado.web
import tornado.ioloop
class basicRequestHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, World this is a python command executed from the backend.")
if __name__ == "__main__":
app = tornado.web.Application([
(r"/", basicRequestHandler)
])
port = 8882
app.listen(port)#Getting exception here
print(f"Application is ready and listening on port {port}")
tornado.ioloop.IOLoop.current().start()

in python 3.8:
import tornado.ioloop
import tornado.web
import asyncio
class basicRequestHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, World this is a python command executed from the backend.")
if __name__ == "__main__":
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
app = tornado.web.Application([
(r"/", basicRequestHandler)
])
port = 8882
app.listen(port)
print(f"Application is ready and listening on port {port}")
tornado.ioloop.IOLoop.current().start()

#gdi313's answer is correct, but let me explain why we have to include asyncio into our code,
till python3.7 Tornado selects 'WindowsSelectorEventLoop' as default, whereas python 3.8 default is not compatible with windows
Thats is why if your application runs on windows using tornado have to have line
"asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())" at the beginning
Hope this is useful to someone who is facing the error!
https://github.com/tornadoweb/tornado/pull/2686/files

Related

How to send ros2 messages from a websocket server to connected clients in tornado

I have a ros2 publisher script that sends custom messages from ros2 nodes. What I need to do is to have a subscriber (which is also my websocket server) to listen to the message that the pulisher sends then convert it to a dictionary and send it as a json from the websocket server to a connected websocket client. I have already checked the rosbridge repo but I could not make it work. It doesn't have enough documentation and I am new to ros.
I need something like this:
import rclpy
import sys
from rclpy.node import Node
import tornado.ioloop
import tornado.httpserver
import tornado.web
import threading
from custom.msg import CustomMsg
from .convert import message_to_ordereddict
wss = []
class wsHandler(tornado.websocket.WebSocketHandler):
def open(self):
print 'Online'
if self not in wss:
wss.append(self)
def on_close(self):
print 'Offline'
if self in wss:
wss.remove(self)
def wsSend(message):
for ws in wss:
ws.write_message(message)
class MinimalSubscriber(Node):
def __init__(self):
super().__init__('minimal_subscriber')
self.subscription = self.create_subscription(CustomMsg, 'topic', self.CustomMsg_callback, 10)
self.subscription # prevent unused variable warning
def CustomMsg_callback(self, msg):
ws_message = message_to_ordereddict(msg)
wsSend(ws_message)
if __name__ == "__main__":
http_server = tornado.httpserver.HTTPServer(tornado.web.Application(wsHandler))
http_server.listen(8888)
main_loop = tornado.ioloop.IOLoop.instance()
# Start main loop
main_loop.start()
so the callback function in MinimalSubscriber class, receives the ros message, converts it to dictionary and sends it to websocket client. I am a bit confused how to make these two threads (ros and websocket) to communicate with each other.
So I think I got a bit confused myself going through the threading. So I changed my approach and made it work using the tornado periodic callback and the spin_once function of rclpy as the callback function. I would post my solution as it might help some people who has the same issue.
import queue
import rclpy
from rclpy.node import Node
import tornado.ioloop
import tornado.httpserver
import tornado.web
from custom.msg import CustomMsg
from .convert import message_to_ordereddict
wss = []
class wsHandler(tornado.websocket.WebSocketHandler):
#classmethod
def route_urls(cls):
return [(r'/',cls, {}),]
def open(self):
print 'Online'
if self not in wss:
wss.append(self)
def on_close(self):
print 'Offline'
if self in wss:
wss.remove(self)
def make_app():
myWebHandler = wsHandler.route_urls()
return tornado.web.Application(myWebHandler)
message_queue = queue.Queue
class MinimalSubscriber(Node):
def __init__(self):
super().__init__('minimal_subscriber')
self.subscription = self.create_subscription(CustomMsg, 'topic', self.CustomMsg_callback, 10)
self.subscription # prevent unused variable warning
def CustomMsg_callback(self, msg):
msg_dict = message_to_ordereddict(msg)
msg_queue.put(msg_dict)
if __name__ == "__main__":
rclpy.init(args=args)
minimal_subscriber = MinimalSubscriber()
def send_ros_to_clients():
rclpy.spin_once(minimal_subscriber)
my_msg = msg_queue.get()
for client in ws_clients:
client.write_message(my_msg)
app = make_app()
server = tornado.httpserver.HTTPServer(app)
server.listen(8888)
tornado.ioloop.PeriodicCallback(send_ros_to_clients, 1).start()
tornado.ioloop.IOLoop.current().start()
minimal_subscriber.destroy_node()
rclpy.shutdown()
I also implemented the wsSend function into the send_ros_to_clients function. Some might say that using a global queue is not the best practice but I could not come up with another solution. I would appreciate any suggestions or corrections on my solution.

How to run Flask SocketIO in a thread?

I'm trying to run Flask SocketIO in thread using Python 3 and I cannot get it to work.
My code will not continue in my while loop.
How can I run it in thread?
import threading
from flask import Flask, render_template, request, redirect, url_for
from flask_socketio import SocketIO
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
#turn the flask app into a socketio app
socketio = SocketIO(app)
#app.route("/")
def index():
return render_template('index.html', **templateData)
if __name__ == "__main__":
threading.Thread(target=socketio.run(app),kwargs=dict(debug=False, use_reloader=False,host='0.0.0.0', port=5000)).start()
sleep(2)
while True:
try:
Print("Hello I'm in a while loop")
except KeyboardInterrupt:
sys.exit()
you should pass socketio.run as target, and app as argument
threading.Thread(
target=socketio.run,
args=(app,),
kwargs=dict(debug=False, use_reloader=False,host='0.0.0.0', port=5000)
).start()
also seems like you forget to import sleep from time
from time import sleep
and also please notice that templateData is not defined in code

Uvicorn not running sanic "before_server_start"

I have a sanic app like so:
from functools import wraps
import os
from sanic import Sanic
from sanic.response import json
from es_api.client import ElasticEngine
from utils import cleanup
app = Sanic(__name__)
async def setup_es_client(app, loop):
app.es_client = ElasticEngine.from_bonsai("xkcd_production", test_instance=False)
#app.route("/", methods=["GET"])
async def home(request):
return json({"hello": "worldddd"})
#app.route("/all", methods=["GET"])
async def display_all_docs(request):
results = app.es_client.search_all().results()
return json(
{"results": results}
)
if __name__ == "__main__":
app.register_listener(setup_es_client,
'before_server_start')
app.run(host="0.0.0.0", port=8000, debug=True, workers=20)
When I run uvicorn myapp, it serves the homepage fine: I see the expected json.
But when I hit /all, it says
"app has not attribute es_client"
, which presumably indicates that the before_server_start function hasn't been run.
How do I fix this? I've looked into the sanic doc but I couldn't find any references to this issue
(It works fine when I run the app as is -- i.e, python3 myapp.py)
Fixed.
Move app.register_listener(setup_es_client,
'before_server_start') above if __name__=="__main__"
Better yet, just use sanic's builtin decorator for nicer ergonomics: https://sanic.readthedocs.io/en/latest/sanic/middleware.html

why daemon process terminate

I use python-daemon for my home project. But I not understand why daemon teminated after 1 day working.
this my code:
import requests
import time
import subprocess
import os
import lockfile
import daemon
import logging
import signal
import sys
Class MyDaemon():
def run(self):
while True:
try:
self.check_updates()
time.sleep(5)
except ConnectionError as e:
self.log.error('Connerction Error')
time.sleep(120)
except (OSError, IOError) as e:
self.log.error('I/O Error')
time.sleep(120)
except Exception as e:
self.log.error('Exception: '.format(e.__class__))
time.sleep(120)
if __name__ == "__main__":
bot = MyDaemon()
context = daemon.DaemonContext(
working_directory=bot.path,
umask=0o002,
pidfile=lockfile.FileLock('/tmp/mydaemon.pid'),
)
# exit()
if context.pidfile.is_locked():
exit('daemon is running now!')
#context.signal_map = {signal.SIGHUP: 'terminate',
# signal.SIGUSR1: bot.reload_bot(),
# signal.SIGTERM: bot.exit_bot(),
# }
context.files_preserve = [bot.fh.stream] # logging
with context:
bot.run()
This privat bot for telegram. In function check_updates(self) send request and treats response for server It's func normali workink in shell(tmux on server). In function run() I catch all exceptions (at least i think so :) ) but this path not workin where i wrong?
Thank's

how to use epoll on tornado

i am trying to make epoll work on tornado
import tornado.ioloop
import tornado.web
from tornado.platform.epoll import EPollIOLoop
from tornado import web, gen
class MainHandler(tornado.web.RequestHandler):
#web.asynchronous
#gen.engine
def get(self):
self.write("Hello, world")
application = tornado.web.Application([
(r"/", MainHandler),
])
if __name__ == "__main__":
application.listen(8888)
EPollIOLoop().start()
but when i start the program and visit the url localhost:8888/ it didn't return anything.
is that my system didn't meet the requirement?my linux version was Ubuntu 12.04.1 LTS.
Just use tornado.ioloop.IOLoop.instance(). It choose best IOLoop for your platform.
if __name__ == "__main__":
application.listen(8888)
ioloop = tornado.ioloop.IOLoop.instance()
print ioloop # prints <tornado.platform.epoll.EPollIOLoop object at ..>
ioloop.start()
You should call self.finish() if you use asynchronous decorator:
If this decorator is given, the response is not finished when the
method returns. It is up to the request handler to call self.finish()
to finish the HTTP request. Without this decorator, the request is
automatically finished when the get() or post() method returns.
class MainHandler(tornado.web.RequestHandler):
#web.asynchronous
#gen.engine
def get(self):
self.write("Hello, world")
self.finish()

Resources