class Nic(ModelBase): __tablename__ = 'nics' __table_args = { UniqueConstraint('mac', 'ip'), } id = Column(Integer, primary_key=True) nodeId = Column(Integer, ForeignKey('nodes.id'), nullable=False) networkId = Column(Integer, ForeignKey('networks.id')) networkDeviceId = Column(Integer, ForeignKey('networkdevices.id')) mac = Column(String(45)) ip = Column(String(45)) boot = Column(Boolean, default=False) nics_nodeId = index_property('nodeId', 'Nics_nodeId') nics_networkId = index_property('networkId', 'Nics_networkId') nics_networkDeviceId = index_property('networkDeviceId', 'Nics_networkDeviceId') network = relationship('Network', uselist=False, lazy=False, backref='nics') networkdevice = relationship('NetworkDevice', uselist=False, lazy=False, backref='nics')
class A(Base): __tablename__ = "a" id = Column("id", Integer, primary_key=True) array = Column("_array", ARRAY(Integer), default=[]) first = index_property("array", 0) fifth = index_property("array", 4)
class Array(fixtures.ComparableEntity, Base): __tablename__ = "array" id = Column(sa.Integer, primary_key=True, test_needs_autoincrement=True) array = Column(ARRAY(Integer), default=[]) array0 = Column(ARRAY(Integer, zero_indexes=True), default=[]) first = index_property('array', 0) first0 = index_property('array0', 0, onebased=False)
class StockAsset(Asset): __tablename__ = 'asset' __mapper_args__ = { 'polymorphic_identity': 'stock', } bps = index_property('data', 'bps') eps = index_property('data', 'eps')
class StockAsset(Asset): __tablename__ = "asset" __mapper_args__ = { "polymorphic_identity": "stock", } bps = index_property("data", "bps") eps = index_property("data", "eps")
class DBEvent(Base): # type: ignore """Database representation of an :class:`.Event`.""" __tablename__ = 'event' event_id = Column(String(40), primary_key=True) event_type = Column(String(255)) event_version = Column(String(20), default='0.0.0') proxy = Column(FriendlyJSON) proxy_id = index_property('proxy', 'agent_identifier') client = Column(FriendlyJSON) client_id = index_property('client', 'agent_identifier') creator = Column(FriendlyJSON) creator_id = index_property('creator', 'agent_identifier') created = Column(DateTime(fsp=6)) data = Column(FriendlyJSON) submission_id = Column( ForeignKey('arXiv_submissions.submission_id'), index=True ) submission = relationship("Submission") def to_event(self) -> Event: """ Instantiate an :class:`.Event` using event data from this instance. Returns ------- :class:`.Event` """ _skip = ['creator', 'proxy', 'client', 'submission_id', 'created', 'event_type', 'event_version'] data = { key: value for key, value in self.data.items() if key not in _skip } data['committed'] = True # Since we're loading from the DB. return event_factory( event_version=self.event_version, event_type=self.event_type, creator=agent_factory(**self.creator), proxy=agent_factory(**self.proxy) if self.proxy else None, client=agent_factory(**self.client) if self.client else None, submission_id=self.submission_id, created=self.get_created(), **data ) def get_created(self) -> datetime: """Get the UTC-localized creation time for this event.""" return self.created.replace(tzinfo=UTC)
class Json(fixtures.ComparableEntity, Base): __tablename__ = "json" id = Column(sa.Integer, primary_key=True, test_needs_autoincrement=True) json = Column(JSON, default={}) field = index_property('json', 'field') json_field = index_property('json', 'field') int_field = json_property('json', 'field', Integer) text_field = json_property('json', 'field', Text) other = index_property('json', 'other') subfield = json_property('other', 'field', Text)
class DBEvent(Base): # type: ignore """Database representation of an :class:`.Event`.""" __tablename__ = 'event' event_id = Column(String(40), primary_key=True) event_type = Column(String(255)) proxy = Column(util.FriendlyJSON) proxy_id = index_property('proxy', 'agent_identifier') client = Column(util.FriendlyJSON) client_id = index_property('client', 'agent_identifier') creator = Column(util.FriendlyJSON) creator_id = index_property('creator', 'agent_identifier') created = Column(DateTime) data = Column(util.FriendlyJSON) submission_id = Column( ForeignKey('arXiv_submissions.submission_id'), index=True ) submission = relationship("Submission") def to_event(self) -> Event: """ Instantiate an :class:`.Event` using event data from this instance. Returns ------- :class:`.Event` """ _skip = ['creator', 'proxy', 'client', 'submission_id', 'created', 'event_type'] data = { key: value for key, value in self.data.items() if key not in _skip } data['committed'] = True, # Since we're loading from the DB. return event_factory( self.event_type, creator=Agent.from_dict(self.creator), proxy=Agent.from_dict(self.proxy) if self.proxy else None, client=Agent.from_dict(self.client) if self.client else None, submission_id=self.submission_id, created=self.created, **data )
class Component(ModelBase): __tablename__ = 'components' __table_args__ = (UniqueConstraint('name', 'kitId'), ) id = Column(Integer, primary_key=True) kitId = Column(Integer, ForeignKey('kits.id', ondelete='CASCADE')) name = Column(String(255), nullable=False) version = Column(String(255), nullable=False) description = Column(String(255)) components_KitId = index_property('kitId', 'Components_kitId') os = relationship('OperatingSystem', secondary='os_components') family = relationship('OperatingSystemFamily', secondary='osfamily_components') os_components = relationship('OsComponent', backref='os_components', cascade='all, delete-orphan', passive_deletes=True) osfamily_components = relationship('OsFamilyComponent', backref='osfamily_components', cascade='all, delete-orphan', passive_deletes=True) def __repr__(self): return format_component_descriptor(self.name, self.version)
class Partition(ModelBase): __tablename__ = 'partitions' __table_args__ = (UniqueConstraint('softwareProfileId', 'name', 'device'), ) id = Column(Integer, primary_key=True) softwareProfileId = Column(Integer, ForeignKey('softwareprofiles.id'), nullable=False) name = Column(String(255), nullable=False) device = Column(String(255), nullable=False) mountPoint = Column(String(255)) fsType = Column(String(20), nullable=False) size = Column(Integer, nullable=False) options = Column(String(255)) preserve = Column(Boolean, default=False) bootLoader = Column(Boolean, default=False) diskSize = Column(Integer, nullable=False, default=8000) directAttachment = Column(String(255), nullable=False, default='local') indirectAttachment = Column(String(255), nullable=False, default='default') sanVolume = Column(String(255)) grow = Column(Boolean, default=False) maxSize = Column(Integer) partitions_softwareProfileId = index_property( 'softwareProfileId', 'Partitions_softwareProfileId')
class OsComponent(ModelBase): __tablename__ = 'os_components' __table_args__ = (UniqueConstraint('osId', 'componentId'), ) id = Column(Integer, primary_key=True) osId = Column(Integer, ForeignKey('operatingsystems.id', ondelete='CASCADE')) componentId = Column(Integer, ForeignKey('components.id', ondelete='CASCADE')) osComponents_componentId = index_property('componentId', 'OsComponents_componentId') osComponents_osId = index_property('osId', 'OsComponents_osId') os = relationship('OperatingSystem', lazy=False)
class SoftwareUsesHardware(ModelBase): __tablename__ = 'software_uses_hardware' id = Column(Integer, primary_key=True) softwareProfileId = Column(Integer, ForeignKey('softwareprofiles.id')) hardwareProfileId = Column(Integer, ForeignKey('hardwareprofiles.id')) softwareUsesHardware_softwareProfileId = index_property( 'softwareProfileId', 'SoftwareUsesHardware_softwareProfileId') softwareUsesHardware_hardwareProfileId = index_property( 'hardwareProfileId', 'SoftwareUsesHardware_hardwareProfileId') def __init__(self, softwareProfileId, hardwareProfileId): super().__init__() self.softwareProfileId = softwareProfileId self.hardwareProfileId = hardwareProfileId
class Netcdf(Metadata): """NetCDF metadata of a file on Raijin As would be found by ``ncdump -h`` """ __mapper_args__ = { 'polymorphic_identity': 'netcdf', } format = pg_json_property('json', 'format', Text) #: File variables variables = index_property('json', 'variables') #: File attributes attributes = index_property('json', 'attributes') #: File dimensions dimensions = index_property('json', 'dimensions')
class HardwareProfileProvisioningNic(ModelBase): __tablename__ = 'hardwareprofile_provisioning_nics' hardwareProfileId = Column(Integer, ForeignKey('hardwareprofiles.id'), nullable=False, primary_key=True) nicId = Column(Integer, ForeignKey('nics.id'), nullable=False, primary_key=True) hardwareProfileProvisioningNics_hardwareProfileId = index_property( 'hardwareProfileId', 'HardwareProfileProvisioningNics_hardwareProfileId' ) hardwareProfileProvisioningNics_nicId = index_property( 'nicId', 'HardwareProfileProvisioningNics_nicId' ) nic = relationship('Nic') hardwareprofile = relationship('HardwareProfile')
class UserStocks(db.Model, UserMixin): __tablename__ = "users_stocks" trans_id = db.Column(db.Integer, primary_key=True, index=True) id = db.Column(db.Integer) amount = db.Column(db.Numeric()) ticker = db.Column(db.String(255)) market = db.Column(db.String(255)) priceInBTC = db.Column(db.Numeric()) priceInUSD = db.Column(db.Numeric()) priceInEUR = db.Column(db.Numeric()) priceInCHY = db.Column(db.Numeric()) last = db.Column(db.String(255)) timestamp = db.Column(db.DateTime()) index = index_property('id', 'index')
class Node(ModelBase): __tablename__ = 'nodes' id = Column(Integer, primary_key=True) name = Column(String(255), unique=True, nullable=False) public_hostname = Column(String(255), unique=True, nullable=True) state = Column(String(255), default='Discovered') bootFrom = Column(Integer, default=0) lastUpdate = Column(String(20)) rack = Column(Integer, default=0) rank = Column(Integer, default=0) hardwareProfileId = Column(Integer, ForeignKey('hardwareprofiles.id')) softwareProfileId = Column(Integer, ForeignKey('softwareprofiles.id')) lockedState = Column(String(20), nullable=False, default='Unlocked') isIdle = Column(Boolean, nullable=False, default=True) addHostSession = Column(String(36)) vcpus = Column(Integer) nodes_softwareProfileId = index_property( 'softwareProfilesId', 'Nodes_softwareProfileId') nodes_hardwareProfileId = index_property( 'hardwareProfilesId', 'Nodes_hardwareProfilesId') nodes_addHostSession = index_property( 'addHostSession', 'Nodes_addHostSession') nics = relationship('Nic', backref='node', lazy=False, cascade='all, delete-orphan') tags = relationship('NodeTag', lazy=False, cascade="all, delete-orphan") instance = relationship( 'InstanceMapping', uselist=False, back_populates='node', cascade='all,delete-orphan') def __repr__(self): return 'Node(name={})'.format(self.name)
class Event(DeclarativeBase): """ Event definition. """ USER_FIELD = "user" AUTHOR_FIELD = "author" CLIENT_TOKEN_FIELD = "client_token" WORKSPACE_FIELD = "workspace" CONTENT_FIELD = "content" MEMBER_FIELD = "member" SUBSCRIPTION_FIELD = "subscription" _ENTITY_SUBTYPE_LENGTH = 100 __tablename__ = "events" event_id = Column(Integer, autoincrement=True, primary_key=True) operation = Column(Enum(OperationType), nullable=False) entity_type = Column(Enum(EntityType), nullable=False) entity_subtype = Column(String(length=_ENTITY_SUBTYPE_LENGTH), nullable=True, default=None) created = Column(DateTime, nullable=False, default=datetime.utcnow) fields = Column(JSON, nullable=False) # easier access to values stored in fields author = index_property("fields", AUTHOR_FIELD) workspace = index_property("fields", WORKSPACE_FIELD) user = index_property("fields", USER_FIELD) content = index_property("fields", CONTENT_FIELD) member = index_property("fields", MEMBER_FIELD) subscription = index_property("fields", SUBSCRIPTION_FIELD) client_token = index_property("fields", CLIENT_TOKEN_FIELD) @property def event_type(self) -> str: type_ = "{}.{}".format(self.entity_type.value, self.operation.value) if self.entity_subtype: type_ = "{}.{}".format(type_, self.entity_subtype) return type_ def __repr__(self): return "<Event(event_id=%s, type=%s, created_date=%s, fields=%s)>" % ( repr(self.event_id), repr(self.event_type), repr(self.created), repr(self.fields), )
class UserMixin: """A user who signs up with email or with email from social media. This mixin provides the default required columns for user model in Websauna. The user contains normal columns and then ``user_data`` JSON field where properties and non-structured data can be easily added without migrations. This is especially handy to store incoming OAuth fields from social networks. Think Facebook login data and user details. """ #: Running counter id of the user id = Column(Integer, autoincrement=True, primary_key=True) #: Publicly exposable ID of the user uuid = Column(UUID(as_uuid=True), default=uuid4) #: Though not displayed on the site, the concept of "username" is still preversed. If the site needs to have username (think Instragram, Twitter) the user is free to choose this username after the sign up. Username is null until the initial user activation is completed after db.flush() in create_activation(). username = Column(String(256), nullable=True, unique=True) email = Column(String(256), nullable=True, unique=True) #: Stores the password + hash + cycles as password hasher internal format.. By default uses Argon 2 format. See :py:meth:`websauna.system.Initializer.configure_password` hashed_password = Column('password', String(256), nullable=True) #: When this account was created created_at = Column(UTCDateTime, default=now) #: When the account data was updated last time updated_at = Column(UTCDateTime, onupdate=now) #: When this user was activated: email confirmed or first social login activated_at = Column(UTCDateTime, nullable=True) #: Is this user account enabled. The support can disable the user account in the case of suspected malicious activity. enabled = Column(Boolean(name="user_enabled_binary"), default=True) #: When this user accessed the system last time. None if the user has never logged in (only activation email sent). Information stored for the security audits. last_login_at = Column(UTCDateTime, nullable=True) #: From which IP address did this user log in from. If this IP is null the user has never logged in (only activation email sent). Information stored for the security audits. It is also useful for identifying the source country of users e.g. for localized versions. last_login_ip = Column(INET, nullable=True) #: Misc. user data as a bag of JSON. Do not access directly, but use JSONBProperties below user_data = Column(NestedMutationDict.as_mutable(JSONB), default=DEFAULT_USER_DATA) #: Store when this user changed the password or authentication details. Updating this value causes the system to drop all sessions which were created before this moment. E.g. you will kick out all old sessions on a password or email change. last_auth_sensitive_operation_at = Column(UTCDateTime, nullable=True, default=now) #: Full name of the user (if given) full_name = index_property("user_data", "full_name") #: How this user signed up to the site. May include string like "email", "facebook" or "dummy". Up to the application to use this field. Default social media logins and email sign up set this. registration_source = index_property("user_data", "registration_source") #: Social media data of the user as a dict keyed by user media social = index_property("user_data", "social") #: Is this the first login the user manages to do to our system. If this flag is set the user has not logged in to the system before and you can give warm welcoming experience. first_login = index_property("user_data", "first_login") @property def friendly_name(self) -> str: """How we present the user's name to the user itself. Picks one of 1) full name if set 2) username if set 3) email. """ full_name = self.full_name username = self.username friendly_name = self.email if full_name: # Return full_name if available friendly_name = full_name elif username and not username.startswith('user-'): # Get the username if it looks like non-automatic form friendly_name = username return friendly_name def generate_username(self) -> str: """The default username we give for the user. In the format user-{id}. """ assert self.id return 'user-{id}'.format(id=self.id) def is_activated(self) -> bool: """Has the user completed the email activation.""" return self.activated_at is not None def can_login(self) -> bool: """Is this user allowed to login.""" return self.enabled and self.is_activated() def is_in_group(self, name) -> bool: # TODO: groups - defined in Horus for g in self.groups: if g.name == name: return True return False def is_admin(self) -> bool: """Does this user the see the main admin interface link. TODO: This is very suboptimal, wasted database cycles, etc. Change this. """ return self.is_in_group(GroupMixin.DEFAULT_ADMIN_GROUP_NAME) def is_valid_session(self, session_created_at: datetime.datetime) -> bool: """Check if the current session is still valid for this user.""" return self.last_auth_sensitive_operation_at <= session_created_at def __str__(self): return self.friendly_name def __repr__(self): return "#{id}: {friendly_name}".format( id=self.id, friendly_name=self.friendly_name)
class J(Base): __tablename__ = 'j' id = Column('id', Integer, primary_key=True) json = Column('_json', JSON, default={}) field = index_property('json', 'field')
class J(Base): __tablename__ = 'j' id = Column(Integer, primary_key=True) json = Column(JSON, default={}) default = index_property('json', 'field', default='default') none = index_property('json', 'field', default=None)
class A(Base): __tablename__ = 'a' id = Column(Integer, primary_key=True) array = Column(ARRAY(Integer)) first = index_property('array', 1, mutable=False)
class Substance(db.Model): """ Indexed Substance The identifiers field is a JSONB object with keys that may change to meet different user requirements. The JSON keys can be individually queried in PostgreSQL like this: SELECT id, identifiers->>'preferred_name' as preferred_name FROM substances """ __tablename__ = "substances" # The identifiers field needs to be indexed for full-JSON search # https://www.postgresql.org/docs/9.5/datatype-json.html#JSON-INDEXING # https://docs.sqlalchemy.org/en/13/orm/extensions/indexable.html id = db.Column(db.String(128), primary_key=True) identifiers = db.Column(JSONB, nullable=False) casrn = index_property("identifiers", "casrn", default=None) preferred_name = index_property("identifiers", "preferred_name", default=None) @hybrid_method def get_matches(self, searchterm=None): if bool(searchterm): # search the identifiers for the term and score them matchlist = {} for id_name in [ "casrn", "preferred_name", "display_name", "compound_id", "inchikey", ]: # an exact match against a top-level identifier # yields a 1.0 score if self.identifiers[id_name]: if self.identifiers[id_name].casefold() == searchterm.casefold(): matchlist[id_name] = 1 if self.identifiers["synonyms"]: synonyms = self.identifiers["synonyms"] # a match against a synonym identifier # yields whatever the weight of the synonym was # set to for synonym in synonyms: synid = synonym["identifier"] if synonym["identifier"] else "" if synid.casefold() == searchterm.casefold(): matchlist[synonym["synonymtype"]] = synonym["weight"] if bool(matchlist): return matchlist else: return None else: return None @hybrid_method def score_result(self, searchterm=None): """ Technical debt here: the identifiers in the indexed document are hard-coded into the scoring loop https://github.com/Chemical-Curation/resolver/pull/16#discussion_r536216962 """ matches = self.get_matches(searchterm) max_score = 0 if matches: max_key = max(matches, key=matches.get) max_score = matches[max_key] return max_score
class J(Base): __tablename__ = "j" id = Column("id", Integer, primary_key=True) json = Column("_json", JSON, default={}) field = index_property("json", "field")
class User: """A user who signs up with email or with email from social media. The user contains normal columns and then ``user_data`` JSON field where properties and non-structured data can \ be easily added without migrations. This is especially handy to store incoming OAuth fields from social networks. \ Think Facebook login data and user details. """ # In PSQL "user", the automatically generated table name, is a reserved word __tablename__ = "users" __init__ = _declarative_constructor #: Current user activation instance for reset password for sign up email verification activation_id = Column(Integer, ForeignKey("user_activation.id")) #: SQLAlchemy relationship for above activation = orm.relationship('Activation', backref='user') #: Current authorization code instance for exchange access token authorization_code_id = Column(Integer, ForeignKey("user_authorization_code.id")) #: SQLAlchemy relationship for above authorization_code = orm.relationship('AuthorizationCode', backref='user') #: Running counter id of the user id = Column(Integer, autoincrement=True, primary_key=True) #: Publicly exposable ID of the user uuid = Column(UUIDType, default=uuid4) # : Though not displayed on the site, the concept of "username" is still preserved. If the site needs to have # username (think Instagram, Twitter) the user is free to choose this username after the sign up. Username is # null until the initial user activation is completed after db.flush() in create_activation(). username = Column(String(256), nullable=True, unique=True) email = Column(String(256), nullable=True, unique=True) # : Stores the password + hash + cycles as password hasher internal format.. By default uses Argon 2 format. hashed_password = Column('password', String(256), nullable=True) #: When this account was created created_at = Column(UTCDateTime, default=now) #: When the account data was updated last time updated_at = Column(UTCDateTime, onupdate=now) #: When this user was activated: email confirmed or first social login activated_at = Column(UTCDateTime, nullable=True) # : Is this user account enabled. The support can lockout/disable the user account in the case of suspected # malicious activity. enabled = Column(Boolean(name="user_enabled_binary"), default=True) # : When this user accessed the system last time. None if the user has never logged in (only activation email # sent). Information stored for the security audits. last_login_at = Column(UTCDateTime, nullable=True) # : From which IP address did this user log in from. If this IP is null the user has never logged in (only # activation email sent). Information stored for the security audits. It is also useful for identifying the # source country of users e.g. for localized versions. last_login_ip = Column(IPAddressType, nullable=True) #: Misc. user data as a bag of JSON. Do not access directly, but use JSONBProperties below user_data = Column(JSONType, default=DEFAULT_USER_DATA) # : Store when this user changed the password or authentication details. Updating this value causes the system to # drop all sessions which were created before this moment. E.g. you will kick out all old sessions on a password # or email change. last_auth_sensitive_operation_at = Column(UTCDateTime, nullable=True, default=now) #: Full name of the user (if given) full_name = index_property("user_data", "full_name") # : How this user signed up to the site. May include string like "email", "facebook" or "dummy". Up to the # application to use this field. Default social media logins and email sign up set this. registration_source = index_property("user_data", "registration_source") #: Social media data of the user as a dict keyed by user media social = index_property("user_data", "social") # : Is this the first login the user manages to do to our system. If this flag is set the user has not logged in # to the system before and you can give warm welcoming experience. first_login = index_property("user_data", "first_login") @property def friendly_name(self) -> str: """How we present the user's name to the user itself. Picks one of 1) full name if set 2) username if set 3) email. """ full_name = self.full_name if full_name: return full_name # Get the username if it looks like non-automatic form if self.username: if self.username.startswith("user-"): return self.email else: return self.username return self.email def generate_username(self) -> str: """The default username we give for the user.""" assert self.id return "user-{}".format(self.id) def is_activated(self) -> bool: """Has the user completed the email activation.""" return self.activated_at is not None def can_login(self) -> bool: """Is this user allowed to login.""" # TODO: is_active defined in Horus return self.enabled and self.is_activated() def is_in_group(self, name) -> bool: # TODO: groups - defined in Horus for g in self.groups: if g.name == name: return True return False def is_admin(self) -> bool: """Does this user the see the main admin interface link. TODO: This is very suboptimal, wasted database cycles, etc. Change this. """ return self.is_in_group(Group.DEFAULT_ADMIN_GROUP_NAME) def is_valid_session(self, session_created_at: datetime.datetime) -> bool: """Check if the current session is still valid for this user.""" return self.last_auth_sensitive_operation_at <= session_created_at def __str__(self): return self.friendly_name def __repr__(self): return "#{}: {}".format(self.id, self.friendly_name)
class J(Base): __tablename__ = "j" id = Column(Integer, primary_key=True) json = Column(JSON, default={}) default = index_property("json", "field", default="default") none = index_property("json", "field", default=None)
class A(Base): __tablename__ = 'a' id = Column('id', Integer, primary_key=True) array = Column('_array', ARRAY(Integer), default=[]) first = index_property('array', 0) fifth = index_property('array', 4)