问题
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