python3 - 2to3 + miscell obvious tweaks
[sfa.git] / sfa / storage / model.py
index 051ba87..a2e3bd4 100644 (file)
@@ -1,7 +1,6 @@
-from types import StringTypes
 from datetime import datetime
 
 from datetime import datetime
 
-from sqlalchemy import or_, and_ 
+from sqlalchemy import or_, and_
 from sqlalchemy import Column, Integer, String, DateTime
 from sqlalchemy import Table, Column, MetaData, join, ForeignKey
 from sqlalchemy.orm import relationship, backref
 from sqlalchemy import Column, Integer, String, DateTime
 from sqlalchemy import Table, Column, MetaData, join, ForeignKey
 from sqlalchemy.orm import relationship, backref
@@ -13,7 +12,8 @@ from sqlalchemy.ext.declarative import declarative_base
 from sfa.storage.record import Record
 from sfa.util.sfalogging import logger
 from sfa.util.sfatime import utcparse, datetime_to_string
 from sfa.storage.record import Record
 from sfa.util.sfalogging import logger
 from sfa.util.sfatime import utcparse, datetime_to_string
-from sfa.util.xml import XML 
+from sfa.util.xml import XML
+from sfa.util.py23 import StringType
 
 from sfa.trust.gid import GID
 
 
 from sfa.trust.gid import GID
 
@@ -27,13 +27,13 @@ Base = declarative_base()
 # sqlalchemy however offers an object interface, meaning that you write obj.id instead of obj['id']
 # which is admittedly much nicer
 # however we still need to deal with dictionaries if only for the xmlrpc layer
 # sqlalchemy however offers an object interface, meaning that you write obj.id instead of obj['id']
 # which is admittedly much nicer
 # however we still need to deal with dictionaries if only for the xmlrpc layer
-# 
-# here are a few utilities for this 
-# 
+#
+# here are a few utilities for this
+#
 # (*) first off, when an old pieve of code needs to be used as-is, if only temporarily, the simplest trick
 # is to use obj.__dict__
 # this behaves exactly like required, i.e. obj.__dict__['field']='new value' does change obj.field
 # (*) first off, when an old pieve of code needs to be used as-is, if only temporarily, the simplest trick
 # is to use obj.__dict__
 # this behaves exactly like required, i.e. obj.__dict__['field']='new value' does change obj.field
-# however this depends on sqlalchemy's implementation so it should be avoided 
+# however this depends on sqlalchemy's implementation so it should be avoided
 #
 # (*) second, when an object needs to be exposed to the xmlrpc layer, we need to convert it into a dict
 # remember though that writing the resulting dictionary won't change the object
 #
 # (*) second, when an object needs to be exposed to the xmlrpc layer, we need to convert it into a dict
 # remember though that writing the resulting dictionary won't change the object
@@ -48,15 +48,18 @@ Base = declarative_base()
 # (*) finally for converting a dictionary into an sqlalchemy object, we provide
 # obj.load_from_dict(dict)
 
 # (*) finally for converting a dictionary into an sqlalchemy object, we provide
 # obj.load_from_dict(dict)
 
+
 class AlchemyObj(Record):
 class AlchemyObj(Record):
-    def __iter__(self): 
+
+    def __iter__(self):
         self._i = iter(object_mapper(self).columns)
         self._i = iter(object_mapper(self).columns)
-        return self 
-    def next(self): 
+        return self
+
+    def __next__(self):
         n = self._i.next().name
         return n, getattr(self, n)
 
         n = self._i.next().name
         return n, getattr(self, n)
 
-#    # only intended for debugging 
+#    # only intended for debugging
 #    def inspect (self, logger, message=""):
 #        logger.info("%s -- Inspecting AlchemyObj -- attrs"%message)
 #        for k in dir(self):
 #    def inspect (self, logger, message=""):
 #        logger.info("%s -- Inspecting AlchemyObj -- attrs"%message)
 #        for k in dir(self):
@@ -72,43 +75,52 @@ class AlchemyObj(Record):
 # various kinds of records are implemented as an inheritance hierarchy
 # RegRecord is the base class for all actual variants
 # a first draft was using 'type' as the discriminator for the inheritance
 # various kinds of records are implemented as an inheritance hierarchy
 # RegRecord is the base class for all actual variants
 # a first draft was using 'type' as the discriminator for the inheritance
-# but we had to define another more internal column (classtype) so we 
+# but we had to define another more internal column (classtype) so we
 # accomodate variants in types like authority+am and the like
 
 class RegRecord(Base, AlchemyObj):
 # accomodate variants in types like authority+am and the like
 
 class RegRecord(Base, AlchemyObj):
-    __tablename__       = 'records'
-    record_id           = Column (Integer, primary_key=True)
+    __tablename__ = 'records'
+    record_id = Column(Integer, primary_key=True)
     # this is the discriminator that tells which class to use
     # this is the discriminator that tells which class to use
-    classtype           = Column (String)
+    classtype = Column(String)
     # in a first version type was the discriminator
     # but that could not accomodate for 'authority+sa' and the like
     # in a first version type was the discriminator
     # but that could not accomodate for 'authority+sa' and the like
-    type                = Column (String)
-    hrn                 = Column (String)
-    gid                 = Column (String)
-    authority           = Column (String)
-    peer_authority      = Column (String)
-    pointer             = Column (Integer, default=-1)
-    date_created        = Column (DateTime)
-    last_updated        = Column (DateTime)
+    type = Column(String)
+    hrn = Column(String)
+    gid = Column(String)
+    authority = Column(String)
+    peer_authority = Column(String)
+    pointer = Column(Integer, default=-1)
+    date_created = Column(DateTime)
+    last_updated = Column(DateTime)
     # use the 'type' column to decide which subclass the object is of
     # use the 'type' column to decide which subclass the object is of
-    __mapper_args__     = { 'polymorphic_on' : classtype }
-
-    fields = [ 'type', 'hrn', 'gid', 'authority', 'peer_authority' ]
-    def __init__ (self, type=None, hrn=None, gid=None, authority=None, peer_authority=None, 
-                  pointer=None, dict=None):
-        if type:                                self.type=type
-        if hrn:                                 self.hrn=hrn
-        if gid: 
-            if isinstance(gid, StringTypes):    self.gid=gid
-            else:                               self.gid=gid.save_to_string(save_parents=True)
-        if authority:                           self.authority=authority
-        if peer_authority:                      self.peer_authority=peer_authority
-        if pointer:                             self.pointer=pointer
-        if dict:                                self.load_from_dict (dict)
+    __mapper_args__ = {'polymorphic_on': classtype}
+
+    fields = ['type', 'hrn', 'gid', 'authority', 'peer_authority']
+
+    def __init__(self, type=None, hrn=None, gid=None, authority=None, peer_authority=None,
+                 pointer=None, dict=None):
+        if type:
+            self.type = type
+        if hrn:
+            self.hrn = hrn
+        if gid:
+            if isinstance(gid, StringType):
+                self.gid = gid
+            else:
+                self.gid = gid.save_to_string(save_parents=True)
+        if authority:
+            self.authority = authority
+        if peer_authority:
+            self.peer_authority = peer_authority
+        if pointer:
+            self.pointer = pointer
+        if dict:
+            self.load_from_dict(dict)
 
     def __repr__(self):
 
     def __repr__(self):
-        result="<Record id=%s, type=%s, hrn=%s, authority=%s" % \
-                (self.record_id, self.type, self.hrn, self.authority)
+        result = "<Record id=%s, type=%s, hrn=%s, authority=%s" % \
+            (self.record_id, self.type, self.hrn, self.authority)
 #        for extra in ('pointer', 'email', 'name'):
 #        for extra in ('email', 'name'):
 # displaying names at this point it too dangerous, because of unicode
 #        for extra in ('pointer', 'email', 'name'):
 #        for extra in ('email', 'name'):
 # displaying names at this point it too dangerous, because of unicode
@@ -117,190 +129,216 @@ class RegRecord(Base, AlchemyObj):
                 result += " {}={},".format(extra, getattr(self, extra))
         # skip the uniform '--- BEGIN CERTIFICATE --' stuff
         if self.gid:
                 result += " {}={},".format(extra, getattr(self, extra))
         # skip the uniform '--- BEGIN CERTIFICATE --' stuff
         if self.gid:
-            result+=" gid=%s..."%self.gid[28:36]
+            result += " gid=%s..." % self.gid[28:36]
         else:
         else:
-            result+=" nogid"
+            result += " nogid"
         result += ">"
         return result
 
     # shortcut - former implem. was record-based
         result += ">"
         return result
 
     # shortcut - former implem. was record-based
-    def get (self, field, default):
-        return getattr(self,field,default)
-
-    @validates ('gid')
-    def validate_gid (self, key, gid):
-        if gid is None:                     return
-        elif isinstance(gid, StringTypes):  return gid
-        else:                               return gid.save_to_string(save_parents=True)
+    def get(self, field, default):
+        return getattr(self, field, default)
+
+    @validates('gid')
+    def validate_gid(self, key, gid):
+        if gid is None:
+            return
+        elif isinstance(gid, StringType):
+            return gid
+        else:
+            return gid.save_to_string(save_parents=True)
 
 
-    def validate_datetime (self, key, incoming):
-        if isinstance (incoming, datetime):
+    def validate_datetime(self, key, incoming):
+        if isinstance(incoming, datetime):
             return incoming
             return incoming
-        elif isinstance (incoming, (int, float)):
-            return datetime.fromtimestamp (incoming)
+        elif isinstance(incoming, (int, float)):
+            return datetime.fromtimestamp(incoming)
         else:
         else:
-            logger.info("Cannot validate datetime for key %s with input %s"%\
-                        (key,incoming))
-
-    @validates ('date_created')
-    def validate_date_created (self, key, incoming):
-        return self.validate_datetime (key, incoming)
-
-    @validates ('last_updated')
-    def validate_last_updated (self, key, incoming):
-        return self.validate_datetime (key, incoming)
-
-    # xxx - there might be smarter ways to handle get/set'ing gid using validation hooks 
-    def get_gid_object (self):
-        if not self.gid:        return None
-        else:                   return GID(string=self.gid)
+            logger.info("Cannot validate datetime for key %s with input %s" %
+                        (key, incoming))
+
+    @validates('date_created')
+    def validate_date_created(self, key, incoming):
+        return self.validate_datetime(key, incoming)
+
+    @validates('last_updated')
+    def validate_last_updated(self, key, incoming):
+        return self.validate_datetime(key, incoming)
+
+    # xxx - there might be smarter ways to handle get/set'ing gid using
+    # validation hooks
+    def get_gid_object(self):
+        if not self.gid:
+            return None
+        else:
+            return GID(string=self.gid)
 
 
-    def just_created (self):
+    def just_created(self):
         now = datetime.utcnow()
         self.date_created = now
         self.last_updated = now
 
         now = datetime.utcnow()
         self.date_created = now
         self.last_updated = now
 
-    def just_updated (self):
+    def just_updated(self):
         now = datetime.utcnow()
         self.last_updated = now
 
         now = datetime.utcnow()
         self.last_updated = now
 
-#################### cross-relations tables
+# cross-relations tables
 # authority x user (pis) association
 authority_pi_table = \
 # authority x user (pis) association
 authority_pi_table = \
-    Table ( 'authority_pi', Base.metadata,
-            Column ('authority_id', Integer, ForeignKey ('records.record_id'), primary_key=True),
-            Column ('pi_id', Integer, ForeignKey ('records.record_id'), primary_key=True),
-            )
+    Table('authority_pi', Base.metadata,
+          Column('authority_id', Integer, ForeignKey(
+              'records.record_id'), primary_key=True),
+          Column('pi_id', Integer, ForeignKey(
+              'records.record_id'), primary_key=True),
+          )
 # slice x user (researchers) association
 slice_researcher_table = \
 # slice x user (researchers) association
 slice_researcher_table = \
-    Table ( 'slice_researcher', Base.metadata,
-            Column ('slice_id', Integer, ForeignKey ('records.record_id'), primary_key=True),
-            Column ('researcher_id', Integer, ForeignKey ('records.record_id'), primary_key=True),
-            )
+    Table('slice_researcher', Base.metadata,
+          Column('slice_id', Integer, ForeignKey(
+              'records.record_id'), primary_key=True),
+          Column('researcher_id', Integer, ForeignKey(
+              'records.record_id'), primary_key=True),
+          )
 
 ##############################
 
 ##############################
-# all subclasses define a convenience constructor with a default value for type, 
+# all subclasses define a convenience constructor with a default value for type,
 # and when applicable a way to define local fields in a kwd=value argument
 ####################
 # and when applicable a way to define local fields in a kwd=value argument
 ####################
+
+
 class RegAuthority(RegRecord):
 class RegAuthority(RegRecord):
-    __tablename__       = 'authorities'
-    __mapper_args__     = { 'polymorphic_identity' : 'authority' }
-    record_id           = Column (Integer, ForeignKey ("records.record_id"), primary_key=True)
-    #### extensions come here
-    name                = Column ('name', String)
-    #### extensions come here
+    __tablename__ = 'authorities'
+    __mapper_args__ = {'polymorphic_identity': 'authority'}
+    record_id = Column(Integer, ForeignKey(
+        "records.record_id"), primary_key=True)
+    # extensions come here
+    name = Column('name', String)
+    # extensions come here
     reg_pis             = relationship \
         ('RegUser',
     reg_pis             = relationship \
         ('RegUser',
-         secondary = authority_pi_table,
-         primaryjoin = RegRecord.record_id==authority_pi_table.c.authority_id,
-         secondaryjoin = RegRecord.record_id==authority_pi_table.c.pi_id,
-         backref = 'reg_authorities_as_pi',
-        )
-    
-    def __init__ (self, **kwds):
+         secondary=authority_pi_table,
+         primaryjoin=RegRecord.record_id == authority_pi_table.c.authority_id,
+         secondaryjoin=RegRecord.record_id == authority_pi_table.c.pi_id,
+         backref='reg_authorities_as_pi',
+         )
+
+    def __init__(self, **kwds):
         # handle local settings
         if 'name' in kwds:
             self.name = kwds.pop('name')
         # fill in type if not previously set
         if 'type' not in kwds:
         # handle local settings
         if 'name' in kwds:
             self.name = kwds.pop('name')
         # fill in type if not previously set
         if 'type' not in kwds:
-            kwds['type']='authority'
+            kwds['type'] = 'authority'
         # base class constructor
         RegRecord.__init__(self, **kwds)
 
     # no proper data yet, just hack the typename
         # base class constructor
         RegRecord.__init__(self, **kwds)
 
     # no proper data yet, just hack the typename
-    def __repr__ (self):
+    def __repr__(self):
         result = RegRecord.__repr__(self).replace("Record", "Authority")
         result = RegRecord.__repr__(self).replace("Record", "Authority")
-# here again trying to display names that can be utf8 is too dangerous        
+# here again trying to display names that can be utf8 is too dangerous
 #        result.replace(">", " name={}>".format(self.name))
         return result
 
 #        result.replace(">", " name={}>".format(self.name))
         return result
 
-    def update_pis (self, pi_hrns, dbsession):
+    def update_pis(self, pi_hrns, dbsession):
         # strip that in case we have <researcher> words </researcher>
         # strip that in case we have <researcher> words </researcher>
-        pi_hrns = [ x.strip() for x in pi_hrns ]
+        pi_hrns = [x.strip() for x in pi_hrns]
         request = dbsession.query(RegUser).filter(RegUser.hrn.in_(pi_hrns))
         request = dbsession.query(RegUser).filter(RegUser.hrn.in_(pi_hrns))
-        logger.info("RegAuthority.update_pis: %d incoming pis, %d matches found"\
+        logger.info("RegAuthority.update_pis: %d incoming pis, %d matches found"
                     % (len(pi_hrns), request.count()))
         pis = dbsession.query(RegUser).filter(RegUser.hrn.in_(pi_hrns)).all()
         self.reg_pis = pis
 
 ####################
                     % (len(pi_hrns), request.count()))
         pis = dbsession.query(RegUser).filter(RegUser.hrn.in_(pi_hrns)).all()
         self.reg_pis = pis
 
 ####################
+
+
 class RegSlice(RegRecord):
 class RegSlice(RegRecord):
-    __tablename__       = 'slices'
-    __mapper_args__     = { 'polymorphic_identity' : 'slice' }
-    record_id           = Column (Integer, ForeignKey ("records.record_id"), primary_key=True)
-    #### extensions come here
+    __tablename__ = 'slices'
+    __mapper_args__ = {'polymorphic_identity': 'slice'}
+    record_id = Column(Integer, ForeignKey(
+        "records.record_id"), primary_key=True)
+    # extensions come here
     reg_researchers     = relationship \
     reg_researchers     = relationship \
-        ('RegUser', 
+        ('RegUser',
          secondary=slice_researcher_table,
          secondary=slice_researcher_table,
-         primaryjoin=RegRecord.record_id==slice_researcher_table.c.slice_id,
-         secondaryjoin=RegRecord.record_id==slice_researcher_table.c.researcher_id,
+         primaryjoin=RegRecord.record_id == slice_researcher_table.c.slice_id,
+         secondaryjoin=RegRecord.record_id == slice_researcher_table.c.researcher_id,
          backref='reg_slices_as_researcher',
          backref='reg_slices_as_researcher',
-        )
+         )
 
 
-    def __init__ (self, **kwds):
+    def __init__(self, **kwds):
         if 'type' not in kwds:
         if 'type' not in kwds:
-            kwds['type']='slice'
+            kwds['type'] = 'slice'
         RegRecord.__init__(self, **kwds)
 
         RegRecord.__init__(self, **kwds)
 
-    def __repr__ (self):
+    def __repr__(self):
         return RegRecord.__repr__(self).replace("Record", "Slice")
 
         return RegRecord.__repr__(self).replace("Record", "Slice")
 
-    def update_researchers (self, researcher_hrns, dbsession):
+    def update_researchers(self, researcher_hrns, dbsession):
         # strip that in case we have <researcher> words </researcher>
         # strip that in case we have <researcher> words </researcher>
-        researcher_hrns = [ x.strip() for x in researcher_hrns ]
-        request = dbsession.query (RegUser).filter(RegUser.hrn.in_(researcher_hrns))
-        logger.info ("RegSlice.update_researchers: %d incoming researchers, %d matches found"\
-                     % (len(researcher_hrns), request.count()))
-        researchers = dbsession.query (RegUser).filter(RegUser.hrn.in_(researcher_hrns)).all()
+        researcher_hrns = [x.strip() for x in researcher_hrns]
+        request = dbsession.query(RegUser).filter(
+            RegUser.hrn.in_(researcher_hrns))
+        logger.info("RegSlice.update_researchers: %d incoming researchers, %d matches found"
+                    % (len(researcher_hrns), request.count()))
+        researchers = dbsession.query(RegUser).filter(
+            RegUser.hrn.in_(researcher_hrns)).all()
         self.reg_researchers = researchers
 
     # when dealing with credentials, we need to retrieve the PIs attached to a slice
     # WARNING: with the move to passing dbsessions around, we face a glitch here because this
     # helper function is called from the trust/ area that
         self.reg_researchers = researchers
 
     # when dealing with credentials, we need to retrieve the PIs attached to a slice
     # WARNING: with the move to passing dbsessions around, we face a glitch here because this
     # helper function is called from the trust/ area that
-    def get_pis (self):
+    def get_pis(self):
         from sqlalchemy.orm import sessionmaker
         Session = sessionmaker()
         dbsession = Session.object_session(self)
         from sfa.util.xrn import get_authority
         authority_hrn = get_authority(self.hrn)
         from sqlalchemy.orm import sessionmaker
         Session = sessionmaker()
         dbsession = Session.object_session(self)
         from sfa.util.xrn import get_authority
         authority_hrn = get_authority(self.hrn)
-        auth_record = dbsession.query(RegAuthority).filter_by(hrn=authority_hrn).first()
+        auth_record = dbsession.query(
+            RegAuthority).filter_by(hrn=authority_hrn).first()
         return auth_record.reg_pis
         return auth_record.reg_pis
-        
-    @validates ('expires')
-    def validate_expires (self, key, incoming):
-        return self.validate_datetime (key, incoming)
+
+    @validates('expires')
+    def validate_expires(self, key, incoming):
+        return self.validate_datetime(key, incoming)
 
 ####################
 
 ####################
+
+
 class RegNode(RegRecord):
 class RegNode(RegRecord):
-    __tablename__       = 'nodes'
-    __mapper_args__     = { 'polymorphic_identity' : 'node' }
-    record_id           = Column (Integer, ForeignKey ("records.record_id"), primary_key=True)
-    
+    __tablename__ = 'nodes'
+    __mapper_args__ = {'polymorphic_identity': 'node'}
+    record_id = Column(Integer, ForeignKey(
+        "records.record_id"), primary_key=True)
+
     def __init__(self, **kwds):
         if 'type' not in kwds:
     def __init__(self, **kwds):
         if 'type' not in kwds:
-            kwds['type']='node'
+            kwds['type'] = 'node'
         RegRecord.__init__(self, **kwds)
 
         RegRecord.__init__(self, **kwds)
 
-    def __repr__ (self):
+    def __repr__(self):
         return RegRecord.__repr__(self).replace("Record", "Node")
 
 ####################
         return RegRecord.__repr__(self).replace("Record", "Node")
 
 ####################
+
+
 class RegUser(RegRecord):
 class RegUser(RegRecord):
-    __tablename__       = 'users'
+    __tablename__ = 'users'
     # these objects will have type='user' in the records table
     # these objects will have type='user' in the records table
-    __mapper_args__     = { 'polymorphic_identity' : 'user' }
-    record_id           = Column (Integer, ForeignKey ("records.record_id"), primary_key=True)
-    #### extensions come here
-    email               = Column ('email', String)
+    __mapper_args__ = {'polymorphic_identity': 'user'}
+    record_id = Column(Integer, ForeignKey(
+        "records.record_id"), primary_key=True)
+    # extensions come here
+    email = Column('email', String)
     # can't use name 'keys' here because when loading from xml we're getting
     # can't use name 'keys' here because when loading from xml we're getting
-    # a 'keys' tag, and assigning a list of strings in a reference column like this crashes
+    # a 'keys' tag, and assigning a list of strings in a reference column like
+    # this crashes
     reg_keys            = relationship \
         ('RegKey', backref='reg_user',
     reg_keys            = relationship \
         ('RegKey', backref='reg_user',
-         cascade = "all, delete, delete-orphan",
-        )
-    
+         cascade="all, delete, delete-orphan",
+         )
+
     # so we can use RegUser (email=.., hrn=..) and the like
     # so we can use RegUser (email=.., hrn=..) and the like
-    def __init__ (self, **kwds):
+    def __init__(self, **kwds):
         # handle local settings
         if 'email' in kwds:
             self.email = kwds.pop('email')
         # handle local settings
         if 'email' in kwds:
             self.email = kwds.pop('email')
@@ -309,12 +347,12 @@ class RegUser(RegRecord):
         RegRecord.__init__(self, **kwds)
 
     # append stuff at the end of the record __repr__
         RegRecord.__init__(self, **kwds)
 
     # append stuff at the end of the record __repr__
-    def __repr__ (self): 
+    def __repr__(self):
         result = RegRecord.__repr__(self).replace("Record", "User")
         result.replace(">", " email={}>".format(self.email))
         return result
 
         result = RegRecord.__repr__(self).replace("Record", "User")
         result.replace(">", " email={}>".format(self.email))
         return result
 
-    @validates('email') 
+    @validates('email')
     def validate_email(self, key, address):
         assert '@' in address
         return address
     def validate_email(self, key, address):
         assert '@' in address
         return address
@@ -322,34 +360,39 @@ class RegUser(RegRecord):
 ####################
 # xxx tocheck : not sure about eager loading of this one
 # meaning, when querying the whole records, we expect there should
 ####################
 # xxx tocheck : not sure about eager loading of this one
 # meaning, when querying the whole records, we expect there should
-# be a single query to fetch all the keys 
-# or, is it enough that we issue a single query to retrieve all the keys 
+# be a single query to fetch all the keys
+# or, is it enough that we issue a single query to retrieve all the keys
+
+
 class RegKey(Base):
 class RegKey(Base):
-    __tablename__       = 'keys'
-    key_id              = Column (Integer, primary_key=True)
-    record_id           = Column (Integer, ForeignKey ("records.record_id"))
-    key                 = Column (String)
-    pointer             = Column (Integer, default = -1)
-    
-    def __init__ (self, key, pointer=None):
+    __tablename__ = 'keys'
+    key_id = Column(Integer, primary_key=True)
+    record_id = Column(Integer, ForeignKey("records.record_id"))
+    key = Column(String)
+    pointer = Column(Integer, default=-1)
+
+    def __init__(self, key, pointer=None):
         self.key = key
         if pointer:
             self.pointer = pointer
 
         self.key = key
         if pointer:
             self.pointer = pointer
 
-    def __repr__ (self):
+    def __repr__(self):
         result = "<key id=%s key=%s..." % (self.key_id, self.key[8:16],)
         result = "<key id=%s key=%s..." % (self.key_id, self.key[8:16],)
-        try:    result += " user=%s" % self.reg_user.record_id
-        except: result += " no-user"
+        try:
+            result += " user=%s" % self.reg_user.record_id
+        except:
+            result += " no-user"
         result += ">"
         return result
 
         result += ">"
         return result
 
-class SliverAllocation(Base,AlchemyObj):
-    __tablename__       = 'sliver_allocation'
-    sliver_id           = Column(String, primary_key=True)
-    client_id           = Column(String)
-    component_id        = Column(String)
-    slice_urn           = Column(String)
-    allocation_state    = Column(String)
+
+class SliverAllocation(Base, AlchemyObj):
+    __tablename__ = 'sliver_allocation'
+    sliver_id = Column(String, primary_key=True)
+    client_id = Column(String)
+    component_id = Column(String)
+    slice_urn = Column(String)
+    allocation_state = Column(String)
 
     def __init__(self, **kwds):
         if 'sliver_id' in kwds:
 
     def __init__(self, **kwds):
         if 'sliver_id' in kwds:
@@ -370,17 +413,19 @@ class SliverAllocation(Base,AlchemyObj):
 
     @validates('allocation_state')
     def validate_allocation_state(self, key, state):
 
     @validates('allocation_state')
     def validate_allocation_state(self, key, state):
-        allocation_states = ['geni_unallocated', 'geni_allocated', 'geni_provisioned']
+        allocation_states = ['geni_unallocated',
+                             'geni_allocated', 'geni_provisioned']
         assert state in allocation_states
         return state
 
         assert state in allocation_states
         return state
 
-    @staticmethod    
+    @staticmethod
     def set_allocations(sliver_ids, state, dbsession):
         if not isinstance(sliver_ids, list):
             sliver_ids = [sliver_ids]
         sliver_state_updated = {}
         constraint = SliverAllocation.sliver_id.in_(sliver_ids)
     def set_allocations(sliver_ids, state, dbsession):
         if not isinstance(sliver_ids, list):
             sliver_ids = [sliver_ids]
         sliver_state_updated = {}
         constraint = SliverAllocation.sliver_id.in_(sliver_ids)
-        sliver_allocations = dbsession.query (SliverAllocation).filter(constraint)
+        sliver_allocations = dbsession.query(
+            SliverAllocation).filter(constraint)
         sliver_ids_found = []
         for sliver_allocation in sliver_allocations:
             sliver_allocation.allocation_state = state
         sliver_ids_found = []
         for sliver_allocation in sliver_allocations:
             sliver_allocation.allocation_state = state
@@ -391,7 +436,8 @@ class SliverAllocation(Base,AlchemyObj):
         # it to geni_allocated.
         sliver_ids_not_found = set(sliver_ids).difference(sliver_ids_found)
         for sliver_id in sliver_ids_not_found:
         # it to geni_allocated.
         sliver_ids_not_found = set(sliver_ids).difference(sliver_ids_found)
         for sliver_id in sliver_ids_not_found:
-            record = SliverAllocation(sliver_id=sliver_id, allocation_state=state)
+            record = SliverAllocation(
+                sliver_id=sliver_id, allocation_state=state)
             dbsession.add(record)
         dbsession.commit()
 
             dbsession.add(record)
         dbsession.commit()
 
@@ -400,29 +446,30 @@ class SliverAllocation(Base,AlchemyObj):
         if not isinstance(sliver_ids, list):
             sliver_ids = [sliver_ids]
         constraint = SliverAllocation.sliver_id.in_(sliver_ids)
         if not isinstance(sliver_ids, list):
             sliver_ids = [sliver_ids]
         constraint = SliverAllocation.sliver_id.in_(sliver_ids)
-        sliver_allocations = dbsession.query(SliverAllocation).filter(constraint)
+        sliver_allocations = dbsession.query(
+            SliverAllocation).filter(constraint)
         for sliver_allocation in sliver_allocations:
             dbsession.delete(sliver_allocation)
         dbsession.commit()
         for sliver_allocation in sliver_allocations:
             dbsession.delete(sliver_allocation)
         dbsession.commit()
-    
+
     def sync(self, dbsession):
         constraints = [SliverAllocation.sliver_id == self.sliver_id]
         results = dbsession.query(SliverAllocation).filter(and_(*constraints))
         records = []
         for result in results:
     def sync(self, dbsession):
         constraints = [SliverAllocation.sliver_id == self.sliver_id]
         results = dbsession.query(SliverAllocation).filter(and_(*constraints))
         records = []
         for result in results:
-            records.append(result) 
-        
+            records.append(result)
+
         if not records:
             dbsession.add(self)
         else:
             record = records[0]
             record.sliver_id = self.sliver_id
         if not records:
             dbsession.add(self)
         else:
             record = records[0]
             record.sliver_id = self.sliver_id
-            record.client_id  = self.client_id
-            record.component_id  = self.component_id
-            record.slice_urn  = self.slice_urn
+            record.client_id = self.client_id
+            record.component_id = self.component_id
+            record.slice_urn = self.slice_urn
             record.allocation_state = self.allocation_state
             record.allocation_state = self.allocation_state
-        dbsession.commit()    
-        
+        dbsession.commit()
+
 
 ##############################
 # although the db needs of course to be reachable for the following functions
 
 ##############################
 # although the db needs of course to be reachable for the following functions
@@ -436,44 +483,54 @@ def init_tables(engine):
     logger.info("Initializing db schema from current/latest model")
     Base.metadata.create_all(engine)
 
     logger.info("Initializing db schema from current/latest model")
     Base.metadata.create_all(engine)
 
+
 def drop_tables(engine):
     logger.info("Dropping tables from current/latest model")
     Base.metadata.drop_all(engine)
 
 ##############################
 # create a record of the right type from either a dict or an xml string
 def drop_tables(engine):
     logger.info("Dropping tables from current/latest model")
     Base.metadata.drop_all(engine)
 
 ##############################
 # create a record of the right type from either a dict or an xml string
-def make_record (dict=None, xml=""):
-    if dict is None: dict={}
-    if dict:    return make_record_dict (dict)
-    elif xml:   return make_record_xml (xml)
-    else:       raise Exception("make_record has no input")
+
+
+def make_record(dict=None, xml=""):
+    if dict is None:
+        dict = {}
+    if dict:
+        return make_record_dict(dict)
+    elif xml:
+        return make_record_xml(xml)
+    else:
+        raise Exception("make_record has no input")
 
 # convert an incoming record - typically from xmlrpc - into an object
 
 # convert an incoming record - typically from xmlrpc - into an object
-def make_record_dict (record_dict):
+
+
+def make_record_dict(record_dict):
     assert ('type' in record_dict)
     type = record_dict['type'].split('+')[0]
     if type == 'authority':
     assert ('type' in record_dict)
     type = record_dict['type'].split('+')[0]
     if type == 'authority':
-        result = RegAuthority (dict=record_dict)
+        result = RegAuthority(dict=record_dict)
     elif type == 'user':
     elif type == 'user':
-        result = RegUser (dict=record_dict)
+        result = RegUser(dict=record_dict)
     elif type == 'slice':
     elif type == 'slice':
-        result = RegSlice (dict=record_dict)
+        result = RegSlice(dict=record_dict)
     elif type == 'node':
     elif type == 'node':
-        result = RegNode (dict=record_dict)
+        result = RegNode(dict=record_dict)
     else:
         logger.debug("Untyped RegRecord instance")
     else:
         logger.debug("Untyped RegRecord instance")
-        result = RegRecord (dict=record_dict)
-    logger.info("converting dict into Reg* with type=%s"%type)
-    logger.info("returning=%s"%result)
+        result = RegRecord(dict=record_dict)
+    logger.info("converting dict into Reg* with type=%s" % type)
+    logger.info("returning=%s" % result)
     # xxx todo
     # register non-db attributes in an extensions field
     return result
     # xxx todo
     # register non-db attributes in an extensions field
     return result
-        
-def make_record_xml (xml_str):
+
+
+def make_record_xml(xml_str):
     xml = XML(xml_str)
     xml_dict = xml.todict()
     xml = XML(xml_str)
     xml_dict = xml.todict()
-    logger.info("load from xml, keys=%s"%xml_dict.keys())
-    return make_record_dict (xml_dict)
+    logger.info("load from xml, keys=%s" % list(xml_dict.keys()))
+    return make_record_dict(xml_dict)
 
 ####################
 # augment local records with data from builtin relationships
 
 ####################
 # augment local records with data from builtin relationships
@@ -481,12 +538,13 @@ def make_record_xml (xml_str):
 # we pick names that clearly won't conflict with the ones used in the old approach,
 # were the relationships data came from the testbed side
 # for each type, a dict of the form {<field-name-exposed-in-record>:<alchemy_accessor_name>}
 # we pick names that clearly won't conflict with the ones used in the old approach,
 # were the relationships data came from the testbed side
 # for each type, a dict of the form {<field-name-exposed-in-record>:<alchemy_accessor_name>}
-# so after that, an 'authority' record will e.g. have a 'reg-pis' field with the hrns of its pi-users
-augment_map = {'authority': {'reg-pis' : 'reg_pis',},
-               'slice': {'reg-researchers' : 'reg_researchers',},
-               'user': {'reg-pi-authorities' : 'reg_authorities_as_pi',
-                        'reg-slices' : 'reg_slices_as_researcher',},
-           }
+# so after that, an 'authority' record will e.g. have a 'reg-pis' field
+# with the hrns of its pi-users
+augment_map = {'authority': {'reg-pis': 'reg_pis', },
+               'slice': {'reg-researchers': 'reg_researchers', },
+               'user': {'reg-pi-authorities': 'reg_authorities_as_pi',
+                        'reg-slices': 'reg_slices_as_researcher', },
+               }
 
 
 # xxx mystery
 
 
 # xxx mystery
@@ -499,16 +557,18 @@ augment_map = {'authority': {'reg-pis' : 'reg_pis',},
 # is what gets exposed to the drivers (this is historical and dates back before sqlalchemy)
 # so it is recommended to always run this function that will make sure
 # that such built-in fields are properly set in __dict__ too
 # is what gets exposed to the drivers (this is historical and dates back before sqlalchemy)
 # so it is recommended to always run this function that will make sure
 # that such built-in fields are properly set in __dict__ too
-# 
+#
 def augment_with_sfa_builtins(local_record):
     # don't ruin the import of that file in a client world
     from sfa.util.xrn import Xrn
     # add a 'urn' field
 def augment_with_sfa_builtins(local_record):
     # don't ruin the import of that file in a client world
     from sfa.util.xrn import Xrn
     # add a 'urn' field
-    setattr(local_record, 'reg-urn', Xrn(xrn=local_record.hrn, type=local_record.type).urn)
-    # users have keys and this is needed to synthesize 'users' sent over to CreateSliver
+    setattr(local_record, 'reg-urn',
+            Xrn(xrn=local_record.hrn, type=local_record.type).urn)
+    # users have keys and this is needed to synthesize 'users' sent over to
+    # CreateSliver
     fields_to_check = []
     if local_record.type == 'user':
     fields_to_check = []
     if local_record.type == 'user':
-        user_keys = [ key.key for key in local_record.reg_keys ]
+        user_keys = [key.key for key in local_record.reg_keys]
         setattr(local_record, 'reg-keys', user_keys)
         fields_to_check = ['email']
     elif local_record.type == 'authority':
         setattr(local_record, 'reg-keys', user_keys)
         fields_to_check = ['email']
     elif local_record.type == 'authority':
@@ -521,10 +581,8 @@ def augment_with_sfa_builtins(local_record):
     # search in map according to record type
     type_map = augment_map.get(local_record.type, {})
     # use type-dep. map to do the job
     # search in map according to record type
     type_map = augment_map.get(local_record.type, {})
     # use type-dep. map to do the job
-    for (field_name, attribute) in type_map.items():
+    for (field_name, attribute) in list(type_map.items()):
         # get related objects
         related_records = getattr(local_record, attribute, [])
         # get related objects
         related_records = getattr(local_record, attribute, [])
-        hrns = [ r.hrn for r in related_records ]
-        setattr (local_record, field_name, hrns)
-    
-
+        hrns = [r.hrn for r in related_records]
+        setattr(local_record, field_name, hrns)