Source code for beat.web.backend.models.environment

#!/usr/bin/env python
# vim: set fileencoding=utf-8 :

###############################################################################
#                                                                             #
# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/           #
# Contact: beat.support@idiap.ch                                              #
#                                                                             #
# This file is part of the beat.web module of the BEAT platform.              #
#                                                                             #
# Commercial License Usage                                                    #
# Licensees holding valid commercial BEAT licenses may use this file in       #
# accordance with the terms contained in a written agreement between you      #
# and Idiap. For further information contact tto@idiap.ch                     #
#                                                                             #
# Alternatively, this file may be used under the terms of the GNU Affero      #
# Public License version 3 as published by the Free Software and appearing    #
# in the file LICENSE.AGPL included in the packaging of this file.            #
# The BEAT platform is distributed in the hope that it will be useful, but    #
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY  #
# or FITNESS FOR A PARTICULAR PURPOSE.                                        #
#                                                                             #
# You should have received a copy of the GNU Affero Public License along      #
# with the BEAT platform. If not, see http://www.gnu.org/licenses/.           #
#                                                                             #
###############################################################################

from django.db import models
from django.db.models import Count
from django.db.models import Q
from django.urls import reverse

from ...code.models import Code
from ...common.models import Shareable
from ...common.models import ShareableManager
from ...common.texts import Messages

# ----------------------------------------------------------


[docs]class EnvironmentManager(ShareableManager):
[docs] def get_by_natural_key(self, name, version): return self.get(name=name, version=version)
[docs] def get_by_fullname(self, fullname): name, version = fullname.rsplit(" ", 1) return self.get_by_natural_key(name, version[1:-1])
[docs] def use_count(self, block_list): """Returns a list of environments used for the blocks in that list with how many times each has been used. Parameters: block_list (Block) : list of blocks to analyze. Returns: list: annotated environments with the number of time they have been used for blocks that are done. """ from ...experiments.models import Block from ...experiments.models import Experiment # Tries to figure through a maximum if blocks in the list have been # successfully used inside an environment. # Case 1) The block is part of an experiment that was successful # Case 2) The block is part of an experiment that is not successful # (failed or other), but it is CACHED (if not cached, then we can't # attest anything about the block/environment relationship!) return ( self.filter( blocks__in=block_list.filter( Q(experiment__status=Experiment.DONE) | ((~Q(experiment__status=Experiment.DONE)) & Q(status=Block.DONE)) ) ) .annotate(use_count=Count("id")) .order_by("-creation_date") .distinct() )
# ----------------------------------------------------------
[docs]class Environment(Shareable): """Defines a software environment to run algorithms""" name = models.CharField(max_length=200, help_text=Messages["name"]) version = models.CharField( max_length=20, help_text="Free-style version for this environment (normally read from the Worker/Scheduler available environments)", ) short_description = models.CharField( max_length=100, default="", blank=True, help_text=Messages["short_description"] ) description = models.TextField( default="", blank=True, help_text=Messages["description"] ) creation_date = models.DateTimeField("Creation date", auto_now_add=True) active = models.BooleanField( default=True, help_text="If this environment can be used in experiments" ) previous_version = models.ForeignKey( "self", related_name="next_versions", null=True, blank=True, on_delete=models.SET_NULL, ) objects = EnvironmentManager() # _____ Meta parameters __________ class Meta: unique_together = ("name", "version") # _____ Overrides __________ def __str__(self): return self.fullname()
[docs] def natural_key(self): return (self.name, self.version)
# _____ Utilities __________
[docs] def fullname(self): return "%s (%s)" % (self.name, self.version)
[docs] def get_absolute_url(self): return reverse("backend:view-environment", args=(self.name, self.version))
[docs] def get_admin_change_url(self): return reverse("admin:backend_environment_change", args=(self.id,))
[docs] def queues_for(self, user): """Returns all queues associated to this environment for which the user has the 'can_access' permission""" return [q for q in self.queues.all() if user.has_perm("backend.can_access", q)]
[docs] def as_dict(self): """Returns a representation as a dictionary""" return dict( name=self.name, version=self.version, short_description=self.short_description, description=self.description, )
# ----------------------------------------------------------
[docs]class EnvironmentLanguage(models.Model): environment = models.ForeignKey( Environment, related_name="languages", on_delete=models.CASCADE ) language = models.CharField( max_length=1, choices=Code.CODE_LANGUAGE, default=Code.PYTHON )