def store_contents(self, content_type: ContentType, container_name: str, content_name: str, content_data: str = None, content_path: str = None): """Function that stores file content. Based on the ContentType the function can either save a text or can read a file path (content_path) and copies it :param content_type: Content type, can be file or text :type content_type: enum :param container_name: Container name :type container_name: str :param content_name: File name :type content_name: str :param content_data: File content as text :type content_data: str :param content_path: File path to be copied into the storage :type content_path: str :raises: :class:`CustomException` """ try: self._logger.info('storing contents') if self._vdc_storage_account_key == None: self._vdc_storage_account_key = self.get_storage_account_key() block_blob_service = BlockBlobService( account_name=self._vdc_storage_account_name, account_key=self._vdc_storage_account_key) # Create container if does not exists if not block_blob_service.exists(container_name): self._logger.info( 'container {} does not exists, proceeding to create it'. format(container_name)) block_blob_service.create_container(container_name) self._logger.info('saving blob') if content_type == ContentType.TEXT: block_blob_service.create_blob_from_text( container_name=container_name, blob_name=content_name, text=content_data) elif content_type == ContentType.FILE: if Path(content_path).exists(): block_blob_service.create_blob_from_path( container_name=container_name, blob_name=content_name, file_path=content_path) else: raise CustomException('File does not exist.') except Exception as ex: raise CustomException( 'There was an unhandled exception: {}'.format(str(ex)))
def get_student(self, student_id): if student_id is None: raise CustomException("Student id missing") student = self.students_collection.find_one({"_id": student_id}) if student is None: raise CustomException("Student not found") return student
def get_contents(self, content_type: ContentType, container_name: str, content_name: str): """Function that retrieves the content data, based on the content type. Currently, it only retrieves text content data :param content_type: Content type, can be file or text :type content_type: enum :param container_name: Container name :type container_name: str :param content_name: File name :type content_name: str :raises: :class:`CustomException` """ if content_type == ContentType.TEXT: try: if self._vdc_storage_account_key == None: self._vdc_storage_account_key = self.get_storage_account_key( ) block_blob_service = BlockBlobService( account_name=self._vdc_storage_account_name, account_key=self._vdc_storage_account_key) response: Blob = block_blob_service.get_blob_to_text( container_name=container_name, blob_name=content_name) return response.content except Exception as ex: raise CustomException( 'There was an unhandled exception: {}'.format(str(ex)))
def get_all_class_students(self, class_id): if class_id is None: raise CustomException("Class id is missing") results = list( self.grades_collection.aggregate([{ "$match": { "class_id": class_id } }, { "$lookup": { "from": "students", "localField": "student_id", "foreignField": "_id", "as": "student" } }, { "$unwind": { "path": "$student", "preserveNullAndEmptyArrays": False } }, { "$project": { "student_id": "$student._id", "student_name": "$student.name", "_id": 0 } }])) return {"class_id": class_id, "students": results}
def get_student_class_scores(self, student_id, class_id): self.get_student(student_id) if class_id is None: raise CustomException("Class id is missing") results = list( self.grades_collection.aggregate([{ "$match": { "student_id": student_id, "class_id": class_id } }, { "$lookup": { "from": "students", "localField": "student_id", "foreignField": "_id", "as": "student" } }, { "$unwind": { "path": "$student", "preserveNullAndEmptyArrays": False } }, { "$project": { "class_id": 1, "student_id": "$student._id", "student_name": "$student.name", "_id": 0, "marks": "$scores", "total_marks": { "$toInt": { "$sum": "$scores.score" } } } }])) if results is None: raise ValidationError("Score not found") result = results[0] for score in result['marks']: score['marks'] = int(score['score']) del score['score'] result['marks'].append({ "type": "total", "score": result['total_marks'] }) del result['total_marks'] return result
def get_class_studentwise_performance(self, class_id): if class_id is None: raise CustomException("Class id is missing") results = list( self.grades_collection.aggregate([{ "$match": { "class_id": class_id } }, { "$lookup": { "from": "students", "localField": "student_id", "foreignField": "_id", "as": "student" } }, { "$unwind": { "path": "$student", "preserveNullAndEmptyArrays": False } }, { "$project": { "student_id": "$student._id", "student_name": "$student.name", "_id": 0, "total_marks": { "$toInt": { "$sum": "$scores.score" } } } }, { "$group": { "_id": { "student_id": "$student_id" }, "max_marks": { "$max": "$total_marks" } } }])) return {"class_id": class_id, "students": results}
def create_or_update_resource_group(self, resource_group_name: str, location: str): """Function that creates or updates a resource group :param resource_group_name: Resource group name to analyze :type resource_group_name: str :param location: Resource group location :type location: str :raises: :class:`Exception` """ if location is None or location == '': raise CustomException('No location has been set') try: resource_group_parameters = \ ResourceGroup(location = location) new_resource_group: ResourceGroup = \ self._resource_management_client\ .resource_groups\ .create_or_update( resource_group_name, resource_group_parameters) self._logger.info( 'resource group {} created on {} location'.format( new_resource_group.name, new_resource_group.location)) except Exception as e: self._logger.error( 'The following error occurred while creating a resource group: ' + str(e)) self._logger.error(e) sys.exit( 1 ) # Exit the module as it is not possible to progress the deployment. raise (e)
def create(self) -> list: '''Main function used to execute a module(s) deployment. This function creates a storage repository to place all deployment outputs, and to to place custom scripts if --upload-scripts argument passed is set to true. :param parameter_initializer: Object containing all required properties used during a module provisioning :type parameter_initializer: ParameterInitializer :param deployment_path: Path that contains deployment and parameters folders :type deployment_path: str :raises: :class:`CustomException<Exception>` ''' try: # Append dummy sas key to default parameters, the key will now be # appended to all deploy templates self.append_to_default_parameters( dict({ 'sas-key': 'xxxxxxxxxx', 'output-params-storage-key': 'xxxxxxxxxx', 'output-params-storage-account-name': 'xxxxxxxxxx' })) module_names = list() if self._deploy_all_modules == True: # Let's get all the deployment folders module_names = self._module_deployment_order self._logger.info( 'validating all modules:{}'.format(module_names)) else: if self._single_module is None or self._single_module == '': raise CustomException('No module has been passed') # Single module, let's add it to the list module_names.append(self._single_module) # Let's create a dummy resource group for the validation to pass self._resource_management_integration_service\ .create_or_update_resource_group( self._resource_group, self._location) self._provision_module_validation_dependencies( self._module_dependencies) for module in module_names: self._deploy(self._module_dependencies, module, self._resource_group) # Let's prepare to delete resource groups created during the validation process self._validation_resource_groups.append(self._resource_group) self._logger\ .info('About to delete the following resource groups: {}'.format( self._validation_resource_groups)) for validation_resource_group in self._validation_resource_groups: # After the validation, let's delete the dummy resource group self._logger\ .info('Deleting the following resource group: {}'.format( validation_resource_group)) self._management_lock_integration_service\ .delete_all_resource_group_locks( validation_resource_group) self._resource_management_integration_service\ .delete_resource_group( validation_resource_group) return list() except Exception as ex: self._logger.error( 'There was an unhandled error while provisioning the modules.') self._logger.error(ex) sys.exit( 1 ) # Exit the module as it is not possible to progress the deployment. raise ex
def get_student_wise_gradesheet(self, class_id): if class_id is None: raise CustomException("Class id is missing") results = list( self.grades_collection.aggregate([{ "$match": { "class_id": class_id } }, { "$lookup": { "from": "students", "localField": "student_id", "foreignField": "_id", "as": "student" } }, { "$unwind": { "path": "$student", "preserveNullAndEmptyArrays": False } }, { "$project": { "student_id": "$student._id", "student_name": "$student.name", "_id": 0, "details": "$scores", "total_marks": { "$toInt": { "$sum": "$scores.score" } } } }, { "$sort": { "total_marks": -1 } }])) count = len(results) for index, student in enumerate(results): for score in student['details']: score['marks'] = int(score['score']) del score['score'] student['details'].append({ "marks": student['total_marks'], "type": "total" }) del student['total_marks'] if index < count / 12: student['grade'] = 'A' elif index < count / 4: student['grade'] = 'B' elif index < count / 2: student['grade'] = 'C' else: student['grade'] = 'D' return {"class_id": class_id, "students": results}
def validate_deployment(self, mode: str, template: dict, parameters: dict, resource_group_name: str, deployment_name: str): """Function that validates whether a template is syntactically correct. :param mode: Deployment mode Values can be Incremental or complete (use: DeploymentMode.incremental or DeploymentMode.complete) :type mode: str :param template: Template file deserialized :type template: dict :param parameters: Parameters file deserialized :type parameters: dict :param resource_group_name: Resource group name to use in the deployment :type resource_group_name: str :param deployment_name: Deployment name to use :type deployment_name: str :return: Deployment output, if any, otherwise None is returned :rtype: dict :raises: :class:`Exception` """ try: deployment_properties = { 'mode': mode, 'template': template, 'parameters': parameters } validation_response = \ self._resource_management_client\ .deployments\ .validate( resource_group_name, deployment_name, deployment_properties) if validation_response.error is not None: inner_exception = 'None' if validation_response.error.details is not None and\ len(validation_response.error.details) > 0 and\ validation_response.error.details[0].message is not None: inner_exception = validation_response.error.details[ 0].message if validation_response.error.details is not None and\ len(validation_response.error.details) > 0 and\ validation_response.error.details[0].details is not None and\ len(validation_response.error.details[0].details) > 0 and\ validation_response.error.details[0].details[0].message is not None: inner_exception = validation_response.error.details[ 0].details[0].message raise CustomException("ERROR: {}, INNER EXCEPTION: {}".format( validation_response.error, inner_exception)) self._logger.info('Deployment successfully validated') except Exception as e: self._logger.error( 'The following error occurred while checking executing a deployment validation: ' + str(e)) self._logger.error(e) self._logger.error(validation_response) sys.exit( 1 ) # Exit the module as it is not possible to progress the deployment. raise (e)