python AttributeError: 'mHID' object has no attribute 'dict' - python
I am trying to make a makeblock mblock implementation with python and i found this api on github but it uses python 2.7 and i am using python 3.8 so i am trying to configure the code so it can run on python 3.8 but i ran into an error which is
init mBot
bot
<lib.mBot.mSerial object at 0x02CE9898>
start with serial
<lib.mBot.mHID object at 0x02E2B310>
self.device = mHID()
'mHID' object has no attribute 'dict'
Exception in thread Thread-2:
self.start()
Traceback (most recent call last):
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 154, in __onRead
start with HID
--------------------
n = self.device.inWaiting()
<lib.mBot.mBot object at 0x002FF640>
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 96, in inWaiting
--------------------
Error in sys.excepthook:
buf = self.dict.device.read(64)
Traceback (most recent call last):
AttributeError: 'mHID' object has no attribute 'dict'
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 134, in excepthook
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\abdsak11\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 932, in _bootstrap_inner
self.close()
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 142, in close
self.device.close()
self.run()
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 106, in close
File "C:\Users\abdsak11\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 870, in run
self.dict.device.close()
AttributeError: 'mHID' object has no attribute 'dict'
Original exception was:
Traceback (most recent call last):
File "c:/Users/abdsak11/OneDrive - Lärande/Dokument/GitHub/python-for-mbot/test.py", line 15, in <module>
self._target(*self._args, **self._kwargs)
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 163, in __onRead
bot.doMove(50,50)
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 179, in doMove
self.close()
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 142, in close
self.__writePackage(bytearray([0xff,0x55,0x7,0x0,0x2,0x5]+self.short2bytes(-leftSpeed)+self.short2bytes(rightSpeed)))
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 278, in short2bytes
self.device.close()
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 106, in close
return [ord(val[0]),ord(val[1])]
TypeError: ord() expected string of length 1, but int found
self.dict.device.close()
AttributeError: 'mHID' object has no attribute 'dict'
'mHID' object has no attribute 'dict'
Exception in thread Thread-1:
Traceback (most recent call last):
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 154, in __onRead
n = self.device.inWaiting()
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 96, in inWaiting
buf = self.dict.device.read(64)
AttributeError: 'mHID' object has no attribute 'dict'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\abdsak11\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 932, in _bootstrap_inner
self.run()
File "C:\Users\abdsak11\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 163, in __onRead
self.close()
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 142, in close
self.device.close()
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 106, in close
self.dict.device.close()
AttributeError: 'mHID' object has no attribute 'dict'
So what i am trying to do is to control and upload code to my mbot via usb COM3 serial and thats the error that i am getting i tried everthing but its not working and i cant seem to figure out the cause of the error.
mbot.py
this is the main api that i found
import serial
import sys,time
import signal
from time import ctime,sleep
import glob,struct
from multiprocessing import Process,Manager,Array
import threading
import hid
class mSerial():
ser = None
def __init__(self):
print (self)
def start(self, port):
self.ser = serial.Serial(port,115200)
def device(self):
return self.ser
def serialPorts(self):
if sys.platform.startswith('win'):
ports = ['COM%s' % (i + 1) for i in range(256)]
elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):
ports = glob.glob('/dev/tty[A-Za-z]*')
elif sys.platform.startswith('darwin'):
ports = glob.glob('/dev/tty.*')
else:
raise EnvironmentError('Unsupported platform')
result = []
for port in ports:
s = serial.Serial()
s.port = port
s.close()
result.append(port)
return result
def writePackage(self,package):
self.ser.write(package)
sleep(0.01)
def read(self):
return self.ser.read()
def isOpen(self):
return self.ser.isOpen()
def inWaiting(self):
return self.ser.inWaiting()
def close(self):
self.ser.close()
class mHID():
def __init__(self):
print (self)
def start(self):
print ("starting start \n\n")
self.manager = Manager()
print("manager pass \n\n")
self.dict = self.manager.dict()
print("dict pass \n\n")
self.dict.device = hid.device()
print("dict device pass \n\n")
self.dict.device.open(0x0416, 0xffff)
print("dict device open pass \n\n")
self.dict.device.hid_set_nonblocking(self.device,1)
print ("start")
self.buffer = []
self.bufferIndex = 0
def enumerate(self):
print ("enumerate")
for dev in self.dict.device.enumerate():
print ('------------------------------------------------------------')
print (dev.description())
def writePackage(self,package):
buf = []
buf += [0, len(package)]
for i in range(len(package)):
buf += [package[i]]
n = self.dict.device.write(buf)
sleep(0.01)
def read(self):
c = self.buffer[0]
self.buffer = self.buffer[1:]
return chr(c)
def isOpen(self):
return True
def inWaiting(self):
buf = self.dict.device.read(64)
l = 0
if len(buf)>0:
l = buf[0]
if l>0:
for i in range(0,l):
self.buffer += [buf[i+1]]
return len(self.buffer)
def close(self):
self.dict.device.close()
class mBot():
def __init__(self):
print ("init mBot")
signal.signal(signal.SIGINT, self.exit)
self.manager = Manager()
self.__selectors = self.manager.dict()
self.buffer = []
self.bufferIndex = 0
self.isParseStart = False
self.exiting = False
self.isParseStartIndex = 0
def startWithSerial(self, port):
self.device = mSerial()
self.device.start(port)
self.start()
def startWithHID(self):
self.device = mHID()
print ("self.device = mHID()\n \n")
self.device.start()
print ("self.device.start()\n \n")
self.start()
print ("self.start()\n \n")
def excepthook(self, exctype, value, traceback):
self.close()
def start(self):
sys.excepthook = self.excepthook
th = threading.Thread(target=self.__onRead,args=(self.onParse,))
th.start()
def close(self):
self.device.close()
def exit(self, signal, frame):
self.exiting = True
sys.exit(0)
def __onRead(self,callback):
while 1:
if(self.exiting==True):
break
try:
if self.device.isOpen()==True:
n = self.device.inWaiting()
for i in range(n):
r = ord(self.device.read())
callback(r)
sleep(0.01)
else:
sleep(0.5)
except Exception as ex:
print (str(ex))
self.close()
sleep(1)
def __writePackage(self,pack):
self.device.writePackage(pack)
def doRGBLed(self,port,slot,index,red,green,blue):
self.__writePackage(bytearray([0xff,0x55,0x9,0x0,0x2,0x8,port,slot,index,red,green,blue]))
def doRGBLedOnBoard(self,index,red,green,blue):
self.doRGBLed(0x7,0x2,index,red,green,blue)
def doMotor(self,port,speed):
self.__writePackage(bytearray([0xff,0x55,0x6,0x0,0x2,0xa,port]+self.short2bytes(speed)))
def doMove(self,leftSpeed,rightSpeed):
self.__writePackage(bytearray([0xff,0x55,0x7,0x0,0x2,0x5]+self.short2bytes(-leftSpeed)+self.short2bytes(rightSpeed)))
def doServo(self,port,slot,angle):
self.__writePackage(bytearray([0xff,0x55,0x6,0x0,0x2,0xb,port,slot,angle]))
def doBuzzer(self,buzzer,time=0):
self.__writePackage(bytearray([0xff,0x55,0x7,0x0,0x2,0x22]+self.short2bytes(buzzer)+self.short2bytes(time)))
def doSevSegDisplay(self,port,display):
self.__writePackage(bytearray([0xff,0x55,0x8,0x0,0x2,0x9,port]+self.float2bytes(display)))
def doIROnBoard(self,message):
self.__writePackage(bytearray([0xff,0x55,len(message)+3,0x0,0x2,0xd,message]))
def requestLightOnBoard(self,extID,callback):
self.requestLight(extID,8,callback)
def requestLight(self,extID,port,callback):
self.__doCallback(extID,callback)
self.__writePackage(bytearray([0xff,0x55,0x4,extID,0x1,0x3,port]))
def requestButtonOnBoard(self,extID,callback):
self.__doCallback(extID,callback)
self.__writePackage(bytearray([0xff,0x55,0x4,extID,0x1,0x1f,0x7]))
def requestIROnBoard(self,extID,callback):
self.__doCallback(extID,callback)
self.__writePackage(bytearray([0xff,0x55,0x3,extID,0x1,0xd]))
def requestUltrasonicSensor(self,extID,port,callback):
self.__doCallback(extID,callback)
self.__writePackage(bytearray([0xff,0x55,0x4,extID,0x1,0x1,port]))
def requestLineFollower(self,extID,port,callback):
self.__doCallback(extID,callback)
self.__writePackage(bytearray([0xff,0x55,0x4,extID,0x1,0x11,port]))
def onParse(self, byte):
position = 0
value = 0
self.buffer+=[byte]
bufferLength = len(self.buffer)
if bufferLength >= 2:
if (self.buffer[bufferLength-1]==0x55 and self.buffer[bufferLength-2]==0xff):
self.isParseStart = True
self.isParseStartIndex = bufferLength-2
if (self.buffer[bufferLength-1]==0xa and self.buffer[bufferLength-2]==0xd and self.isParseStart==True):
self.isParseStart = False
position = self.isParseStartIndex+2
extID = self.buffer[position]
position+=1
type = self.buffer[position]
position+=1
# 1 byte 2 float 3 short 4 len+string 5 double
if type == 1:
value = self.buffer[position]
if type == 2:
value = self.readFloat(position)
if(value<-255 or value>1023):
value = 0
if type == 3:
value = self.readShort(position)
if type == 4:
value = self.readString(position)
if type == 5:
value = self.readDouble(position)
if(type<=5):
self.responseValue(extID,value)
self.buffer = []
def readFloat(self, position):
v = [self.buffer[position], self.buffer[position+1],self.buffer[position+2],self.buffer[position+3]]
return struct.unpack('<f', struct.pack('4B', *v))[0]
def readShort(self, position):
v = [self.buffer[position], self.buffer[position+1]]
return struct.unpack('<h', struct.pack('2B', *v))[0]
def readString(self, position):
l = self.buffer[position]
position+=1
s = ""
for i in Range(l):
s += self.buffer[position+i].charAt(0)
return s
def readDouble(self, position):
v = [self.buffer[position], self.buffer[position+1],self.buffer[position+2],self.buffer[position+3]]
return struct.unpack('<f', struct.pack('4B', *v))[0]
def responseValue(self, extID, value):
self.__selectors["callback_"+str(extID)](value)
def __doCallback(self, extID, callback):
self.__selectors["callback_"+str(extID)] = callback
def float2bytes(self,fval):
val = struct.pack("f",fval)
return [ord(val[0]),ord(val[1]),ord(val[2]),ord(val[3])]
def short2bytes(self,sval):
val = struct.pack("h",sval)
return [ord(val[0]),ord(val[1])]
test.py
this is the test file that i am working with
from lib.mBot import *
if __name__ == "__main__":
bot = mBot()
print ("bot \n\n")
bot.startWithSerial("COM3")
print ("start with serial\n\n")
bot.startWithHID()
print ("start with HID \n\n")
print(f'--------------------\n')
print (bot)
print(f'--------------------\n')
bot.doMove(50,50)
I believe your trouble is here:
class mHID():
def __init__(self):
print (self)
def start(self):
# ...
self.dict = self.manager.dict()
# ...
def close(self):
self.dict.device.close()
You should always define your instance attributes in __init__(), at least with an initial value of None, even if you plan to change them later.
Additionally, whenever you have a situation where "A must be called before B", you should write the code to properly handle when B is called without A. In this case, what should close() do if start() was never called? For simplicity, I'm just having it do nothing, but you may consider raising an exception.
class mHID():
def __init__(self):
print (self)
self.dct = None
def start(self):
# ...
self.dct = self.manager.dict()
# ...
def close(self):
if self.dct:
self.dct.device.close()
You'll notice I also renamed self.dict to self.dct. Although the former name may technically be allowable because of the self. namespace, dict is actually a built-in class. Under various circumstances, you could wind up dealing with shadowing. In the very least, it's confusing to always have to remind oneself that "this isn't the built-in dict, but an instance variable instead.
(Possible aside: is there a particular reason why you don't want to call start() from the initializer?)
WARNING: This is not a simple case of "copy and paste the answer". I've illustrated a couple of design principles here that you should incorporate into the rest of your code.
Related
Looking for fix for this BrokenPipeError in my python project socket/Threads
first time questioner here! I´m currently working on a python project that´s supposed to read soil moisture through a sensor on a raspberry pi, which then sends the data to another laptop through a socket connection. That other laptop displays the data in a UI. That UI is also capable of controllig the script flow. My Server starts up just fine, but when the client connects to it(connection itself works), I get the following Error Stack: Exception in thread Thread-2: Traceback (most recent call last): File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner self.run() File "/usr/lib/python3.5/threading.py", line 862, in run self._target(self._args, **self._kwargs) File "/home/pi/Py_Scripts/MoistureSensor/Server.py", line 77, in worker_recv self.JSON_Control = pickle.loads(self.data_recv) EOFError: Ran out of input Exception in thread Thread-1: Traceback (most recent call last): File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner self.run() File "/usr/lib/python3.5/threading.py", line 862, in run self._target(self._args, **self._kwargs) File "/home/pi/Py_Scripts/MoistureSensor/Server.py", line 70, in worker_send self.conn.send(self.data_send) BrokenPipeError: [Errno 32] Broken pipe My Scripts look as follows: Client-side: import sys from socket import * from threading import Thread from time import sleep import pickle from PySide6 import QtWidgets, QtGui class MyClient: def __init__(self, server_port, buf_size, host): self.server_port = server_port self.buf_size = buf_size self.host = host self.data_send = None self.data_recv = None self.exit = False self.JSON_Control = { "measure": False, "exit": False, } self.JSON_Moisture = { "moisture_level": 0 } self.socket_connection = socket(AF_INET, SOCK_STREAM) self.socket_connection.connect((self.host, self.server_port)) print("Connected with Server: %s: " % self.host) # thread for sending self.thread_send = Thread(target=self.worker_send) # thread for receiving self.thread_recv = Thread(target=self.worker_recv) # starting Threads self.thread_send.start() self.thread_recv.start() def worker_send(self): while not self.exit: self.data_send = pickle.dumps(self.JSON_Control) self.socket_connection.send(self.data_send) sleep(0.5) def worker_recv(self): while not self.exit: self.data_recv = self.socket_connection.recv(self.buf_size) if self.data_recv is not None: self.JSON_Moisture = pickle.loads(self.data_recv) class UiDisplay(QtWidgets.QWidget): def __init__(self): super().__init__() self.moisture_label = None self.moisture_level = None self.start_button = None self.refresh_button = None self.stop_button = None self.reset_button = None self.quit_button = None self.create_widgets() def create_widgets(self): # create a label to display the current time self.moisture_label = QtWidgets.QLabel(self) self.moisture_label.setFont(QtGui.QFont("Helvetica", 16)) self.moisture_level = client.JSON_Moisture["moisture_level"] self.moisture_label.setText('Bodenfeuchtigkeit: ' + str(self.moisture_level)[:3] + '%') # button to start the weight measuring self.start_button = QtWidgets.QPushButton("Start measuring", self) self.start_button.clicked.connect(self.measure_moisture) # button to refresh the Weight label self.refresh_button = QtWidgets.QPushButton("Refresh", self) self.refresh_button.clicked.connect(self.refresh) # button to stop measuring self.stop_button = QtWidgets.QPushButton("Stop measuring", self) self.stop_button.clicked.connect(self.stop_measuring) # button to quit the program self.quit_button = QtWidgets.QPushButton("Quit", self) self.quit_button.clicked.connect(self.quit) # create a layout to hold the widgets layout = QtWidgets.QVBoxLayout() layout.addWidget(self.moisture_label) layout.addWidget(self.start_button) layout.addWidget(self.refresh_button) layout.addWidget(self.stop_button) layout.addWidget(self.reset_button) layout.addWidget(self.quit_button) self.setLayout(layout) def measure_moisture(self): client.JSON_Control["measure"] = True def refresh(self): # get current weight ( niederlag auf ein qm rechnen fehlt noch) self.moisture_level = round(client.JSON_Moisture["moisture_level"] - 2.7) / (1 - 2.7) print(self.moisture_level) # umrechnen von analogem Wert zu Prozentanteil print(self.moisture_level) # update the weight label with the current time self.moisture_label.setText('Bodenfeuchtigkeit: ' + str(self.moisture_level)[:5] + '%') def stop_measuring(self): if client.JSON_Control["measure"]: client.JSON_Control["measure"] = False else: pass def quit(self): QtWidgets.QApplication.instance().quit() client.JSON_Control["exit"] = True sleep(2) client.exit = True client.thread_recv.join() client.thread_send.join() client.socket_connection.close() print("Server connection is closed") print('exiting...') sleep(1) sys.exit() client = MyClient(1957, 1024, "192.168.86.121") app = QtWidgets.QApplication() window = UiDisplay() window.show() app.exec() -------------------------------------------------------- The Server-side: import sys from socket import * from threading import Thread import pickle from time import sleep import Adafruit_ADS1x15 adc_channel_0 = 0 class SoilMoistureSensor: def __init__(self, gain, sps, dry_voltage, saturated_voltage): self.adc = Adafruit_ADS1x15.ADS1115() self.raw_data = None self.moisture_level = None # self.voltage = None self.gain = gain self.sps = sps self.dry_voltage = dry_voltage self.saturated_voltage = saturated_voltage class MyServer: def __init__(self, echo_port, buf_size): self.buf_size = buf_size self.echo_port = echo_port self.data_send = None self.data_recv = None self.exit = False self.data_json = None self.moisture_sensor = SoilMoistureSensor(2, 32, 1, 2.7) # gain, sps, saturated_voltage, dry_voltage self.JSON_Control = { "measure": False, "exit": False } self.JSON_Moisture = { "moisture_level": 0, } self.socket_connection = socket(AF_INET, SOCK_STREAM) self.socket_connection.bind(("", self.echo_port)) self.socket_connection.listen(1) print("Server gestartet") print("Name des Hosts: ", gethostname()) print("IP des Hosts: ", gethostbyname(gethostname())) self.conn, (self.remotehost, self.remoteport) = self.socket_connection.accept() print("Verbunden mit %s %s " % (self.remotehost, self.remoteport)) # thread for sending self.thread_send = Thread(target=self.worker_send) # thread for receiving self.thread_recv = Thread(target=self.worker_recv) # thread for checking Json Control self.thread_check_json_control = Thread(target=self.check_json_control) # starting Threads self.thread_send.start() self.thread_recv.start() self.thread_check_json_control.start() def worker_send(self): while not self.exit: self.data_send = pickle.dumps(self.JSON_Moisture) self.conn.send(self.data_send) sleep(0.5) def worker_recv(self): while not self.exit: self.data_recv = self.conn.recv(self.buf_size) if self.data_recv is not None: self.JSON_Control = pickle.loads(self.data_recv) def measure_moisture(self, channel): channel = adc_channel_0 self.moisture_sensor.raw_data = self.moisture_sensor.adc.read_adc( channel, self.moisture_sensor.gain, self.moisture_sensor.sps) self.JSON_Moisture["moisture_level"] = self.moisture_sensor.raw_data print(self.moisture_sensor.raw_data) def stop_connection(self): self.thread_recv.join() self.thread_send.join() self.thread_check_json_control.join() self.socket_connection.close() print("Server connection is closed") print('exiting...') sys.exit() def check_json_control(self): while not self.exit: if self.JSON_Control["measure"]: self.measure_moisture(0) if self.JSON_Control["exit"]: self.stop_connection() sleep(0.5) server = MyServer(1957, 1024) I´d be ever so grateful for help and I´m incredibly sorry if I´ve disregarded any question conventions. Cheers!
How to Update a Label in Pyglet without Invalid Operation Error?
I have a pyglet program that runs a GUI in one thread and receives a message from another thread. It's supposed to update the GUI based on that message. The problem though is whenever I go to update a GUI element, I get an error message like this one: Traceback (most recent call last): File --- line 40, in run pub.sendMessage("update", msg="Banana") File --- line 77, in updateDisplay self.label.text = msg File "---\pyglet\text\__init__.py", line 289, in text self.document.text = text File "---\pyglet\text\document.py", line 294, in text self.insert_text(0, text) File "---\pyglet\text\document.py", line 425, in insert_text self.dispatch_event('on_insert_text', start, text) File "---\pyglet\event.py", line 408, in dispatch_event if handler(*args): File "---\pyglet\text\layout.py", line 1045, in on_insert_text self._init_document() File "---\pyglet\text\layout.py", line 1034, in _init_document self._update() File "---\pyglet\text\layout.py", line 957, in _update lines = self._get_lines() File "---\pyglet\text\layout.py", line 933, in _get_lines glyphs = self._get_glyphs() ... File "---\pyglet\font\base.py", line 246, in fit region.blit_into(image, 0, 0, 0) File "---\pyglet\image\__init__.py", line 1730, in blit_into self.owner.blit_into(source, x + self.x, y + self.y, z + self.z) File "---\pyglet\image\__init__.py", line 1622, in blit_into glBindTexture(self.target, self.id) File "---\pyglet\gl\lib.py", line 107, in errcheck raise GLException(msg) pyglet.gl.lib.GLException: b'invalid operation' The operative error being pyglet.gl.lib.GLException: b'invalid operation' I know self.label.text = Y works because it updates the text if I put it in the init() function. However, trying to do any kind of update from the update_display function (see code below) throws this error. I know the function gets called correctly because it successfully prints the message to console, but it breaks on the update element line. I've tried other elements than label and it's the same thing. I have no idea why it's throwing this error or how to resolve it. Any ideas? My code is: import pyglet from threading import Thread from random import choice from time import sleep from pubsub import pub RUN = True class MessageThread(Thread): def __init__(self): """Init Thread Class.""" Thread.__init__(self) self.start() # start the thread def run(self): """Run Thread.""" array = [0, 1, 2] while True: if RUN == False: print("End runner") break value = choice(array) sleep(1) if value == 0: print("event", value, ": Apple", flush=True) pub.sendMessage("update", msg="Apple") elif value == 1: print("event", value, ": Banana", flush=True) pub.sendMessage("update", msg="Banana") else: print("event", value, ": Carrot", flush=True) pub.sendMessage("update", msg="Carrot") class MyGUI(pyglet.window.Window): # Note: With this structure, there is no "self.app", you just use # self. This structure allows onDraw() to be called. def __init__(self): super(MyGUI, self).__init__(width=600,height=650,resizable=True) self.label = pyglet.text.Label('Waiting...', font_name='Times New Roman', font_size=36, x=self.width/2, y=self.height - 36, anchor_x='center', anchor_y='center') # create a pubsub receiver # update is the topic subscribed to, updateDisplay the callable pub.subscribe(self.updateDisplay, "update") MessageThread() def on_draw(self): self.clear() self.label.draw() def updateDisplay(self, msg): """ Receives data from thread and updates the display """ print ("Updating Display") self.label.text = msg def on_close(self): """ Override the normal onClose behavior so that we can kill the MessageThread, too """ print("Closing Application") global RUN RUN = False self.close() # Need to include since defining on_close overrides it if __name__ == "__main__": window = MyGUI() pyglet.app.run()
Python signals: ValueError: signal only works in main thread
I have this python code: from pytchat import LiveChat import time import requests import threading video_id = None liveChat = None def runChat(): global liveChat liveChat = LiveChat(video_id) while liveChat.is_alive(): try: chatdata = liveChat.get() for c in chatdata.items: print(f"{c.datetime} [{c.author.channelId}]- {c.message}") chatdata.tick() except KeyboardInterrupt: liveChat.terminate() break def checkId(): threading.Timer(1.0, checkId).start() global video_id req = requests.get("http://localhost/getId") if req.status_code == 200: vidId = req.text if vidId != "null" and vidId != video_id: video_id = vidId print(f"got id: {video_id}") if liveChat is not None: liveChat.terminate() runChat() def main(): checkId() if __name__ == '__main__': main() That utilizes the pytchat library (https://github.com/taizan-hokuto/pytchat). As you can see, I want to dynamically change the videoId that the chat is bundled to, but with the code above this is the result: root#vps:~# python3 liveChat.py got id: a10TAdVZmOq # First id, the library works, we can capture chat messages. got id: NMre6IAPoLI # After second id appears, there is this exception: Exception in thread Thread-52: Traceback (most recent call last): File "/usr/local/lib/python3.6/threading.py", line 916, in _bootstrap_inner self.run() File "/usr/local/lib/python3.6/threading.py", line 1182, in run self.function(*self.args, **self.kwargs) File "liveChat.py", line 36, in checkId runChat() File "liveChat.py", line 11, in runChat liveChat = LiveChat(video_id) File "/usr/local/lib/python3.6/site-packages/pytchat/core_multithread/livechat.py", line 110, in __init__ signal.signal(signal.SIGINT, lambda a, b: self.terminate()) File "/usr/local/lib/python3.6/signal.py", line 47, in signal handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler)) ValueError: signal only works in main thread How can this be solved since signals only work in main thread?
Adding the parameter interruptable=False to the LiveChat object solved the issue. def runChat(): global liveChat liveChat = LiveChat(video_id, interruptable=False) # <---THIS while liveChat.is_alive(): # .... https://github.com/taizan-hokuto/pytchat/issues/8
emulate file-like behavior in python
I'm writing a script, where I have to dump some columns of tables from an SQL database into a file, and transfer it via FTP. Because dumps can get really big, my Idea was to write a FakeFile which querys row by row from a cursor in its readline method and pass it to ftplib.FTP.storlines. This is what I have so far: import ftplib import MySQLdb def MySQLFakeFile(object): ''' Simulates a read-only file, which dumps rows on demand. Use this, to pass it to the FTP protocol to make the dump more efficient, without the need to dump it somewhere and copy it over the net afterwords ''' def __init__(self, cursor, delimeter, table_name, query): self.cursor = cursor self.delimeter = delimeter self.table_name = table_name #query is something along select ... FROM %s self.cursor.execute(query, table_name) self._has_written_index = False #file attrs self.closed = False self.name = table_name + ".csv" self.encoding = "utf-8" self.mode = "r" def close(self): self.cursor.close() self.closed = True def flush(self): '''No-OP''' pass def read(self, size): pass def readline(self, size): if not self._has_written_index: ret = [] for desc in self.cursor.description: ret.append(desc[0]) self._has_written_index = True else: ret = self.cursor.fetchone() if not ret: return None s = "" for col in ret: s += str(col) + self.delimeter return s + "\n" def readlines(self, size): ret = [] line = self.readline() while line: ret.append(line) line = self.readline() def write(self, string): raise Exception("cannot write to a MySQLFakeFile") def writelines(self, lines) raise Exception("cannot write to a MySQLFakeFile") db = MySQLdb("host", "user", "pass", "db") ftp = ftplib.FTP("host", "user", "pass") fakeFile = MySQLFakeFile(db.cursor(), ";", "tableName", "SELECT * FROM %s") ftp.storlines("STOR tableName.csv", fakeFile) gives me Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python2.7/ftplib.py", line 496, in storlines if len(buf) > self.maxline: TypeError: object of type 'NoneType' has no len() What am I doing wrong, and whats the NoneType here?
Your readline returns None instead of empty string "" when reached end-of-rows. Your readlines returns nothing. def readlines(self, size): ret = [] while True: line = self.readline() if not line: break ret.append(line) return ret
TypeError: cannot concatenate 'str'
I got this error TypeError: cannot concatenate 'str' and 'builtin_function_or_method' objects when i tried to change directory in the ftp. ftp.py from ftplib import FTP ftp = FTP() class FTPClient(): connection_id = None login_ok = False message_array = [] def __init__(self): pass def log_message(self, message, clear=True): if clear: self.message_array = message def get_message(self): return self.message_array def connect(self, server, ftp_user, ftp_password, is_passive = False): self.connection_id = ftp.connect(server) login_result = ftp.login(user=ftp_user, passwd=ftp_password) ftp.set_pasv(is_passive) if not self.connection_id or not login_result: self.log_message("FTP Connection has Failed") self.log_message("Attempted to connect to {0} for {1}".format(server, ftp_user)) return False else: self.log_message("Connected to {0} for {1}".format(server, ftp_user)) self.login_ok = True return True def make_dir(self, directory): if ftp.mkd(directory): self.log_message("Directory {0} created successfully".format(directory)) return True else: self.log_message("Failed creating directory") return False def change_directory(self, directory): if ftp.cwd(directory): self.log_message("Current Directory is now {0}".format(ftp.pwd)) else: self.log_message("Can't change Directory") def upload_file(self, file_from, file_to): if file_from.endswith(('.csv', '.txt')): with open(file_from, 'r') as f: self.connection_id.storelines("Uploaded from {0} to {1}".format(file_from, file_to), f) else: with open(file_from, 'rb') as f: self.connection_id.storebinary('Uploaded from {0} to {1}'.format(file_from, file_to), f) ftp_obj = FTPClient() FTP_HOST = "yyy" FTP_USER = "xxx" FTP_PASS = "zzz" ftp_obj.connect(FTP_HOST, FTP_USER, FTP_PASS) print(ftp_obj.get_message()) FILE_FROM = "config.txt" FILE_TO = ftp_obj.change_directory(dir) ftp_obj.upload_file(FILE_FROM, FILE_TO) print(ftp_obj.get_message()) Full traceback: Connected to yyy for xxx Traceback (most recent call last): File "C:/Users/Ajay/PycharmProjects/database/test.py", line 67, in <module> FILE_TO = ftp_obj.change_directory(dir) File "C:/Users/Ajay/PycharmProjects/database/test.py", line 44, in change_directory if ftp.cwd(directory): File "C:\Python27\lib\ftplib.py", line 552, in cwd cmd = 'CWD ' + dirname TypeError: cannot concatenate 'str' and 'builtin_function_or_method' objects Whats happening there ? and why this error ?
Error is here: FILE_TO = ftp_obj.change_directory(dir) you have not declared dir var, builtin function dir passed instead.