Python function to implement an image-processing pipeline I have written the following function to process images. Now I am not sure if it's pythonic or considered as spaghetti code. I know being flat is better than nested, but I don't see a way around it.

I could easily apply list comprehensions if the "if" statements are only resolving true/false, but each step depends on the output of the previous steps, so I don't think I could use itertools. 

def get_image(width, height, collection_sku, order_id, name, handle):
    """image processing pipeline"""

    # Check-1 image exception should be checked before proceeding further
    # covers both images in exception(currently bookshelves) list and also personal true doors
    #   1. bookshelves need to be cropped
    #   2. personal images needs to be added in the required size
    if helpers.image_exception(collection_sku):

        # Step-1 Find image folder
        directory_sizes = helpers.find_directory(width, height)

        if directory_sizes is not None:
            # Step-2 Find the image from the given folder.
            key = helpers.find_image(directory_sizes, collection_sku)

            if key is not None:

                requires_resize = helpers.should_resize(width, height)
                requires_flip = helpers.should_flip(handle) and not helpers.flip_exception(collection_sku)

                # Check-2 check whether image requires resizing or flipping
                if requires_resize or requires_flip:

                    # Step-3 Create local directory to store temporary images
                    location, is_created = helpers.local_directory(
                        order_id)

                    if is_created:
                        # Step-4 Download image
                        image = helpers.download_image(key, location, name)

                        if image is not None:
                            width_px = helpers.cm_to_pixel(width)
                            height_px = helpers.cm_to_pixel(height)
                            image_modified = False

                            # Step-5.1 Resize image
                            if requires_resize:
                                helpers.resize_image(image, width_px, height_px)
                                image_modified = True

                            # Step-5.2 Flip image
                            if requires_flip:
                                helpers.flip_image(image)
                                image_modified = True

                            # Step-6 Upload image
                            if image_modified:
                                helpers.upload_image(image, key)

                    # Step-3 No local dir created
                    # Step-4 Can't download image
                    # Step-5.1 Can't resize image
                    # Step-5.2 Can't flip image
                    # Step-6 Can't upload image
                    return None

                # Check-2 if no image processing required then copy image over
                helpers.copy_image(key, target=None) # TODO
                return True

    # raise exception in sub job
    #   Check-1 if image door image cannot be processed
    #   Step-1 if directory not available
    #   Step-2 if image not available

    return None
As Reinderien mentions, you can decrease some of the complexity of your code by inverting your if-statements. While I cannot test this because I do not have your whole code, here is how it could be done:

def get_image(width, height, collection_sku, order_id, name, handle):
    """image processing pipeline"""

    # Check-1 image exception should be checked before proceeding further
    # covers both images in exception(currently bookshelves) list and also personal true doors
    #   1. bookshelves need to be cropped
    #   2. personal TD images needs to be added in the required size when it's submitted by the user.
    if not helpers.image_exception(collection_sku):
        return None

    # Step-1 Find image folder
    directory_sizes = helpers.find_directory(width, height)

    if directory_sizes is None:
        return None

    # Step-2 Find the image from the given folder.
    key = helpers.find_image(directory_sizes, collection_sku)

    if key is None:
        return None

    requires_resize = helpers.should_resize(width, height)
    requires_flip = helpers.should_flip(handle) and not helpers.flip_exception(collection_sku)

    # Check-2 check whether image requires resizing or flipping
    if requires_resize or requires_flip:

        # Step-3 Create local directory to store temporary images
        location, is_created = helpers.local_directory(
            order_id)

        if not is_created:
            return None

        # Step-4 Download image
        image = helpers.download_image(key, location, name)

        if image is not None:
            width_px = helpers.cm_to_pixel(width)
            height_px = helpers.cm_to_pixel(height)
            image_modified = False

            # Step-5.1 Resize image
            if requires_resize:
                helpers.resize_image(image, width_px, height_px)
                image_modified = True

            # Step-5.2 Flip image
            if requires_flip:
                helpers.flip_image(image)
                image_modified = True

            # Step-6 Upload image
            if image_modified:
                helpers.upload_image(image, key)

        # Step-3 No local dir created
        # Step-4 Can't download image
        # Step-5.1 Can't resize image
        # Step-5.2 Can't flip image
        # Step-6 Can't upload image

    # Check-2 if no image processing required then copy image over
    helpers.copy_image(key, target = None) # TODO
    return True

    # raise exception in sub job
    #   Check-1 if image door image cannot be processed
    #   Step-1 if directory not available
    #   Step-2 if image not available


This, for me, vastly increases readability -- before, it was hard to figure out which if-statements do what (especially with fragments of code at the ends of them). However, your comments are useful in describing the process as it goes along.

I'm sure it could be flattened more, but this should demonstrate the idea of it. Hope this helps!