TypeError: coercing to Unicode: need string or buffer, NoneType found. Seems to be because of time function

こ雲淡風輕ζ 提交于 2020-06-29 04:05:32

问题


I'm a beginner at python, trying to make this code work which was provided by someone else. This code queries the API for alerts and send it over to the syslog server periodically. The error I'm getting seems to be related to the time function. Pasted below the line in the code that is generating the error.

Traceback (most recent call last):
  File "/Users/arunlingamariyappa/Documents/API/PythonAPI.py", line 182, in <module>
    main()
  File "/Users/arunlingamariyappa/Documents/API/PythonAPI.py", line 179, in main
    updater.schedule()
  File "/Users/arunlingamariyappa/Documents/API/PythonAPI.py", line 146, in schedule
    self.last = self.get_time()
  File "/Users/arunlingamariyappa/Documents/API/PythonAPI.py", line 92, in get_time
    self.set_time()
  File "/Users/arunlingamariyappa/Documents/API/PythonAPI.py", line 102, in set_time
    with open(self.timefile, 'w') as f:
TypeError: coercing to Unicode: need string or buffer, NoneType found

Here is the complete code. I looked at another post with similar error, unfortunately I couldn't correlate that into my code.

from logging import handlers

import argparse #for parsing user arguments
from six.moves import configparser
import json
import logging #for sending the events to syslog server
import requests #for making http/https requests
import sched
import sys
import time #https://www.programiz.com/python-programming/time
import urlparse

logging.basicConfig(level=logging.ERROR, stream=sys.stderr)

def get_opt():
    '''
    Parse user arguments
    https://docs.python.org/3/library/argparse.html
    '''
    parser = argparse.ArgumentParser()
    parser.add_argument('--url',
        dest='url',
        action='store',
        default='https://api.xxx.com/ddd',
        help='API URL'
    )
    parser.add_argument('--user', dest='user', action='store', help='API user credential')
    parser.add_argument('--pass', dest='password', action='store', help='API password credential')
    parser.add_argument('--interval', dest='interval', action='store', type=int, default=3600, help='Polling interval in seconds')
    parser.add_argument('--file', dest='file', action='store', help='Path to timestamp file')
    parser.add_argument('--syslog_host', dest='syslog_host', action='store', default='localhost', help='Syslog host')
    parser.add_argument('--syslog_port', dest='syslog_port', action='store', type=int, default=514, help='Syslog port')

    args = parser.parse_args()
    return args

class Updater(object):
    '''
    Keeps track of the last update and periodically runs the update on
    a schedule
    '''

    def __init__(self, url, a1s_user, a1s_pass, syslog_host, syslog_port, interval, timefile):
        '''
        Returns an instance of the updater.
        @param url: str representing the API URL
        @param a1s_user: str representing API username
        @param a1s_pass: str representing API password
        @param syslog_host: str representing the syslog host
        @param syslog_port: int representing the syslog port
        @param interval: int representing the update interval, in seconds
        @param timefile: str path to file to keep the last date
        '''
        self.url = url
        self.creds = requests.auth.HTTPBasicAuth(a1s_user, a1s_pass)
        self.interval = interval
        self.timefile = timefile

        self.syslog = logging.getLogger('SyslogClient')
        self.syslog.propagate = False
        self.syslog.setLevel(logging.INFO)
        handler = handlers.SysLogHandler(address=(syslog_host, syslog_port))
        handler.formatter = logging.Formatter('%(message)s')
        self.syslog.addHandler(handler)

        # Last time an update was found. Will be updated by self.get_time()
        self.last = None

    def get_time(self):
        '''
        Read and return the epoch time from the file.
        Set the time in the file to the current time if it does not exist
        or is invalid
        '''
        logging.debug('Getting time')
        try:
            with open(self.timefile, 'r') as f:
                epoch = f.read().strip()
                try:
                    ts = int(epoch)
                    logging.debug('Got time')
                    return ts

                except:
                    logging.exception("Couldn't get epoch time as int")
                    self.set_time()

        except:
            logging.debug('Time file did not exist')
            self.set_time()

        return self.last 

    def set_time(self):
        '''
        Set the epoch time in the file.
        Failure to open the file is fatal.
        '''
        logging.debug('Setting time')
        with open(self.timefile, 'w') as f:
            self.last = int(time.time())
            try:
                f.write(str(self.last))
                logging.debug('Set time to {}'.format(self.last))
                return

            except:
                logging.exception("Couldn't write to time file \"{}\"".format(self.timefile))

    def update(self):
        '''
        Polls the API and sends results over syslog
        '''
        logging.debug('Updating')
        params = {
            'disposition': 'all',
            'since': str(self.last),
            'end': str(int(time.time())),
        }

        try:
            resp = requests.get(self.url, auth=self.creds, params=params) #making a request to the Area 1 API
            if not resp.ok:
                logging.error("API status {}: {}".format(resp.status_code, resp.reason))
                return

            update = json.loads(resp.content)
            if update:
                logging.debug('Received {} alerts'.format(len(update)))
                self.syslog.info(resp.content)
                logging.debug('Update complete')
                return

            logging.debug('No update content')

        except:
            logging.exception("Exception contacting the API server")

    def schedule(self):
        '''
        Schedules the updater to run on its interval
        '''
        while True:
            self.last = self.get_time()
            if not self.last:
                time.sleep(self.interval)
                continue

            try:
                self.update()

            except KeyboardInterrupt:
                logging.info('Keyboard interrupt; exiting')
                return

            except:
                logging.exception('Exception during update')

            finally:
                self.set_time()

            time.sleep(self.interval)

def main():
    args = get_opt()

    updater = Updater(
        args.url,
        args.user,
        args.password,
        args.syslog_host,
        args.syslog_port,
        args.interval,
        args.file
    )

    updater.schedule()

if __name__ == '__main__':
    main()
    enter code here

来源:https://stackoverflow.com/questions/62286907/typeerror-coercing-to-unicode-need-string-or-buffer-nonetype-found-seems-to

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!