From ebfce47c62d9c4614a5285132bb261e053c12f95 Mon Sep 17 00:00:00 2001 From: Robert Clark Date: Mon, 16 Nov 2020 12:28:45 -0600 Subject: [PATCH 1/4] Add Python type hints Type hints make it easier to determine the object type that should be used for all functions. Signed-Off-By: Robert Clark --- imagine/imagine.py | 67 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 14 deletions(-) diff --git a/imagine/imagine.py b/imagine/imagine.py index 656c69a..93c82f5 100755 --- a/imagine/imagine.py +++ b/imagine/imagine.py @@ -15,7 +15,7 @@ import os import re import numpy -from argparse import ArgumentParser +from argparse import ArgumentParser, Namespace from PIL import Image from multiprocessing.pool import Pool try: @@ -23,6 +23,7 @@ except ImportError: IRHeader = None from time import perf_counter +from typing import Generator, List, NoReturn, Optional, Tuple from math import ceil try: from tensorflow.io import TFRecordWriter @@ -42,7 +43,7 @@ "bitmap": "bmp", "png": "png"} -def parse_args(): +def parse_args() -> Namespace: message = """ CLI for generating a fake dataset of various quantities at different resolutions. @@ -92,19 +93,28 @@ def parse_args(): return parser.parse_args() -def try_create_directory(directory): +def try_create_directory(directory: str) -> NoReturn: if not os.path.exists(directory): os.mkdir(directory) -def check_directory_exists(directory): +def check_directory_exists(directory: str) -> NoReturn: if not os.path.exists(directory): raise RuntimeError('Error: Please specify an input directory which ' 'contains valid images.') -def create_images(path, name, width, height, count, image_format, seed, size, - chunksize=64): +def create_images( + path: str, + name: str, + width: int, + height: int, + count: int, + image_format: str, + seed: Optional[int] = 0, + size: Optional[bool] = False, + chunksize: Optional[int] = 64 +) -> NoReturn: print('Creating {} {} files located at {} of {}x{} resolution with a base ' 'base filename of {}'.format(count, image_format, path, width, height, name)) @@ -135,8 +145,14 @@ def create_images(path, name, width, height, count, image_format, seed, size, print('Created {} files in {} seconds'.format(count, stop_time-start_time)) -def record_slice(source_path, dest_path, name, image_files, images_per_file, - num_of_records): +def record_slice( + source_path: str, + dest_path: str, + name: str, + image_files: List[str], + images_per_file: int, + num_of_records: int +) -> Generator[Tuple[str, str, str, List[str], int], None, None]: for num in range(num_of_records): subset = num * images_per_file yield (source_path, @@ -146,7 +162,12 @@ def record_slice(source_path, dest_path, name, image_files, images_per_file, num) -def create_recordio(source_path, dest_path, name, img_per_file): +def create_recordio( + source_path: str, + dest_path: str, + name: str, + img_per_file: int +) -> NoReturn: print('Creating RecordIO files at {} from {} targeting {} files per ' 'record with a base filename of {}'.format(dest_path, source_path, @@ -186,7 +207,12 @@ def create_recordio(source_path, dest_path, name, img_per_file): print('Completed in {} seconds'.format(stop_time-start_time)) -def create_tfrecords(source_path, dest_path, name, img_per_file): +def create_tfrecords( + source_path: str, + dest_path: str, + name: str, + img_per_file: int +) -> NoReturn: print('Creating TFRecord files at {} from {} targeting {} files per ' 'TFRecord with a base filename of {}'.format(dest_path, source_path, @@ -234,7 +260,7 @@ def create_tfrecords(source_path, dest_path, name, img_per_file): print('Completed in {} seconds'.format(stop_time-start_time)) -def print_image_information(path): +def print_image_information(path: str) -> NoReturn: is_first_image = True first_image_size = 0 directory_size = 0 @@ -251,7 +277,13 @@ def print_image_information(path): print('Directory {} size, in bytes: {}'.format(path, directory_size)) -def recordio_creation(source_path, dest_path, name, image_files, n): +def recordio_creation( + source_path: str, + dest_path: str, + name: str, + image_files: List[str], + n: int +) -> NoReturn: combined_path = os.path.join(dest_path, name) regex = re.compile(r'\d+') dataset_rec = combined_path + str(n) + '.rec' @@ -271,7 +303,14 @@ def recordio_creation(source_path, dest_path, name, image_files, n): recordio_ds.close() -def image_creation(combined_path, width, height, seed, image_format, n): +def image_creation( + combined_path: str, + width: int, + height: int, + seed: int, + image_format: str, + n: int +) -> NoReturn: numpy.random.seed(seed + n) a = numpy.random.rand(height, width, 3) * 255 file_ext = SUPPORTED_IMAGE_FORMATS.get(image_format.lower(), 'png') @@ -283,7 +322,7 @@ def image_creation(combined_path, width, height, seed, image_format, n): im_out.save('%s%d.%s' % (combined_path, n, file_ext)) -def main(): +def main() -> NoReturn: args = parse_args() if args.command == STANDARD_IMAGE: create_images(args.path, args.name, args.width, args.height, From 1277210c3b38fa34890a38f8e69c178359784bbd Mon Sep 17 00:00:00 2001 From: Robert Clark Date: Mon, 16 Nov 2020 12:47:15 -0600 Subject: [PATCH 2/4] Add docstrings In preparation for better documentation, docstrings should be added to properly document what each function does, what arguments need to be passed, and any returns or errors that may occur. Signed-Off-By: Robert Clark --- imagine/imagine.py | 231 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) diff --git a/imagine/imagine.py b/imagine/imagine.py index 93c82f5..ee5659c 100755 --- a/imagine/imagine.py +++ b/imagine/imagine.py @@ -44,6 +44,18 @@ def parse_args() -> Namespace: + """ + Parse arguments passed to the application. + + A custom argument parser handles multiple commands and options to launch + the desired function. + + Returns + ------- + Namespace + Returns a ``Namespace`` of all of the arguments that were parsed from + the application during runtime. + """ message = """ CLI for generating a fake dataset of various quantities at different resolutions. @@ -94,11 +106,38 @@ def parse_args() -> Namespace: def try_create_directory(directory: str) -> NoReturn: + """ + Create a directory if it doesn't exist. + + Given a name of a directory as a ``string``, a directory should be created + with the requested name if and only if it doesn't exist already. If the + directory exists, the function will return without any changes. + + Parameters + ---------- + directory : string + A ``string`` of a path pointing to a directory to attempt to create. + """ if not os.path.exists(directory): os.mkdir(directory) def check_directory_exists(directory: str) -> NoReturn: + """ + Check if a directory exists. + + Check if a requested directory exists and raise an error if not. + + Parameters + ---------- + directory : string + A ``string`` of the requested directory to check. + + Raises + ------ + RuntimeError + Raises a ``RuntimeError`` if the requested directory does not exist. + """ if not os.path.exists(directory): raise RuntimeError('Error: Please specify an input directory which ' 'contains valid images.') @@ -115,6 +154,44 @@ def create_images( size: Optional[bool] = False, chunksize: Optional[int] = 64 ) -> NoReturn: + """ + Randomly generate standard images. + + Generate random images of standard formats, such as JPG, PNG, and BMP of + variable height and width. Images are generated by creating a random numpy + array of the requested dimensions and converting the image to the desired + format. All images will be saved in the specified directory with each name + beginning with the passed ``name`` variable and ending with a counter + starting at zero. + + Parameters + ---------- + path : string + The path to the directory to save images to. The directory will be + created if it doesn't exist. + name : string + A ``string`` to prepend to all filenames, such as `random_image_`. + Filenames will end with a counter starting at zero, followed by the + file format's extension. + width : int + The width of the image to generate in pixels. + height : int + The height of the image to generate in pixels. + count : int + The number of images to generate. + image_format : str + The format the images should be saved as. Choices are: {} + seed : int (optional) + A seed to use for numpy for creating the random image data. Defaults + to 0. + size : bool (optional) + If `True`, will print image size information including the size of the + first image and the final directory size. + chunksize : int (optional) + Specify the number of chunks to divide the requested amount of images + into. Higher chunksizes reduce the amount of memory consumed with minor + additional overhead. + """.format(SUPPORTED_IMAGE_FORMATS.keys()) print('Creating {} {} files located at {} of {}x{} resolution with a base ' 'base filename of {}'.format(count, image_format, path, width, height, name)) @@ -153,6 +230,45 @@ def record_slice( images_per_file: int, num_of_records: int ) -> Generator[Tuple[str, str, str, List[str], int], None, None]: + """ + Generate subcomponents for a thread. + + While creating RecordIO files, a tuple needs to be generated to pass to + every thread in a multiprocessing pool. Each tuple corresponds with a + unique record file with a new path, name, and subset of images. The subset + of images is calculated by taking the first N-images where + N = (total images) / (number of records). The next subset begins at N + 1 + and so on. + + Parameters + ---------- + source_path : string + Path to the directory where the input images are stored. + dest_path : string + Path to the directory where the record files should be saved. Will be + created if it does not exist. + name : string + A ``string`` to prepend to all filenames, such as `random_record_`. + Filenames will end with a counter starting at zero, followed by the + file format's extension. + image_files : list + A ``list`` of ``strings`` of the image filenames to use for the record + files. + images_per_file : int + The number of images to include per record file. + num_of_records : int + The total number of record files to create. Note that one record + assumes a record file plus a corresponding index file. + + Returns + ------- + Generator + Yields a ``tuple`` of objects specific to each record file. The tuple + includes the `source_path` as a ``string``, `dest_path` as a + ``string``, `name` as a ``string``, a subset of image names from + `image_files` as a ``list`` of ``strings``, and a counter for the + record file starting at 0 as an ``int``. + """ for num in range(num_of_records): subset = num * images_per_file yield (source_path, @@ -168,6 +284,32 @@ def create_recordio( name: str, img_per_file: int ) -> NoReturn: + """ + Create RecordIO files based on standard images. + + Generate one or multiple RecordIO records based on standard input images. + Records are created by specifying an input path containing standard image + files in JPG, PNG, or BMP format, an output directory to save the images + to, a name to prepend the records with, and the number of record files to + generate. Each record file contains N images where N is the total number of + images in the input directory divided by the number of images per record + file. Images are pulled sequentially from the input directory and placed + into each record. + + Parameters + ---------- + source_path : string + Path to the directory where the input images are stored. + dest_path : string + Path to the directory where the record files should be saved. Will be + created if it does not exist. + name : string + A ``string`` to prepend to all filenames, such as `random_record_`. + Filenames will end with a counter starting at zero, followed by the + file format's extension. + images_per_file : int + The number of images to include per record file. + """ print('Creating RecordIO files at {} from {} targeting {} files per ' 'record with a base filename of {}'.format(dest_path, source_path, @@ -213,6 +355,31 @@ def create_tfrecords( name: str, img_per_file: int ) -> NoReturn: + """ + Create TFRecords based on standard images. + + Generate one or multiple TFRecords based on standard input images. Records + are created by specifying an input path containing standard image files in + JPG, PNG, or BMP format, an output directory to save the images to, a name + to prepend the records with, and the number of record files to generate. + Each record file contains N images where N is the total number of images in + the input directory divided by the number of images per record file. Images + are pulled sequentially from the input directory and placed into each + record. + + Parameters + ---------- + source_path : string + Path to the directory where the input images are stored. + dest_path : string + Path to the directory where the record files should be saved. Will be + created if it does not exist. + name : string + A ``string`` to prepend to all filenames, such as `random_record_`. + Filenames will end with a counter starting at zero. + images_per_file : int + The number of images to include per record file. + """ print('Creating TFRecord files at {} from {} targeting {} files per ' 'TFRecord with a base filename of {}'.format(dest_path, source_path, @@ -261,6 +428,18 @@ def create_tfrecords( def print_image_information(path: str) -> NoReturn: + """ + Print the image and directory size. + + Print the size of the first image in the directory, which is assumed to be + a good approximator for the average image size of all images in the + directory, as well as the total size of the directory, in bytes. + + Parameters + ---------- + path : string + The path to the directory where generated images are stored. + """ is_first_image = True first_image_size = 0 directory_size = 0 @@ -284,6 +463,28 @@ def recordio_creation( image_files: List[str], n: int ) -> NoReturn: + """ + Create a RecordIO file based on input images. + + Given a subset of images, a RecordIO file should be created with a + corresponding index file with the given name and counter. + + Parameters + ---------- + source_path : string + Path to the directory where the input images are stored. + dest_path : string + Path to the directory where the record files should be saved. Will be + created if it does not exist. + name : string + A ``string`` to prepend the record filename with. + image_files : list + A ``list`` of ``strings`` of image filenames to be used for the record + creation. + n : int + An ``integer`` of the current count the record file points to, starting + at zero. + """ combined_path = os.path.join(dest_path, name) regex = re.compile(r'\d+') dataset_rec = combined_path + str(n) + '.rec' @@ -311,6 +512,30 @@ def image_creation( image_format: str, n: int ) -> NoReturn: + """ + Generate a random image. + + Given a name, dimensions, a seed, and an image format, a random image is + generated by creating a numpy array of random data for the specified + dimensions and three color channels, then converting the array to an image + of the specified format and saving the result to the output directory with + the requested name postfixed with with the zero-based image counter and the + file extension. + + Parameters + ---------- + combined_path : string + The full path to the output image file including the requested name as + a prefix for the filename. + width : int + The width of the image to generate in pixels. + height : int + The height of the image to generate in pixels. + image_format : str + The format the images should be saved as. + n : int + The zero-based counter for the image. + """ numpy.random.seed(seed + n) a = numpy.random.rand(height, width, 3) * 255 file_ext = SUPPORTED_IMAGE_FORMATS.get(image_format.lower(), 'png') @@ -323,6 +548,12 @@ def image_creation( def main() -> NoReturn: + """ + Randomly generate images or record files. + + Create standard images or record files using randomized data to be ingested + into a deep learning application. + """ args = parse_args() if args.command == STANDARD_IMAGE: create_images(args.path, args.name, args.width, args.height, From d3c01ffb9005916061bee182f651b747a676dfb0 Mon Sep 17 00:00:00 2001 From: Robert Clark Date: Mon, 16 Nov 2020 16:20:41 -0600 Subject: [PATCH 3/4] Allow library to be imported To enable developers to include the functionality in existing pipelines, the functionality should be easy to include in Python modules as an imported library. Signed-Off-By: Robert Clark --- README.md | 43 +++++++++++++++++++++++++++ imagine/__init__.py | 4 +++ imagine/imagine.py | 4 --- setup.py | 2 +- tests/functional/test_jpg_creation.py | 2 +- tests/functional/test_png_creation.py | 2 +- tests/functional/test_recordio.py | 2 +- tests/functional/test_tfrecord.py | 2 +- 8 files changed, 52 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 902cd53..d3f51f7 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,49 @@ This command uses the JPEGs created during the previous step and creates TFRecords based on those images. The TFRecords will be saved to `/mnt/nvme/record_files` where each file will be comprised of 100 JPEGs. +## Importing +Imageinary can be imported directly by a Python script to hook into a deep +learning workflow. + +To write random images of a specific size to the system, import the library and +specify the requested parameters: + +```python +from imagine import create_images + +create_images('path/to/save/images', # Path to save images + 'random_image_prefix_', # Image name prefix + 3840, # Width + 2160, # Height + 1000, # Number of images to create + 'png') # Image format +``` + +The above command will save 1000 random PNG images of dimension 3840x2160 to the +`path/to/save/images` directory, each prefixed with `random_image_prefix_`. + +Similary, TFRecords can be generated from Python: + +```python +from imagine import create_tfrecords + +create_tfrecords('path/to/saved_images', # Path to saved images + 'path/to/save/tfrecords', # Path to save TFRecords + 'random_tfrecord_', # TFRecord file prefix + 100) # Number of images per file +``` + +As can RecordIO files: + +```python +from imagine import create_recordio + +create_recordio('path/to/saved_images', # Path to saved images + 'path/to/save/recordio', # Path to save RecordIO files + 'random_recordio_', # RecordIO file prefix + 100) # Number of images per file +``` + ## Testing This repository includes functional tests for the major modules listed above which can be verified locally using `pytest`. While in the virtual environment, diff --git a/imagine/__init__.py b/imagine/__init__.py index e69de29..0d09ec5 100644 --- a/imagine/__init__.py +++ b/imagine/__init__.py @@ -0,0 +1,4 @@ +from imagine.imagine import (create_images, + create_recordio, + create_tfrecords, + main) diff --git a/imagine/imagine.py b/imagine/imagine.py index ee5659c..f8c25b4 100755 --- a/imagine/imagine.py +++ b/imagine/imagine.py @@ -564,7 +564,3 @@ def main() -> NoReturn: elif args.command == RECORDIO: create_recordio(args.source_path, args.dest_path, args.name, args.img_per_file) - - -if __name__ == "__main__": - main() diff --git a/setup.py b/setup.py index 571f829..bf4db35 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ license='Apache v2.0', python_requires='>=3.6', entry_points={ - 'console_scripts': ['imagine=imagine.imagine:main'] + 'console_scripts': ['imagine=imagine:main'] }, install_requires=[ 'numpy >= 1.18.0', diff --git a/tests/functional/test_jpg_creation.py b/tests/functional/test_jpg_creation.py index 721f2d2..f5b1c5b 100644 --- a/tests/functional/test_jpg_creation.py +++ b/tests/functional/test_jpg_creation.py @@ -15,7 +15,7 @@ import re import os from glob import glob -from imagine.imagine import create_images +from imagine import create_images from PIL import Image diff --git a/tests/functional/test_png_creation.py b/tests/functional/test_png_creation.py index 55a6e8e..4122f04 100644 --- a/tests/functional/test_png_creation.py +++ b/tests/functional/test_png_creation.py @@ -15,7 +15,7 @@ import re import os from glob import glob -from imagine.imagine import create_images +from imagine import create_images from PIL import Image diff --git a/tests/functional/test_recordio.py b/tests/functional/test_recordio.py index b7f1f8b..cab7c7e 100644 --- a/tests/functional/test_recordio.py +++ b/tests/functional/test_recordio.py @@ -15,7 +15,7 @@ import re import os from glob import glob -from imagine.imagine import create_images, create_recordio +from imagine import create_images, create_recordio from PIL import Image diff --git a/tests/functional/test_tfrecord.py b/tests/functional/test_tfrecord.py index ffbe361..8c28309 100644 --- a/tests/functional/test_tfrecord.py +++ b/tests/functional/test_tfrecord.py @@ -15,7 +15,7 @@ import re import os from glob import glob -from imagine.imagine import create_images, create_tfrecords +from imagine import create_images, create_tfrecords from PIL import Image From 60c52b424364618a7eaadbf418ce99c98a758f4b Mon Sep 17 00:00:00 2001 From: Robert Clark Date: Thu, 7 Jan 2021 11:19:35 -0600 Subject: [PATCH 4/4] Make non-public functions private To make it clear how to interact with the library from Python applications, only the functions which create standard images, RecordIO files, and TFRecords should be public, indicating which functions can be called directly. Signed-Off-By: Robert Clark --- imagine/__init__.py | 2 +- imagine/imagine.py | 50 ++++++++++++++++++++-------------------- setup.py | 2 +- tests/unit/test_units.py | 18 +++++++-------- 4 files changed, 36 insertions(+), 36 deletions(-) diff --git a/imagine/__init__.py b/imagine/__init__.py index 0d09ec5..c56d942 100644 --- a/imagine/__init__.py +++ b/imagine/__init__.py @@ -1,4 +1,4 @@ from imagine.imagine import (create_images, create_recordio, create_tfrecords, - main) + _main) diff --git a/imagine/imagine.py b/imagine/imagine.py index f8c25b4..13917e2 100755 --- a/imagine/imagine.py +++ b/imagine/imagine.py @@ -43,7 +43,7 @@ "bitmap": "bmp", "png": "png"} -def parse_args() -> Namespace: +def _parse_args() -> Namespace: """ Parse arguments passed to the application. @@ -105,7 +105,7 @@ def parse_args() -> Namespace: return parser.parse_args() -def try_create_directory(directory: str) -> NoReturn: +def _try_create_directory(directory: str) -> NoReturn: """ Create a directory if it doesn't exist. @@ -122,7 +122,7 @@ def try_create_directory(directory: str) -> NoReturn: os.mkdir(directory) -def check_directory_exists(directory: str) -> NoReturn: +def _check_directory_exists(directory: str) -> NoReturn: """ Check if a directory exists. @@ -195,7 +195,7 @@ def create_images( print('Creating {} {} files located at {} of {}x{} resolution with a base ' 'base filename of {}'.format(count, image_format, path, width, height, name)) - try_create_directory(path) + _try_create_directory(path) combined_path = os.path.join(path, name) # Expected to yield a thread pool equivalent to the number of CPU cores in @@ -206,7 +206,7 @@ def create_images( # NOTE: For very large image counts on memory-constrained systems, this # can stall-out. Either reduce the image count request, or increase the # chunk size. - pool.starmap(image_creation, + pool.starmap(_image_creation, ((combined_path, width, height, seed, image_format, n) for n in range(count)), chunksize=chunksize) @@ -217,12 +217,12 @@ def create_images( stop_time = perf_counter() if size: - print_image_information(path) + _print_image_information(path) print('Created {} files in {} seconds'.format(count, stop_time-start_time)) -def record_slice( +def _record_slice( source_path: str, dest_path: str, name: str, @@ -321,10 +321,10 @@ def create_recordio( image_files = [] source_path = os.path.abspath(source_path) dest_path = os.path.abspath(dest_path) - check_directory_exists(source_path) - try_create_directory(dest_path) + _check_directory_exists(source_path) + _try_create_directory(dest_path) - print_image_information(source_path) + _print_image_information(source_path) for image_name in os.listdir(source_path): if not os.path.isdir(os.path.join(source_path, image_name)): @@ -334,13 +334,13 @@ def create_recordio( pool = Pool() try: start_time = perf_counter() - pool.starmap(recordio_creation, - record_slice(source_path, - dest_path, - name, - image_files, - img_per_file, - num_of_records)) + pool.starmap(_recordio_creation, + _record_slice(source_path, + dest_path, + name, + image_files, + img_per_file, + num_of_records)) finally: pool.close() pool.join() @@ -389,11 +389,11 @@ def create_tfrecords( raise ImportError('TensorFlow not found! Please install TensorFlow ' 'dependency using "pip install ' 'nvidia-imageinary[\'tfrecord\']".') - check_directory_exists(source_path) - try_create_directory(dest_path) + _check_directory_exists(source_path) + _try_create_directory(dest_path) combined_path = os.path.join(dest_path, name) - print_image_information(source_path) + _print_image_information(source_path) image_count = 0 record = 0 @@ -427,7 +427,7 @@ def create_tfrecords( print('Completed in {} seconds'.format(stop_time-start_time)) -def print_image_information(path: str) -> NoReturn: +def _print_image_information(path: str) -> NoReturn: """ Print the image and directory size. @@ -456,7 +456,7 @@ def print_image_information(path: str) -> NoReturn: print('Directory {} size, in bytes: {}'.format(path, directory_size)) -def recordio_creation( +def _recordio_creation( source_path: str, dest_path: str, name: str, @@ -504,7 +504,7 @@ def recordio_creation( recordio_ds.close() -def image_creation( +def _image_creation( combined_path: str, width: int, height: int, @@ -547,14 +547,14 @@ def image_creation( im_out.save('%s%d.%s' % (combined_path, n, file_ext)) -def main() -> NoReturn: +def _main() -> NoReturn: """ Randomly generate images or record files. Create standard images or record files using randomized data to be ingested into a deep learning application. """ - args = parse_args() + args = _parse_args() if args.command == STANDARD_IMAGE: create_images(args.path, args.name, args.width, args.height, args.count, args.image_format, args.seed, args.size) diff --git a/setup.py b/setup.py index bf4db35..ec618a3 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ license='Apache v2.0', python_requires='>=3.6', entry_points={ - 'console_scripts': ['imagine=imagine:main'] + 'console_scripts': ['imagine=imagine:_main'] }, install_requires=[ 'numpy >= 1.18.0', diff --git a/tests/unit/test_units.py b/tests/unit/test_units.py index 5702784..fa10b7c 100644 --- a/tests/unit/test_units.py +++ b/tests/unit/test_units.py @@ -29,21 +29,21 @@ def teardown_method(self): pass def test_directory_creation_if_not_exist(self): - imagine.try_create_directory(str(self.tmpdir)) + imagine._try_create_directory(str(self.tmpdir)) def test_error_input_directory_doesnt_exist(self): with pytest.raises(RuntimeError): - imagine.check_directory_exists(os.path.join(str(self.tmpdir), - 'dne')) + imagine._check_directory_exists(os.path.join(str(self.tmpdir), + 'dne')) def test_record_slice_yields_expected_results(self): slices = [range(x, x + 100) for x in range(0, 1000, 100)] - results = imagine.record_slice(self.tmpdir, - self.tmpdir, - 'test_record_', - range(0, 1000), - 100, - 10) + results = imagine._record_slice(self.tmpdir, + self.tmpdir, + 'test_record_', + range(0, 1000), + 100, + 10) for count, result in enumerate(results): source, dest, name, images, num = result