class InputFile(DB.Model): """ Class that represents an input file to the job """ id = DB.Column(DB.Integer, primary_key=True) input_key = DB.Column(DB.String(length=120)) internal_path = DB.Column(DB.Text, nullable=False) public_url = DB.Column(DB.Text) job_id = DB.Column(DB.String(length=120), DB.ForeignKey('delayed_job.id'), nullable=False)
class Good(db.Model): __tablename__: str = "Good" id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(128), unique=True) weight = db.Column(db.String(64)) description = db.Column(db.Text) measure = db.Column(db.String(64)) price = db.Column(db.Float) category_id = db.Column(db.Integer, db.ForeignKey("Category.id")) link = db.Column(db.Text) user_id = db.relationship( "Busket", backref="good", lazy="dynamic", foreign_keys="Busket.good_id", cascade="all, delete-orphan" ) def __repr__(self) -> str: return self.name def commit(self) -> bool: db.session.add(self) try: db.session.commit() return True except IntegrityError: return False def update(self, **kwargs): for key, value in kwargs.items(): if key != "category": self.__setattr__(key, value) db.session.commit() @staticmethod def first(**kwargs) -> Good: return Good.query.filter_by(**kwargs).first() @staticmethod def all() -> List[Good]: return Good.query.all() @staticmethod def delete(**kwargs) -> bool: try: db.session.delete(Good.query.filter_by(**kwargs).first()) db.session.commit() return True except UnmappedInstanceError: return False
class CustomJobConfig(DB.Model): """ Class that represents a custom key-value instance for the configuration of jobs, that will be passed to the job's run params """ job_type = DB.Column(DB.String(length=60), DB.ForeignKey('default_job_config.job_type'), nullable=False, primary_key=True) key = DB.Column(DB.Text, primary_key=True) value = DB.Column(DB.Text)
class DefaultJobConfig(DB.Model): """ Class that represents a default container image for a job type """ job_type = DB.Column(DB.String(length=60), primary_key=True) docker_image_url = DB.Column(DB.Text) docker_registry_username = DB.Column( DB.Text) # Username for the container registry (optional) docker_registry_password = DB.Column( DB.Text) # Password for the container registry (optional) requirements_script_path = DB.Column(DB.Text)
class User(db.Model): __tablename__: str = "User" id = db.Column(db.Integer, primary_key=True) firstName = db.Column(db.String(64)) lastName = db.Column(db.String(64)) login = db.Column(db.String(64), unique=True) email = db.Column(db.String(128), unique=True) password = db.Column(db.String(32)) goods = db.relationship("Busket", backref="user", lazy="dynamic", foreign_keys="Busket.user_id") def __repr__(self) -> str: return "{} {}".format(self.firstName, self.lastName) @staticmethod def is_exists_login(login: Optional[None]) -> bool: return db.session\ .query(User.id).\ filter_by(login=login)\ .scalar() is not None @staticmethod def is_exists_email(email: str) -> bool: return db.session\ .query(User.id)\ .filter_by(email=email)\ .scalar() is not None @property def commit(self) -> User: db.session.add(self) db.session.commit() return self @staticmethod def log_in(login: str, password: str) -> User: return User.query.filter_by(login=login, password=password).first()
class Category(db.Model): __tablename__ = "Category" id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64), unique=True) goods = db.relationship("Good", backref="category", lazy="dynamic") def __repr__(self): return self.name def commit(self) -> bool: db.session.add(self) try: db.session.commit() return True except IntegrityError: return False @staticmethod def get_all_goods(category_name: str) -> List[Good]: goods = Category.query.filter_by(name=category_name).first() return goods.goods.all() if goods else [] @staticmethod def all() -> List[Category]: return Category.query.all() @staticmethod def first(**kwargs) -> Category: return Category.query.filter_by(**kwargs).first() @staticmethod def delete(**kwargs) -> bool: try: db.session.delete(Category.query.filter_by(**kwargs).first()) db.session.commit() return True except UnmappedInstanceError: return False
class Order(db.Model): id = db.Column(db.Integer, primary_key=True) wayOfPaiment = db.Column(db.String(128)) oddMoney = db.Column(db.String(128)) address = db.Column(db.String(128)) porch = db.Column(db.String(128)) floor = db.Column(db.String(128)) apartment = db.Column(db.String(128)) comment = db.Column(db.Text) firstName = db.Column(db.String(128)) lastName = db.Column(db.String(128)) phone = db.Column(db.String(128)) email = db.Column(db.String(128)) login = db.Column(db.String(128)) @property def commit(self) -> Order: db.session.add(self) db.session.commit() return self @staticmethod def all(login) -> List[Order]: return Order.query.filter_by(login=login).all()
class DelayedJob(DB.Model): """ Class that represents a delayed job in the database. """ id = DB.Column(DB.String(length=120), primary_key=True) type = DB.Column(DB.String(length=60), DB.ForeignKey('default_job_config.job_type'), nullable=False) status = DB.Column(DB.Enum(JobStatuses), default=JobStatuses.CREATED) status_log = DB.Column( DB.Text) # a comment about the status, for example 'Compressing file' progress = DB.Column(DB.Integer, default=0) created_at = DB.Column(DB.DateTime, default=datetime.datetime.utcnow) started_at = DB.Column(DB.DateTime) finished_at = DB.Column(DB.DateTime) run_dir_path = DB.Column(DB.Text) output_dir_path = DB.Column(DB.Text) raw_params = DB.Column(DB.Text) expires_at = DB.Column(DB.DateTime) api_initial_url = DB.Column(DB.Text) docker_image_url = DB.Column(DB.Text) timezone = DB.Column(DB.String(length=60), default=str(datetime.timezone.utc)) num_failures = DB.Column(DB.Integer, default=0) # How many times the job has failed. lsf_job_id = DB.Column(DB.Integer) lsf_host = DB.Column(DB.Text) requirements_parameters_string = DB.Column(DB.Text) status_description = DB.Column(DB.Text) run_environment = DB.Column(DB.String(length=60)) input_files = DB.relationship('InputFile', backref='delayed_job', lazy=True, cascade='all, delete-orphan') output_files = DB.relationship('OutputFile', backref='delayed_job', lazy=True, cascade='all, delete-orphan') def __repr__(self): return f'<DelayedJob ${self.id} ${self.type} ${self.status}>' def public_dict(self, server_base_url='http://0.0.0.0:5000'): """ Returns a dictionary representation of the object with all the fields that are safe to be public :param server_base_url: url to use as base for building the output files urls """ plain_properties = { key: str(getattr(self, key)) for key in [ 'id', 'type', 'status', 'status_log', 'progress', 'created_at', 'started_at', 'finished_at', 'raw_params', 'expires_at', 'api_initial_url', 'docker_image_url', 'timezone', 'num_failures', 'status_description' ] } input_files_urls = utils.get_input_files_dict(self.input_files, server_base_url) output_files_urls = utils.get_output_files_dict( self.output_files, server_base_url) return { **plain_properties, 'input_files_urls': input_files_urls, 'output_files_urls': output_files_urls } def update_run_status(self, new_value): """ Updates the run status of the job, if status switches to running, it calculates started_at. If the status switches to running, it calculates finished_at, and expires_at :param new_value: new run status """ old_value = self.status if str(old_value) != str(new_value): if new_value == str(JobStatuses.RUNNING): self.started_at = datetime.datetime.utcnow() elif new_value == str(JobStatuses.FINISHED): self.finished_at = datetime.datetime.utcnow() self.expires_at = datetime.datetime.utcnow( ) + datetime.timedelta(days=DAYS_TO_LIVE) self.status = new_value def get_executions_count(self): """ :return: how many times a job has been executed """ return len(self.executions)