Top

intern.service.boss.v1.metadata 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.
from intern.resource.boss.resource import *
from intern.service.boss.httperrorlist import HTTPErrorList
from requests import HTTPError
from intern.service.boss import BaseVersion
from intern.service.boss.v1 import BOSS_API_VERSION


class MetadataService_1(BaseVersion):
    def __init__(self):
        BaseVersion.__init__(self)

    @property
    def version(self):
        """Return the API Version for this implementation
        """
        return BOSS_API_VERSION

    def list(self, resource, url_prefix, auth, session, send_opts):
        """List metadata keys associated with the given resource.

        Args:
            resource (intern.resource.boss.BossResource): List keys associated with this resource.
            url_prefix (string): Protocol + host such as https://api.theboss.io
            auth (string): Token to send in the request header.
            session (requests.Session): HTTP session to use for request.
            send_opts (dictionary): Additional arguments to pass to session.send().

        Returns:
            (list): List of key names.

        Raises:
            requests.HTTPError on failure.
        """

        req = self.get_metadata_request(
            resource, 'GET', 'application/json', url_prefix, auth)

        prep = session.prepare_request(req)
        resp = session.send(prep, **send_opts)
        if resp.status_code == 200:
            keys_dict = resp.json()
            return keys_dict['keys']

        err = ('List failed on {}, got HTTP response: ({}) - {}'.format(
            resource.name, resp.status_code, resp.text))
        raise HTTPError(err, request = req, response = resp)

    def create(self, resource, keys_vals, url_prefix, auth, session, send_opts):
        """Create the given key-value pairs for the given resource.

        Will attempt to create all key-value pairs even if a failure is encountered.

        Args:
            resource (intern.resource.boss.BossResource): List keys associated with this resource.
            keys_vals (dictionary): The metadata to associate with the resource.
            url_prefix (string): Protocol + host such as https://api.theboss.io
            auth (string): Token to send in the request header.
            session (requests.Session): HTTP session to use for request.
            send_opts (dictionary): Additional arguments to pass to session.send().

        Raises:
            HTTPErrorList on failure.
        """
        success = True
        exc = HTTPErrorList('At least one key-value create failed.')

        for pair in keys_vals.items():
            key = pair[0]
            value = pair[1]
            req = self.get_metadata_request(
                resource, 'POST', 'application/json', url_prefix, auth,
                key, value)
            prep = session.prepare_request(req)
            resp = session.send(prep, **send_opts)
            if resp.status_code == 201:
                continue

            err = (
                'Create failed for {}: {}:{}, got HTTP response: ({}) - {}'
                .format(resource.name, key, value, resp.status_code, resp.text))
            exc.http_errors.append(HTTPError(err, request=req, response=resp))
            success = False

        if not success:
            raise exc

    def get(self, resource, keys, url_prefix, auth, session, send_opts):
        """Get metadata key-value pairs associated with the given resource.

        Args:
            resource (intern.resource.boss.BossResource): Get key-value pairs associated with this resource.
            keys (list): Keys to retrieve.
            url_prefix (string): Protocol + host such as https://api.theboss.io
            auth (string): Token to send in the request header.
            session (requests.Session): HTTP session to use for request.
            send_opts (dictionary): Additional arguments to pass to session.send().

        Returns:
            (dictionary): The requested metadata for the given resource.

        Raises:
            HTTPErrorList on failure.
        """
        resDict = {}
        success = True
        exc = HTTPErrorList('At least one key-value update failed.')

        for key in keys:
            req = self.get_metadata_request(
                resource, 'GET', 'application/json', url_prefix, auth, key)
            prep = session.prepare_request(req)
            resp = session.send(prep, **send_opts)
            if resp.status_code == 200:
                resDict[key] = resp.json()['value']
            else:
                err = ('Get failed on {}, got HTTP response: ({}) - {}'.format(
                    resource.name, resp.status_code, resp.text))
                exc.http_errors.append(HTTPError(err, request=req, response=resp))
                success = False

        if not success:
            raise exc

        return resDict

    def update(self, resource, keys_vals, url_prefix, auth, session, send_opts):
        """Update the given key-value pairs for the given resource.

        Keys must already exist before they may be updated.  Will attempt to
        update all key-value pairs even if a failure is encountered.

        Args:
            resource (intern.resource.boss.BossResource): Update values associated with this resource.
            keys_vals (dictionary): The metadata to update for the resource.
            url_prefix (string): Protocol + host such as https://api.theboss.io
            auth (string): Token to send in the request header.
            session (requests.Session): HTTP session to use for request.
            send_opts (dictionary): Additional arguments to pass to session.send().

        Raises:
            HTTPErrorList on failure.
        """
        success = True
        exc = HTTPErrorList('At least one key-value update failed.')

        for pair in keys_vals.items():
            key = pair[0]
            value = pair[1]
            req = self.get_metadata_request(
                resource, 'PUT', 'application/json', url_prefix, auth,
                key, value)
            prep = session.prepare_request(req)
            resp = session.send(prep, **send_opts)

            if resp.status_code == 200:
                continue

            err = (
                'Update failed for {}: {}:{}, got HTTP response: ({}) - {}'
                .format(resource.name, key, value, resp.status_code, resp.text))
            exc.http_errors.append(HTTPError(err, request=req, response=resp))
            success = False

        if not success:
            raise exc

    def delete(self, resource, keys, url_prefix, auth, session, send_opts):
        """Delete metadata key-value pairs associated with the given resource.

        Will attempt to delete all given key-value pairs even if a failure
        occurs.

        Args:
            resource (intern.resource.boss.BossResource): Delete key-value pairs associated with this resource.
            keys (list): Keys to delete.
            url_prefix (string): Protocol + host such as https://api.theboss.io
            auth (string): Token to send in the request header.
            session (requests.Session): HTTP session to use for request.
            send_opts (dictionary): Additional arguments to pass to session.send().

        Raises:
            HTTPErrorList on failure.
        """
        success = True
        exc = HTTPErrorList('At least one key-value update failed.')

        for key in keys:
            req = self.get_metadata_request(
                resource, 'DELETE', 'application/json', url_prefix, auth, key)
            prep = session.prepare_request(req)
            resp = session.send(prep, **send_opts)
            if resp.status_code == 204:
                continue
            err = (
                'Delete failed for {}: {}, got HTTP response: ({}) - {}'
                .format(resource.name, key, resp.status_code, resp.text))
            exc.http_errors.append(HTTPError(err, request=req, response=resp))
            success = False

        if not success:
            raise exc

Module variables

var BOSS_API_VERSION

Classes

class MetadataService_1

class MetadataService_1(BaseVersion):
    def __init__(self):
        BaseVersion.__init__(self)

    @property
    def version(self):
        """Return the API Version for this implementation
        """
        return BOSS_API_VERSION

    def list(self, resource, url_prefix, auth, session, send_opts):
        """List metadata keys associated with the given resource.

        Args:
            resource (intern.resource.boss.BossResource): List keys associated with this resource.
            url_prefix (string): Protocol + host such as https://api.theboss.io
            auth (string): Token to send in the request header.
            session (requests.Session): HTTP session to use for request.
            send_opts (dictionary): Additional arguments to pass to session.send().

        Returns:
            (list): List of key names.

        Raises:
            requests.HTTPError on failure.
        """

        req = self.get_metadata_request(
            resource, 'GET', 'application/json', url_prefix, auth)

        prep = session.prepare_request(req)
        resp = session.send(prep, **send_opts)
        if resp.status_code == 200:
            keys_dict = resp.json()
            return keys_dict['keys']

        err = ('List failed on {}, got HTTP response: ({}) - {}'.format(
            resource.name, resp.status_code, resp.text))
        raise HTTPError(err, request = req, response = resp)

    def create(self, resource, keys_vals, url_prefix, auth, session, send_opts):
        """Create the given key-value pairs for the given resource.

        Will attempt to create all key-value pairs even if a failure is encountered.

        Args:
            resource (intern.resource.boss.BossResource): List keys associated with this resource.
            keys_vals (dictionary): The metadata to associate with the resource.
            url_prefix (string): Protocol + host such as https://api.theboss.io
            auth (string): Token to send in the request header.
            session (requests.Session): HTTP session to use for request.
            send_opts (dictionary): Additional arguments to pass to session.send().

        Raises:
            HTTPErrorList on failure.
        """
        success = True
        exc = HTTPErrorList('At least one key-value create failed.')

        for pair in keys_vals.items():
            key = pair[0]
            value = pair[1]
            req = self.get_metadata_request(
                resource, 'POST', 'application/json', url_prefix, auth,
                key, value)
            prep = session.prepare_request(req)
            resp = session.send(prep, **send_opts)
            if resp.status_code == 201:
                continue

            err = (
                'Create failed for {}: {}:{}, got HTTP response: ({}) - {}'
                .format(resource.name, key, value, resp.status_code, resp.text))
            exc.http_errors.append(HTTPError(err, request=req, response=resp))
            success = False

        if not success:
            raise exc

    def get(self, resource, keys, url_prefix, auth, session, send_opts):
        """Get metadata key-value pairs associated with the given resource.

        Args:
            resource (intern.resource.boss.BossResource): Get key-value pairs associated with this resource.
            keys (list): Keys to retrieve.
            url_prefix (string): Protocol + host such as https://api.theboss.io
            auth (string): Token to send in the request header.
            session (requests.Session): HTTP session to use for request.
            send_opts (dictionary): Additional arguments to pass to session.send().

        Returns:
            (dictionary): The requested metadata for the given resource.

        Raises:
            HTTPErrorList on failure.
        """
        resDict = {}
        success = True
        exc = HTTPErrorList('At least one key-value update failed.')

        for key in keys:
            req = self.get_metadata_request(
                resource, 'GET', 'application/json', url_prefix, auth, key)
            prep = session.prepare_request(req)
            resp = session.send(prep, **send_opts)
            if resp.status_code == 200:
                resDict[key] = resp.json()['value']
            else:
                err = ('Get failed on {}, got HTTP response: ({}) - {}'.format(
                    resource.name, resp.status_code, resp.text))
                exc.http_errors.append(HTTPError(err, request=req, response=resp))
                success = False

        if not success:
            raise exc

        return resDict

    def update(self, resource, keys_vals, url_prefix, auth, session, send_opts):
        """Update the given key-value pairs for the given resource.

        Keys must already exist before they may be updated.  Will attempt to
        update all key-value pairs even if a failure is encountered.

        Args:
            resource (intern.resource.boss.BossResource): Update values associated with this resource.
            keys_vals (dictionary): The metadata to update for the resource.
            url_prefix (string): Protocol + host such as https://api.theboss.io
            auth (string): Token to send in the request header.
            session (requests.Session): HTTP session to use for request.
            send_opts (dictionary): Additional arguments to pass to session.send().

        Raises:
            HTTPErrorList on failure.
        """
        success = True
        exc = HTTPErrorList('At least one key-value update failed.')

        for pair in keys_vals.items():
            key = pair[0]
            value = pair[1]
            req = self.get_metadata_request(
                resource, 'PUT', 'application/json', url_prefix, auth,
                key, value)
            prep = session.prepare_request(req)
            resp = session.send(prep, **send_opts)

            if resp.status_code == 200:
                continue

            err = (
                'Update failed for {}: {}:{}, got HTTP response: ({}) - {}'
                .format(resource.name, key, value, resp.status_code, resp.text))
            exc.http_errors.append(HTTPError(err, request=req, response=resp))
            success = False

        if not success:
            raise exc

    def delete(self, resource, keys, url_prefix, auth, session, send_opts):
        """Delete metadata key-value pairs associated with the given resource.

        Will attempt to delete all given key-value pairs even if a failure
        occurs.

        Args:
            resource (intern.resource.boss.BossResource): Delete key-value pairs associated with this resource.
            keys (list): Keys to delete.
            url_prefix (string): Protocol + host such as https://api.theboss.io
            auth (string): Token to send in the request header.
            session (requests.Session): HTTP session to use for request.
            send_opts (dictionary): Additional arguments to pass to session.send().

        Raises:
            HTTPErrorList on failure.
        """
        success = True
        exc = HTTPErrorList('At least one key-value update failed.')

        for key in keys:
            req = self.get_metadata_request(
                resource, 'DELETE', 'application/json', url_prefix, auth, key)
            prep = session.prepare_request(req)
            resp = session.send(prep, **send_opts)
            if resp.status_code == 204:
                continue
            err = (
                'Delete failed for {}: {}, got HTTP response: ({}) - {}'
                .format(resource.name, key, resp.status_code, resp.text))
            exc.http_errors.append(HTTPError(err, request=req, response=resp))
            success = False

        if not success:
            raise exc

Ancestors (in MRO)

Instance variables

var version

Return the API Version for this implementation

Methods

def __init__(

self)

def __init__(self):
    BaseVersion.__init__(self)

def build_cutout_url(

self, resource, url_prefix, resolution, x_range, y_range, z_range, time_range=None, id_list=[], access_mode=None)

Build the url to access the cutout function of the Boss' volume service.

Args:
    url_prefix (string): Do not end with a slash. Example of expected value: https://api.theboss.io
    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[int]]): list of object ids to filter the cutout by.
    access_mode (optional [Enum]): Identifies one of three cache access options:
cache = Will check both cache and for dirty keys
no_cache = Will skip cache check but check for dirty keys
raw = Will skip both the cache and dirty keys check
    NOTE: No default here since when building a cutout url to create_cutout there is no need for access_mode

Returns

    (string): Full URL to access API.

Raises

    (RuntimeError): if *_range invalid.

def build_cutout_url(
    self, resource, url_prefix, resolution, x_range, y_range, z_range, time_range=None, id_list=[], access_mode=None):
    """Build the url to access the cutout function of the Boss' volume service.
    Args:
        url_prefix (string): Do not end with a slash.  Example of expected value: https://api.theboss.io
        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[int]]): list of object ids to filter the cutout by.
        access_mode (optional [Enum]): Identifies one of three cache access options:
            cache = Will check both cache and for dirty keys
            no_cache = Will skip cache check but check for dirty keys
            raw = Will skip both the cache and dirty keys check
            NOTE: No default here since when building a cutout url to create_cutout there is no need for access_mode
    Returns:
        (string): Full URL to access API.
    Raises:
        (RuntimeError): if *_range invalid.
    """
    baseUrl = self.build_url(resource, url_prefix, 'cutout', req_type='cutout')
    x_rng_lst = self.convert_int_list_range_to_str(x_range)
    y_rng_lst = self.convert_int_list_range_to_str(y_range)
    z_rng_lst = self.convert_int_list_range_to_str(z_range)
    urlWithParams = (
        baseUrl + '/' + str(resolution) + '/' + x_rng_lst + '/' + y_rng_lst +
        '/' + z_rng_lst + '/')
    if time_range is not None:
        t_rng_lst = self.convert_int_list_range_to_str(time_range)
        urlWithParams += t_rng_lst + '/'
    queryParamDict = {}
    if len(id_list) > 0:
        queryParamDict['filter'] = self.convert_int_list_to_comma_sep_str(id_list)

    # If creating a cutout, the url will not include the access_mode otherwise it will
    if access_mode is not None:
        queryParamDict['access-mode'] = access_mode.value 
    """
    TODO: LMR
    The following could be done using urlib.urlencode(urlWithParams += '?' + urllib.parse.urlencode(queryParamDict,safe=",")),
    however urllib's python2 version of this function does not take in the 'safe' parameter and thus we can not use the 
    function interchangable for python2/3. In order to keep our python2/3 compatability, we do not use urllib. 
    """
    if queryParamDict:
        # The first time include '?'
        urlWithParams += '?'
        for k, v in queryParamDict.items():
            # if this is the first run through, last char in str will be ?, so don't include '&'
            if urlWithParams[len(urlWithParams)-1] == '?':
                pass
            # otherwise use '&'
            else:
                urlWithParams += '&'
            # Add key and value members
            urlWithParams += '{}={}'.format(k,v)
    return urlWithParams

def build_ids_url(

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

Build the url to access the ids function of the Boss' volume service.

Args:
    resource (intern.resource.boss.BossResource): Resource to perform operation on.
    url_prefix (string): Do not end with a slash. Example of expected value: https://api.theboss.io
    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.

Returns

    (string): Full URL to access API.

Raises

    (RuntimeError): if *_range invalid.

def build_ids_url(
        self, resource, url_prefix, resolution,
        x_range, y_range, z_range, time_range=None):
    """Build the url to access the ids function of the Boss' volume service.
    Args:
        resource (intern.resource.boss.BossResource): Resource to perform operation on.
        url_prefix (string): Do not end with a slash.  Example of expected value: https://api.theboss.io
        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.
    Returns:
        (string): Full URL to access API.
    Raises:
        (RuntimeError): if *_range invalid.
    """
    base_url = self.build_url(resource, url_prefix, 'ids', req_type='cutout')
    x_rng_lst = self.convert_int_list_range_to_str(x_range)
    y_rng_lst = self.convert_int_list_range_to_str(y_range)
    z_rng_lst = self.convert_int_list_range_to_str(z_range)
    url_with_params = (
        base_url + '/' + str(resolution) + '/' + x_rng_lst + '/' + y_rng_lst +
        '/' + z_rng_lst + '/')
    if time_range is not None:
        t_rng_lst = self.convert_int_list_range_to_str(time_range)
        url_with_params += t_rng_lst + '/'
    return url_with_params

def build_metadata_url(

self, resource, url_prefix, key, value=None)

Build the url to access the Boss' metadata service.

Args:
    url_prefix (string): Do not end with a slash. Example of expected value: https://api.theboss.io
    key (string): Key to get/create/update/delete.
    value (string): Value to assign to key or None.

Returns

    (string): Full URL to access API.

def build_metadata_url(self, resource, url_prefix, key, value=None):
    """Build the url to access the Boss' metadata service.
    Args:
        url_prefix (string): Do not end with a slash.  Example of expected value: https://api.theboss.io
        key (string): Key to get/create/update/delete.
        value (string): Value to assign to key or None.
    Returns:
        (string): Full URL to access API.
    """
    if url_prefix is None or url_prefix == '':
        raise RuntimeError('url_prefix required.')
    suffix = resource.get_meta_route()
    urlNoParams = (url_prefix + '/' + self.version + '/meta/' + suffix)
    if key is None:
        return urlNoParams
    urlWithKey = urlNoParams + '/?key=' + key
    if value is None:
        return urlWithKey
    return urlWithKey + '&value=' + str(value)

def build_url(

self, resource, url_prefix, service, req_type='normal')

Build the url to access the Boss' project service.

Args:
    url_prefix (string): Do not end with a slash. Example of expected value: https://api.theboss.io
    service (string): Name of service to access, such as collection, meta, coord, etc.
    req_type (optional[string]): Valid values ['normal', 'list', 'cutout']. Defaults to 'normal'.

Returns

    (string): Full URL to access API.

Raises

    (RuntimeError): if invalid req_type given or url_prefix not given.

def build_url(self, resource, url_prefix, service, req_type='normal'):
    """Build the url to access the Boss' project service.
    Args:
        url_prefix (string): Do not end with a slash.  Example of expected value: https://api.theboss.io
        service (string): Name of service to access, such as collection, meta, coord, etc.
        req_type (optional[string]): Valid values ['normal', 'list', 'cutout'].  Defaults to 'normal'.
    Returns:
        (string): Full URL to access API.
    Raises:
        (RuntimeError): if invalid req_type given or url_prefix not given.
    """
    if url_prefix is None or url_prefix == '':
        raise RuntimeError('url_prefix required.')
    if req_type == 'normal':
        suffix = resource.get_route()
    elif req_type == 'list':
        # No suffix required for a list request.
        suffix = resource.get_list_route()
    elif req_type == 'cutout':
        suffix = resource.get_cutout_route()
    else:
        raise RuntimeError('Invalid request type: {}'.format(req_type))
    url = (url_prefix + '/' + self.version + '/' + service + '/' + suffix)
    return url

def convert_int_list_range_to_str(

self, int_list)

Convert range in list of two ints to string representation.

Returned string can then be placed in URL as a query parameter.

Args:
    int_list (list[int]): range such as [10, 20] which means x>=10 and x<20.

Returns

    (string): [10, 20] => '10:20'

Raises

    (RuntimeError): if given invalid range.

def convert_int_list_range_to_str(self, int_list):
    """Convert range in list of two ints to string representation.
    Returned string can then be placed in URL as a query parameter.
    Args:
        int_list (list[int]): range such as [10, 20] which means x>=10 and x<20.
    Returns:
        (string): [10, 20] => '10:20'
    Raises:
        (RuntimeError): if given invalid range.
    """
    if len(int_list) != 2:
        raise RuntimeError('int_list must contain exactly two values.')
    if int_list[0] > int_list[1]:
        raise RuntimeError('Invalid range: int_list[0] > int_list[1].')
    return '{}:{}'.format(int_list[0], int_list[1])

def convert_int_list_to_comma_sep_str(

self, int_list)

Convert list of ints to comma separated stringj.

Args:
    int_list (list[int]): list of ints.

Returns

    (string): Example: [1, 7, 9] => '1, 7, 9'

def convert_int_list_to_comma_sep_str(self, int_list):
    """Convert list of ints to comma separated stringj.
    Args:
        int_list (list[int]): list of ints.
    Returns:
        (string): Example: [1, 7, 9] => '1, 7, 9'
    """
    if len(int_list) == 1:
        return str(int_list[0])
    str_list = []
    for n in int_list:
        str_list.append(str(n))
    return (',').join(str_list)

def create(

self, resource, keys_vals, url_prefix, auth, session, send_opts)

Create the given key-value pairs for the given resource.

Will attempt to create all key-value pairs even if a failure is encountered.

Args:
    resource (intern.resource.boss.BossResource): List keys associated with this resource.
    keys_vals (dictionary): The metadata to associate with the resource.
    url_prefix (string): Protocol + host such as https://api.theboss.io
    auth (string): Token to send in the request header.
    session (requests.Session): HTTP session to use for request.
    send_opts (dictionary): Additional arguments to pass to session.send().

Raises

HTTPErrorList on failure.
def create(self, resource, keys_vals, url_prefix, auth, session, send_opts):
    """Create the given key-value pairs for the given resource.
    Will attempt to create all key-value pairs even if a failure is encountered.
    Args:
        resource (intern.resource.boss.BossResource): List keys associated with this resource.
        keys_vals (dictionary): The metadata to associate with the resource.
        url_prefix (string): Protocol + host such as https://api.theboss.io
        auth (string): Token to send in the request header.
        session (requests.Session): HTTP session to use for request.
        send_opts (dictionary): Additional arguments to pass to session.send().
    Raises:
        HTTPErrorList on failure.
    """
    success = True
    exc = HTTPErrorList('At least one key-value create failed.')
    for pair in keys_vals.items():
        key = pair[0]
        value = pair[1]
        req = self.get_metadata_request(
            resource, 'POST', 'application/json', url_prefix, auth,
            key, value)
        prep = session.prepare_request(req)
        resp = session.send(prep, **send_opts)
        if resp.status_code == 201:
            continue
        err = (
            'Create failed for {}: {}:{}, got HTTP response: ({}) - {}'
            .format(resource.name, key, value, resp.status_code, resp.text))
        exc.http_errors.append(HTTPError(err, request=req, response=resp))
        success = False
    if not success:
        raise exc

def delete(

self, resource, keys, url_prefix, auth, session, send_opts)

Delete metadata key-value pairs associated with the given resource.

Will attempt to delete all given key-value pairs even if a failure
occurs.

Args:
    resource (intern.resource.boss.BossResource): Delete key-value pairs associated with this resource.
    keys (list): Keys to delete.
    url_prefix (string): Protocol + host such as https://api.theboss.io
    auth (string): Token to send in the request header.
    session (requests.Session): HTTP session to use for request.
    send_opts (dictionary): Additional arguments to pass to session.send().

Raises

HTTPErrorList on failure.
def delete(self, resource, keys, url_prefix, auth, session, send_opts):
    """Delete metadata key-value pairs associated with the given resource.
    Will attempt to delete all given key-value pairs even if a failure
    occurs.
    Args:
        resource (intern.resource.boss.BossResource): Delete key-value pairs associated with this resource.
        keys (list): Keys to delete.
        url_prefix (string): Protocol + host such as https://api.theboss.io
        auth (string): Token to send in the request header.
        session (requests.Session): HTTP session to use for request.
        send_opts (dictionary): Additional arguments to pass to session.send().
    Raises:
        HTTPErrorList on failure.
    """
    success = True
    exc = HTTPErrorList('At least one key-value update failed.')
    for key in keys:
        req = self.get_metadata_request(
            resource, 'DELETE', 'application/json', url_prefix, auth, key)
        prep = session.prepare_request(req)
        resp = session.send(prep, **send_opts)
        if resp.status_code == 204:
            continue
        err = (
            'Delete failed for {}: {}, got HTTP response: ({}) - {}'
            .format(resource.name, key, resp.status_code, resp.text))
        exc.http_errors.append(HTTPError(err, request=req, response=resp))
        success = False
    if not success:
        raise exc

def get(

self, resource, keys, url_prefix, auth, session, send_opts)

Get metadata key-value pairs associated with the given resource.

Args:
    resource (intern.resource.boss.BossResource): Get key-value pairs associated with this resource.
    keys (list): Keys to retrieve.
    url_prefix (string): Protocol + host such as https://api.theboss.io
    auth (string): Token to send in the request header.
    session (requests.Session): HTTP session to use for request.
    send_opts (dictionary): Additional arguments to pass to session.send().

Returns

    (dictionary): The requested metadata for the given resource.

Raises

HTTPErrorList on failure.
def get(self, resource, keys, url_prefix, auth, session, send_opts):
    """Get metadata key-value pairs associated with the given resource.
    Args:
        resource (intern.resource.boss.BossResource): Get key-value pairs associated with this resource.
        keys (list): Keys to retrieve.
        url_prefix (string): Protocol + host such as https://api.theboss.io
        auth (string): Token to send in the request header.
        session (requests.Session): HTTP session to use for request.
        send_opts (dictionary): Additional arguments to pass to session.send().
    Returns:
        (dictionary): The requested metadata for the given resource.
    Raises:
        HTTPErrorList on failure.
    """
    resDict = {}
    success = True
    exc = HTTPErrorList('At least one key-value update failed.')
    for key in keys:
        req = self.get_metadata_request(
            resource, 'GET', 'application/json', url_prefix, auth, key)
        prep = session.prepare_request(req)
        resp = session.send(prep, **send_opts)
        if resp.status_code == 200:
            resDict[key] = resp.json()['value']
        else:
            err = ('Get failed on {}, got HTTP response: ({}) - {}'.format(
                resource.name, resp.status_code, resp.text))
            exc.http_errors.append(HTTPError(err, request=req, response=resp))
            success = False
    if not success:
        raise exc
    return resDict

def get_bounding_box_request(

self, resource, method, content, url_prefix, token, resolution, id, bb_type)

Args:
    resource (intern.resource.boss.BossResource): Resource to perform operation on.
    method (string): HTTP verb such as 'GET'.
    content (string): HTTP Content-Type such as 'application/json'.
    url_prefix (string): protocol + initial portion of URL such as https://api.theboss.io Do not end with a forward slash.
    token (string): Django Rest Framework token for auth.
    resolution (int): 0 = default resolution.
    id (int): Annotation object id.
    bb_type (string): 'loose' | 'tight'.

Returns

    (requests.Request): A newly constructed Request object.

Raises

RuntimeError if url_prefix is None or an empty string.
def get_bounding_box_request(
        self, resource, method, content, url_prefix, token, resolution,
        id, bb_type):
    """
    Args:
        resource (intern.resource.boss.BossResource): Resource to perform operation on.
        method (string): HTTP verb such as 'GET'.
        content (string): HTTP Content-Type such as 'application/json'.
        url_prefix (string): protocol + initial portion of URL such as https://api.theboss.io  Do not end with a forward slash.
        token (string): Django Rest Framework token for auth.
        resolution (int): 0 = default resolution.
        id (int): Annotation object id.
        bb_type (string): 'loose' | 'tight'.
    Returns:
        (requests.Request): A newly constructed Request object.
    Raises:
        RuntimeError if url_prefix is None or an empty string.
    """
    if url_prefix is None or url_prefix == '':
        raise RuntimeError('url_prefix required.')
    url = (url_prefix + '/' + self.version + '/boundingbox/' +
           resource.get_cutout_route() + '/{}/{}/?type={}'.format(
        resolution, id, bb_type))
    headers = self.get_headers(content, token)
    return Request(method, url, headers=headers)

def get_cutout_request(

self, resource, method, content, url_prefix, token, resolution, x_range, y_range, z_range, time_range, numpyVolume=None, id_list=[], access_mode=None)

Create a request for working with cutouts (part of the Boss' volume service).

Args:
    resource (intern.resource.boss.BossResource): Resource to perform operation on.
    method (string): HTTP verb such as 'GET'.
    content (string): HTTP Content-Type such as 'application/json'.
    url_prefix (string): protocol + initial portion of URL such as https://api.theboss.io Do not end with a forward slash.
    token (string): Django Rest Framework token for auth.
    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 (list[int]): time range such as [30, 40] which means t>=30 and t<40.
    numpyVolume (optional numpy array): The data volume encoded in a numpy array.
    id_list (optional [list[int]]): list of object ids to filter the cutout by.
    access_mode (optional [Enum]): Identifies one of three cache access options:
cache = Will check both cache and for dirty keys
no_cache = Will skip cache check but check for dirty keys
raw = Will skip both the cache and dirty keys check

Returns

    (requests.Request): A newly constructed Request object.

Raises

RuntimeError if url_prefix is None or an empty string.
def get_cutout_request(
    self, resource, method, content, url_prefix, token,
    resolution, x_range, y_range, z_range, time_range,  numpyVolume=None, id_list=[], access_mode=None,):
    """Create a request for working with cutouts (part of the Boss' volume service).
    Args:
        resource (intern.resource.boss.BossResource): Resource to perform operation on.
        method (string): HTTP verb such as 'GET'.
        content (string): HTTP Content-Type such as 'application/json'.
        url_prefix (string): protocol + initial portion of URL such as https://api.theboss.io  Do not end with a forward slash.
        token (string): Django Rest Framework token for auth.
        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 (list[int]): time range such as [30, 40] which means t>=30 and t<40.
        numpyVolume (optional numpy array): The data volume encoded in a numpy array.
        id_list (optional [list[int]]): list of object ids to filter the cutout by.
        access_mode (optional [Enum]): Identifies one of three cache access options:
            cache = Will check both cache and for dirty keys
            no_cache = Will skip cache check but check for dirty keys
            raw = Will skip both the cache and dirty keys check
    Returns:
        (requests.Request): A newly constructed Request object.
    Raises:
        RuntimeError if url_prefix is None or an empty string.
    """
    url = self.build_cutout_url(
        resource, url_prefix, resolution, x_range, y_range, z_range,  time_range, id_list, access_mode)
    headers = self.get_headers(content, token)
    return Request(method, url, headers = headers, data = numpyVolume)

def get_group_maintainers_request(

self, method, content, url_prefix, token, group_name, user_name=None)

Get a request object for working with group maintainers.

Args:
    method (string): HTTP verb such as 'GET'.
    content (string): HTTP Content-Type such as 'application/json'.
    url_prefix (string): protocol + initial portion of URL such as https://api.theboss.io Do not end with a forward slash.
    token (string): Django Rest Framework token for auth.
    group_name (string): Name of group.
    user_name (optional[string]): Provide a user name if not doing a list operation. Defaults to None.

Returns

    (requests.Request): A newly constructed Request object.

Raises

RuntimeError if url_prefix is None or an empty string.
def get_group_maintainers_request(
    self, method, content, url_prefix, token, group_name, user_name=None):
    """Get a request object for working with group maintainers.
    Args:
        method (string): HTTP verb such as 'GET'.
        content (string): HTTP Content-Type such as 'application/json'.
        url_prefix (string): protocol + initial portion of URL such as https://api.theboss.io  Do not end with a forward slash.
        token (string): Django Rest Framework token for auth.
        group_name (string): Name of group.
        user_name (optional[string]): Provide a user name if not doing a list operation.  Defaults to None.
    Returns:
        (requests.Request): A newly constructed Request object.
    Raises:
        RuntimeError if url_prefix is None or an empty string.
    """
    if url_prefix is None or url_prefix == '':
        raise RuntimeError('url_prefix required.')
    url = url_prefix + '/' + self.version + '/groups/' + group_name + '/maintainers/'
    if user_name is not None:
        url += user_name
    headers = self.get_headers(content, token)
    return Request(method, url, headers = headers)

def get_group_members_request(

self, method, content, url_prefix, token, group_name, user_name=None)

Get a request object for working with group membership.

Args:
    method (string): HTTP verb such as 'GET'.
    content (string): HTTP Content-Type such as 'application/json'.
    url_prefix (string): protocol + initial portion of URL such as https://api.theboss.io Do not end with a forward slash.
    token (string): Django Rest Framework token for auth.
    group_name (string): Name of group.
    user_name (optional[string]): Provide a user name if not doing a list operation. Defaults to None.

Returns

    (requests.Request): A newly constructed Request object.

Raises

RuntimeError if url_prefix is None or an empty string.
def get_group_members_request(
    self, method, content, url_prefix, token, group_name, user_name=None):
    """Get a request object for working with group membership.
    Args:
        method (string): HTTP verb such as 'GET'.
        content (string): HTTP Content-Type such as 'application/json'.
        url_prefix (string): protocol + initial portion of URL such as https://api.theboss.io  Do not end with a forward slash.
        token (string): Django Rest Framework token for auth.
        group_name (string): Name of group.
        user_name (optional[string]): Provide a user name if not doing a list operation.  Defaults to None.
    Returns:
        (requests.Request): A newly constructed Request object.
    Raises:
        RuntimeError if url_prefix is None or an empty string.
    """
    if url_prefix is None or url_prefix == '':
        raise RuntimeError('url_prefix required.')
    url = url_prefix + '/' + self.version + '/groups/' + group_name + '/members/'
    if user_name is not None:
        url += user_name
    headers = self.get_headers(content, token)
    return Request(method, url, headers = headers)

def get_group_request(

self, method, content, url_prefix, token, name=None)

Get a request for getting group information.

Args:
    method (string): HTTP verb such as 'GET'.
    content (string): HTTP Content-Type such as 'application/json'.
    url_prefix (string): protocol + initial portion of URL such as https://api.theboss.io Do not end with a forward slash.
    token (string): Django Rest Framework token for auth.
    name (optional[string|None]): Name of group. Defaults to None.

Returns

    (requests.Request): A newly constructed Request object.

Raises

RuntimeError if url_prefix is None or an empty string.
def get_group_request(self, method, content, url_prefix, token, name=None):
    """Get a request for getting group information.
    Args:
        method (string): HTTP verb such as 'GET'.
        content (string): HTTP Content-Type such as 'application/json'.
        url_prefix (string): protocol + initial portion of URL such as https://api.theboss.io  Do not end with a forward slash.
        token (string): Django Rest Framework token for auth.
        name (optional[string|None]): Name of group.  Defaults to None.
    Returns:
        (requests.Request): A newly constructed Request object.
    Raises:
        RuntimeError if url_prefix is None or an empty string.
    """
    if url_prefix is None or url_prefix == '':
        raise RuntimeError('url_prefix required.')
    url = url_prefix + '/' + self.version + '/groups/'
    if name is not None:
        url += name + '/'
    headers = self.get_headers(content, token)
    return Request(method, url, headers = headers)

def get_headers(

self, content_type, token)

Get headers to place in Request object.

The auth token is added to the header for authenthication and
authorization.

Args:
    content_type (string): HTTP content type of request.
    token (string): Django Rest Framework token.

Returns

    (dictionary): Use as headers argument to the Request object.

def get_headers(self, content_type, token):
    """Get headers to place in Request object.
    The auth token is added to the header for authenthication and
    authorization.
    Args:
        content_type (string):  HTTP content type of request.
        token (string):  Django Rest Framework token.
    Returns:
        (dictionary): Use as headers argument to the Request object.
    """
    return {
        'Authorization': 'Token ' + token,
        'Content-Type': content_type
    }

def get_ids_request(

self, resource, method, content, url_prefix, token, resolution, x_range, y_range, z_range, time_range)

Create a request for getting ids in a region (part of the Boss' volume service).

Args:
    resource (intern.resource.boss.BossResource): Resource to perform operation on.
    method (string): HTTP verb such as 'GET'.
    content (string): HTTP Content-Type such as 'application/json'.
    url_prefix (string): protocol + initial portion of URL such as https://api.theboss.io Do not end with a forward slash.
    token (string): Django Rest Framework token for auth.
    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 (list[int]): time range such as [30, 40] which means t>=30 and t<40.

Returns

    (requests.Request): A newly constructed Request object.

Raises

RuntimeError if url_prefix is None or an empty string.
def get_ids_request(
        self, resource, method, content, url_prefix, token,
        resolution, x_range, y_range, z_range, time_range):
    """Create a request for getting ids in a region (part of the Boss' volume service).
    Args:
        resource (intern.resource.boss.BossResource): Resource to perform operation on.
        method (string): HTTP verb such as 'GET'.
        content (string): HTTP Content-Type such as 'application/json'.
        url_prefix (string): protocol + initial portion of URL such as https://api.theboss.io  Do not end with a forward slash.
        token (string): Django Rest Framework token for auth.
        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 (list[int]): time range such as [30, 40] which means t>=30 and t<40.
    Returns:
        (requests.Request): A newly constructed Request object.
    Raises:
        RuntimeError if url_prefix is None or an empty string.
    """
    url = self.build_ids_url(
        resource, url_prefix, resolution, x_range, y_range, z_range, time_range)
    headers = self.get_headers(content, token)
    return Request(method, url, headers=headers)

def get_metadata_request(

self, resource, method, content, url_prefix, token, key=None, value=None)

Create a request for accessing the Boss' metadata service.

Do not use this method for list operations. Instead, use the
get_request() method.

Args:
    resource (intern.resource.boss.BossResource): Resource to perform operation on.
    method (string): HTTP verb such as 'GET'.
    content (string): HTTP Content-Type such as 'application/json'.
    url_prefix (string): protocol + initial portion of URL such as https://api.theboss.io Do not end with a forward slash.
    token (string): Django Rest Framework token for auth.
    key (string): Name of key to operate on. Defaults to None.
    value (string): Value to assign to key Defaults to None.

Returns

    (requests.Request): A newly constructed Request object.

Raises

RuntimeError if url_prefix is None or an empty string.
def get_metadata_request(
    self, resource, method, content, url_prefix, token,
    key=None, value=None):
    """Create a request for accessing the Boss' metadata service.
    Do not use this method for list operations.  Instead, use the
    get_request() method.
    Args:
        resource (intern.resource.boss.BossResource): Resource to perform operation on.
        method (string): HTTP verb such as 'GET'.
        content (string): HTTP Content-Type such as 'application/json'.
        url_prefix (string): protocol + initial portion of URL such as https://api.theboss.io  Do not end with a forward slash.
        token (string): Django Rest Framework token for auth.
        key (string): Name of key to operate on.  Defaults to None.
        value (string): Value to assign to key  Defaults to None.
    Returns:
        (requests.Request): A newly constructed Request object.
    Raises:
        RuntimeError if url_prefix is None or an empty string.
    """
    url = self.build_metadata_url(resource, url_prefix, key, value)
    headers = self.get_headers(content, token)
    return Request(method, url, headers = headers)

def get_permission_request(

self, method, content, url_prefix, token, query_params=None, post_data=None)

Generate a request for manipulating permissions of a data model object.

Manipulate what members of the named group can do with the given data
model object.

Args:
    method (string): HTTP verb such as 'GET'.
    content (string): HTTP Content-Type such as 'application/json'.
    url_prefix (string): protocol + initial portion of URL such as https://api.theboss.io Do not end with a forward slash.
    token (string): Django Rest Framework token for auth.
    query_params (dict): Query params for GET requests. Defaults to None.
    post_data (dict): POST body data. Defaults to None.

Returns

    (requests.Request): A newly constructed Request object.

Raises

RuntimeError if url_prefix is None or an empty string.
def get_permission_request(self, method, content, url_prefix, token, query_params=None, post_data=None):
    """Generate a request for manipulating permissions of a data model object.
    Manipulate what members of the named group can do with the given data
    model object.
    Args:
        method (string): HTTP verb such as 'GET'.
        content (string): HTTP Content-Type such as 'application/json'.
        url_prefix (string): protocol + initial portion of URL such as https://api.theboss.io  Do not end with a forward slash.
        token (string): Django Rest Framework token for auth.
        query_params (dict): Query params for GET requests.  Defaults to None.
        post_data (dict): POST body data.  Defaults to None.
    Returns:
        (requests.Request): A newly constructed Request object.
    Raises:
        RuntimeError if url_prefix is None or an empty string.
    """
    if url_prefix is None or url_prefix == '':
        raise RuntimeError('url_prefix required.')
    url = (url_prefix + '/' + self.version + '/permissions/')
    headers = self.get_headers(content, token)
    if method == "GET" or method == "DELETE":
        return Request(method, url, headers=headers, params=query_params)
    else:
        # Assuming POST or PATCH
        return Request(method, url, headers=headers, json=post_data)

def get_request(

self, resource, method, content, url_prefix, token, proj_list_req=False, json=None, data=None)

Create a request for accessing the Boss' data model services.

Use for the project service or listing keys via the metadata service.

Args:
    resource (intern.resource.boss.BossResource): Resource to perform operation on.
    method (string): HTTP verb such as 'GET'.
    content (string): HTTP Content-Type such as 'application/json'.
    url_prefix (string): protocol + initial portion of URL such as https://api.theboss.io Do not end with a forward slash.
    token (string): Django Rest Framework token for auth.
    proj_list_req (bool): Set to True if performing a list operation on the project service. Defaults to False.
    json (dict): POST body data. Defaults to None.
    data (): Raw data. Defaults to None.

Returns

    (requests.Request): A newly constructed Request object.

Raises

RuntimeError if url_prefix is None or an empty string.
def get_request(self, resource, method, content, url_prefix, token, proj_list_req=False, json=None, data=None):
    """Create a request for accessing the Boss' data model services.
    Use for the project service or listing keys via the metadata service.
    Args:
        resource (intern.resource.boss.BossResource): Resource to perform operation on.
        method (string): HTTP verb such as 'GET'.
        content (string): HTTP Content-Type such as 'application/json'.
        url_prefix (string): protocol + initial portion of URL such as https://api.theboss.io  Do not end with a forward slash.
        token (string): Django Rest Framework token for auth.
        proj_list_req (bool): Set to True if performing a list operation on the project service.  Defaults to False.
        json (dict): POST body data.  Defaults to None.
        data (): Raw data.  Defaults to None.
    Returns:
        (requests.Request): A newly constructed Request object.
    Raises:
        RuntimeError if url_prefix is None or an empty string.
    """
    if isinstance(resource, CoordinateFrameResource):
        service = 'coord'
    else:
        service = 'collection'
    if proj_list_req:
        req_type = 'list'
    else:
        req_type = 'normal'
    url = self.build_url(resource, url_prefix, service, req_type)
    headers = self.get_headers(content, token)
    req = Request(method, url, headers = headers, json = json, data = data)
    return req

def get_reserve_request(

self, resource, method, content, url_prefix, token, num_ids)

Args:
    resource (intern.resource.boss.BossResource): Resource to perform operation on.
    method (string): HTTP verb such as 'GET'.
    content (string): HTTP Content-Type such as 'application/json'.
    url_prefix (string): protocol + initial portion of URL such as https://api.theboss.io Do not end with a forward slash.
    token (string): Django Rest Framework token for auth.
    num_ids (int): Number of ids to reserve.

Returns

    (requests.Request): A newly constructed Request object.

Raises

RuntimeError if url_prefix is None or an empty string.
def get_reserve_request(
        self, resource, method, content, url_prefix, token, num_ids):
    """
    Args:
        resource (intern.resource.boss.BossResource): Resource to perform operation on.
        method (string): HTTP verb such as 'GET'.
        content (string): HTTP Content-Type such as 'application/json'.
        url_prefix (string): protocol + initial portion of URL such as https://api.theboss.io  Do not end with a forward slash.
        token (string): Django Rest Framework token for auth.
        num_ids (int): Number of ids to reserve.
    Returns:
        (requests.Request): A newly constructed Request object.
    Raises:
        RuntimeError if url_prefix is None or an empty string.
    """
    if url_prefix is None or url_prefix == '':
        raise RuntimeError('url_prefix required.')
    url = (url_prefix + '/' + self.version + '/reserve/' +
           resource.get_reserve_route() + '/{}'.format(num_ids))
    headers = self.get_headers(content, token)
    return Request(method, url, headers=headers)

def get_user_request(

self, method, content, url_prefix, token, user, first_name=None, last_name=None, email=None, password=None)

Generate a request for working with the /sso endpoint.

Args:
    method (string): HTTP verb such as 'GET'.
    content (string): HTTP Content-Type such as 'application/json'.
    url_prefix (string): protocol + initial portion of URL such as https://api.theboss.io Do not end with a forward slash.
    token (string): Django Rest Framework token for auth.
    user (string): Name of user.
    first_name (optional[string]): User's first name. Defaults to None.
    last_name (optional[string]): User's last name. Defaults to None.
    email: (optional[string]): User's email address. Defaults to None.
    password: (optional[string]): User's password. Defaults to None.

Returns

    (requests.Request): A newly constructed Request object.

Raises

RuntimeError if url_prefix is None or an empty string.
def get_user_request(
    self, method, content, url_prefix, token, user, first_name=None,
    last_name=None, email=None, password=None):
    """Generate a request for working with the /sso endpoint.
    Args:
        method (string): HTTP verb such as 'GET'.
        content (string): HTTP Content-Type such as 'application/json'.
        url_prefix (string): protocol + initial portion of URL such as https://api.theboss.io  Do not end with a forward slash.
        token (string): Django Rest Framework token for auth.
        user (string): Name of user.
        first_name (optional[string]): User's first name.  Defaults to None.
        last_name (optional[string]): User's last name.  Defaults to None.
        email: (optional[string]): User's email address.  Defaults to None.
        password: (optional[string]): User's password.  Defaults to None.
    Returns:
        (requests.Request): A newly constructed Request object.
    Raises:
        RuntimeError if url_prefix is None or an empty string.
    """
    if url_prefix is None or url_prefix == '':
        raise RuntimeError('url_prefix required.')
    data = {}
    url = url_prefix + '/' + self.version + '/sso/user/' + user
    if first_name is not None:
        data['first_name'] = first_name
    if last_name is not None:
        data['last_name'] = last_name
    if email is not None:
        data['email'] = email
    if password is not None:
        data['password'] = password
    headers = self.get_headers(content, token)
    return Request(method, url, headers=headers, json=data)

def get_user_role_request(

self, method, content, url_prefix, token, user, role=None)

Generate a request for manipulating roles for a user.

Args:
    method (string): HTTP verb such as 'GET'.
    content (string): HTTP Content-Type such as 'application/json'.
    url_prefix (string): protocol + initial portion of URL such as https://api.theboss.io Do not end with a forward slash.
    token (string): Django Rest Framework token for auth.
    user (string): Name of user.
    role (optional[string]): Name of role. Defaults to None.

Returns

    (requests.Request): A newly constructed Request object.

Raises

RuntimeError if url_prefix is None or an empty string.
def get_user_role_request(
    self, method, content, url_prefix, token, user, role=None):
    """Generate a request for manipulating roles for a user.
    Args:
        method (string): HTTP verb such as 'GET'.
        content (string): HTTP Content-Type such as 'application/json'.
        url_prefix (string): protocol + initial portion of URL such as https://api.theboss.io  Do not end with a forward slash.
        token (string): Django Rest Framework token for auth.
        user (string): Name of user.
        role (optional[string]): Name of role.  Defaults to None.
    Returns:
        (requests.Request): A newly constructed Request object.
    Raises:
        RuntimeError if url_prefix is None or an empty string.
    """
    if url_prefix is None or url_prefix == '':
        raise RuntimeError('url_prefix required.')
    url = url_prefix + '/' + self.version + '/sso/user-role/' + user
    if role is not None:
        url = url + '/' + role
    headers = self.get_headers(content, token)
    return Request(method, url, headers=headers)

def list(

self, resource, url_prefix, auth, session, send_opts)

List metadata keys associated with the given resource.

Args:
    resource (intern.resource.boss.BossResource): List keys associated with this resource.
    url_prefix (string): Protocol + host such as https://api.theboss.io
    auth (string): Token to send in the request header.
    session (requests.Session): HTTP session to use for request.
    send_opts (dictionary): Additional arguments to pass to session.send().

Returns

    (list): List of key names.

Raises

requests.HTTPError on failure.
def list(self, resource, url_prefix, auth, session, send_opts):
    """List metadata keys associated with the given resource.
    Args:
        resource (intern.resource.boss.BossResource): List keys associated with this resource.
        url_prefix (string): Protocol + host such as https://api.theboss.io
        auth (string): Token to send in the request header.
        session (requests.Session): HTTP session to use for request.
        send_opts (dictionary): Additional arguments to pass to session.send().
    Returns:
        (list): List of key names.
    Raises:
        requests.HTTPError on failure.
    """
    req = self.get_metadata_request(
        resource, 'GET', 'application/json', url_prefix, auth)
    prep = session.prepare_request(req)
    resp = session.send(prep, **send_opts)
    if resp.status_code == 200:
        keys_dict = resp.json()
        return keys_dict['keys']
    err = ('List failed on {}, got HTTP response: ({}) - {}'.format(
        resource.name, resp.status_code, resp.text))
    raise HTTPError(err, request = req, response = resp)

def update(

self, resource, keys_vals, url_prefix, auth, session, send_opts)

Update the given key-value pairs for the given resource.

Keys must already exist before they may be updated. Will attempt to
update all key-value pairs even if a failure is encountered.

Args:
    resource (intern.resource.boss.BossResource): Update values associated with this resource.
    keys_vals (dictionary): The metadata to update for the resource.
    url_prefix (string): Protocol + host such as https://api.theboss.io
    auth (string): Token to send in the request header.
    session (requests.Session): HTTP session to use for request.
    send_opts (dictionary): Additional arguments to pass to session.send().

Raises

HTTPErrorList on failure.
def update(self, resource, keys_vals, url_prefix, auth, session, send_opts):
    """Update the given key-value pairs for the given resource.
    Keys must already exist before they may be updated.  Will attempt to
    update all key-value pairs even if a failure is encountered.
    Args:
        resource (intern.resource.boss.BossResource): Update values associated with this resource.
        keys_vals (dictionary): The metadata to update for the resource.
        url_prefix (string): Protocol + host such as https://api.theboss.io
        auth (string): Token to send in the request header.
        session (requests.Session): HTTP session to use for request.
        send_opts (dictionary): Additional arguments to pass to session.send().
    Raises:
        HTTPErrorList on failure.
    """
    success = True
    exc = HTTPErrorList('At least one key-value update failed.')
    for pair in keys_vals.items():
        key = pair[0]
        value = pair[1]
        req = self.get_metadata_request(
            resource, 'PUT', 'application/json', url_prefix, auth,
            key, value)
        prep = session.prepare_request(req)
        resp = session.send(prep, **send_opts)
        if resp.status_code == 200:
            continue
        err = (
            'Update failed for {}: {}:{}, got HTTP response: ({}) - {}'
            .format(resource.name, key, value, resp.status_code, resp.text))
        exc.http_errors.append(HTTPError(err, request=req, response=resp))
        success = False
    if not success:
        raise exc