instead of client.terminate I tried client.stop, disconnect but the program continues to work smoothly
from pyrogram import Client
from pyrogram.handlers import MessageHandler
app = Client(name='345674565245693979010')
messages = []
def log(client, message):
messages.append(message.text)
print(*messages)
client.terminate()
app.add_handler(MessageHandler(log))
app.run()
the log() function stops working after receiving the message as planned, but for some reason the program works smoothly!
Related
So I believe the crux of my issue is that the python GPIO event detection is threaded, and so is the Socket.IO Emit stuff. I'm trying to call an Emit when a GPIO event detection fires. And I'm getting errors with not awaiting the socket.io.emit, when I attempt to throw an await in front of it I get bad syntax.
Anyway I'm simply trying to send messages up to a web client when an interrupt happens on the IO. For example an LED blink happens I want to send that up to the client. Using socket.io does the message to the client part, and GPIO interrupts via event detection does the other part (without tying up the app) I just need to send those event detections from GPIO to the socket.io emits somehow.
Also I'm using a Sanic web server.
Anyway here's the code:
sio = socketio.AsyncServer(async_mode='sanic')
app = Sanic()
sio.attach(app)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
#this gets called when the gpio.add_event_detect event is hit upon the gpio pin #going high (led lighting up). This works fine except sio.emit needs to be #awaited, but if I throw an await in front of it I get bad syntax, I put async #in front of the function def and then I get errors saying I never awaited the #function my_callback_one when it gets called from the GPIO.add_event_detect #event firing. I'm not sure what to do or if this is possible.
def my_callback_one(channel):
sio.emit('my_response', {'data': 'test'})
print('========button press LED lighting detected========')
GPIO.add_event_detect(18, GPIO.RISING, callback=my_callback_one)
#Starts the web application
if __name__ == "__main__":
app.run(host='0.0.0.0', port= 8090, workers=4)
Under normal circumstances I could do emits from the web server in a threaded fashion like so:
async def background_task():
count = 0
while count < 10:
await sio.sleep(.05)
print("message sent to client")
count += 1
await sio.emit('my_response', {'data': count})
pass
#app.listener('before_server_start')
def before_server_start(sanic, loop):
sio.start_background_task(background_task)
Which works fine, but as soon as I try to do that sio.emit from the gpio callback (another thread) I get issues with not awaiting the sio.emit. I've tried making my def my_callback_one(channel) asyc defined and that didn't help. (async def my_callback_one(channel))
I know this is a threading issue but I'm just not sure where to go with it.
Try to put a "#sio.event" before the function, telling sanic that is a socket event (with async and await also well). Here's an example:
https://github.com/miguelgrinberg/python-socketio/blob/master/examples/server/sanic/app.py
I am trying to print updates to my telegram acount . This is my code :
client = TelegramClient('session_name', api_id, api_hash, update_workers=4)
client.connect()
from telethon.tl.types import UpdateShortMessage, PeerUser
def callback(update):
print(1)
print('I received', update)
client.add_update_handler(callback)
whats wrong ? nothing prints .
First of all I suggest you add:
import logging
logging.basicConfig(level=logging.INFO)
So you can see what errors you are getting but can't yet see.
Significantly your program will end straight away because it never waits to receive any inbound messages. You will need to use something like client.loop.run_until_complete(somefunctionthattreadswater) at the end so that it hangs around until you press ctrl-C.
I'm trying to make an application that normally sends a request to a server and receives a response. If it would have been only that, I'd go with HTTP and call it a deal. But some requests to the server make a change for other clients, so I want the server to send all the affected clients a message that they should update.
For that, I've chosen WebSockets protocol and the Tornado library to work with it using Python. The simple message exchange was pretty straightforward, despite the asynchrony. However, the WebSocket client is really not that configurable and I've been struggling to make a client listen for incoming notifications without this interrupting the main message exchange.
The server part is represented by the tornado.websocket.WebSocketHandler, which has an on_message method:
from tornado.websocket import WebSocketHandler
class MyHandler(WebSocketHandler):
def on_message(self, message):
print('message:', message)
And I'd like something like that in the client part, which is only represented by a function tornado.websocket.websocket_connect (source). This function initiates a tornado.websocket.WebSocketClientConnection (source) object, which has an on_message method, but due to the entangled asynchronous structure, I haven't been able to override it properly, without breaking the main message exchange.
Another way I tried to go was the on_message_callback. This sounded like something I could use, but I couldn't figure out how to use it with read_message. This was my best attempt:
import tornado.websocket
import tornado.ioloop
ioloop = tornado.ioloop.IOLoop.current()
def clbk(message):
print('received', message)
async def main():
url = 'server_url_here'
conn = await tornado.websocket.websocket_connect(url, io_loop = ioloop, on_message_callback=clbk)
while True:
print(await conn.read_message()) # The execution hangs here
st = input()
conn.write_message(st)
ioloop.run_sync(main)
With this being the server code:
import tornado.ioloop
import tornado.web
import tornado.websocket
import os
class EchoWebSocket(tornado.websocket.WebSocketHandler):
def open(self):
self.write_message('hello')
def on_message(self, message):
self.write_message(message)
self.write_message('notification')
if __name__ == "__main__":
app = tornado.web.Application([(r"/", EchoWebSocket)])
app.listen(os.getenv('PORT', 8080))
tornado.ioloop.IOLoop.current().start()
I don't know what's going on here. Am I even going in the right direction with this?
There are two issues here:
Use on_message_callback or loop on await read_message(), but not both. If you give a callback the messages will only be passed to that callback and not saved for use by read_message.
input is blocking and doesn't play well with Tornado. It's fine in this little toy demo but if you want to do something like this in production you'll probably want to do something like wrap a PipeIOStream around sys.stdin and use stream.read_until('\n').
This is a simple example script from dev.deluge-torrent.org for interacting with the Deluge API.
Nothing happens after reactor.run() and I don't get the "Connection was successful" message, it just hangs forever.
I ran this on my Ubuntu machine where it works fine, but I couldn't get it to work on my Windows machine where i really want to put it to use.
from deluge.ui.client import client
# Import the reactor module from Twisted - this is for our mainloop
from twisted.internet import reactor
# Set up the logger to print out errors
from deluge.log import setupLogger
setupLogger()
# Connect to a daemon running on the localhost
# We get a Deferred object from this method and we use this to know if and when
# the connection succeeded or failed.
d = client.connect()
# We create a callback function to be called upon a successful connection
def on_connect_success(result):
print "Connection was successful!"
print "result:", result
# Disconnect from the daemon once we successfully connect
client.disconnect()
# Stop the twisted main loop and exit
reactor.stop()
# We add the callback to the Deferred object we got from connect()
d.addCallback(on_connect_success)
# We create another callback function to be called when an error is encountered
def on_connect_fail(result):
print "Connection failed!"
print "result:", result
# We add the callback (in this case it's an errback, for error)
d.addErrback(on_connect_fail)
# Run the twisted main loop to make everything go
reactor.run()
I have no idea of how to go about debugging this issue. I'm very new to Twisted, and from what I understand it's a huge library.
I have a jabber client that is reading from its stdin and posting PubSub messages. If I get EOF on stdin, I want to terminate the client.
I first tried sys.exit(), but this causes an exception and the client does not exit. I then did some searching and found out that I should call reactor.stop(), but I am unable to make this work. The following code in my client:
from twisted.internet import reactor
reactor.stop()
Results in exceptions.AttributeError: 'module' object has no attribute 'stop'
What do I need to do to cause twistd to shut my application down and exit?
EDIT 2
The original problem was caused by some symlinks messing up the module import. After fixing that problem, I get a new exception:
twisted.internet.error.ReactorNotRunning: Can't stop reactor that isn't running.
After the exception, twistd shuts down. I think this may be caused by the call to MyClient.loop in MyClient.connectionInitialized. Perhaps I need to defer the call until later?
EDIT
Here's the .tac file for my client
import sys
from twisted.application import service
from twisted.words.protocols.jabber.jid import JID
from myApp.clients import MyClient
clientJID = JID('client#example.com')
serverJID = JID('pubsub.example.com')
password = 'secret'
application = service.Application('XMPP client')
xmppClient = client.XMPPClient(clientJID, password)
xmppClient.logTraffic = True
xmppClient.setServiceParent(application)
handler = MyClient(clientJID, serverJID, sys.stdin)
handler.setHandlerParent(xmppClient)
Which I'm invoking with
twistd -noy sentry/myclient.tac < input.txt
Here's the code for MyClient:
import os
import sys
import time
from datetime import datetime
from wokkel.pubsub import PubSubClient
class MyClient(PubSubClient):
def __init__(self, entity, server, file, sender=None):
self.entity = entity
self.server = server
self.sender = sender
self.file = file
def loop(self):
while True:
line = self.file.readline()
if line:
print line
else:
from twisted.internet import reactor
reactor.stop()
def connectionInitialized(self):
self.loop()
from twisted.internet import reactor
reactor.stop()
that should work. The fact that it doesn't means something else is wrong on your application. I can't figure out what's wrong from the information you provided.
Can you provide more (all) of the code?
EDIT:
Ok, now the problem is that you don't stop your own while True loop, so it will keep looping and eventually stop the reactor again.
Try this:
from twisted.internet import reactor
reactor.stop()
return
Now, I suspect your loop isn't very good thing for a event-driven framework. While you're just printing lines, it is fine, but depending on what you want to really do (I suspect you'll do more than just print lines) you'll have to refactor that loop to work with events.
Use reactor.callFromThread(reactor.stop) instead of reactor.stop. This should solve the issue.
I used to do this way (in sigint handler of a non-twistd called application):
reactor.removeAll()
reactor.iterate()
reactor.stop()
I'm not 100% sure it is the right way, but twisted is happy
the same application started in a tac is handled directly by twistd signal handler, I've found this question because I have some rpc client requests that I would to wait for and handle result before exiting and looks like twistd is just killing the reactor without letting the call finish