From f49ebce640533e9a03c364bf1371d162cf6ebeac Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20K=C3=A1cha?= <ph@cesnet.cz>
Date: Fri, 21 Jul 2017 14:55:27 +0200
Subject: [PATCH] Some PEP8 fixes

---
 warden3/warden_server/warden_server.py | 349 ++++++++++++-------------
 1 file changed, 168 insertions(+), 181 deletions(-)

diff --git a/warden3/warden_server/warden_server.py b/warden3/warden_server/warden_server.py
index dd9d787..5015e8d 100644
--- a/warden3/warden_server/warden_server.py
+++ b/warden3/warden_server/warden_server.py
@@ -32,6 +32,7 @@ from jsonschema import Draft4Validator
 
 VERSION = "3.0-beta2"
 
+
 class Error(Exception):
 
     def __init__(self, method=None, req_id=None, errors=None, **kwargs):
@@ -41,11 +42,9 @@ class Error(Exception):
         if errors:
             self.errors.extend(errors)
 
-
     def append(self, _events=None, **kwargs):
         self.errors.append(kwargs)
 
-
     def get_http_err_msg(self):
         try:
             err = self.errors[0]["error"]
@@ -64,11 +63,9 @@ class Error(Exception):
                 msg = "Multiple errors"
         return err, msg
 
-
     def __str__(self):
         return "\n".join(self.str_err(e) for e in self.errors)
 
-
     def log(self, logger, prio=logging.ERROR):
         for e in self.errors:
             logger.log(prio, self.str_err(e))
@@ -79,7 +76,6 @@ class Error(Exception):
             if debug:
                 logger.debug(debug)
 
-
     def str_err(self, e):
         out = []
         out.append("Error(%s) %s " % (e.get("error", 0), e.get("message", "Unknown error")))
@@ -87,7 +83,6 @@ class Error(Exception):
             out.append("(cause was %s: %s)" % (e["exc"][0].__name__, str(e["exc"][1])))
         return "".join(out)
 
-
     def str_info(self, e):
         ecopy = dict(e)    # shallow copy
         ecopy.pop("req_id", None)
@@ -101,7 +96,6 @@ class Error(Exception):
             out = ""
         return out
 
-
     def str_debug(self, e):
         out = []
         if not "exc" in e or not e["exc"]:
@@ -112,7 +106,6 @@ class Error(Exception):
             out.extend(format_tb(exc_tb))
         return "".join(out)
 
-
     def to_dict(self):
         errlist = []
         for e in self.errors:
@@ -127,7 +120,6 @@ class Error(Exception):
         return d
 
 
-
 def get_clean_root_logger(level=logging.INFO):
     """ Attempts to get logging module into clean slate state """
 
@@ -149,7 +141,6 @@ def get_clean_root_logger(level=logging.INFO):
     return logger
 
 
-
 def StreamLogger(stream=sys.stderr, level=logging.DEBUG):
     """ Fallback handler just for setup, not meant to be used from
         configuration file because during wsgi query stdout/stderr
@@ -164,7 +155,6 @@ def StreamLogger(stream=sys.stderr, level=logging.DEBUG):
     return logger
 
 
-
 class LogRequestFilter(logging.Filter):
     """ Filter class, instance of which is added to logger class to add
         info about request automatically into every logline, no matter
@@ -175,7 +165,6 @@ class LogRequestFilter(logging.Filter):
         logging.Filter.__init__(self)
         self.req = req
 
-
     def filter(self, record):
         if self.req.env:
             record.req_preamble = "%08x/%s: " % (self.req.req_id or 0, self.req.path)
@@ -184,7 +173,6 @@ class LogRequestFilter(logging.Filter):
         return True
 
 
-
 def FileLogger(req, filename, level=logging.INFO):
 
     fhand = logging.FileHandler(filename)
@@ -198,7 +186,6 @@ def FileLogger(req, filename, level=logging.INFO):
     return logger
 
 
-
 def SysLogger(req, socket="/dev/log", facility=logging.handlers.SysLogHandler.LOG_DAEMON, level=logging.INFO):
 
     fhand = logging.handlers.SysLogHandler(address=socket, facility=facility)
@@ -208,13 +195,13 @@ def SysLogger(req, socket="/dev/log", facility=logging.handlers.SysLogHandler.LO
     logger = get_clean_root_logger(level)
     logger.addFilter(ffilt)
     logger.addHandler(fhand)
-    logger.info("Initialized SysLogger(req=%s, socket=\"%s\", facility=\"%d\", level=\"%d\")" % (type(req).__name__, socket, facility, level))
+    logger.info("Initialized SysLogger(req=%s, socket=\"%s\", facility=\"%d\", level=\"%d\")" % (
+        type(req).__name__, socket, facility, level))
     return logger
 
 
-
-Client = namedtuple("Client",
-    ["id", "registered", "requestor", "hostname", "name",
+Client = namedtuple("Client", [
+    "id", "registered", "requestor", "hostname", "name",
     "secret", "valid", "read", "debug", "write", "test", "note"])
 
 
@@ -224,7 +211,6 @@ class Object(object):
         return "%s()" % type(self).__name__
 
 
-
 class Request(Object):
     """ Simple container for info about ongoing request.
         One instance gets created before server startup, and all other
@@ -246,11 +232,9 @@ class Request(Object):
         Object.__init__(self)
         self.reset()
 
-
     def __str__(self):
         return "%s(env='%s', client='%s')" % (type(self).__name__, str(self.env), str(self.client))
 
-
     def reset(self, env=None, client=None, path=None, req_id=None):
         self.env = env
         self.client = client
@@ -260,12 +244,10 @@ class Request(Object):
         else:
             self.req_id = 0 if env is None else randint(0x00000000, 0xFFFFFFFF)
 
-
     def error(self, **kwargs):
         return Error(self.path, self.req_id, **kwargs)
 
 
-
 class ObjectBase(Object):
 
     def __init__(self, req, log):
@@ -273,24 +255,20 @@ class ObjectBase(Object):
         self.req = req
         self.log = log
 
-
     def __str__(self):
         return "%s(req=%s)" % (type(self).__name__, type(self.req).__name__)
 
 
-
 class PlainAuthenticator(ObjectBase):
 
     def __init__(self, req, log, db):
         ObjectBase.__init__(self, req, log)
         self.db = db
 
-
     def __str__(self):
         return "%s(req=%s, db=%s)" % (type(self).__name__, type(self.req).__name__, type(self.db).__name__)
 
-
-    def authenticate(self, env, args, hostnames = None, check_secret = True):
+    def authenticate(self, env, args, hostnames=None, check_secret=True):
         name = args.get("client", [None])[0]
         secret = args.get("secret", [None])[0] if check_secret else None
 
@@ -315,7 +293,6 @@ class PlainAuthenticator(ObjectBase):
 
         return client
 
-
     def authorize(self, env, client, path, method):
         if method.debug:
             if not client.debug:
@@ -347,9 +324,9 @@ class X509Authenticator(PlainAuthenticator):
         commons = [n.get_data().as_text() for n in subj.get_entries_by_nid(subj.nid["CN"])]
 
         try:
-           extstrs = cert.get_ext("subjectAltName").get_value().split(",")
+            extstrs = cert.get_ext("subjectAltName").get_value().split(",")
         except LookupError:
-           extstrs = []
+            extstrs = []
         extstrs = [val.strip() for val in extstrs]
         altnames = [val[4:] for val in extstrs if val.startswith("DNS:")]
 
@@ -357,17 +334,17 @@ class X509Authenticator(PlainAuthenticator):
         firstcommon = commons[0]
         return [firstcommon] + list(set(altnames+commons) - set([firstcommon]))
 
-
     def is_verified_by_apache(self, env, args):
         # Allows correct work while SSLVerifyClient both "optional" and "required"
         verify = env.get("SSL_CLIENT_VERIFY")
         if verify == "SUCCESS":
             return True
-        exception = self.req.error(message="authenticate: certificate verification failed", error=403, args = args, ssl_client_verify=verify, cert=env.get("SSL_CLIENT_CERT"))
+        exception = self.req.error(
+            message="authenticate: certificate verification failed",
+            error=403, args=args, ssl_client_verify=verify, cert=env.get("SSL_CLIENT_CERT"))
         exception.log(self.log)
         return False
 
-
     def authenticate(self, env, args):
         if not self.is_verified_by_apache(env, args):
             return None
@@ -375,12 +352,14 @@ class X509Authenticator(PlainAuthenticator):
         try:
             cert_names = self.get_cert_dns_names(env["SSL_CLIENT_CERT"])
         except:
-            exception = self.req.error(message="authenticate: cannot get or parse certificate from env", error=403, exc=sys.exc_info(), env=env)
+            exception = self.req.error(
+                message="authenticate: cannot get or parse certificate from env",
+                error=403, exc=sys.exc_info(), env=env)
             exception.log(self.log)
             return None
 
-        return PlainAuthenticator.authenticate(self, env, args, hostnames = cert_names)
-        
+        return PlainAuthenticator.authenticate(self, env, args, hostnames=cert_names)
+
 
 class X509NameAuthenticator(X509Authenticator):
 
@@ -391,16 +370,20 @@ class X509NameAuthenticator(X509Authenticator):
         try:
             cert_name = env["SSL_CLIENT_S_DN_CN"]
         except:
-            exception = self.req.error(message="authenticate: cannot get or parse certificate from env", error=403, exc=sys.exc_info(), env=env)
+            exception = self.req.error(
+                message="authenticate: cannot get or parse certificate from env",
+                error=403, exc=sys.exc_info(), env=env)
             exception.log(self.log)
             return None
 
         if cert_name != args.setdefault("client", [cert_name])[0]:
-            exception = self.req.error(message="authenticate: client name does not correspond with certificate", error=403, cn = cert_name, args = args)
+            exception = self.req.error(
+                message="authenticate: client name does not correspond with certificate",
+                error=403, cn=cert_name, args=args)
             exception.log(self.log)
             return None
 
-        return PlainAuthenticator.authenticate(self, env, args, check_secret = False)
+        return PlainAuthenticator.authenticate(self, env, args, check_secret=False)
 
 
 class X509MixMatchAuthenticator(X509Authenticator):
@@ -410,7 +393,6 @@ class X509MixMatchAuthenticator(X509Authenticator):
         self.hostname_auth = X509Authenticator(req, log, db)
         self.name_auth = X509NameAuthenticator(req, log, db)
 
-
     def authenticate(self, env, args):
         if not self.is_verified_by_apache(env, args):
             return None
@@ -418,11 +400,13 @@ class X509MixMatchAuthenticator(X509Authenticator):
         try:
             cert_name = env["SSL_CLIENT_S_DN_CN"]
         except:
-            exception = self.req.error(message="authenticate: cannot get or parse certificate from env", error=403, exc=sys.exc_info(), env=env)
+            exception = self.req.error(
+                message="authenticate: cannot get or parse certificate from env",
+                error=403, exc=sys.exc_info(), env=env)
             exception.log(self.log)
             return None
         name = args.get("client", [None])[0]
-        secret =  args.get("secret", [None])[0]
+        secret = args.get("secret", [None])[0]
 
         # Client names are in reverse notation than DNS, client name should
         # thus never be the same as machine hostname (if it is, client
@@ -447,11 +431,9 @@ class NoValidator(ObjectBase):
     def __init__(self, req, log):
         ObjectBase.__init__(self, req, log)
 
-
     def __str__(self):
         return "%s(req=%s)" % (type(self).__name__, type(self.req).__name__)
 
-
     def check(self, event):
         return []
 
@@ -465,11 +447,9 @@ class JSONSchemaValidator(NoValidator):
             self.schema = json.load(f)
         self.validator = Draft4Validator(self.schema)
 
-
     def __str__(self):
         return "%s(req=%s, filename=\"%s\")" % (type(self).__name__, type(self.req).__name__, self.path)
 
-
     def check(self, event):
 
         def sortkey(k):
@@ -490,10 +470,10 @@ class JSONSchemaValidator(NoValidator):
         return res
 
 
-
 class MySQL(ObjectBase):
 
-    def __init__(self, req, log, host, user, password, dbname, port, retry_count,
+    def __init__(
+            self, req, log, host, user, password, dbname, port, retry_count,
             retry_pause, event_size_limit, catmap_filename, tagmap_filename):
         ObjectBase.__init__(self, req, log)
         self.host = host
@@ -518,17 +498,18 @@ class MySQL(ObjectBase):
 
         self.con = None
 
-
     def __str__(self):
-        return "%s(req=%s, host='%s', user='%s', dbname='%s', port=%d, retry_count=%d, retry_pause=%d, catmap_filename=\"%s\", tagmap_filename=\"%s\")" % (
-            type(self).__name__, type(self.req).__name__, self.host, self.user, self.dbname, self.port, self.retry_count, self.retry_pause, self.catmap_filename, self.tagmap_filename)
-
+        return (
+            "%s(req=%s, host='%s', user='%s', dbname='%s', port=%d, retry_count=%d, "
+            "retry_pause=%d, catmap_filename=\"%s\", tagmap_filename=\"%s\")") % (
+            type(self).__name__, type(self.req).__name__, self.host, self.user, self.dbname, self.port, self.retry_count,
+            self.retry_pause, self.catmap_filename, self.tagmap_filename)
 
     def connect(self):
-        self.con = my.connect(host=self.host, user=self.user, passwd=self.password,
+        self.con = my.connect(
+            host=self.host, user=self.user, passwd=self.password,
             db=self.dbname, port=self.port, cursorclass=mycursors.DictCursor)
 
-
     def close(self):
         try:
             if self.con:
@@ -537,10 +518,8 @@ class MySQL(ObjectBase):
             pass
         self.con = None
 
-
     __del__ = close
-    
-    
+
     def repeat(self):
         """ Allows for graceful repeating of transactions self.retry_count
             times. Unsuccessful attempts wait for self.retry_pause until
@@ -563,7 +542,6 @@ class MySQL(ObjectBase):
             self.retry_attempt -= 1
             yield self
 
-
     def __enter__(self):
         """ Context manager protocol. Guarantees that transaction will
             get either commited or rolled back in case of database
@@ -580,7 +558,6 @@ class MySQL(ObjectBase):
             self.retry_attempt = 0
         return self
 
-
     def __exit__(self, exc_type, exc_val, exc_tb):
         """ Context manager protocol. If db exception is fired and
             self.retry_attempt is not zero, it is only logged and
@@ -605,7 +582,6 @@ class MySQL(ObjectBase):
                 self.log.info("Database error (%d attempts left): %s %s" % (self.retry_attempt, exc_type.__name__, exc_val))
                 return True
 
-
     def query(self, *args, **kwargs):
         if not self.con:
             self.connect()
@@ -614,15 +590,12 @@ class MySQL(ObjectBase):
         crs.execute(*args, **kwargs)
         return crs
 
-
     def _get_comma_perc(self, l):
         return ','.join(['%s'] * len(l))
 
-
     def _get_not(self, b):
         return "" if b else "NOT"
 
-
     def get_client_by_name(self, cert_names=None, name=None, secret=None):
         query = ["SELECT * FROM clients WHERE valid = 1"]
         params = []
@@ -639,15 +612,14 @@ class MySQL(ObjectBase):
         for attempt in self.repeat():
             with attempt as db:
                 rows = db.query("".join(query), params).fetchall()
-
-                if len(rows)>1:
-                    self.log.warn("get_client_by_name: query returned more than one result (cert_names = %s, name = %s, secret = %s): %s" % (cert_names, name, secret, ", ".join([str(Client(**row)) for row in rows])))
+                if len(rows) > 1:
+                    self.log.warn(
+                        "get_client_by_name: query returned more than one result (cert_names = %s, name = %s, secret = %s): %s" % (
+                            cert_names, name, secret, ", ".join([str(Client(**row)) for row in rows])))
                     return None
 
                 return Client(**rows[0]) if rows else None
 
-
-
     def get_clients(self, id=None):
         query = ["SELECT * FROM clients"]
         params = []
@@ -660,7 +632,6 @@ class MySQL(ObjectBase):
                 rows = db.query(" ".join(query), params).fetchall()
                 return [Client(**row) for row in rows]
 
-
     def add_modify_client(self, id=None, **kwargs):
         query = []
         params = []
@@ -689,7 +660,6 @@ class MySQL(ObjectBase):
                 newid = crs.lastrowid if id is None else id
                 return newid
 
-
     def get_debug(self):
         for attempt in self.repeat():
             with attempt as db:
@@ -701,33 +671,36 @@ class MySQL(ObjectBase):
                     "tables": tablestat
                 }
 
-
     def getMaps(self, section, variables):
         maps = []
         for v in variables:
             try:
                 mapped = section[v]
             except KeyError:
-                raise self.req.error(message="Wrong tag or category used in query.", error=422,
-                    exc=sys.exc_info(), key=v)
+                raise self.req.error(
+                    message="Wrong tag or category used in query.",
+                    error=422, exc=sys.exc_info(), key=v)
             maps.append(mapped)
         return set(maps)    # unique
 
-
-    def fetch_events(self, client, id, count,
+    def fetch_events(
+            self, client, id, count,
             cat=None, nocat=None,
             tag=None, notag=None,
             group=None, nogroup=None):
-       
+
         if cat and nocat:
-            raise self.req.error(message="Unrealizable conditions. Choose cat or nocat option.", error=422,
-                        cat=cat, nocat=nocat)
+            raise self.req.error(
+                message="Unrealizable conditions. Choose cat or nocat option.",
+                error=422, cat=cat, nocat=nocat)
         if tag and notag:
-            raise self.req.error(message="Unrealizable conditions. Choose tag or notag option.", error=422,
-                        tag=tag, notag=notag)
+            raise self.req.error(
+                message="Unrealizable conditions. Choose tag or notag option.",
+                error=422, tag=tag, notag=notag)
         if group and nogroup:
-            raise self.req.error(message="Unrealizable conditions. Choose group or nogroup option.", error=422,
-                        group=group, nogroup=nogroup)
+            raise self.req.error(
+                message="Unrealizable conditions. Choose group or nogroup option.",
+                error=422, group=group, nogroup=nogroup)
 
         query = ["SELECT e.id, e.data FROM clients c RIGHT JOIN events e ON c.id = e.client_id WHERE e.id > %s"]
         params = [id or 0]
@@ -779,8 +752,9 @@ class MySQL(ObjectBase):
                 # Note that we use Error object just for proper formatting,
                 # but do not raise it; from client perspective invalid
                 # events get skipped silently.
-                err = self.req.error(message="Unable to deserialize JSON event from db, id=%s" % r["id"], error=500,
-                    exc=sys.exc_info(), id=r["id"])
+                err = self.req.error(
+                    message="Unable to deserialize JSON event from db, id=%s" % r["id"],
+                    error=500, exc=sys.exc_info(), id=r["id"])
                 err.log(self.log, prio=logging.WARNING)
             events.append(e)
 
@@ -789,13 +763,13 @@ class MySQL(ObjectBase):
             "events": events
         }
 
-
     def store_events(self, client, events, events_raw):
         try:
             for attempt in self.repeat():
                 with attempt as db:
                     for event, raw_event in zip(events, events_raw):
-                        lastid = db.query("INSERT INTO events (received,client_id,data) VALUES (NOW(), %s, %s)",
+                        lastid = db.query(
+                            "INSERT INTO events (received,client_id,data) VALUES (NOW(), %s, %s)",
                             (client.id, raw_event)).lastrowid
 
                         catlist = event.get('Category', ["Other"])
@@ -817,37 +791,36 @@ class MySQL(ObjectBase):
             exception.log(self.log)
             return [{"error": 500, "message": "DB error %s" % type(e).__name__}]
 
-
     def insertLastReceivedId(self, client, id):
         self.log.debug("insertLastReceivedId: id %i for client %i(%s)" % (id, client.id, client.hostname))
         for attempt in self.repeat():
             with attempt as db:
                 db.query("INSERT INTO last_events(client_id, event_id, timestamp) VALUES(%s, %s, NOW())", (client.id, id))
 
-
     def getLastEventId(self):
         for attempt in self.repeat():
             with attempt as db:
                 row = db.query("SELECT MAX(id) as id FROM events").fetchall()[0]
                 return row['id'] or 1
 
-
     def getLastReceivedId(self, client):
         for attempt in self.repeat():
             with attempt as db:
-                res = db.query("SELECT event_id as id FROM last_events WHERE client_id = %s ORDER BY last_events.id DESC LIMIT 1", (client.id,)).fetchall()
+                res = db.query(
+                    "SELECT event_id as id FROM last_events WHERE client_id = %s ORDER BY last_events.id DESC LIMIT 1",
+                    (client.id,)).fetchall()
                 try:
                     row = res[0]
                 except IndexError:
                     id = None
-                    self.log.debug("getLastReceivedId: probably first access, unable to get id for client %i(%s)" % (client.id, client.hostname))
+                    self.log.debug("getLastReceivedId: probably first access, unable to get id for client %i(%s)" % (
+                        client.id, client.hostname))
                 else:
                     id = row["id"]
                     self.log.debug("getLastReceivedId: id %i for client %i(%s)" % (id, client.id, client.hostname))
 
                 return id
 
-
     def load_maps(self):
         with self as db:
             db.query("DELETE FROM tags")
@@ -857,11 +830,11 @@ class MySQL(ObjectBase):
             for cat_subcat, num in self.catmap.iteritems():
                 catsplit = cat_subcat.split(".", 1)
                 category = catsplit[0]
-                subcategory = catsplit[1] if len(catsplit)>1 else None
-                db.query("INSERT INTO categories(id, category, subcategory, cat_subcat) VALUES (%s, %s, %s, %s)",
+                subcategory = catsplit[1] if len(catsplit) > 1 else None
+                db.query(
+                    "INSERT INTO categories(id, category, subcategory, cat_subcat) VALUES (%s, %s, %s, %s)",
                     (num, category, subcategory, cat_subcat))
 
-
     def purge_lastlog(self, days):
         with self as db:
             return db.query(
@@ -873,7 +846,6 @@ class MySQL(ObjectBase):
                 " WHERE timestamp < DATE_SUB(CURDATE(), INTERVAL %s DAY) AND last IS NULL",
                 (days,)).rowcount
 
-
     def purge_events(self, days):
         with self as db:
             affected = 0
@@ -891,7 +863,6 @@ class MySQL(ObjectBase):
             return affected
 
 
-
 def expose(read=1, write=0, debug=0):
 
     def expose_deco(meth):
@@ -913,10 +884,9 @@ class Server(ObjectBase):
         self.auth = auth
         self.handler = handler
 
-
     def __str__(self):
-        return "%s(req=%s, auth=%s, handler=%s)" % (type(self).__name__, type(self.req).__name__, type(self.auth).__name__, type(self.handler).__name__)
-
+        return "%s(req=%s, auth=%s, handler=%s)" % (
+            type(self).__name__, type(self.req).__name__, type(self.auth).__name__, type(self.handler).__name__)
 
     def sanitize_args(self, path, func, args, exclude=["self", "post"]):
         # silently remove internal args, these should never be used
@@ -937,7 +907,6 @@ class Server(ObjectBase):
 
         return args
 
-
     def wsgi_app(self, environ, start_response, exc_info=None):
         path = environ.get("PATH_INFO", "").lstrip("/")
         self.req.reset(env=environ, path=path)
@@ -996,11 +965,9 @@ class Server(ObjectBase):
         self.req.reset()
         return [output]
 
-
     __call__ = wsgi_app
 
 
-
 def json_wrapper(method):
 
     def meth_deco(self, post, **args):
@@ -1008,7 +975,8 @@ def json_wrapper(method):
             try:
                 events = json.loads(post) if post else None
             except Exception as e:
-                raise self.req.error(message="Deserialization error.", error=400,
+                raise self.req.error(
+                    message="Deserialization error.", error=400,
                     exc=sys.exc_info(), args=post, parser=str(e))
             if events:
                 args["events"] = events
@@ -1020,8 +988,7 @@ def json_wrapper(method):
             # which could (although shouldn't) appear in handler code
             output = json.dumps(result, default=lambda v: str(v))
         except Exception as e:
-            raise self.req.error(message="Serialization error", error=500,
-                exc=sys.exc_info(), args=str(result))
+            raise self.req.error(message="Serialization error", error=500, exc=sys.exc_info(), args=str(result))
 
         return [('Content-type', 'application/json')], output
 
@@ -1034,7 +1001,8 @@ def json_wrapper(method):
 
 class WardenHandler(ObjectBase):
 
-    def __init__(self, req, log, validator, db, auth,
+    def __init__(
+            self, req, log, validator, db, auth,
             send_events_limit=500, get_events_limit=1000,
             description=None):
 
@@ -1046,13 +1014,11 @@ class WardenHandler(ObjectBase):
         self.get_events_limit = get_events_limit
         self.description = description
 
-
     def __str__(self):
         return "%s(req=%s, validator=%s, db=%s, send_events_limit=%s, get_events_limit=%s, description=\"%s\")" % (
             type(self).__name__, type(self.req).__name__, type(self.validator).__name__, type(self.db).__name__,
             self.get_events_limit, self.send_events_limit, self.description)
 
-
     @expose(read=1, debug=1)
     @json_wrapper
     def getDebug(self):
@@ -1076,7 +1042,6 @@ class WardenHandler(ObjectBase):
             }
         }
 
-
     @expose(read=1)
     @json_wrapper
     def getInfo(self):
@@ -1089,10 +1054,10 @@ class WardenHandler(ObjectBase):
             info["description"] = self.description
         return info
 
-
     @expose(read=1)
     @json_wrapper
-    def getEvents(self, id=None, count=None,
+    def getEvents(
+            self, id=None, count=None,
             cat=None, nocat=None,
             tag=None, notag=None,
             group=None, nogroup=None):
@@ -1108,7 +1073,7 @@ class WardenHandler(ObjectBase):
                 id = self.db.getLastReceivedId(self.req.client)
             except Exception as e:
                 self.log.info("cannot getLastReceivedId - " + type(e).__name__ + ": " + str(e))
-                
+
         if id is None:
             # First access, remember the guy and get him last id
             id = self.db.getLastEventId()
@@ -1118,10 +1083,10 @@ class WardenHandler(ObjectBase):
                 "events": []
             }
 
-        if id<=0:
+        if id <= 0:
             # Client wants to get only last N events and reset server notion of last id
             id += self.db.getLastEventId()
-            if id<0: id=0
+            if id < 0: id = 0
 
         try:
             count = int(count[0])
@@ -1139,7 +1104,6 @@ class WardenHandler(ObjectBase):
 
         return res
 
-
     def check_node(self, event, name):
         try:
             ev_id = event['Node'][0]['Name'].lower()
@@ -1150,7 +1114,6 @@ class WardenHandler(ObjectBase):
             return [{"error": 422, "message": "Node does not correspond with saving client"}]
         return []
 
-
     def add_event_nums(self, ilist, events, errlist):
         for err in errlist:
             err.setdefault("events", []).extend(ilist)
@@ -1164,7 +1127,6 @@ class WardenHandler(ObjectBase):
                 ev_ids.append(id)
         return errlist
 
-
     @expose(write=1)
     @json_wrapper
     def sendEvents(self, events=[]):
@@ -1172,11 +1134,9 @@ class WardenHandler(ObjectBase):
             raise self.req.error(message="List of events expected.", error=400)
 
         errs = []
-        if len(events)>self.send_events_limit:
-            errs.extend(
-                self.add_event_nums(range(self.send_events_limit, len(events)), events,
-                    [{"error": 507, "message": "Too much events in one batch.",
-                      "send_events_limit": self.send_events_limit}]))
+        if len(events) > self.send_events_limit:
+            errs.extend(self.add_event_nums(range(self.send_events_limit, len(events)), events, [
+                {"error": 507, "message": "Too much events in one batch.", "send_events_limit": self.send_events_limit}]))
 
         saved = 0
         events_tosend = []
@@ -1194,14 +1154,19 @@ class WardenHandler(ObjectBase):
                 continue
 
             if self.req.client.test and not 'Test' in event.get('Category', []):
-                errs.extend(self.add_event_nums([i], events, [{"error": 422,
-                    "message": "You're allowed to send only messages, containing \"Test\" among categories.",
-                    "categories": event.get('Category', [])}]))
+                errs.extend(
+                    self.add_event_nums([i], events, [{
+                        "error": 422,
+                        "message": "You're allowed to send only messages, containing \"Test\" among categories.",
+                        "categories": event.get('Category', [])}]))
                 continue
 
             raw_event = json.dumps(event)
             if len(raw_event) >= self.db.event_size_limit:
-                errs.extend(self.add_event_nums([i], events, [{"error": 413, "message": "Event too long (>%i B)" % self.db.event_size_limit}]))
+                errs.extend(
+                    self.add_event_nums([i], events, [
+                        {"error": 413, "message": "Event too long (>%i B)" % self.db.event_size_limit}
+                    ]))
                 continue
 
             events_tosend.append(event)
@@ -1222,7 +1187,6 @@ class WardenHandler(ObjectBase):
         return {"saved": saved}
 
 
-
 def read_ini(path):
     c = ConfigParser.RawConfigParser()
     res = c.read(path)
@@ -1245,8 +1209,9 @@ def read_cfg(path):
         conf = json.loads(stripcomments)
 
     # Lowercase keys
-    conf = dict((sect.lower(), dict(
-        (subkey.lower(), val) for subkey, val in subsect.iteritems())
+    conf = dict((
+        sect.lower(), dict(
+            (subkey.lower(), val) for subkey, val in subsect.iteritems())
     ) for sect, subsect in conf.iteritems())
 
     return conf
@@ -1256,8 +1221,8 @@ def fallback_wsgi(environ, start_response, exc_info=None):
 
     # If server does not start, set up simple server, returning
     # Warden JSON compliant error message
-    error=503
-    message="Server not running due to initialization error"
+    error = 503
+    message = "Server not running due to initialization error"
     headers = [('Content-type', 'application/json')]
 
     logline = "Error(%d): %s" % (error, message)
@@ -1364,7 +1329,6 @@ def build_server(conf, section_order=section_order, section_def=section_def, par
 
     objects = {}    # Already initialized objects
 
-
     # Functions for validation and conversion of config values
     def facility(name):
         return int(getattr(logging.handlers.SysLogHandler, "LOG_" + name.upper()))
@@ -1374,7 +1338,7 @@ def build_server(conf, section_order=section_order, section_def=section_def, par
 
     def natural(name):
         num = int(name)
-        if num<1:
+        if num < 1:
             raise ValueError("Not a natural number")
         return num
 
@@ -1385,7 +1349,6 @@ def build_server(conf, section_order=section_order, section_def=section_def, par
     def obj(name):
         return objects[name.lower()]
 
-
     # Typedef dictionary
     conv_dict = {
         "facility": facility,
@@ -1396,7 +1359,6 @@ def build_server(conf, section_order=section_order, section_def=section_def, par
         "str": str
     }
 
-
     def init_obj(sect_name):
         config = conf.get(sect_name, {})
         sect_name = sect_name.lower()
@@ -1407,7 +1369,7 @@ def build_server(conf, section_order=section_order, section_def=section_def, par
             del config["type"]
         except KeyError:    # No, fetch default object type for this section
             cls = sect_def[0]
-        else:	# Yes, get corresponding class/callable
+        else:  # Yes, get corresponding class/callable
             names = [o.__name__ for o in sect_def]
             try:
                 idx = names.index(objtype)
@@ -1469,7 +1431,6 @@ def build_server(conf, section_order=section_order, section_def=section_def, par
     return objects["server"]
 
 
-
 # Command line utilities
 
 def check_config():
@@ -1503,13 +1464,13 @@ def modify_client(**kwargs):
     def isValidHostname(hostname):
         if len(hostname) > 255:
             return False
-        if hostname.endswith("."): # A single trailing dot is legal
-            hostname = hostname[:-1] # strip exactly one dot from the right, if present
+        if hostname.endswith("."):  # A single trailing dot is legal
+            hostname = hostname[:-1]  # strip exactly one dot from the right, if present
         disallowed = re.compile(r"[^A-Z\d-]", re.IGNORECASE)
-        return all( # Split by labels and verify individually
-            (label and len(label) <= 63 # length is within proper range
-             and not label.startswith("-") and not label.endswith("-") # no bordering hyphens
-             and not disallowed.search(label)) # contains only legal characters
+        return all(  # Split by labels and verify individually
+            (label and len(label) <= 63  # length is within proper range
+             and not label.startswith("-") and not label.endswith("-")  # no bordering hyphens
+             and not disallowed.search(label))  # contains only legal characters
             for label in hostname.split("."))
 
     def isValidNSID(nsid):
@@ -1518,7 +1479,7 @@ def modify_client(**kwargs):
 
     def isValidEmail(mail):
         mails = (email.utils.parseaddr(m) for m in mail.split(","))
-        allowed = re.compile(r"^[a-zA-Z0-9_.%!+-]+@[a-zA-Z0-9-.]+$") # just basic check
+        allowed = re.compile(r"^[a-zA-Z0-9_.%!+-]+@[a-zA-Z0-9-.]+$")  # just basic check
         valid = (allowed.match(ms[1]) for ms in mails)
         return all(valid)
 
@@ -1526,7 +1487,6 @@ def modify_client(**kwargs):
         client = server.handler.db.get_clients(id)
         return client and True or False
 
-
     if kwargs["name"] is not None:
         kwargs["name"] = kwargs["name"].lower()
         if not isValidNSID(kwargs["name"]):
@@ -1548,10 +1508,10 @@ def modify_client(**kwargs):
         return 251
 
     for c in server.handler.db.get_clients():
-        if kwargs["name"] is not None and kwargs["name"].lower()==c.name:
+        if kwargs["name"] is not None and kwargs["name"].lower() == c.name:
             print("Clash with existing name: %s" % (str(c)), file=sys.stderr)
             return 250
-        if kwargs["secret"] is not None and kwargs["secret"]==c.secret:
+        if kwargs["secret"] is not None and kwargs["secret"] == c.secret:
             print("Clash with existing secret: %s" % str(c), file=sys.stderr)
             return 249
 
@@ -1580,41 +1540,52 @@ def purge(days=30, lastlog=None, events=None):
 def add_client_args(subargp, mod=False):
     subargp.add_argument("--help", action="help", help="show this help message and exit")
     if mod:
-        subargp.add_argument("-i", "--id", required=True, type=int,
+        subargp.add_argument(
+            "-i", "--id", required=True, type=int,
             help="client id")
-    subargp.add_argument("-n", "--name", required=not mod,
+    subargp.add_argument(
+        "-n", "--name", required=not mod,
         help="client name (in dotted reverse path notation)")
-    subargp.add_argument("-h", "--hostname", required=not mod,
+    subargp.add_argument(
+        "-h", "--hostname", required=not mod,
         help="client FQDN hostname")
-    subargp.add_argument("-r", "--requestor", required=not mod,
+    subargp.add_argument(
+        "-r", "--requestor", required=not mod,
         help="requestor email")
-    subargp.add_argument("-s", "--secret",
+    subargp.add_argument(
+        "-s", "--secret",
         help="authentication token (use explicit empty string to disable)")
-    subargp.add_argument("--note",
+    subargp.add_argument(
+        "--note",
         help="client freetext description")
 
     reg_valid = subargp.add_mutually_exclusive_group(required=False)
-    reg_valid.add_argument("--valid", action="store_const", const=1, default=None,
+    reg_valid.add_argument(
+        "--valid", action="store_const", const=1, default=None,
         help="valid client (default)")
     reg_valid.add_argument("--novalid", action="store_const", const=0, dest="valid", default=None)
 
     reg_read = subargp.add_mutually_exclusive_group(required=False)
-    reg_read.add_argument("--read", action="store_const", const=1, default=None,
+    reg_read.add_argument(
+        "--read", action="store_const", const=1, default=None,
         help="client is allowed to read (default)")
     reg_read.add_argument("--noread", action="store_const", const=0, dest="read", default=None)
 
     reg_write = subargp.add_mutually_exclusive_group(required=False)
-    reg_write.add_argument("--nowrite", action="store_const", const=0, dest="write", default=None,
+    reg_write.add_argument(
+        "--nowrite", action="store_const", const=0, dest="write", default=None,
         help="client is allowed to send (default - no)")
     reg_write.add_argument("--write", action="store_const", const=1, default=None)
 
     reg_debug = subargp.add_mutually_exclusive_group(required=False)
-    reg_debug.add_argument("--nodebug", action="store_const", const=0, dest="debug", default=None,
+    reg_debug.add_argument(
+        "--nodebug", action="store_const", const=0, dest="debug", default=None,
         help="client is allowed receive debug output (default - no)")
     reg_debug.add_argument("--debug", action="store_const", const=1, default=None)
 
     reg_test = subargp.add_mutually_exclusive_group(required=False)
-    reg_test.add_argument("--test", action="store_const", const=1, default=None,
+    reg_test.add_argument(
+        "--test", action="store_const", const=1, default=None,
         help="client is yet in testing phase (default - yes)")
     reg_test.add_argument("--notest", action="store_const", const=0, dest="test", default=None)
 
@@ -1623,71 +1594,87 @@ def get_args():
     import argparse
     argp = argparse.ArgumentParser(
         description="Warden server " + VERSION, add_help=False)
-    argp.add_argument("--help", action="help",
+    argp.add_argument(
+        "--help", action="help",
         help="show this help message and exit")
-    argp.add_argument("-c", "--config",
+    argp.add_argument(
+        "-c", "--config",
         help="path to configuration file")
     subargp = argp.add_subparsers(title="commands")
 
-    subargp_check = subargp.add_parser("check", add_help=False,
+    subargp_check = subargp.add_parser(
+        "check", add_help=False,
         description="Try to setup server based on configuration file.",
         help="check configuration")
     subargp_check.set_defaults(command=check_config)
-    subargp_check.add_argument("--help", action="help",
+    subargp_check.add_argument(
+        "--help", action="help",
         help="show this help message and exit")
 
-    subargp_reg = subargp.add_parser("register", add_help=False,
+    subargp_reg = subargp.add_parser(
+        "register", add_help=False,
         description="Add new client registration entry.",
         help="register new client")
     subargp_reg.set_defaults(command=register_client)
     add_client_args(subargp_reg)
 
-    subargp_mod = subargp.add_parser("modify", add_help=False,
+    subargp_mod = subargp.add_parser(
+        "modify", add_help=False,
         description="Modify details of client registration entry.",
         help="modify client registration")
     subargp_mod.set_defaults(command=modify_client)
     add_client_args(subargp_mod, mod=True)
 
-    subargp_list = subargp.add_parser("list", add_help=False,
+    subargp_list = subargp.add_parser(
+        "list", add_help=False,
         description="List details of client registration entries.",
         help="list registered clients")
     subargp_list.set_defaults(command=list_clients)
-    subargp_list.add_argument("--help", action="help",
+    subargp_list.add_argument(
+        "--help", action="help",
         help="show this help message and exit")
-    subargp_list.add_argument("--id", action="store", type=int,
+    subargp_list.add_argument(
+        "--id", action="store", type=int,
         help="client id", default=None)
 
-    subargp_purge = subargp.add_parser("purge", add_help=False,
-        description=
+    subargp_purge = subargp.add_parser(
+        "purge", add_help=False,
+        description=(
             "Purge old events or lastlog records."
             " Note that lastlog purge retains at least one newest record for each"
-            " client, even if it is more than number of 'days' old.",
+            " client, even if it is more than number of 'days' old."),
         help="purge old events or lastlog records")
     subargp_purge.set_defaults(command=purge)
-    subargp_purge.add_argument("--help", action="help",
+    subargp_purge.add_argument(
+        "--help", action="help",
         help="show this help message and exit")
-    subargp_purge.add_argument("-l", "--lastlog", action="store_true", dest="lastlog", default=None,
+    subargp_purge.add_argument(
+        "-l", "--lastlog", action="store_true", dest="lastlog", default=None,
         help="purge lastlog records")
-    subargp_purge.add_argument("-e", "--events", action="store_true", dest="events", default=None,
+    subargp_purge.add_argument(
+        "-e", "--events", action="store_true", dest="events", default=None,
         help="purge events")
-    subargp_purge.add_argument("-d", "--days", action="store", dest="days", type=int, default=30,
+    subargp_purge.add_argument(
+        "-d", "--days", action="store", dest="days", type=int, default=30,
         help="records older than 'days' back from today will get purged")
 
-    subargp_loadmaps = subargp.add_parser("loadmaps", add_help=False,
-        description=
+    subargp_loadmaps = subargp.add_parser(
+        "loadmaps", add_help=False,
+        description=(
             "Load 'categories' and 'tags' table from 'catmap_mysql.json' and 'tagmap_mysql.json'."
             " Note that this is NOT needed for server at all, load them into db at will,"
             " should you need to run your own specific SQL queries on data directly."
-            " Note also that previous content of both tables will be lost.",
+            " Note also that previous content of both tables will be lost."),
         help="load catmap and tagmap into db")
     subargp_loadmaps.set_defaults(command=load_maps)
-    subargp_loadmaps.add_argument("--help", action="help",
+    subargp_loadmaps.add_argument(
+        "--help", action="help",
         help="show this help message and exit")
 
     return argp.parse_args()
 
 
-if __name__=="__main__":
+if __name__ == "__main__":
     args = get_args()
     config = path.join(path.dirname(__file__), args.config or "warden_server.cfg")
     server = build_server(read_cfg(config))
-- 
GitLab