[Twisted-Python] attribute error when I am trying to make one factory to send data to another
I am working on this messaging app and I would like to pass data from one factory to another. I have been referencing to other answers provided in other similar questions by trying to add a variable storing the data from one factory then initiate another factory and write the data to it. Unfortunately there is an error when i call the other class, and I cannot figure out why. Is there anything I can do to fix it? I have been stuck in here for quite a while this is the error: receivermessage = self.factory.app.handle_message2(data) exceptions.AttributeError: MultiEcho instance has no attribute 'factory' Here is the code: import kivyfrom kivy.app import Appfrom kivy.uix.label import Labelfrom kivy.uix.scatter import Scatterfrom kivy.uix.boxlayout import BoxLayoutfrom kivy.uix.scrollview import ScrollViewfrom kivy.uix.button import Buttonfrom kivy.graphics.vertex_instructions import Rectanglefrom kivy.graphics.context_instructions import Colorfrom kivy.graphics.instructions import Instructionfrom kivy.base import runTouchAppfrom kivy.lang import Builderimport socketfrom kivy.core.window import Windowimport pygameimport randomfrom kivy.support import install_twisted_reactor install_twisted_reactor()from twisted.internet import reactor, protocol Window.size = (550, 400) # monitoring wordlistwith open("wordlist.txt") as word_file: wordlist = list(word.strip().lower() for word in word_file) # protocols for senderclass EchoProtocol(protocol.Protocol): """This is just about the simplest possible protocol""" def dataReceived(self, data): "As soon as any data is received, write it back." sendermessage = self.factory.app.handle_message(data) if sendermessage: self.transport.write(data) #this line here is the trouble maker that caused the error MultiEcho().dataReceived(sendermessage) class EchoFactory(protocol.Factory): protocol = EchoProtocol def __init__(self, app): self.app = app # protocols for receiver class MultiEcho(protocol.Protocol): def connectionMade(self): self.factory.echoers.append(self) def dataReceived(self, data): receivermessage = self.factory.app.handle_message2(data) if receivermessage: self.transport.write(data) #this line here is the trouble maker that caused the error EchoProtocol().dataReceived(receivermessage) class MultiEchoFactory(protocol.Factory): protocol = MultiEcho def __init__(self, app): self.echoers = [] self.app = app class ServerApp(App): def build(self): self.layout = BoxLayout(orientation='vertical', spacing=10) self.label = Button(text='Censoring process begin\nBeware of keyword "umbrella"\n ', color=[1.0, 1.0, 1.0, 1.0]) self.label.color = [0.9, 0.2, 0.2, 1.0] self.upperscroll = Button(pos_hint={'x': 0, 'center_y': .5}, size_hint=(None, None)) self.scatter = Scatter() self.displaybox = Label() self.displaybox.color = [0.4, 0.9, 0.4, 1.0] reactor.listenTCP(8000, EchoFactory(self)) # for sender reactor.listenTCP(8001, MultiEchoFactory(self)) # for receiver self.layout.add_widget(self.label) self.layout.add_widget(self.scatter) self.scatter.add_widget(self.displaybox) return self.layout def handle_message(self, msg): if any(word in msg.lower() for word in wordlist): self.displaybox.color = [0.9, 0.4, 0.4, 1.0] self.displaybox.text = "content blocked" self.label.text += "Alert! Sender posts %s \n" % msg else: self.label.text += "Safe - sender posts %s \n" % msg self.displaybox.color = [0.4, 0.9, 0.4, 1.0] self.displaybox.text = "%s" % msg msg = msg return msg def handle_message2(self, msg): if any(word in msg.lower() for word in wordlist): self.label.color = [0.8, 0.8, 0.5, 1.0] self.label.text += "Alert! Receiver got %s \n" % msg else: self.label.color = [0.2, 0.2, 1.0, 1.0] self.label.text += "Safe - receiver sends %s \n" % msg msg = msg return msg if __name__ == '__main__': ServerApp().run()
Hi Jessica,
On Apr 28, 2015, at 10:14 AM, Jessica Tsui <jesadjust@gmail.com> wrote: SNIP exceptions.AttributeError: MultiEcho instance has no attribute ‘factory' SNIP MultiEcho().dataReceived(sendermessage) Here you create an instance of the protocol directly, i.e., without having instantiated a MutilEchoFactory. The factory’s buildProtocol method is what assigns the factory instance as a member of the protocol (self.factory), and since you didn’t create the protocol via a factory, you have no factory attribute on your protocol instance.
There are a number of ways to fix this, but generally speaking, you need to provide a way for your factories and their protocols to be aware of each other. Hope this helps, Daniel -- L. Daniel Burr ldanielburr@me.com (312) 656-8387
Hi Daniel, Thank you so much for your suggestion. I am quite new to python and twisted so I am not very certain about how to make it work well. Does that mean if I change the dataReceived by adding a line to instantiate the MultiEchoFactory like this, it will work? def dataReceived(self, data): "As soon as any data is received, write it back." handlesendermessage = self.factory.app.handle_message(data) if handlesendermessage: self.transport.write(data) MultiEchoFactory() MultiEcho().dataReceived(data) 2015-04-29 0:33 GMT+08:00 Louis D. Burr <ldanielburr@me.com>:
Hi Jessica,
On Apr 28, 2015, at 10:14 AM, Jessica Tsui <jesadjust@gmail.com> wrote:
SNIP
exceptions.AttributeError: MultiEcho instance has no attribute ‘factory'
SNIP
MultiEcho().dataReceived(sendermessage)
Here you create an instance of the protocol directly, i.e., without having instantiated a MutilEchoFactory. The factory’s buildProtocol method is what assigns the factory instance as a member of the protocol (self.factory), and since you didn’t create the protocol via a factory, you have no factory attribute on your protocol instance.
There are a number of ways to fix this, but generally speaking, you need to provide a way for your factories and their protocols to be aware of each other.
Hope this helps,
Daniel -- L. Daniel Burr ldanielburr@me.com (312) 656-8387
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
No, I don't think that would work. You would need something like changing these lines: reactor.listenTCP(8000, EchoFactory(self)) # for sender reactor.listenTCP(8001, MultiEchoFactory(self)) # for receiver to: self.echofactory = EchoFactory(self) self.multiechofactory = MultiEchoFactory(self) reactor.listenTCP(8000, self.echofactory) # for sender reactor.listenTCP(8001, self.multiechofactory) # for receiver so, your "app" object (which is just a normal Python object) knows the other two objects (the instances of the 2 factories). Then, your calls: if sendermessage: self.transport.write(data) #this line here is the trouble maker that caused the error MultiEcho().dataReceived(sendermessage) could be written: if sendermessage: self.transport.write(data) self.app.multiechofactory.dataReceived(sendermessage) On Tue, Apr 28, 2015 at 6:28 PM, Jessica Tsui <jesadjust@gmail.com> wrote:
Hi Daniel,
Thank you so much for your suggestion. I am quite new to python and twisted so I am not very certain about how to make it work well. Does that mean if I change the dataReceived by adding a line to instantiate the MultiEchoFactory like this, it will work?
def dataReceived(self, data): "As soon as any data is received, write it back." handlesendermessage = self.factory.app.handle_message(data)
if handlesendermessage: self.transport.write(data) MultiEchoFactory() MultiEcho().dataReceived(data)
2015-04-29 0:33 GMT+08:00 Louis D. Burr <ldanielburr@me.com>:
Hi Jessica,
On Apr 28, 2015, at 10:14 AM, Jessica Tsui <jesadjust@gmail.com> wrote:
SNIP
exceptions.AttributeError: MultiEcho instance has no attribute ‘factory'
SNIP
MultiEcho().dataReceived(sendermessage)
Here you create an instance of the protocol directly, i.e., without having instantiated a MutilEchoFactory. The factory’s buildProtocol method is what assigns the factory instance as a member of the protocol (self.factory), and since you didn’t create the protocol via a factory, you have no factory attribute on your protocol instance.
There are a number of ways to fix this, but generally speaking, you need to provide a way for your factories and their protocols to be aware of each other.
Hope this helps,
Daniel -- L. Daniel Burr ldanielburr@me.com (312) 656-8387
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
On Tue, Apr 28, 2015 at 6:46 PM, Pantelis Theodosiou <ypercube@gmail.com> wrote:
No, I don't think that would work.
You would need something like changing these lines:
reactor.listenTCP(8000, EchoFactory(self)) # for sender reactor.listenTCP(8001, MultiEchoFactory(self)) # for receiver
to:
self.echofactory = EchoFactory(self) self.multiechofactory = MultiEchoFactory(self) reactor.listenTCP(8000, self.echofactory) # for sender reactor.listenTCP(8001, self.multiechofactory) # for receiver
so, your "app" object (which is just a normal Python object) knows the other two objects (the instances of the 2 factories).
Then, your calls:
if sendermessage: self.transport.write(data) #this line here is the trouble maker that caused the error MultiEcho().dataReceived(sendermessage)
could be written:
if sendermessage: self.transport.write(data)
self.app.multiechofactory.dataReceived(sendermessage)
Oh, I messed it up. The first part is good but the factories do not have dataReceived methods. It would have to be - depending on what you want to do - say, you want to echo to all echoers: if sendermessage: self.transport.write(data) for echoer in self.app.multiechofactory.echoers: echoer.dataReceived(sendermessage) or: if sendermessage: self.transport.write(data) self.app.multiechofactory.echo_them_all() and define the echo_them_all() method in the MultiEchoFactory() class.
On Tue, Apr 28, 2015 at 6:28 PM, Jessica Tsui <jesadjust@gmail.com> wrote:
Hi Daniel,
Thank you so much for your suggestion. I am quite new to python and twisted so I am not very certain about how to make it work well. Does that mean if I change the dataReceived by adding a line to instantiate the MultiEchoFactory like this, it will work?
def dataReceived(self, data): "As soon as any data is received, write it back." handlesendermessage = self.factory.app.handle_message(data)
if handlesendermessage: self.transport.write(data) MultiEchoFactory() MultiEcho().dataReceived(data)
2015-04-29 0:33 GMT+08:00 Louis D. Burr <ldanielburr@me.com>:
Hi Jessica,
On Apr 28, 2015, at 10:14 AM, Jessica Tsui <jesadjust@gmail.com> wrote:
SNIP
exceptions.AttributeError: MultiEcho instance has no attribute ‘factory'
SNIP
MultiEcho().dataReceived(sendermessage)
Here you create an instance of the protocol directly, i.e., without having instantiated a MutilEchoFactory. The factory’s buildProtocol method is what assigns the factory instance as a member of the protocol (self.factory), and since you didn’t create the protocol via a factory, you have no factory attribute on your protocol instance.
There are a number of ways to fix this, but generally speaking, you need to provide a way for your factories and their protocols to be aware of each other.
Hope this helps,
Daniel -- L. Daniel Burr ldanielburr@me.com (312) 656-8387
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
Pantellis thank you so much for your guide! I am still quite unfamiliar with python and twisted so I made all kind of silly mistakes and could not figure out how to fix them I tried your code, it seems to me that it should be working with by referencing the factories as well as the self.app...Unfortunately when I ran it it did not work well, the program has an error with your line for echoer in self.app.multiechofactory.echoers: echoer.dataReceived(sendermessage) The error is: exceptions.AttributeError: MultiEcho instance has no attribute 'app' I thought that the "app" has already been referenced? 2015-04-29 1:55 GMT+08:00 Pantelis Theodosiou <ypercube@gmail.com>:
On Tue, Apr 28, 2015 at 6:46 PM, Pantelis Theodosiou <ypercube@gmail.com> wrote:
No, I don't think that would work.
You would need something like changing these lines:
reactor.listenTCP(8000, EchoFactory(self)) # for sender reactor.listenTCP(8001, MultiEchoFactory(self)) # for receiver
to:
self.echofactory = EchoFactory(self) self.multiechofactory = MultiEchoFactory(self) reactor.listenTCP(8000, self.echofactory) # for sender reactor.listenTCP(8001, self.multiechofactory) # for receiver
so, your "app" object (which is just a normal Python object) knows the other two objects (the instances of the 2 factories).
Then, your calls:
if sendermessage: self.transport.write(data) #this line here is the trouble maker that caused the error MultiEcho().dataReceived(sendermessage)
could be written:
if sendermessage: self.transport.write(data)
self.app.multiechofactory.dataReceived(sendermessage)
Oh, I messed it up. The first part is good but the factories do not have dataReceived methods.
It would have to be - depending on what you want to do - say, you want to echo to all echoers:
if sendermessage: self.transport.write(data)
for echoer in self.app.multiechofactory.echoers: echoer.dataReceived(sendermessage)
or:
if sendermessage: self.transport.write(data)
self.app.multiechofactory.echo_them_all()
and define the echo_them_all() method in the MultiEchoFactory() class.
On Tue, Apr 28, 2015 at 6:28 PM, Jessica Tsui <jesadjust@gmail.com> wrote:
Hi Daniel,
Thank you so much for your suggestion. I am quite new to python and twisted so I am not very certain about how to make it work well. Does that mean if I change the dataReceived by adding a line to instantiate the MultiEchoFactory like this, it will work?
def dataReceived(self, data): "As soon as any data is received, write it back." handlesendermessage = self.factory.app.handle_message(data)
if handlesendermessage: self.transport.write(data) MultiEchoFactory() MultiEcho().dataReceived(data)
2015-04-29 0:33 GMT+08:00 Louis D. Burr <ldanielburr@me.com>:
Hi Jessica,
On Apr 28, 2015, at 10:14 AM, Jessica Tsui <jesadjust@gmail.com> wrote:
SNIP
exceptions.AttributeError: MultiEcho instance has no attribute ‘factory'
SNIP
MultiEcho().dataReceived(sendermessage)
Here you create an instance of the protocol directly, i.e., without having instantiated a MutilEchoFactory. The factory’s buildProtocol method is what assigns the factory instance as a member of the protocol (self.factory), and since you didn’t create the protocol via a factory, you have no factory attribute on your protocol instance.
There are a number of ways to fix this, but generally speaking, you need to provide a way for your factories and their protocols to be aware of each other.
Hope this helps,
Daniel -- L. Daniel Burr ldanielburr@me.com (312) 656-8387
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
That's what happens when one doesn't try running the code he suggests, sorry. It should be self.factory.app... : for echoer in self.factory.app.multiechofactory.echoers: echoer.dataReceived(sendermessage) On Tue, Apr 28, 2015 at 7:41 PM, Jessica Tsui <jesadjust@gmail.com> wrote:
Pantellis thank you so much for your guide! I am still quite unfamiliar with python and twisted so I made all kind of silly mistakes and could not figure out how to fix them
I tried your code, it seems to me that it should be working with by referencing the factories as well as the self.app...Unfortunately when I ran it it did not work well, the program has an error with your line
for echoer in self.app.multiechofactory.echoers: echoer.dataReceived(sendermessage)
The error is: exceptions.AttributeError: MultiEcho instance has no attribute 'app'
I thought that the "app" has already been referenced?
2015-04-29 1:55 GMT+08:00 Pantelis Theodosiou <ypercube@gmail.com>:
On Tue, Apr 28, 2015 at 6:46 PM, Pantelis Theodosiou <ypercube@gmail.com> wrote:
No, I don't think that would work.
You would need something like changing these lines:
reactor.listenTCP(8000, EchoFactory(self)) # for sender reactor.listenTCP(8001, MultiEchoFactory(self)) # for receiver
to:
self.echofactory = EchoFactory(self) self.multiechofactory = MultiEchoFactory(self) reactor.listenTCP(8000, self.echofactory) # for sender reactor.listenTCP(8001, self.multiechofactory) # for receiver
so, your "app" object (which is just a normal Python object) knows the other two objects (the instances of the 2 factories).
Then, your calls:
if sendermessage: self.transport.write(data) #this line here is the trouble maker that caused the error MultiEcho().dataReceived(sendermessage)
could be written:
if sendermessage: self.transport.write(data)
self.app.multiechofactory.dataReceived(sendermessage)
Oh, I messed it up. The first part is good but the factories do not have dataReceived methods.
It would have to be - depending on what you want to do - say, you want to echo to all echoers:
if sendermessage: self.transport.write(data)
for echoer in self.app.multiechofactory.echoers: echoer.dataReceived(sendermessage)
or:
if sendermessage: self.transport.write(data)
self.app.multiechofactory.echo_them_all()
and define the echo_them_all() method in the MultiEchoFactory() class.
On Tue, Apr 28, 2015 at 6:28 PM, Jessica Tsui <jesadjust@gmail.com> wrote:
Hi Daniel,
Thank you so much for your suggestion. I am quite new to python and twisted so I am not very certain about how to make it work well. Does that mean if I change the dataReceived by adding a line to instantiate the MultiEchoFactory like this, it will work?
def dataReceived(self, data): "As soon as any data is received, write it back." handlesendermessage = self.factory.app.handle_message(data)
if handlesendermessage: self.transport.write(data) MultiEchoFactory() MultiEcho().dataReceived(data)
2015-04-29 0:33 GMT+08:00 Louis D. Burr <ldanielburr@me.com>:
Hi Jessica,
On Apr 28, 2015, at 10:14 AM, Jessica Tsui <jesadjust@gmail.com> wrote:
SNIP
exceptions.AttributeError: MultiEcho instance has no attribute ‘factory'
SNIP
MultiEcho().dataReceived(sendermessage)
Here you create an instance of the protocol directly, i.e., without having instantiated a MutilEchoFactory. The factory’s buildProtocol method is what assigns the factory instance as a member of the protocol (self.factory), and since you didn’t create the protocol via a factory, you have no factory attribute on your protocol instance.
There are a number of ways to fix this, but generally speaking, you need to provide a way for your factories and their protocols to be aware of each other.
Hope this helps,
Daniel -- L. Daniel Burr ldanielburr@me.com (312) 656-8387
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
Hi Pantelis, sorry for bothering you again. But I just ran the code and it still has error with the line self.factory.app.echoFactory().dataReceived(receivermessage) as well as for echoer in self.factory.app.multiechofactory.echoers the errors are 'ServerApp' object has no attribute 'echoFactory' and no 'multiechofactory' respectively
On Apr 28, 2015, at 8:14 AM, Jessica Tsui <jesadjust@gmail.com> wrote:
I am working on this messaging app and I would like to pass data from one factory to another.
Hi Jessica, I will hopefully have more useful feedback for you when I have a chance to read the whole thread (if others haven't answered all your questions already), but I wanted to quickly note that I think it's super cool you're integrating Twisted with Kivy - I am always excited to see people bringing Twisted to a diversity of environments, and we don't have enough people using it for front-end stuff, although that is very much of a part of its design. So thanks for using Twisted! I hope we can help make your experience of it as positive as possible, -glyph
Hi glyph, Thanks for your quick note. Even though I do not have deep understanding in Twisted, based on the documentation I have read I truly think that Twisted can be used on a more front-end stuff and I hope that it will work out well for this testing project, so that i can work further on it later to explore more possibilities with it. Actually what I was trying to do is that I am trying to build a server app with two clients app, one is called "sender" which is connected on port 8000, and one is called "receiver" which is on the port 8001. My target is to create the server app that listens to what the "sender" posts first, then decide to push it to "receiver" or not with a button created in kivy; the "receiver" can directly write back to the "sender". Right now my code is based on various examples that I have found online, so I am not sure if I am really doing things right. I hope that I am on the right track for it with the help from Twisted and kivy. 2015-04-29 6:20 GMT+08:00 Glyph Lefkowitz <glyph@twistedmatrix.com>:
On Apr 28, 2015, at 8:14 AM, Jessica Tsui <jesadjust@gmail.com> wrote:
I am working on this messaging app and I would like to pass data from one factory to another.
Hi Jessica,
I will hopefully have more useful feedback for you when I have a chance to read the whole thread (if others haven't answered all your questions already), but I wanted to quickly note that I think it's super cool you're integrating Twisted with Kivy - I am always excited to see people bringing Twisted to a diversity of environments, and we don't have enough people using it for front-end stuff, although that is very much of a part of its design. So thanks for using Twisted! I hope we can help make your experience of it as positive as possible,
-glyph
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
participants (4)
-
Glyph Lefkowitz
-
Jessica Tsui
-
Louis D. Burr
-
Pantelis Theodosiou