0

Help to sort out the json error -

C:\Users\123\AppData\Local\Programs\Python\Python38>python C:\main_3.py
Traceback (most recent call last):
  File "C:\main_3.py", line 10, in <module>
    data = json.load(file)
  File "C:\Users\123\AppData\Local\Programs\Python\Python38\lib\json\__init__.py", line 293, in load
    return loads(fp.read(),
  File "C:\Users\123\AppData\Local\Programs\Python\Python38\lib\json\__init__.py", line 357, in loads
    return _default_decoder.decode(s)
  File "C:\Users\123\AppData\Local\Programs\Python\Python38\lib\json\decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "C:\Users\123\AppData\Local\Programs\Python\Python38\lib\json\decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

C:\Users\123\AppData\Local\Programs\Python\Python38>

Perhaps this error is due to an empty file - ping_data.json? In this case, I do not know how to prepare this file for the first launch.

Telegram bot. The point of the program is to ping hosts and keep a record of the status of the last check, and in case of program crashes and startup, all the results of the last check must be read from the file.

Complete code

import telebot
from pythonping import ping
import time
import yaml
from libs.host import address
import json

ping_data = dict()
with open('C:\ping_data.json') as file:
    data = json.load(file)

def init():

    global bot, userid, interval

    interval = 30

    with open('C:\config2.yaml', encoding="utf-8") as f:
        try:
            docs = yaml.load_all(f, Loader=yaml.FullLoader)

            for doc in docs:
                for k, v in doc.items():
                    if k == "botkey":
                        bot = telebot.TeleBot(v)
                    elif k == "userid":
                        userid = v
                    elif k == "hosts":
                        set_hosts(v)
                    elif k == "interval":
                        interval = int(v)

        except yaml.YAMLError as exc:
            print(exc)

def set_hosts(hosts):

    """
    Здесь парсим список хостов и передаем их в массив
    """

    global hosts_list
    hosts_list = []

    for item in hosts:
        ac = item.split(":")
        hosts_list.append(address(ac[0], ac[1]))

def send_message(message):

    """
    Посылаем сообщение пользователю
    """

    bot.send_message(userid, message)

def ping_host(address):

    status = ping_url(address.address)
    if data['address.address'] != status:
        ping_data['address.address'] = status
        send_message(( "! " if status is None else "+ " if status else "- ") + address.comment)

def ping_url(url):

    """
    Пинг хоста. Response list - это ответ библиотеки ping. По умолчанию она
    посылает четыре пакета. Если хотя бы один пинг успешен, хост активен
    """

    try:
        response_list = ping(url, timeout=5, verbose = True)
    except:
        return None

    return sum(1 for x in response_list if x.success) > 0

def main():

    """
    Бесконечный цикл, который пингует сервисы один за другим.
    """

    init()

    while True:

        for host in hosts_list:
            ping_host(host)
            with open('C:\ping_data.json','w') as file:
                json.dump(ping_data, file, indent=2)

        time.sleep(interval)

if __name__ == '__main__':
    main()

The contents of the config2.yaml file for example.

botkey: ***********************************
userid: -**********
interval: 60
hosts:
  - "google.com:Google.ru"
  - "ya.ru:Yandex.ru"
  - "mail.ru:Mail.ru"
  - "rambler.ru:Rambler.ru"
Alexandr
  • 9
  • 2
  • 3
    that is indeed, because of empty ping_data file. – Alvi15 Oct 30 '20 at 06:01
  • "Perhaps this error is due to an empty file - ping_data.json?" Yes, the described error is exactly what you should expect for an empty file. "In this case, I do not know how to prepare this file for the first launch." Well, *what should `data` become equal to* on the first launch? – Karl Knechtel Oct 30 '20 at 06:04
  • 1
    A better approach is probably to not create the file until you have something to put into it, and adapt the code accordingly. – tripleee Oct 30 '20 at 06:12
  • @karl-knechtel On first launch, all hosts are online by default, i.e. true - host.py `code` class address: def __init__ (self, address, comment): self.address = address self.comment = comment self.status = True `code` – Alexandr Oct 30 '20 at 06:14
  • The file should consist of the result of the status of the checks True and False ... True True True False True False False – Alexandr Oct 30 '20 at 07:11
  • How about trying `C:\\ping_data.json` (note the double slash) ? – ChatterOne Oct 30 '20 at 08:00

2 Answers2

0

You can't read a empty file as dictionary. But you can read a empty dictionary from a file.

So, Try saving a empty dictionary in the file rather than empty file for your first launch i.e: The content of ping_data.json should be empty flower brackets(like the one below)

{}

Cheers.

WDR
  • 53
  • 7
  • Added a line to the json file, the error remained. `{"10.42.1.43":True}` An empty dictionary also throws an error. – Alexandr Oct 30 '20 at 07:57
  • It's weired man. I just tried running from line no 7 to 12 with a empty dictionary in my PC And It works well. This one is peculiar for you – WDR Oct 30 '20 at 10:37
0

Understood, everything works. The error is only due to the encoding of the JSON file.

Alexandr
  • 9
  • 2