Top

intern.remote.remote module

# Copyright 2016 The Johns Hopkins University Applied Physics Laboratory
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import six
from abc import ABCMeta
from six.moves import configparser
import os

CONFIG_FILE ='~/.intern/intern.cfg'


@six.add_metaclass(ABCMeta)
class Remote(object):
    """Base class for communicating with remote data stores.

    Attributes:
        _volume (intern.service.Service): Class that communicates with the volume service.
        _metadata (intern.service.Service): Class that communicates with the metadata service.
        _project (intern.service.Service): Class that communicates with the project service.
        _object (intern.service.Service): Class that communicates with the object service.
    """

    def __init__(self, cfg_file_or_dict=None):
        """Constructor.

        Loads credentials in order from user provided dictionary > user provided file > default file > environment vars

        Args:
            cfg_file_or_dict (optional[string|dict]): Path to config file in INI format or a dict of config parameters.
        """

        # Service Objects
        self._volume = None
        self._metadata = None
        self._project = None
        self._object = None

        # Configuration data loaded from file or passed directly to the constructor
        # Is available for children Remote classes to use as needed
        self._config = None

        # Tokens for Services
        self._token_project = None
        self._token_metadata = None
        self._token_volume = None
        self._token_object = None

        if cfg_file_or_dict is None:
            # Default to the config file in the user directory if no config file was provided
            cfg_file_or_dict = os.path.expanduser(CONFIG_FILE)

        if isinstance(cfg_file_or_dict, dict) is True:
            # A config dictionary was provided directly. Keep things consistent by creating an INI string.
            cfg_str = "[Default]\n"
            for key in cfg_file_or_dict:
                cfg_str = "{}{} = {}\n".format(cfg_str, key, cfg_file_or_dict[key])
            self._config = self.load_config_file(six.StringIO(cfg_str))

        else:
            # A file path was provided by the user
            if os.path.isfile(cfg_file_or_dict):
                with open(cfg_file_or_dict, 'r') as cfg_file_handle:
                    self._config = self.load_config_file(cfg_file_handle)
            else:
                # Provided file or default file do not exist.  Try loading from env variables
                if "INTERN_PROTOCOL" in os.environ and "INTERN_HOST" in os.environ and "INTERN_TOKEN" in os.environ:
                    cfg_str = "[Default]\n"
                    cfg_str = "{}{} = {}\n".format(cfg_str, "protocol", os.environ['INTERN_PROTOCOL'])
                    cfg_str = "{}{} = {}\n".format(cfg_str, "host", os.environ['INTERN_HOST'])
                    cfg_str = "{}{} = {}\n".format(cfg_str, "token", os.environ['INTERN_TOKEN'])

                    self._config = self.load_config_file(six.StringIO(cfg_str))
                else:
                    raise IOError("Configuration file not found: {}. Please provide credential file or set environment variables".format(cfg_file_or_dict))

    def load_config_file(self, config_handle):
        """Load config data for the Remote.

        Args:
            config_handle (io.StringIO): Config data encoded in a string.

        Returns:
            (configparser.ConfigParser)
        """
        cfg_parser = configparser.ConfigParser()
        cfg_parser.readfp(config_handle)
        return cfg_parser

    @property
    def volume_service(self):
        return self._volume

    @property
    def project_service(self):
        return self._project

    @property
    def metadata_service(self):
        return self._metadata

    @property
    def object_service(self):
        return self._object

    def list_project(self, **kwargs):
        """Perform list operation on the project.

        What this does is highly dependent on project's data model.

        Args:
            (**kwargs): Args are implementation dependent.

        Returns:
            (list)
        """
        return self._project.list(**kwargs)

    def get_cutout(self, resource, resolution, x_range, y_range, z_range, time_range=None, id_list=[], **kwargs):
        """Get a cutout from the volume service.

        Args:
            resource (intern.resource.Resource): Resource compatible with cutout operations.
            resolution (int): 0 indicates native resolution.
            x_range (list[int]): x range such as [10, 20] which means x>=10 and x<20.
            y_range (list[int]): y range such as [10, 20] which means y>=10 and y<20.
            z_range (list[int]): z range such as [10, 20] which means z>=10 and z<20.
            time_range (optional [list[int]]): time range such as [30, 40] which means t>=30 and t<40.
            id_list (optional [list]): list of object ids to filter the cutout by.

        Returns:
            (): Return type depends on volume service's implementation.

        Raises:
            RuntimeError when given invalid resource.
            Other exceptions may be raised depending on the volume service's implementation.
        """

        if not resource.valid_volume():
            raise RuntimeError('Resource incompatible with the volume service.')
        return self._volume.get_cutout(
            resource, resolution, x_range, y_range, z_range, time_range, id_list, **kwargs)

    def create_cutout(self, resource, resolution, x_range, y_range, z_range, data, time_range=None):
        """Upload a cutout to the volume service.

        Args:
            resource (intern.resource.Resource): Resource compatible with cutout operations.
            resolution (int): 0 indicates native resolution.
            x_range (list[int]): x range such as [10, 20] which means x>=10 and x<20.
            y_range (list[int]): y range such as [10, 20] which means y>=10 and y<20.
            z_range (list[int]): z range such as [10, 20] which means z>=10 and z<20.
            data (object): Type depends on implementation.
            time_range (optional [list[int]]): time range such as [30, 40] which means t>=30 and t<40.

        Returns:
            (): Return type depends on volume service's implementation.

        Raises:
            RuntimeError when given invalid resource.
            Other exceptions may be raised depending on the volume service's implementation.
        """
        if not resource.valid_volume():
            raise RuntimeError('Resource incompatible with the volume service.')
        return self._volume.create_cutout(
            resource, resolution, x_range, y_range, z_range, data, time_range)

    def reserve_ids(self, resource, num_ids):
        """Reserve a block of unique, sequential ids for annotations.

        Args:
            resource (intern.resource.Resource): Resource compatible with annotation operations.
            num_ids (int): Number of ids to reserve.

        Returns:
            (int): First id reserved.

        """
        if not resource.valid_volume():
            raise RuntimeError('Resource incompatible with the volume service.')
        return self._volume.reserve_ids(resource, num_ids)

    def get_bounding_box(self, resource, resolution, id, bb_type='loose'):
        """Get bounding box containing object specified by id.

        Currently only supports 'loose' bounding boxes.  The bounding box
        returned is cuboid aligned.

        Args:
            resource (intern.resource.Resource): Resource compatible with annotation operations.
            resolution (int): 0 indicates native resolution.
            id (int): Id of object of interest.
            bb_type (optional[string]): Defaults to 'loose'.

        Returns:
            (dict): {'x_range': [0, 10], 'y_range': [0, 10], 'z_range': [0, 10], 't_range': [0, 10]}
        """
        if not resource.valid_volume():
            raise RuntimeError('Resource incompatible with the volume service.')

        if bb_type != 'loose' and bb_type != 'tight':
            raise RuntimeError("bb_type must be either 'loose' or 'tight'.")

        return self._volume.get_bounding_box(resource, resolution, id, bb_type)

    def get_ids_in_region(
            self, resource, resolution,
            x_range, y_range, z_range, time_range=[0, 1]):
        """Get all ids in the region defined by x_range, y_range, z_range.

        Args:
            resource (intern.resource.Resource): Resource compatible with annotation operations.
            resolution (int): 0 indicates native resolution.
            x_range (list[int]): x range such as [10, 20] which means x>=10 and x<20.
            y_range (list[int]): y range such as [10, 20] which means y>=10 and y<20.
            z_range (list[int]): z range such as [10, 20] which means z>=10 and z<20.
            time_range (optional [list[int]]): time range such as [30, 40] which means t>=30 and t<40.  Defaults to [0, 1].

        Returns:
            (list[int]): Example: [1, 2, 25].

        Raises:
            requests.HTTPError
            TypeError: if resource is not an annotation channel.
        """
        return self._volume.get_ids_in_region(
            resource, resolution, x_range, y_range, z_range, time_range)

Module variables

var CONFIG_FILE

Classes

class Remote

Base class for communicating with remote data stores.

Attributes:
    _volume (intern.service.Service): Class that communicates with the volume service.
    _metadata (intern.service.Service): Class that communicates with the metadata service.
    _project (intern.service.Service): Class that communicates with the project service.
    _object (intern.service.Service): Class that communicates with the object service.

class Remote(object):
    """Base class for communicating with remote data stores.

    Attributes:
        _volume (intern.service.Service): Class that communicates with the volume service.
        _metadata (intern.service.Service): Class that communicates with the metadata service.
        _project (intern.service.Service): Class that communicates with the project service.
        _object (intern.service.Service): Class that communicates with the object service.
    """

    def __init__(self, cfg_file_or_dict=None):
        """Constructor.

        Loads credentials in order from user provided dictionary > user provided file > default file > environment vars

        Args:
            cfg_file_or_dict (optional[string|dict]): Path to config file in INI format or a dict of config parameters.
        """

        # Service Objects
        self._volume = None
        self._metadata = None
        self._project = None
        self._object = None

        # Configuration data loaded from file or passed directly to the constructor
        # Is available for children Remote classes to use as needed
        self._config = None

        # Tokens for Services
        self._token_project = None
        self._token_metadata = None
        self._token_volume = None
        self._token_object = None

        if cfg_file_or_dict is None:
            # Default to the config file in the user directory if no config file was provided
            cfg_file_or_dict = os.path.expanduser(CONFIG_FILE)

        if isinstance(cfg_file_or_dict, dict) is True:
            # A config dictionary was provided directly. Keep things consistent by creating an INI string.
            cfg_str = "[Default]\n"
            for key in cfg_file_or_dict:
                cfg_str = "{}{} = {}\n".format(cfg_str, key, cfg_file_or_dict[key])
            self._config = self.load_config_file(six.StringIO(cfg_str))

        else:
            # A file path was provided by the user
            if os.path.isfile(cfg_file_or_dict):
                with open(cfg_file_or_dict, 'r') as cfg_file_handle:
                    self._config = self.load_config_file(cfg_file_handle)
            else:
                # Provided file or default file do not exist.  Try loading from env variables
                if "INTERN_PROTOCOL" in os.environ and "INTERN_HOST" in os.environ and "INTERN_TOKEN" in os.environ:
                    cfg_str = "[Default]\n"
                    cfg_str = "{}{} = {}\n".format(cfg_str, "protocol", os.environ['INTERN_PROTOCOL'])
                    cfg_str = "{}{} = {}\n".format(cfg_str, "host", os.environ['INTERN_HOST'])
                    cfg_str = "{}{} = {}\n".format(cfg_str, "token", os.environ['INTERN_TOKEN'])

                    self._config = self.load_config_file(six.StringIO(cfg_str))
                else:
                    raise IOError("Configuration file not found: {}. Please provide credential file or set environment variables".format(cfg_file_or_dict))

    def load_config_file(self, config_handle):
        """Load config data for the Remote.

        Args:
            config_handle (io.StringIO): Config data encoded in a string.

        Returns:
            (configparser.ConfigParser)
        """
        cfg_parser = configparser.ConfigParser()
        cfg_parser.readfp(config_handle)
        return cfg_parser

    @property
    def volume_service(self):
        return self._volume

    @property
    def project_service(self):
        return self._project

    @property
    def metadata_service(self):
        return self._metadata

    @property
    def object_service(self):
        return self._object

    def list_project(self, **kwargs):
        """Perform list operation on the project.

        What this does is highly dependent on project's data model.

        Args:
            (**kwargs): Args are implementation dependent.

        Returns:
            (list)
        """
        return self._project.list(**kwargs)

    def get_cutout(self, resource, resolution, x_range, y_range, z_range, time_range=None, id_list=[], **kwargs):
        """Get a cutout from the volume service.

        Args:
            resource (intern.resource.Resource): Resource compatible with cutout operations.
            resolution (int): 0 indicates native resolution.
            x_range (list[int]): x range such as [10, 20] which means x>=10 and x<20.
            y_range (list[int]): y range such as [10, 20] which means y>=10 and y<20.
            z_range (list[int]): z range such as [10, 20] which means z>=10 and z<20.
            time_range (optional [list[int]]): time range such as [30, 40] which means t>=30 and t<40.
            id_list (optional [list]): list of object ids to filter the cutout by.

        Returns:
            (): Return type depends on volume service's implementation.

        Raises:
            RuntimeError when given invalid resource.
            Other exceptions may be raised depending on the volume service's implementation.
        """

        if not resource.valid_volume():
            raise RuntimeError('Resource incompatible with the volume service.')
        return self._volume.get_cutout(
            resource, resolution, x_range, y_range, z_range, time_range, id_list, **kwargs)

    def create_cutout(self, resource, resolution, x_range, y_range, z_range, data, time_range=None):
        """Upload a cutout to the volume service.

        Args:
            resource (intern.resource.Resource): Resource compatible with cutout operations.
            resolution (int): 0 indicates native resolution.
            x_range (list[int]): x range such as [10, 20] which means x>=10 and x<20.
            y_range (list[int]): y range such as [10, 20] which means y>=10 and y<20.
            z_range (list[int]): z range such as [10, 20] which means z>=10 and z<20.
            data (object): Type depends on implementation.
            time_range (optional [list[int]]): time range such as [30, 40] which means t>=30 and t<40.

        Returns:
            (): Return type depends on volume service's implementation.

        Raises:
            RuntimeError when given invalid resource.
            Other exceptions may be raised depending on the volume service's implementation.
        """
        if not resource.valid_volume():
            raise RuntimeError('Resource incompatible with the volume service.')
        return self._volume.create_cutout(
            resource, resolution, x_range, y_range, z_range, data, time_range)

    def reserve_ids(self, resource, num_ids):
        """Reserve a block of unique, sequential ids for annotations.

        Args:
            resource (intern.resource.Resource): Resource compatible with annotation operations.
            num_ids (int): Number of ids to reserve.

        Returns:
            (int): First id reserved.

        """
        if not resource.valid_volume():
            raise RuntimeError('Resource incompatible with the volume service.')
        return self._volume.reserve_ids(resource, num_ids)

    def get_bounding_box(self, resource, resolution, id, bb_type='loose'):
        """Get bounding box containing object specified by id.

        Currently only supports 'loose' bounding boxes.  The bounding box
        returned is cuboid aligned.

        Args:
            resource (intern.resource.Resource): Resource compatible with annotation operations.
            resolution (int): 0 indicates native resolution.
            id (int): Id of object of interest.
            bb_type (optional[string]): Defaults to 'loose'.

        Returns:
            (dict): {'x_range': [0, 10], 'y_range': [0, 10], 'z_range': [0, 10], 't_range': [0, 10]}
        """
        if not resource.valid_volume():
            raise RuntimeError('Resource incompatible with the volume service.')

        if bb_type != 'loose' and bb_type != 'tight':
            raise RuntimeError("bb_type must be either 'loose' or 'tight'.")

        return self._volume.get_bounding_box(resource, resolution, id, bb_type)

    def get_ids_in_region(
            self, resource, resolution,
            x_range, y_range, z_range, time_range=[0, 1]):
        """Get all ids in the region defined by x_range, y_range, z_range.

        Args:
            resource (intern.resource.Resource): Resource compatible with annotation operations.
            resolution (int): 0 indicates native resolution.
            x_range (list[int]): x range such as [10, 20] which means x>=10 and x<20.
            y_range (list[int]): y range such as [10, 20] which means y>=10 and y<20.
            z_range (list[int]): z range such as [10, 20] which means z>=10 and z<20.
            time_range (optional [list[int]]): time range such as [30, 40] which means t>=30 and t<40.  Defaults to [0, 1].

        Returns:
            (list[int]): Example: [1, 2, 25].

        Raises:
            requests.HTTPError
            TypeError: if resource is not an annotation channel.
        """
        return self._volume.get_ids_in_region(
            resource, resolution, x_range, y_range, z_range, time_range)

Ancestors (in MRO)

Instance variables

var metadata_service

var object_service

var project_service

var volume_service

Methods

def __init__(

self, cfg_file_or_dict=None)

Constructor.

Loads credentials in order from user provided dictionary > user provided file > default file > environment vars

Args:
    cfg_file_or_dict (optional[string|dict]): Path to config file in INI format or a dict of config parameters.

def __init__(self, cfg_file_or_dict=None):
    """Constructor.
    Loads credentials in order from user provided dictionary > user provided file > default file > environment vars
    Args:
        cfg_file_or_dict (optional[string|dict]): Path to config file in INI format or a dict of config parameters.
    """
    # Service Objects
    self._volume = None
    self._metadata = None
    self._project = None
    self._object = None
    # Configuration data loaded from file or passed directly to the constructor
    # Is available for children Remote classes to use as needed
    self._config = None
    # Tokens for Services
    self._token_project = None
    self._token_metadata = None
    self._token_volume = None
    self._token_object = None
    if cfg_file_or_dict is None:
        # Default to the config file in the user directory if no config file was provided
        cfg_file_or_dict = os.path.expanduser(CONFIG_FILE)
    if isinstance(cfg_file_or_dict, dict) is True:
        # A config dictionary was provided directly. Keep things consistent by creating an INI string.
        cfg_str = "[Default]\n"
        for key in cfg_file_or_dict:
            cfg_str = "{}{} = {}\n".format(cfg_str, key, cfg_file_or_dict[key])
        self._config = self.load_config_file(six.StringIO(cfg_str))
    else:
        # A file path was provided by the user
        if os.path.isfile(cfg_file_or_dict):
            with open(cfg_file_or_dict, 'r') as cfg_file_handle:
                self._config = self.load_config_file(cfg_file_handle)
        else:
            # Provided file or default file do not exist.  Try loading from env variables
            if "INTERN_PROTOCOL" in os.environ and "INTERN_HOST" in os.environ and "INTERN_TOKEN" in os.environ:
                cfg_str = "[Default]\n"
                cfg_str = "{}{} = {}\n".format(cfg_str, "protocol", os.environ['INTERN_PROTOCOL'])
                cfg_str = "{}{} = {}\n".format(cfg_str, "host", os.environ['INTERN_HOST'])
                cfg_str = "{}{} = {}\n".format(cfg_str, "token", os.environ['INTERN_TOKEN'])
                self._config = self.load_config_file(six.StringIO(cfg_str))
            else:
                raise IOError("Configuration file not found: {}. Please provide credential file or set environment variables".format(cfg_file_or_dict))

def create_cutout(

self, resource, resolution, x_range, y_range, z_range, data, time_range=None)

Upload a cutout to the volume service.

Args:
    resource (intern.resource.Resource): Resource compatible with cutout operations.
    resolution (int): 0 indicates native resolution.
    x_range (list[int]): x range such as [10, 20] which means x>=10 and x<20.
    y_range (list[int]): y range such as [10, 20] which means y>=10 and y<20.
    z_range (list[int]): z range such as [10, 20] which means z>=10 and z<20.
    data (object): Type depends on implementation.
    time_range (optional [list[int]]): time range such as [30, 40] which means t>=30 and t<40.

Returns

    (): Return type depends on volume service's implementation.

Raises

RuntimeError when given invalid resource.
Other exceptions may be raised depending on the volume service's implementation.
def create_cutout(self, resource, resolution, x_range, y_range, z_range, data, time_range=None):
    """Upload a cutout to the volume service.
    Args:
        resource (intern.resource.Resource): Resource compatible with cutout operations.
        resolution (int): 0 indicates native resolution.
        x_range (list[int]): x range such as [10, 20] which means x>=10 and x<20.
        y_range (list[int]): y range such as [10, 20] which means y>=10 and y<20.
        z_range (list[int]): z range such as [10, 20] which means z>=10 and z<20.
        data (object): Type depends on implementation.
        time_range (optional [list[int]]): time range such as [30, 40] which means t>=30 and t<40.
    Returns:
        (): Return type depends on volume service's implementation.
    Raises:
        RuntimeError when given invalid resource.
        Other exceptions may be raised depending on the volume service's implementation.
    """
    if not resource.valid_volume():
        raise RuntimeError('Resource incompatible with the volume service.')
    return self._volume.create_cutout(
        resource, resolution, x_range, y_range, z_range, data, time_range)

def get_bounding_box(

self, resource, resolution, id, bb_type='loose')

Get bounding box containing object specified by id.

Currently only supports 'loose' bounding boxes. The bounding box
returned is cuboid aligned.

Args:
    resource (intern.resource.Resource): Resource compatible with annotation operations.
    resolution (int): 0 indicates native resolution.
    id (int): Id of object of interest.
    bb_type (optional[string]): Defaults to 'loose'.

Returns

    (dict): {'x_range': [0, 10], 'y_range': [0, 10], 'z_range': [0, 10], 't_range': [0, 10]}

def get_bounding_box(self, resource, resolution, id, bb_type='loose'):
    """Get bounding box containing object specified by id.
    Currently only supports 'loose' bounding boxes.  The bounding box
    returned is cuboid aligned.
    Args:
        resource (intern.resource.Resource): Resource compatible with annotation operations.
        resolution (int): 0 indicates native resolution.
        id (int): Id of object of interest.
        bb_type (optional[string]): Defaults to 'loose'.
    Returns:
        (dict): {'x_range': [0, 10], 'y_range': [0, 10], 'z_range': [0, 10], 't_range': [0, 10]}
    """
    if not resource.valid_volume():
        raise RuntimeError('Resource incompatible with the volume service.')
    if bb_type != 'loose' and bb_type != 'tight':
        raise RuntimeError("bb_type must be either 'loose' or 'tight'.")
    return self._volume.get_bounding_box(resource, resolution, id, bb_type)

def get_cutout(

self, resource, resolution, x_range, y_range, z_range, time_range=None, id_list=[], **kwargs)

Get a cutout from the volume service.

Args:
    resource (intern.resource.Resource): Resource compatible with cutout operations.
    resolution (int): 0 indicates native resolution.
    x_range (list[int]): x range such as [10, 20] which means x>=10 and x<20.
    y_range (list[int]): y range such as [10, 20] which means y>=10 and y<20.
    z_range (list[int]): z range such as [10, 20] which means z>=10 and z<20.
    time_range (optional [list[int]]): time range such as [30, 40] which means t>=30 and t<40.
    id_list (optional [list]): list of object ids to filter the cutout by.

Returns

    (): Return type depends on volume service's implementation.

Raises

RuntimeError when given invalid resource.
Other exceptions may be raised depending on the volume service's implementation.
def get_cutout(self, resource, resolution, x_range, y_range, z_range, time_range=None, id_list=[], **kwargs):
    """Get a cutout from the volume service.
    Args:
        resource (intern.resource.Resource): Resource compatible with cutout operations.
        resolution (int): 0 indicates native resolution.
        x_range (list[int]): x range such as [10, 20] which means x>=10 and x<20.
        y_range (list[int]): y range such as [10, 20] which means y>=10 and y<20.
        z_range (list[int]): z range such as [10, 20] which means z>=10 and z<20.
        time_range (optional [list[int]]): time range such as [30, 40] which means t>=30 and t<40.
        id_list (optional [list]): list of object ids to filter the cutout by.
    Returns:
        (): Return type depends on volume service's implementation.
    Raises:
        RuntimeError when given invalid resource.
        Other exceptions may be raised depending on the volume service's implementation.
    """
    if not resource.valid_volume():
        raise RuntimeError('Resource incompatible with the volume service.')
    return self._volume.get_cutout(
        resource, resolution, x_range, y_range, z_range, time_range, id_list, **kwargs)

def get_ids_in_region(

self, resource, resolution, x_range, y_range, z_range, time_range=[0, 1])

Get all ids in the region defined by x_range, y_range, z_range.

Args:
    resource (intern.resource.Resource): Resource compatible with annotation operations.
    resolution (int): 0 indicates native resolution.
    x_range (list[int]): x range such as [10, 20] which means x>=10 and x<20.
    y_range (list[int]): y range such as [10, 20] which means y>=10 and y<20.
    z_range (list[int]): z range such as [10, 20] which means z>=10 and z<20.
    time_range (optional [list[int]]): time range such as [30, 40] which means t>=30 and t<40. Defaults to [0, 1].

Returns

    (list[int]): Example: [1, 2, 25].

Raises

requests.HTTPError

    TypeError: if resource is not an annotation channel.

def get_ids_in_region(
        self, resource, resolution,
        x_range, y_range, z_range, time_range=[0, 1]):
    """Get all ids in the region defined by x_range, y_range, z_range.
    Args:
        resource (intern.resource.Resource): Resource compatible with annotation operations.
        resolution (int): 0 indicates native resolution.
        x_range (list[int]): x range such as [10, 20] which means x>=10 and x<20.
        y_range (list[int]): y range such as [10, 20] which means y>=10 and y<20.
        z_range (list[int]): z range such as [10, 20] which means z>=10 and z<20.
        time_range (optional [list[int]]): time range such as [30, 40] which means t>=30 and t<40.  Defaults to [0, 1].
    Returns:
        (list[int]): Example: [1, 2, 25].
    Raises:
        requests.HTTPError
        TypeError: if resource is not an annotation channel.
    """
    return self._volume.get_ids_in_region(
        resource, resolution, x_range, y_range, z_range, time_range)

def list_project(

self, **kwargs)

Perform list operation on the project.

What this does is highly dependent on project's data model.

Args:
    (**kwargs): Args are implementation dependent.

Returns

(list)
def list_project(self, **kwargs):
    """Perform list operation on the project.
    What this does is highly dependent on project's data model.
    Args:
        (**kwargs): Args are implementation dependent.
    Returns:
        (list)
    """
    return self._project.list(**kwargs)

def load_config_file(

self, config_handle)

Load config data for the Remote.

Args:
    config_handle (io.StringIO): Config data encoded in a string.

Returns

(configparser.ConfigParser)
def load_config_file(self, config_handle):
    """Load config data for the Remote.
    Args:
        config_handle (io.StringIO): Config data encoded in a string.
    Returns:
        (configparser.ConfigParser)
    """
    cfg_parser = configparser.ConfigParser()
    cfg_parser.readfp(config_handle)
    return cfg_parser

def reserve_ids(

self, resource, num_ids)

Reserve a block of unique, sequential ids for annotations.

Args:
    resource (intern.resource.Resource): Resource compatible with annotation operations.
    num_ids (int): Number of ids to reserve.

Returns

    (int): First id reserved.

def reserve_ids(self, resource, num_ids):
    """Reserve a block of unique, sequential ids for annotations.
    Args:
        resource (intern.resource.Resource): Resource compatible with annotation operations.
        num_ids (int): Number of ids to reserve.
    Returns:
        (int): First id reserved.
    """
    if not resource.valid_volume():
        raise RuntimeError('Resource incompatible with the volume service.')
    return self._volume.reserve_ids(resource, num_ids)