rawpython / remi

Python REMote Interface library. Platform independent. In about 100 Kbytes, perfect for your diet.
Apache License 2.0
3.51k stars 401 forks source link

Index Out of Range error #446

Closed bashkan closed 3 years ago

bashkan commented 3 years ago

I have a script that parses some values from web and then presents them in a table. Occasionally ıt is given the following error and the web interface stops working. Any ideas?

remi.server INFO Started httpserver http://0.0.0.0:8000/ remi.server.ws INFO connection established: ('192.168.2.17', 49770) remi.server.ws INFO connection established: ('192.168.2.17', 49773) remi.server.ws INFO connection established: ('192.168.2.17', 49774) 192.168.2.17 - - [06/May/2021 11:15:23] "HEAD / HTTP/1.1" 200 - remi.request INFO built UI (path=/) remi.server.ws INFO connection established: ('192.168.2.17', 49780) remi.server.ws INFO handshake complete 192.168.2.17 - - [06/May/2021 11:15:24] "GET / HTTP/1.1" 200 - remi.server.ws ERROR error parsing websocket Traceback (most recent call last): File "C:\Python34\lib\site-packages\remi\server.py", line 269, in on_message callback = get_method_by_name(runtimeInstances[widget_id], function_name) File "C:\Python34\lib\weakref.py", line 125, in getitem o = self.data[key]() KeyError: '27886736' remi.server.ws ERROR Error managing incoming websocket message Traceback (most recent call last): File "C:\Python34\lib\site-packages\remi\server.py", line 162, in read_next_me ssage length = self.rfile.read(2) File "C:\Python34\lib\socket.py", line 371, in readinto return self._sock.recv_into(b) ConnectionAbortedError: [WinError 10053] An established connection was aborted b y the software in your host machine remi.server.ws INFO connection established: ('192.168.2.17', 49781) remi.server.ws INFO handshake complete remi.server.ws INFO connection established: ('192.168.2.18', 63589) remi.server.ws INFO handshake complete remi.server.ws ERROR Error managing incoming websocket message Traceback (most recent call last): File "C:\Python34\lib\site-packages\remi\server.py", line 166, in read_next_me ssage length = self.bytetonum(length[1]) & 127 IndexError: index out of range

dddomodossola commented 3 years ago

Hello @bashkan please excuse me for the late reply. The errors shown here are not related to the problem you are getting. The error shows that you restarted the application but the webpage was not closed. So the old widget instances in the browser were not recognized by the server. But this should not cause problems. Do you have threads in your application? Or maybe possibly infinite loops?

bashkan commented 3 years ago

Hello @dddomodossola, thank you for your reply. You are correct, in order to refresh the values on the table, I do restart the script (within itself). I do not have any threads or any loops in the script. It is quite a simple application with only 160 lines. Strangely enough, the problem seems to be gone now. I mean the script seems to be working fine on my good old XP machine. The only problem left is that when I run the same script on a Rasberry Pi (Raspian OS), I always get the "port in use" error when the script restarts itself. But anyway, life is not always easy right :) You may close this issue, and thank you again for your time and efforts.

dddomodossola commented 3 years ago

@bashkan If you show here your code I can try to understand the problem. However I suppose you are not stopping and restarting the script in the right way. Can you please also describe how you restart the script?

bashkan commented 3 years ago

@dddomodossola sure, I am pasting my entire script below. I am sure the goal can be achieved in a much better/easier way. I am not an expert and I just needed the job done. Thank you so much for your support:

import requests
import remi.gui as gui
from remi import start, App

import sys
import os

from datetime import datetime
now = datetime.now()
current_time = now.strftime("%H:%M:%S")
print("Current Time = ", current_time)

global eth
global hot
global ada
global doge
global stc

global eth_amount
global hot_amount
global ada_amount
global doge_amount
global stc_amount

global eth_price
global hot_price
global ada_price
global doge_price
global stc_price

global eth_total
global hot_total
global ada_total
global doge_total
global stc_total

eth_amount = 0.486
hot_amount = 83064.00
ada_amount = 457.85
doge_amount = 74.00
stc_amount = 3328.43

eth = "https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD"
hot = "https://min-api.cryptocompare.com/data/price?fsym=HOT&tsyms=USD"
ada = "https://min-api.cryptocompare.com/data/price?fsym=ADA&tsyms=USD"
doge = "https://min-api.cryptocompare.com/data/price?fsym=DOGE&tsyms=USD"
stc = "https://min-api.cryptocompare.com/data/price?fsym=STC&tsyms=USD"

response_eth = requests.get(eth)
json_eth = response_eth.json()
eth_value = json_eth["USD"]
print("Ethereum: " + str(eth_value) + " USD")
eth_price = float(eth_value)

response_hot = requests.get(hot)
json_hot = response_hot.json()
hot_value = json_hot["USD"]
print("Holo: " + str(hot_value) + " USD")
hot_price = float(hot_value)

response_ada = requests.get(ada)
json_ada = response_ada.json()
ada_value = json_ada["USD"]
print("ADA: " + str(ada_value) + " USD")
ada_price = float(ada_value)

response_doge = requests.get(doge)
json_doge = response_doge.json()
doge_value = json_doge["USD"]
print("DOGE: " + str(doge_value) + " USD")
doge_price = float(doge_value)

response_stc = requests.get(stc)
json_stc = response_stc.json()
stc_value = json_stc["USD"]
print("STC: " + str(stc_value) + " USD")
stc_price = float(stc_value)

def restart():
    print('Restarting now...')
    os.execv(sys.executable, ['python'] + sys.argv)

def response_to_value(the_response):
    the_response_1 = the_response.rsplit(":")
    the_response_2 = the_response_1[-1]
    the_response_3 = the_response_2[:-1]
    print(the_response_3)

class MyApp(App):
    def __init__(self, *args):
        super(MyApp, self).__init__(*args)

    def main(self):
        global eth_amount
        global hot_amount
        global ada_amount
        global doge_amount
        global stc_amount
        global eth_price
        global hot_price
        global ada_price
        global doge_price
        global stc_price
        global eth_total
        global hot_total
        global ada_total
        global doge_total
        global stc_total

        self.lbl_asset = gui.Label("ASSET")
        self.lbl_amount = gui.Label("AMOUNT")
        self.lbl_price = gui.Label("PRICE")
        self.lbl_total = gui.Label("TOTAL")

        self.title_box = gui.HBox(children=[self.lbl_asset, self.lbl_amount, self.lbl_price, self.lbl_total])

        #eth_total = eth_amount*eth_price
        eth_total = round((eth_amount*eth_price), 2)
        hot_total = round((hot_amount*hot_price), 2)
        ada_total = round((ada_amount*ada_price), 2)
        doge_total = round((doge_amount*doge_price), 2)
        stc_total = round((stc_amount*stc_price), 2)

        grand_total = eth_total + hot_total + ada_total + doge_total + stc_total

        self.lbl_eth = gui.Label('Ethereum: ')
        self.lbl_eth_amount = gui.Label(str(eth_amount))
        self.lbl_eth_price = gui.Label(str(eth_price))
        self.lbl_eth_total = gui.Label(str(eth_total))

        self.table = gui.Table.new_from_list([('Asset', 'Amount', 'Price', 'Total'), ('ETH: ', str(eth_amount), str(eth_price), str(eth_total)), ('HOT: ', str(hot_amount), str(hot_price), str(hot_total)), ('ADA: ', str(ada_amount), str(ada_price), str(ada_total)), ('DOGE: ', str(doge_amount), str(doge_price), str(doge_total)), ('STC: ', str(stc_amount), str(stc_price), str(stc_total)), ('Time:', current_time, 'SUM: ', str(grand_total))], width=360, height=450, margin='10px')

        self.bt = gui.Button('REFRESH')

        # setting the listener for the onclick event of the button
        self.bt.onclick.do(self.on_button_pressed)

        vert_container = gui.VBox(children=[self.table], style={'width':'360px', 'height':'550px', 'margin':'20px', 'background-color':'white', "align-items":"center", "justify-content":"space-around"})

        vert_container.append(self.bt)

        # returning the root widget
        return vert_container
        #return table

    # listener function

    def on_button_pressed(self, widget):
        #self.bt.set_text('Hi!')
        restart()
        #self.MyApp.shutdown

# starts the web server
#start(MyApp)

start(MyApp, address='0.0.0.0', port=8000, update_interval=180, start_browser=False)
dddomodossola commented 3 years ago

Hello @bashkan, you are restarting the application without closing it. Try to call App.close() before restarting.

However I think you don't need to restart. Here is the version without restart:

import requests
import remi.gui as gui
from remi import start, App

import sys
import os

from datetime import datetime

global eth
global hot
global ada
global doge
global stc

global eth_amount
global hot_amount
global ada_amount
global doge_amount
global stc_amount

global eth_price
global hot_price
global ada_price
global doge_price
global stc_price

global eth_total
global hot_total
global ada_total
global doge_total
global stc_total

eth_amount = 0.486
hot_amount = 83064.00
ada_amount = 457.85
doge_amount = 74.00
stc_amount = 3328.43

eth = "https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD"
hot = "https://min-api.cryptocompare.com/data/price?fsym=HOT&tsyms=USD"
ada = "https://min-api.cryptocompare.com/data/price?fsym=ADA&tsyms=USD"
doge = "https://min-api.cryptocompare.com/data/price?fsym=DOGE&tsyms=USD"
stc = "https://min-api.cryptocompare.com/data/price?fsym=STC&tsyms=USD"

def response_to_value(the_response):
    the_response_1 = the_response.rsplit(":")
    the_response_2 = the_response_1[-1]
    the_response_3 = the_response_2[:-1]
    print(the_response_3)

class MyApp(App):
    def __init__(self, *args):
        super(MyApp, self).__init__(*args)

    def idle(self):
        global eth_amount
        global hot_amount
        global ada_amount
        global doge_amount
        global stc_amount
        global eth_price
        global hot_price
        global ada_price
        global doge_price
        global stc_price
        global eth_total
        global hot_total
        global ada_total
        global doge_total
        global stc_total

        now = datetime.now()
        current_time = now.strftime("%H:%M:%S")
        print("Current Time = ", current_time)

        response_eth = requests.get(eth)
        json_eth = response_eth.json()
        eth_value = json_eth["USD"]
        print("Ethereum: " + str(eth_value) + " USD")
        eth_price = float(eth_value)

        response_hot = requests.get(hot)
        json_hot = response_hot.json()
        hot_value = json_hot["USD"]
        print("Holo: " + str(hot_value) + " USD")
        hot_price = float(hot_value)

        response_ada = requests.get(ada)
        json_ada = response_ada.json()
        ada_value = json_ada["USD"]
        print("ADA: " + str(ada_value) + " USD")
        ada_price = float(ada_value)

        response_doge = requests.get(doge)
        json_doge = response_doge.json()
        doge_value = json_doge["USD"]
        print("DOGE: " + str(doge_value) + " USD")
        doge_price = float(doge_value)

        response_stc = requests.get(stc)
        json_stc = response_stc.json()
        stc_value = json_stc["USD"]
        print("STC: " + str(stc_value) + " USD")
        stc_price = float(stc_value)

        #eth_total = eth_amount*eth_price
        eth_total = round((eth_amount*eth_price), 2)
        hot_total = round((hot_amount*hot_price), 2)
        ada_total = round((ada_amount*ada_price), 2)
        doge_total = round((doge_amount*doge_price), 2)
        stc_total = round((stc_amount*stc_price), 2)

        grand_total = eth_total + hot_total + ada_total + doge_total + stc_total

        self.lbl_eth_amount.set_text( str(eth_amount) )
        self.lbl_eth_price.set_text( str(eth_price) )
        self.lbl_eth_total.set_text( str(eth_total) )

        table_content = [('Asset', 'Amount', 'Price', 'Total'), ('ETH: ', str(eth_amount), str(eth_price), str(eth_total)), ('HOT: ', str(hot_amount), str(hot_price), str(hot_total)), ('ADA: ', str(ada_amount), str(ada_price), str(ada_total)), ('DOGE: ', str(doge_amount), str(doge_price), str(doge_total)), ('STC: ', str(stc_amount), str(stc_price), str(stc_total)), ('Time:', current_time, 'SUM: ', str(grand_total))]
        r_index = 0
        for row in table_content:
            c_index = 0
            for col in row:
                print("iterating")
                self.table.children[str(r_index)].children[str(c_index)].set_text(col)
                c_index += 1
            r_index += 1

    def main(self):
        self.lbl_asset = gui.Label("ASSET")
        self.lbl_amount = gui.Label("AMOUNT")
        self.lbl_price = gui.Label("PRICE")
        self.lbl_total = gui.Label("TOTAL")

        self.title_box = gui.HBox(children=[self.lbl_asset, self.lbl_amount, self.lbl_price, self.lbl_total])

        self.lbl_eth = gui.Label('Ethereum: ')
        self.lbl_eth_amount = gui.Label("")
        self.lbl_eth_price = gui.Label("")
        self.lbl_eth_total = gui.Label("")

        self.table = gui.Table.new_from_list([('Asset', 'Amount', 'Price', 'Total'), ('ETH: ', "", "", ""), ('HOT: ', "", "", ""), ('ADA: ', "", "", ""), ('DOGE: ', "", "", ""), ('STC: ', "", "", ""), ('Time:', "", 'SUM: ', "")], width=360, height=450, margin='10px')

        vert_container = gui.VBox(children=[self.table], style={'width':'360px', 'height':'550px', 'margin':'20px', 'background-color':'white', "align-items":"center", "justify-content":"space-around"})

        # returning the root widget
        return vert_container
        #return table

# starts the web server
#start(MyApp)

start(MyApp, address='0.0.0.0', port=8000, update_interval=1, start_browser=False)
bashkan commented 3 years ago

@dddomodossola , thanks a lot you for your time and support. Your script is so much better than mine, I will use it instead. I need to even study it to understand things better.