def kernels_push(self, folder):
        """ read the metadata file and kernel files from a notebook, validate
            both, and use Kernel API to push to Kaggle if all is valid.
             Parameters
            ==========
            folder: the path of the folder
        """
        if not os.path.isdir(folder):
            raise ValueError('Invalid folder: ' + folder)

        meta_file = os.path.join(folder, self.KERNEL_METADATA_FILE)
        if not os.path.isfile(meta_file):
            raise ValueError('Metadata file not found: ' +
                             self.KERNEL_METADATA_FILE)

        with open(meta_file) as f:
            meta_data = json.load(f)

        title = self.get_or_default(meta_data, 'title', None)
        if title and len(title) < 5:
            raise ValueError('Title must be at least five characters')

        code_path = self.get_or_default(meta_data, 'code_file', '')
        if not code_path:
            raise ValueError('A source file must be specified in the metadata')

        code_file = os.path.join(folder, code_path)
        if not os.path.isfile(code_file):
            raise ValueError('Source file not found: ' + code_file)

        slug = meta_data.get('id')
        id_no = meta_data.get('id_no')
        if not slug and not id_no:
            raise ValueError('ID or slug must be specified in the metadata')
        if slug:
            self.validate_kernel_string(slug)
            if '/' in slug:
                kernel_slug = slug.split('/')[1]
            else:
                kernel_slug = slug
            if title:
                as_slug = slugify(title)
                if kernel_slug.lower() != as_slug:
                    print(
                        'Your kernel title does not resolve to the specified '
                        'id. This may result in surprising behavior. We '
                        'suggest making your title something that resolves to '
                        'the specified id. See %s for more information on '
                        'how slugs are determined.' %
                        'https://en.wikipedia.org/wiki/Clean_URL#Slug')

        valid_languages = ['python', 'r', 'rmarkdown']
        language = self.get_or_default(meta_data, 'language', '')
        if language not in valid_languages:
            raise ValueError(
                'A valid language must be specified in the metadata. Valid '
                'options are ' + str(valid_languages))

        valid_kernel_types = ['script', 'notebook']
        kernel_type = self.get_or_default(meta_data, 'kernel_type', '')
        if kernel_type not in valid_kernel_types:
            raise ValueError(
                'A valid kernel type must be specified in the metadata. Valid '
                'options are ' + str(valid_kernel_types))

        if kernel_type == 'notebook' and language == 'rmarkdown':
            language = 'r'

        dataset_sources = self.get_or_default(meta_data, 'dataset_sources', [])
        for source in dataset_sources:
            self.validate_dataset_string(source)

        kernel_sources = self.get_or_default(meta_data, 'kernel_sources', [])
        for source in kernel_sources:
            self.validate_kernel_string(source)

        with open(code_file) as f:
            script_body = f.read()

        if kernel_type == 'notebook':
            json_body = json.loads(script_body)
            if 'cells' in json_body:
                for cell in json_body['cells']:
                    if 'outputs' in cell and cell['cell_type'] == 'code':
                        cell['outputs'] = []
            script_body = json.dumps(json_body)

        kernel_push_request = KernelPushRequest(
            id=id_no,
            slug=slug,
            new_title=self.get_or_default(meta_data, 'title', None),
            text=script_body,
            language=language,
            kernel_type=kernel_type,
            is_private=self.get_or_default(meta_data, 'is_private', None),
            enable_gpu=self.get_or_default(meta_data, 'enable_gpu', None),
            enable_internet=self.get_or_default(meta_data, 'enable_internet',
                                                None),
            dataset_data_sources=dataset_sources,
            competition_data_sources=self.get_or_default(
                meta_data, 'competition_sources', []),
            kernel_data_sources=kernel_sources,
            category_ids=self.get_or_default(meta_data, 'keywords', []))

        result = KernelPushResponse(
            self.process_response(
                self.kernel_push_with_http_info(
                    kernel_push_request=kernel_push_request)))
        return result