def bgr2gray(img, keepdim=False):
    """Convert a BGR image to grayscale image.

    Args:
        img (ndarray): The input image.
        keepdim (bool): If False (by default), then return the grayscale image
            with 2 dims, otherwise 3 dims.

    Returns:
        ndarray: The converted grayscale image.
    """
    out_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    if keepdim:
        out_img = out_img[..., None]
    return out_img

def bgr2gray ( img , keepdim = False ) : out_img = cv2 . cvtColor ( img , cv2 . COLOR_BGR2GRAY ) if keepdim : out_img = out_img [ ... , None ] return out_img

Convert a BGR image to grayscale image .


def gray2bgr(img):
    """Convert a grayscale image to BGR image.

    Args:
        img (ndarray or str): The input image.

    Returns:
        ndarray: The converted BGR image.
    """
    img = img[..., None] if img.ndim == 2 else img
    out_img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
    return out_img

def gray2bgr ( img ) : img = img [ ... , None ] if img . ndim == 2 else img out_img = cv2 . cvtColor ( img , cv2 . COLOR_GRAY2BGR ) return out_img

Convert a grayscale image to BGR image .


def iter_cast(inputs, dst_type, return_type=None):
    """Cast elements of an iterable object into some type.

    Args:
        inputs (Iterable): The input object.
        dst_type (type): Destination type.
        return_type (type, optional): If specified, the output object will be
            converted to this type, otherwise an iterator.

    Returns:
        iterator or specified type: The converted object.
    """
    if not isinstance(inputs, collections_abc.Iterable):
        raise TypeError('inputs must be an iterable object')
    if not isinstance(dst_type, type):
        raise TypeError('"dst_type" must be a valid type')

    out_iterable = six.moves.map(dst_type, inputs)

    if return_type is None:
        return out_iterable
    else:
        return return_type(out_iterable)

def
iter_cast
(
inputs
,
dst_type
,
return_type
=
)
:
if
not
isinstance
(
inputs
,
collections_abc
.
Iterable
)
:
raise
TypeError
(
'inputs must be an iterable object'
)
if
not
isinstance
(
dst_type
,
type
)
:
raise
TypeError
(
'"dst_type" must be a valid type'
)
out_iterable
=
six
.
moves
.
map
(
dst_type
,
inputs
)
if
return_type
is
:
return
out_iterable
else
:
return
return_type
(
out_iterable
)

Cast elements of an iterable object into some type .


def is_seq_of(seq, expected_type, seq_type=None):
    """Check whether it is a sequence of some type.

    Args:
        seq (Sequence): The sequence to be checked.
        expected_type (type): Expected type of sequence items.
        seq_type (type, optional): Expected sequence type.

    Returns:
        bool: Whether the sequence is valid.
    """
    if seq_type is None:
        exp_seq_type = collections_abc.Sequence
    else:
        assert isinstance(seq_type, type)
        exp_seq_type = seq_type
    if not isinstance(seq, exp_seq_type):
        return False
    for item in seq:
        if not isinstance(item, expected_type):
            return False
    return True

def is_seq_of ( seq , expected_type , seq_type = None ) : if seq_type is None : exp_seq_type = collections_abc . Sequence else : assert isinstance ( seq_type , type ) exp_seq_type = seq_type if not isinstance ( seq , exp_seq_type ) : return False for item in seq : if not isinstance ( item , expected_type ) : return False return True

Check whether it is a sequence of some type .


def slice_list(in_list, lens):
    """Slice a list into several sub lists by a list of given length.

    Args:
        in_list (list): The list to be sliced.
        lens(int or list): The expected length of each out list.

    Returns:
        list: A list of sliced list.
    """
    if not isinstance(lens, list):
        raise TypeError('"indices" must be a list of integers')
    elif sum(lens) != len(in_list):
        raise ValueError(
            'sum of lens and list length does not match: {} != {}'.format(
                sum(lens), len(in_list)))
    out_list = []
    idx = 0
    for i in range(len(lens)):
        out_list.append(in_list[idx:idx + lens[i]])
        idx += lens[i]
    return out_list

Slice a list into several sub lists by a list of given length .


def check_prerequisites(
        prerequisites,
        checker,
        msg_tmpl='Prerequisites "{}" are required in method "{}" but not '
        'found, please install them first.'):
    """A decorator factory to check if prerequisites are satisfied.

    Args:
        prerequisites (str of list[str]): Prerequisites to be checked.
        checker (callable): The checker method that returns True if a
            prerequisite is meet, False otherwise.
        msg_tmpl (str): The message template with two variables.

    Returns:
        decorator: A specific decorator.
    """

    def wrap(func):

        @functools.wraps(func)
        def wrapped_func(*args, **kwargs):
            requirements = [prerequisites] if isinstance(
                prerequisites, str) else prerequisites
            missing = []
            for item in requirements:
                if not checker(item):
                    missing.append(item)
            if missing:
                print(msg_tmpl.format(', '.join(missing), func.__name__))
                raise RuntimeError('Prerequisites not meet.')
            else:
                return func(*args, **kwargs)

        return wrapped_func

    return wrap

A decorator factory to check if prerequisites are satisfied .


def average(self, n=0):
        """Average latest n values or all values"""
        assert n >= 0
        for key in self.val_history:
            values = np.array(self.val_history[key][-n:])
            nums = np.array(self.n_history[key][-n:])
            avg = np.sum(values * nums) / np.sum(nums)
            self.output[key] = avg
        self.ready = True

def average ( self , n = 0 ) : assert n >= 0 for key in self . val_history : values = np . array ( self . val_history [ key ] [ - n : ] ) nums = np . array ( self . n_history [ key ] [ - n : ] ) avg = np . sum ( values * nums ) / np . sum ( nums ) self . output [ key ] = avg self . ready = True


def scatter(input, devices, streams=None):
    """Scatters tensor across multiple GPUs.
    """
    if streams is None:
        streams = [None] * len(devices)

    if isinstance(input, list):
        chunk_size = (len(input) - 1) // len(devices) + 1
        outputs = [
            scatter(input[i], [devices[i // chunk_size]],
                    [streams[i // chunk_size]]) for i in range(len(input))
        ]
        return outputs
    elif isinstance(input, torch.Tensor):
        output = input.contiguous()
        # TODO: copy to a pinned buffer first (if copying from CPU)
        stream = streams[0] if output.numel() > 0 else None
        with torch.cuda.device(devices[0]), torch.cuda.stream(stream):
            output = output.cuda(devices[0], non_blocking=True)
        return output
    else:
        raise Exception('Unknown type {}.'.format(type(input)))

def
scatter
(
input
,
devices
,
streams
=
)
:
if
streams
is
:
streams
=
[
]
*
len
(
devices
)
if
isinstance
(
input
,
list
)
:
chunk_size
=
(
len
(
input
)
1
)
//
len
(
devices
)
+
1
outputs
=
[
scatter
(
input
[
i
]
,
[
devices
[
i
//
chunk_size
]
]
,
[
streams
[
i
//
chunk_size
]
]
)
for
i
in
range
(
len
(
input
)
)
]
return
outputs
elif
isinstance
(
input
,
torch
.
Tensor
)
:
output
=
input
.
contiguous
(
)
stream
=
streams
[
0
]
if
output
.
numel
(
)
>
0
else
with
torch
.
cuda
.
device
(
devices
[
0
]
)
,
torch
.
cuda
.
stream
(
stream
)
:
output
=
output
.
cuda
(
devices
[
0
]
,
non_blocking
=
True
)
return
output
else
:
raise
Exception
(
'Unknown type {}.'
.
format
(
type
(
input
)
)
)


def color_val(color):
    """Convert various input to color tuples.

    Args:
        color (:obj:`Color`/str/tuple/int/ndarray): Color inputs

    Returns:
        tuple[int]: A tuple of 3 integers indicating BGR channels.
    """
    if is_str(color):
        return Color[color].value
    elif isinstance(color, Color):
        return color.value
    elif isinstance(color, tuple):
        assert len(color) == 3
        for channel in color:
            assert channel >= 0 and channel <= 255
        return color
    elif isinstance(color, int):
        assert color >= 0 and color <= 255
        return color, color, color
    elif isinstance(color, np.ndarray):
        assert color.ndim == 1 and color.size == 3
        assert np.all((color >= 0) & (color <= 255))
        color = color.astype(np.uint8)
        return tuple(color)
    else:
        raise TypeError('Invalid type for color: {}'.format(type(color)))

def
color_val
(
color
)
:
if
is_str
(
color
)
:
return
Color
[
color
]
.
value
elif
isinstance
(
color
,
Color
)
:
return
color
.
value
elif
isinstance
(
color
,
tuple
)
:
assert
len
(
color
)
==
3
for
channel
in
color
:
assert
channel
>=
0
and
channel
<=
255
return
color
elif
isinstance
(
color
,
int
)
:
assert
color
>=
0
and
color
<=
255
return
color
,
color
,
color
elif
isinstance
(
color
,
np
.
ndarray
)
:
assert
color
.
ndim
==
1
and
color
.
size
==
3
assert
np
.
all
(
(
color
>=
0
)
&
(
color
<=
255
)
)
color
=
color
.
astype
(
np
.
uint8
)
return
tuple
(
color
)
else
:
raise
TypeError
(
'Invalid type for color: {}'
.
format
(
type
(
color
)
)
)


def check_time(timer_id):
    """Add check points in a single line.

    This method is suitable for running a task on a list of items. A timer will
    be registered when the method is called for the first time.

    :Example:

    >>> import time
    >>> import mmcv
    >>> for i in range(1, 6):
    >>>     # simulate a code block
    >>>     time.sleep(i)
    >>>     mmcv.check_time('task1')
    2.000
    3.000
    4.000
    5.000

    Args:
        timer_id (str): Timer identifier.
    """
    if timer_id not in _g_timers:
        _g_timers[timer_id] = Timer()
        return 0
    else:
        return _g_timers[timer_id].since_last_check()

def check_time ( timer_id ) : if timer_id not in _g_timers : _g_timers [ timer_id ] = Timer ( ) return 0 else : return _g_timers [ timer_id ] . since_last_check ( )


def start(self):
        """Start the timer."""
        if not self._is_running:
            self._t_start = time()
            self._is_running = True
        self._t_last = time()

def start ( self ) : if not self . _is_running : self . _t_start = time ( ) self . _is_running = True self . _t_last = time ( )


def since_start(self):
        """Total time since the timer is started.

        Returns (float): Time in seconds.
        """
        if not self._is_running:
            raise TimerError('timer is not running')
        self._t_last = time()
        return self._t_last - self._t_start

def
since_start
(
self
)
:
if
not
self
.
_is_running
:
raise
TimerError
(
'timer is not running'
)
self
.
_t_last
=
time
(
)
return
self
.
_t_last
self
.
_t_start


def since_last_check(self):
        """Time since the last checking.

        Either :func:`since_start` or :func:`since_last_check` is a checking
        operation.

        Returns (float): Time in seconds.
        """
        if not self._is_running:
            raise TimerError('timer is not running')
        dur = time() - self._t_last
        self._t_last = time()
        return dur

def
since_last_check
(
self
)
:
if
not
self
.
_is_running
:
raise
TimerError
(
'timer is not running'
)
dur
=
time
(
)
self
.
_t_last
self
.
_t_last
=
time
(
)
return
dur


def flowshow(flow, win_name='', wait_time=0):
    """Show optical flow.

    Args:
        flow (ndarray or str): The optical flow to be displayed.
        win_name (str): The window name.
        wait_time (int): Value of waitKey param.
    """
    flow = flowread(flow)
    flow_img = flow2rgb(flow)
    imshow(rgb2bgr(flow_img), win_name, wait_time)

def flowshow ( flow , win_name = '' , wait_time = 0 ) : flow = flowread ( flow ) flow_img = flow2rgb ( flow ) imshow ( rgb2bgr ( flow_img ) , win_name , wait_time )


def flow2rgb(flow, color_wheel=None, unknown_thr=1e6):
    """Convert flow map to RGB image.

    Args:
        flow (ndarray): Array of optical flow.
        color_wheel (ndarray or None): Color wheel used to map flow field to
            RGB colorspace. Default color wheel will be used if not specified.
        unknown_thr (str): Values above this threshold will be marked as
            unknown and thus ignored.

    Returns:
        ndarray: RGB image that can be visualized.
    """
    assert flow.ndim == 3 and flow.shape[-1] == 2
    if color_wheel is None:
        color_wheel = make_color_wheel()
    assert color_wheel.ndim == 2 and color_wheel.shape[1] == 3
    num_bins = color_wheel.shape[0]

    dx = flow[:, :, 0].copy()
    dy = flow[:, :, 1].copy()

    ignore_inds = (np.isnan(dx) | np.isnan(dy) | (np.abs(dx) > unknown_thr) |
                   (np.abs(dy) > unknown_thr))
    dx[ignore_inds] = 0
    dy[ignore_inds] = 0

    rad = np.sqrt(dx**2 + dy**2)
    if np.any(rad > np.finfo(float).eps):
        max_rad = np.max(rad)
        dx /= max_rad
        dy /= max_rad

    [h, w] = dx.shape

    rad = np.sqrt(dx**2 + dy**2)
    angle = np.arctan2(-dy, -dx) / np.pi

    bin_real = (angle + 1) / 2 * (num_bins - 1)
    bin_left = np.floor(bin_real).astype(int)
    bin_right = (bin_left + 1) % num_bins
    w = (bin_real - bin_left.astype(np.float32))[..., None]
    flow_img = (
        1 - w) * color_wheel[bin_left, :] + w * color_wheel[bin_right, :]
    small_ind = rad <= 1
    flow_img[small_ind] = 1 - rad[small_ind, None] * (1 - flow_img[small_ind])
    flow_img[np.logical_not(small_ind)] *= 0.75

    flow_img[ignore_inds, :] = 0

    return flow_img

def flow2rgb ( flow , color_wheel = None , unknown_thr = 1e6 ) : assert flow . ndim == 3 and flow . shape [ - 1 ] == 2 if color_wheel is None : color_wheel = make_color_wheel ( ) assert color_wheel . ndim == 2 and color_wheel . shape [ 1 ] == 3 num_bins = color_wheel . shape [ 0 ] dx = flow [ : , : , 0 ] . copy ( ) dy = flow [ : , : , 1 ] . copy ( ) ignore_inds = ( np . isnan ( dx ) | np . isnan ( dy ) | ( np . abs ( dx ) > unknown_thr ) | ( np . abs ( dy ) > unknown_thr ) ) dx [ ignore_inds ] = 0 dy [ ignore_inds ] = 0 rad = np . sqrt ( dx ** 2 + dy ** 2 ) if np . any ( rad > np . finfo ( float ) . eps ) : max_rad = np . max ( rad ) dx /= max_rad dy /= max_rad [ h , w ] = dx . shape rad = np . sqrt ( dx ** 2 + dy ** 2 ) angle = np . arctan2 ( - dy , - dx ) / np . pi bin_real = ( angle + 1 ) / 2 * ( num_bins - 1 ) bin_left = np . floor ( bin_real ) . astype ( int ) bin_right = ( bin_left + 1 ) % num_bins w = ( bin_real - bin_left . astype ( np . float32 ) ) [ ... , None ] flow_img = ( 1 - w ) * color_wheel [ bin_left , : ] + w * color_wheel [ bin_right , : ] small_ind = rad <= 1 flow_img [ small_ind ] = 1 - rad [ small_ind , None ] * ( 1 - flow_img [ small_ind ] ) flow_img [ np . logical_not ( small_ind ) ] *= 0.75 flow_img [ ignore_inds , : ] = 0 return flow_img


def make_color_wheel(bins=None):
    """Build a color wheel.

    Args:
        bins(list or tuple, optional): Specify the number of bins for each
            color range, corresponding to six ranges: red -> yellow,
            yellow -> green, green -> cyan, cyan -> blue, blue -> magenta,
            magenta -> red. [15, 6, 4, 11, 13, 6] is used for default
            (see Middlebury).

    Returns:
        ndarray: Color wheel of shape (total_bins, 3).
    """
    if bins is None:
        bins = [15, 6, 4, 11, 13, 6]
    assert len(bins) == 6

    RY, YG, GC, CB, BM, MR = tuple(bins)

    ry = [1, np.arange(RY) / RY, 0]
    yg = [1 - np.arange(YG) / YG, 1, 0]
    gc = [0, 1, np.arange(GC) / GC]
    cb = [0, 1 - np.arange(CB) / CB, 1]
    bm = [np.arange(BM) / BM, 0, 1]
    mr = [1, 0, 1 - np.arange(MR) / MR]

    num_bins = RY + YG + GC + CB + BM + MR

    color_wheel = np.zeros((3, num_bins), dtype=np.float32)

    col = 0
    for i, color in enumerate([ry, yg, gc, cb, bm, mr]):
        for j in range(3):
            color_wheel[j, col:col + bins[i]] = color[j]
        col += bins[i]

    return color_wheel.T

def make_color_wheel ( bins = None ) : if bins is None : bins = [ 15 , 6 , 4 , 11 , 13 , 6 ] assert len ( bins ) == 6 RY , YG , GC , CB , BM , MR = tuple ( bins ) ry = [ 1 , np . arange ( RY ) / RY , 0 ] yg = [ 1 - np . arange ( YG ) / YG , 1 , 0 ] gc = [ 0 , 1 , np . arange ( GC ) / GC ] cb = [ 0 , 1 - np . arange ( CB ) / CB , 1 ] bm = [ np . arange ( BM ) / BM , 0 , 1 ] mr = [ 1 , 0 , 1 - np . arange ( MR ) / MR ] num_bins = RY + YG + GC + CB + BM + MR color_wheel = np . zeros ( ( 3 , num_bins ) , dtype = np . float32 ) col = 0 for i , color in enumerate ( [ ry , yg , gc , cb , bm , mr ] ) : for j in range ( 3 ) : color_wheel [ j , col : col + bins [ i ] ] = color [ j ] col += bins [ i ] return color_wheel . T


def accuracy(output, target, topk=(1, )):
    """Computes the precision@k for the specified values of k"""
    with torch.no_grad():
        maxk = max(topk)
        batch_size = target.size(0)

        _, pred = output.topk(maxk, 1, True, True)
        pred = pred.t()
        correct = pred.eq(target.view(1, -1).expand_as(pred))

        res = []
        for k in topk:
            correct_k = correct[:k].view(-1).float().sum(0, keepdim=True)
            res.append(correct_k.mul_(100.0 / batch_size))
        return res

def accuracy ( output , target , topk = ( 1 , ) ) : with torch . no_grad ( ) : maxk = max ( topk ) batch_size = target . size ( 0 ) _ , pred = output . topk ( maxk , 1 , True , True ) pred = pred . t ( ) correct = pred . eq ( target . view ( 1 , - 1 ) . expand_as ( pred ) ) res = [ ] for k in topk : correct_k = correct [ : k ] . view ( - 1 ) . float ( ) . sum ( 0 , keepdim = True ) res . append ( correct_k . mul_ ( 100.0 / batch_size ) ) return res


def scatter(inputs, target_gpus, dim=0):
    """Scatter inputs to target gpus.

    The only difference from original :func:`scatter` is to add support for
    :type:`~mmcv.parallel.DataContainer`.
    """

    def scatter_map(obj):
        if isinstance(obj, torch.Tensor):
            return OrigScatter.apply(target_gpus, None, dim, obj)
        if isinstance(obj, DataContainer):
            if obj.cpu_only:
                return obj.data
            else:
                return Scatter.forward(target_gpus, obj.data)
        if isinstance(obj, tuple) and len(obj) > 0:
            return list(zip(*map(scatter_map, obj)))
        if isinstance(obj, list) and len(obj) > 0:
            out = list(map(list, zip(*map(scatter_map, obj))))
            return out
        if isinstance(obj, dict) and len(obj) > 0:
            out = list(map(type(obj), zip(*map(scatter_map, obj.items()))))
            return out
        return [obj for targets in target_gpus]

    # After scatter_map is called, a scatter_map cell will exist. This cell
    # has a reference to the actual function scatter_map, which has references
    # to a closure that has a reference to the scatter_map cell (because the
    # fn is recursive). To avoid this reference cycle, we set the function to
    # None, clearing the cell
    try:
        return scatter_map(inputs)
    finally:
        scatter_map = None

def scatter ( inputs , target_gpus , dim = 0 ) : def scatter_map ( obj ) : if isinstance ( obj , torch . Tensor ) : return OrigScatter . apply ( target_gpus , None , dim , obj ) if isinstance ( obj , DataContainer ) : if obj . cpu_only : return obj . data else : return Scatter . forward ( target_gpus , obj . data ) if isinstance ( obj , tuple ) and len ( obj ) > 0 : return list ( zip ( * map ( scatter_map , obj ) ) ) if isinstance ( obj , list ) and len ( obj ) > 0 : out = list ( map ( list , zip ( * map ( scatter_map , obj ) ) ) ) return out if isinstance ( obj , dict ) and len ( obj ) > 0 : out = list ( map ( type ( obj ) , zip ( * map ( scatter_map , obj . items ( ) ) ) ) ) return out return [ obj for targets in target_gpus ] try : return scatter_map ( inputs ) finally : scatter_map = None


def scatter_kwargs(inputs, kwargs, target_gpus, dim=0):
    """Scatter with support for kwargs dictionary"""
    inputs = scatter(inputs, target_gpus, dim) if inputs else []
    kwargs = scatter(kwargs, target_gpus, dim) if kwargs else []
    if len(inputs) < len(kwargs):
        inputs.extend([() for _ in range(len(kwargs) - len(inputs))])
    elif len(kwargs) < len(inputs):
        kwargs.extend([{} for _ in range(len(inputs) - len(kwargs))])
    inputs = tuple(inputs)
    kwargs = tuple(kwargs)
    return inputs, kwargs

def scatter_kwargs ( inputs , kwargs , target_gpus , dim = 0 ) : inputs = scatter ( inputs , target_gpus , dim ) if inputs else [ ] kwargs = scatter ( kwargs , target_gpus , dim ) if kwargs else [ ] if len ( inputs ) < len ( kwargs ) : inputs . extend ( [ ( ) for _ in range ( len ( kwargs ) - len ( inputs ) ) ] ) elif len ( kwargs ) < len ( inputs ) : kwargs . extend ( [ { } for _ in range ( len ( inputs ) - len ( kwargs ) ) ] ) inputs = tuple ( inputs ) kwargs = tuple ( kwargs ) return inputs , kwargs


async def fetch(self) -> Response:
        """Fetch all the information by using aiohttp"""
        if self.request_config.get('DELAY', 0) > 0:
            await asyncio.sleep(self.request_config['DELAY'])

        timeout = self.request_config.get('TIMEOUT', 10)
        try:
            async with async_timeout.timeout(timeout):
                resp = await self._make_request()
            try:
                resp_data = await resp.text(encoding=self.encoding)
            except UnicodeDecodeError:
                resp_data = await resp.read()

            response = Response(
                url=self.url,
                method=self.method,
                encoding=resp.get_encoding(),
                html=resp_data,
                metadata=self.metadata,
                cookies=resp.cookies,
                headers=resp.headers,
                history=resp.history,
                status=resp.status,
                aws_json=resp.json,
                aws_text=resp.text,
                aws_read=resp.read)
            # Retry middleware
            aws_valid_response = self.request_config.get('VALID')
            if aws_valid_response and iscoroutinefunction(aws_valid_response):
                response = await aws_valid_response(response)
            if response.ok:
                return response
            else:
                return await self._retry(error_msg='request url failed!')
        except asyncio.TimeoutError:
            return await self._retry(error_msg='timeout')
        except Exception as e:
            return await self._retry(error_msg=e)
        finally:
            # Close client session
            await self._close_request_session()

async
def
fetch
(
self
)
->
Response
:
if
self
.
request_config
.
get
(
'DELAY'
,
0
)
>
0
:
await
asyncio
.
sleep
(
self
.
request_config
[
'DELAY'
]
)
timeout
=
self
.
request_config
.
get
(
'TIMEOUT'
,
10
)
try
:
async
with
async_timeout
.
timeout
(
timeout
)
:
resp
=
await
self
.
_make_request
(
)
try
:
resp_data
=
await
resp
.
text
(
encoding
=
self
.
encoding
)
except
UnicodeDecodeError
:
resp_data
=
await
resp
.
read
(
)
response
=
Response
(
url
=
self
.
url
,
method
=
self
.
method
,
encoding
=
resp
.
get_encoding
(
)
,
html
=
resp_data
,
metadata
=
self
.
metadata
,
cookies
=
resp
.
cookies
,
headers
=
resp
.
headers
,
history
=
resp
.
history
,
status
=
resp
.
status
,
aws_json
=
resp
.
json
,
aws_text
=
resp
.
text
,
aws_read
=
resp
.
read
)
aws_valid_response
=
self
.
request_config
.
get
(
'VALID'
)
if
aws_valid_response
and
iscoroutinefunction
(
aws_valid_response
)
:
response
=
await
aws_valid_response
(
response
)
if
response
.
ok
:
return
response
else
:
return
await
self
.
_retry
(
error_msg
=
'request url failed!'
)
except
asyncio
.
TimeoutError
:
return
await
self
.
_retry
(
error_msg
=
'timeout'
)
except
Exception
as
e
:
return
await
self
.
_retry
(
error_msg
=
e
)
finally
:
await
self
.
_close_request_session
(
)


async def json(self,
                   *,
                   encoding: str = None,
                   loads: JSONDecoder = DEFAULT_JSON_DECODER,
                   content_type: Optional[str] = 'application/json') -> Any:
        """Read and decodes JSON response."""
        return await self._aws_json(
            encoding=encoding, loads=loads, content_type=content_type)

async def json ( self , * , encoding : str = None , loads : JSONDecoder = DEFAULT_JSON_DECODER , content_type : Optional [ str ] = 'application/json' ) -> Any : return await self . _aws_json ( encoding = encoding , loads = loads , content_type = content_type )


async def text(self,
                   *,
                   encoding: Optional[str] = None,
                   errors: str = 'strict') -> str:
        """Read response payload and decode."""
        return await self._aws_text(encoding=encoding, errors=errors)

async def text ( self , * , encoding : Optional [ str ] = None , errors : str = 'strict' ) -> str : return await self . _aws_text ( encoding = encoding , errors = errors )


async def handle_callback(self, aws_callback: typing.Coroutine, response):
        """Process coroutine callback function"""
        callback_result = None

        try:
            callback_result = await aws_callback
        except NothingMatchedError as e:
            self.logger.error(f'<Item: {str(e).lower()}>')
        except Exception as e:
            self.logger.error(f'<Callback[{aws_callback.__name__}]: {e}')
        return callback_result, response


async def multiple_request(self, urls, is_gather=False, **kwargs):
        """For crawling multiple urls"""
        if is_gather:
            resp_results = await asyncio.gather(
                *[
                    self.handle_request(self.request(url=url, **kwargs))
                    for url in urls
                ],
                return_exceptions=True)
            for index, task_result in enumerate(resp_results):
                if not isinstance(task_result, RuntimeError) and task_result:
                    _, response = task_result
                    response.index = index
                    yield response
        else:
            for index, url in enumerate(urls):
                _, response = await self.handle_request(
                    self.request(url=url, **kwargs))
                response.index = index
                yield response

async def multiple_request ( self , urls , is_gather = False , ** kwargs ) : if is_gather : resp_results = await asyncio . gather ( * [ self . handle_request ( self . request ( url = url , ** kwargs ) ) for url in urls ] , return_exceptions = True ) for index , task_result in enumerate ( resp_results ) : if not isinstance ( task_result , RuntimeError ) and task_result : _ , response = task_result response . index = index yield response else : for index , url in enumerate ( urls ) : _ , response = await self . handle_request ( self . request ( url = url , ** kwargs ) ) response . index = index yield response


def request(self,
                url: str,
                method: str = 'GET',
                *,
                callback=None,
                encoding: typing.Optional[str] = None,
                headers: dict = None,
                metadata: dict = None,
                request_config: dict = None,
                request_session=None,
                **kwargs):
        """Init a Request class for crawling html"""
        headers = headers or {}
        metadata = metadata or {}
        request_config = request_config or {}
        request_session = request_session or self.request_session

        headers.update(self.headers.copy())
        request_config.update(self.request_config.copy())
        kwargs.update(self.kwargs.copy())

        return Request(
            url=url,
            method=method,
            callback=callback,
            encoding=encoding,
            headers=headers,
            metadata=metadata,
            request_config=request_config,
            request_session=request_session,
            **kwargs)

def request ( self , url : str , method : str = 'GET' , * , callback = None , encoding : typing . Optional [ str ] = None , headers : dict = None , metadata : dict = None , request_config : dict = None , request_session = None , ** kwargs ) : headers = headers or { } metadata = metadata or { } request_config = request_config or { } request_session = request_session or self . request_session headers . update ( self . headers . copy ( ) ) request_config . update ( self . request_config . copy ( ) ) kwargs . update ( self . kwargs . copy ( ) ) return Request ( url = url , method = method , callback = callback , encoding = encoding , headers = headers , metadata = metadata , request_config = request_config , request_session = request_session , ** kwargs )


async def start_master(self):
        """Actually start crawling."""
        for url in self.start_urls:
            request_ins = self.request(
                url=url, callback=self.parse, metadata=self.metadata)
            self.request_queue.put_nowait(self.handle_request(request_ins))
        workers = [
            asyncio.ensure_future(self.start_worker())
            for i in range(self.worker_numbers)
        ]
        for worker in workers:
            self.logger.info(f"Worker started: {id(worker)}")
        await self.request_queue.join()

        if not self.is_async_start:
            await self.stop(SIGINT)
        else:
            await self._cancel_tasks()

async
def
start_master
(
self
)
:
for
url
in
self
.
start_urls
:
request_ins
=
self
.
request
(
url
=
url
,
callback
=
self
.
parse
,
metadata
=
self
.
metadata
)
self
.
request_queue
.
put_nowait
(
self
.
handle_request
(
request_ins
)
)
workers
=
[
asyncio
.
ensure_future
(
self
.
start_worker
(
)
)
for
i
in
range
(
self
.
worker_numbers
)
]
for
worker
in
workers
:
self
.
logger
.
info
(
f"Worker started: {id(worker)}"
)
await
self
.
request_queue
.
join
(
)
if
not
self
.
is_async_start
:
await
self
.
stop
(
SIGINT
)
else
:
await
self
.
_cancel_tasks
(
)


def normalize_task_v2(task):
    '''Ensures tasks have an action key and strings are converted to python objects'''

    result = dict()
    mod_arg_parser = ModuleArgsParser(task)
    try:
        action, arguments, result['delegate_to'] = mod_arg_parser.parse()
    except AnsibleParserError as e:
        try:
            task_info = "%s:%s" % (task[FILENAME_KEY], task[LINE_NUMBER_KEY])
            del task[FILENAME_KEY]
            del task[LINE_NUMBER_KEY]
        except KeyError:
            task_info = "Unknown"
        try:
            import pprint
            pp = pprint.PrettyPrinter(indent=2)
            task_pprint = pp.pformat(task)
        except ImportError:
            task_pprint = task
        raise SystemExit("Couldn't parse task at %s (%s)\n%s" % (task_info, e.message, task_pprint))

    # denormalize shell -> command conversion
    if '_uses_shell' in arguments:
        action = 'shell'
        del(arguments['_uses_shell'])

    for (k, v) in list(task.items()):
        if k in ('action', 'local_action', 'args', 'delegate_to') or k == action:
            # we don't want to re-assign these values, which were
            # determined by the ModuleArgsParser() above
            continue
        else:
            result[k] = v

    result['action'] = dict(__ansible_module__=action)

    if '_raw_params' in arguments:
        result['action']['__ansible_arguments__'] = arguments['_raw_params'].split(' ')
        del(arguments['_raw_params'])
    else:
        result['action']['__ansible_arguments__'] = list()

    if 'argv' in arguments and not result['action']['__ansible_arguments__']:
        result['action']['__ansible_arguments__'] = arguments['argv']
        del(arguments['argv'])

    result['action'].update(arguments)
    return result

def
normalize_task_v2
(
task
)
:
result
=
dict
(
)
mod_arg_parser
=
ModuleArgsParser
(
task
)
try
:
action
,
arguments
,
result
[
'delegate_to'
]
=
mod_arg_parser
.
parse
(
)
except
AnsibleParserError
as
e
:
try
:
task_info
=
"%s:%s"
%
(
task
[
FILENAME_KEY
]
,
task
[
LINE_NUMBER_KEY
]
)
del
task
[
FILENAME_KEY
]
del
task
[
LINE_NUMBER_KEY
]
except
KeyError
:
task_info
=
"Unknown"
try
:
import
pprint
pp
=
pprint
.
PrettyPrinter
(
indent
=
2
)
task_pprint
=
pp
.
pformat
(
task
)
except
ImportError
:
task_pprint
=
task
raise
SystemExit
(
"Couldn't parse task at %s (%s)\n%s"
%
(
task_info
,
e
.
message
,
task_pprint
)
)
if
'_uses_shell'
in
arguments
:
action
=
'shell'
del
(
arguments
[
'_uses_shell'
]
)
for
(
k
,
v
)
in
list
(
task
.
items
(
)
)
:
if
k
in
(
'action'
,
'local_action'
,
'args'
,
'delegate_to'
)
or
k
==
action
:
continue
else
:
result
[
k
]
=
v
result
[
'action'
]
=
dict
(
__ansible_module__
=
action
)
if
'_raw_params'
in
arguments
:
result
[
'action'
]
[
'__ansible_arguments__'
]
=
arguments
[
'_raw_params'
]
.
split
(
' '
)
del
(
arguments
[
'_raw_params'
]
)
else
:
result
[
'action'
]
[
'__ansible_arguments__'
]
=
list
(
)
if
'argv'
in
arguments
and
not
result
[
'action'
]
[
'__ansible_arguments__'
]
:
result
[
'action'
]
[
'__ansible_arguments__'
]
=
arguments
[
'argv'
]
del
(
arguments
[
'argv'
]
)
result
[
'action'
]
.
update
(
arguments
)
return
result


def parse_yaml_linenumbers(data, filename):
    """Parses yaml as ansible.utils.parse_yaml but with linenumbers.

    The line numbers are stored in each node's LINE_NUMBER_KEY key.
    """

    def compose_node(parent, index):
        # the line number where the previous token has ended (plus empty lines)
        line = loader.line
        node = Composer.compose_node(loader, parent, index)
        node.__line__ = line + 1
        return node

    def construct_mapping(node, deep=False):
        if ANSIBLE_VERSION < 2:
            mapping = Constructor.construct_mapping(loader, node, deep=deep)
        else:
            mapping = AnsibleConstructor.construct_mapping(loader, node, deep=deep)
        if hasattr(node, '__line__'):
            mapping[LINE_NUMBER_KEY] = node.__line__
        else:
            mapping[LINE_NUMBER_KEY] = mapping._line_number
        mapping[FILENAME_KEY] = filename
        return mapping

    try:
        if ANSIBLE_VERSION < 2:
            loader = yaml.Loader(data)
        else:
            import inspect
            kwargs = {}
            if 'vault_password' in inspect.getargspec(AnsibleLoader.__init__).args:
                kwargs['vault_password'] = DEFAULT_VAULT_PASSWORD
            loader = AnsibleLoader(data, **kwargs)
        loader.compose_node = compose_node
        loader.construct_mapping = construct_mapping
        data = loader.get_single_data()
    except (yaml.parser.ParserError, yaml.scanner.ScannerError) as e:
        raise SystemExit("Failed to parse YAML in %s: %s" % (filename, str(e)))
    return data

def
parse_yaml_linenumbers
(
data
,
filename
)
:
def
compose_node
(
parent
,
index
)
:
line
=
loader
.
line
node
=
Composer
.
compose_node
(
loader
,
parent
,
index
)
node
.
__line__
=
line
+
1
return
node
def
construct_mapping
(
node
,
deep
=
False
)
:
if
ANSIBLE_VERSION
<
2
:
mapping
=
Constructor
.
construct_mapping
(
loader
,
node
,
deep
=
deep
)
else
:
mapping
=
AnsibleConstructor
.
construct_mapping
(
loader
,
node
,
deep
=
deep
)
if
hasattr
(
node
,
'__line__'
)
:
mapping
[
LINE_NUMBER_KEY
]
=
node
.
__line__
else
:
mapping
[
LINE_NUMBER_KEY
]
=
mapping
.
_line_number
mapping
[
FILENAME_KEY
]
=
filename
return
mapping
try
:
if
ANSIBLE_VERSION
<
2
:
loader
=
yaml
.
Loader
(
data
)
else
:
import
inspect
kwargs
=
{
}
if
'vault_password'
in
inspect
.
getargspec
(
AnsibleLoader
.
__init__
)
.
args
:
kwargs
[
'vault_password'
]
=
DEFAULT_VAULT_PASSWORD
loader
=
AnsibleLoader
(
data
,
**
kwargs
)
loader
.
compose_node
=
compose_node
loader
.
construct_mapping
=
construct_mapping
data
=
loader
.
get_single_data
(
)
except
(
yaml
.
parser
.
ParserError
,
yaml
.
scanner
.
ScannerError
)
as
e
:
raise
SystemExit
(
"Failed to parse YAML in %s: %s"
%
(
filename
,
str
(
e
)
)
)
return
data

Parses yaml as ansible . utils . parse_yaml but with linenumbers .


def wheel_dist_name(self):
        """Return distribution full name with - replaced with _"""
        return '-'.join((safer_name(self.distribution.get_name()),
                         safer_version(self.distribution.get_version())))

def wheel_dist_name ( self ) : return '-' . join ( ( safer_name ( self . distribution . get_name ( ) ) , safer_version ( self . distribution . get_version ( ) ) ) )


def get_archive_basename(self):
        """Return archive name without extension"""

        impl_tag, abi_tag, plat_tag = self.get_tag()

        archive_basename = "%s-%s-%s-%s" % (
            self.wheel_dist_name,
            impl_tag,
            abi_tag,
            plat_tag)
        return archive_basename

def get_archive_basename ( self ) : impl_tag , abi_tag , plat_tag = self . get_tag ( ) archive_basename = "%s-%s-%s-%s" % ( self . wheel_dist_name , impl_tag , abi_tag , plat_tag ) return archive_basename


def add_requirements(self, metadata_path):
        """Add additional requirements from setup.cfg to file metadata_path"""
        additional = list(self.setupcfg_requirements())
        if not additional: return
        pkg_info = read_pkg_info(metadata_path)
        if 'Provides-Extra' in pkg_info or 'Requires-Dist' in pkg_info:
            warnings.warn('setup.cfg requirements overwrite values from setup.py')
            del pkg_info['Provides-Extra']
            del pkg_info['Requires-Dist']
        for k, v in additional:
            pkg_info[k] = v
        write_pkg_info(metadata_path, pkg_info)

Add additional requirements from setup . cfg to file metadata_path


def egg2dist(self, egginfo_path, distinfo_path):
        """Convert an .egg-info directory into a .dist-info directory"""
        def adios(p):
            """Appropriately delete directory, file or link."""
            if os.path.exists(p) and not os.path.islink(p) and os.path.isdir(p):
                shutil.rmtree(p)
            elif os.path.exists(p):
                os.unlink(p)

        adios(distinfo_path)

        if not os.path.exists(egginfo_path):
            # There is no egg-info. This is probably because the egg-info
            # file/directory is not named matching the distribution name used
            # to name the archive file. Check for this case and report
            # accordingly.
            import glob
            pat = os.path.join(os.path.dirname(egginfo_path), '*.egg-info')
            possible = glob.glob(pat)
            err = "Egg metadata expected at %s but not found" % (egginfo_path,)
            if possible:
                alt = os.path.basename(possible[0])
                err += " (%s found - possible misnamed archive file?)" % (alt,)

            raise ValueError(err)

        if os.path.isfile(egginfo_path):
            # .egg-info is a single file
            pkginfo_path = egginfo_path
            pkg_info = self._pkginfo_to_metadata(egginfo_path, egginfo_path)
            os.mkdir(distinfo_path)
        else:
            # .egg-info is a directory
            pkginfo_path = os.path.join(egginfo_path, 'PKG-INFO')
            pkg_info = self._pkginfo_to_metadata(egginfo_path, pkginfo_path)

            # ignore common egg metadata that is useless to wheel
            shutil.copytree(egginfo_path, distinfo_path,
                            ignore=lambda x, y: set(('PKG-INFO',
                                                     'requires.txt',
                                                     'SOURCES.txt',
                                                     'not-zip-safe',)))

            # delete dependency_links if it is only whitespace
            dependency_links_path = os.path.join(distinfo_path, 'dependency_links.txt')
            with open(dependency_links_path, 'r') as dependency_links_file:
                dependency_links = dependency_links_file.read().strip()
            if not dependency_links:
                adios(dependency_links_path)

        write_pkg_info(os.path.join(distinfo_path, 'METADATA'), pkg_info)

        # XXX deprecated. Still useful for current distribute/setuptools.
        metadata_path = os.path.join(distinfo_path, 'METADATA')
        self.add_requirements(metadata_path)

        # XXX intentionally a different path than the PEP.
        metadata_json_path = os.path.join(distinfo_path, 'metadata.json')
        pymeta = pkginfo_to_dict(metadata_path,
                                 distribution=self.distribution)

        if 'description' in pymeta:
            description_filename = 'DESCRIPTION.rst'
            description_text = pymeta.pop('description')
            description_path = os.path.join(distinfo_path,
                                            description_filename)
            with open(description_path, "wb") as description_file:
                description_file.write(description_text.encode('utf-8'))
            pymeta['extensions']['python.details']['document_names']['description'] = description_filename

        # XXX heuristically copy any LICENSE/LICENSE.txt?
        license = self.license_file()
        if license:
            license_filename = 'LICENSE.txt'
            shutil.copy(license, os.path.join(self.distinfo_dir, license_filename))
            pymeta['extensions']['python.details']['document_names']['license'] = license_filename

        with open(metadata_json_path, "w") as metadata_json:
            json.dump(pymeta, metadata_json, sort_keys=True)

        adios(egginfo_path)

Convert an . egg - info directory into a . dist - info directory


def text(text: str, speak: str = None, input_hint: Union[InputHints, str] = InputHints.accepting_input) -> Activity:
        """
        Returns a simple text message.

        :Example:
        message = MessageFactory.text('Greetings from example message')
        await context.send_activity(message)

        :param text:
        :param speak:
        :param input_hint:
        :return:
        """
        message = Activity(type=ActivityTypes.message, text=text, input_hint=input_hint)
        if speak:
            message.speak = speak

        return message

def text ( text : str , speak : str = None , input_hint : Union [ InputHints , str ] = InputHints . accepting_input ) -> Activity : message = Activity ( type = ActivityTypes . message , text = text , input_hint = input_hint ) if speak : message . speak = speak return message


def suggested_actions(actions: List[CardAction], text: str = None, speak: str = None,
                          input_hint: Union[InputHints, str] = InputHints.accepting_input) -> Activity:
        """
        Returns a message that includes a set of suggested actions and optional text.

        :Example:
        message = MessageFactory.suggested_actions([CardAction(title='a', type=ActionTypes.im_back, value='a'),
                                                    CardAction(title='b', type=ActionTypes.im_back, value='b'),
                                                    CardAction(title='c', type=ActionTypes.im_back, value='c')], 'Choose a color')
        await context.send_activity(message)

        :param actions:
        :param text:
        :param speak:
        :param input_hint:
        :return:
        """
        actions = SuggestedActions(actions=actions)
        message = Activity(type=ActivityTypes.message, input_hint=input_hint, suggested_actions=actions)
        if text:
            message.text = text
        if speak:
            message.speak = speak
        return message

def suggested_actions ( actions : List [ CardAction ] , text : str = None , speak : str = None , input_hint : Union [ InputHints , str ] = InputHints . accepting_input ) -> Activity : actions = SuggestedActions ( actions = actions ) message = Activity ( type = ActivityTypes . message , input_hint = input_hint , suggested_actions = actions ) if text : message . text = text if speak : message . speak = speak return message

Returns a message that includes a set of suggested actions and optional text .


def attachment(attachment: Attachment, text: str = None, speak: str = None,
                   input_hint: Union[InputHints, str] = None):
        """
        Returns a single message activity containing an attachment.

        :Example:
        message = MessageFactory.attachment(CardFactory.hero_card(HeroCard(title='White T-Shirt',
                                                                  images=[CardImage(url='https://example.com/whiteShirt.jpg')],
                                                                  buttons=[CardAction(title='buy')])))
        await context.send_activity(message)

        :param attachment:
        :param text:
        :param speak:
        :param input_hint:
        :return:
        """
        return attachment_activity(AttachmentLayoutTypes.list, [attachment], text, speak, input_hint)

def attachment ( attachment : Attachment , text : str = None , speak : str = None , input_hint : Union [ InputHints , str ] = None ) : return attachment_activity ( AttachmentLayoutTypes . list , [ attachment ] , text , speak , input_hint )

Returns a single message activity containing an attachment .


def list(attachments: List[Attachment], text: str = None, speak: str = None,
             input_hint: Union[InputHints, str] = None) -> Activity:
        """
        Returns a message that will display a set of attachments in list form.

        :Example:
        message = MessageFactory.list([CardFactory.hero_card(HeroCard(title='title1',
                                                             images=[CardImage(url='imageUrl1')],
                                                             buttons=[CardAction(title='button1')])),
                                       CardFactory.hero_card(HeroCard(title='title2',
                                                             images=[CardImage(url='imageUrl2')],
                                                             buttons=[CardAction(title='button2')])),
                                       CardFactory.hero_card(HeroCard(title='title3',
                                                             images=[CardImage(url='imageUrl3')],
                                                             buttons=[CardAction(title='button3')]))])
        await context.send_activity(message)

        :param attachments:
        :param text:
        :param speak:
        :param input_hint:
        :return:
        """
        return attachment_activity(AttachmentLayoutTypes.list, attachments, text, speak, input_hint)

def list ( attachments : List [ Attachment ] , text : str = None , speak : str = None , input_hint : Union [ InputHints , str ] = None ) -> Activity : return attachment_activity ( AttachmentLayoutTypes . list , attachments , text , speak , input_hint )

Returns a message that will display a set of attachments in list form .


def content_url(url: str, content_type: str, name: str = None, text: str = None, speak: str = None,
                    input_hint: Union[InputHints, str] = None):
        """
        Returns a message that will display a single image or video to a user.

        :Example:
        message = MessageFactory.content_url('https://example.com/hawaii.jpg', 'image/jpeg',
                                             'Hawaii Trip', 'A photo from our family vacation.')
        await context.send_activity(message)

        :param url:
        :param content_type:
        :param name:
        :param text:
        :param speak:
        :param input_hint:
        :return:
        """
        attachment = Attachment(content_type=content_type, content_url=url)
        if name:
            attachment.name = name
        return attachment_activity(AttachmentLayoutTypes.list, [attachment], text, speak, input_hint)

def content_url ( url : str , content_type : str , name : str = None , text : str = None , speak : str = None , input_hint : Union [ InputHints , str ] = None ) : attachment = Attachment ( content_type = content_type , content_url = url ) if name : attachment . name = name return attachment_activity ( AttachmentLayoutTypes . list , [ attachment ] , text , speak , input_hint )

Returns a message that will display a single image or video to a user .


def create_trace(
        turn_activity: Activity,
        name: str,
        value: object = None,
        value_type: str = None,
        label: str = None,
    ) -> Activity:
        """Creates a trace activity based on this activity.

        :param turn_activity:
        :type turn_activity: Activity
        :param name: The value to assign to the trace activity's <see cref="Activity.name"/> property.
        :type name: str
        :param value: The value to assign to the trace activity's <see cref="Activity.value"/> property., defaults to None
        :param value: object, optional
        :param value_type: The value to assign to the trace activity's <see cref="Activity.value_type"/> property, defaults to None
        :param value_type: str, optional
        :param label: The value to assign to the trace activity's <see cref="Activity.label"/> property, defaults to None
        :param label: str, optional
        :return: The created trace activity.
        :rtype: Activity
        """

        from_property = (
            ChannelAccount(
                id=turn_activity.recipient.id, name=turn_activity.recipient.name
            )
            if turn_activity.recipient is not None
            else ChannelAccount()
        )
        if value_type is None and value is not None:
            value_type = type(value).__name__

        reply = Activity(
            type=ActivityTypes.trace,
            timestamp=datetime.utcnow(),
            from_property=from_property,
            recipient=ChannelAccount(
                id=turn_activity.from_property.id, name=turn_activity.from_property.name
            ),
            reply_to_id=turn_activity.id,
            service_url=turn_activity.service_url,
            channel_id=turn_activity.channel_id,
            conversation=ConversationAccount(
                is_group=turn_activity.conversation.is_group,
                id=turn_activity.conversation.id,
                name=turn_activity.conversation.name,
            ),
            name=name,
            label=label,
            value_type=value_type,
            value=value,
        )
        return reply

def create_trace ( turn_activity : Activity , name : str , value : object = None , value_type : str = None , label : str = None , ) -> Activity : from_property = ( ChannelAccount ( id = turn_activity . recipient . id , name = turn_activity . recipient . name ) if turn_activity . recipient is not None else ChannelAccount ( ) ) if value_type is None and value is not None : value_type = type ( value ) . __name__ reply = Activity ( type = ActivityTypes . trace , timestamp = datetime . utcnow ( ) , from_property = from_property , recipient = ChannelAccount ( id = turn_activity . from_property . id , name = turn_activity . from_property . name ) , reply_to_id = turn_activity . id , service_url = turn_activity . service_url , channel_id = turn_activity . channel_id , conversation = ConversationAccount ( is_group = turn_activity . conversation . is_group , id = turn_activity . conversation . id , name = turn_activity . conversation . name , ) , name = name , label = label , value_type = value_type , value = value , ) return reply

Creates a trace activity based on this activity .


def telemetry_client(self, value: BotTelemetryClient) -> None:
        """
        Sets the telemetry client for logging events.
        """
        if value is None:
            self._telemetry_client = NullTelemetryClient()
        else:
            self._telemetry_client = value

def telemetry_client ( self , value : BotTelemetryClient ) -> None : if value is None : self . _telemetry_client = NullTelemetryClient ( ) else : self . _telemetry_client = value

Sets the telemetry client for logging events .


async def read(self, keys: List[str]) -> dict:
        """Read storeitems from storage.

        :param keys:
        :return dict:
        """
        try:
            # check if the database and container exists and if not create
            if not self.__container_exists:
                self.__create_db_and_container()
            if len(keys) > 0:
                # create the parameters object
                parameters = [
                    {'name': f'@id{i}', 'value': f'{self.__sanitize_key(key)}'}
                    for i, key in enumerate(keys)
                    ]
                # get the names of the params
                parameter_sequence = ','.join(param.get('name')
                                              for param in parameters)
                # create the query
                query = {
                    "query":
                    f"SELECT c.id, c.realId, c.document, c._etag \
FROM c WHERE c.id in ({parameter_sequence})",
                    "parameters": parameters
                    }
                options = {'enableCrossPartitionQuery': True}
                # run the query and store the results as a list
                results = list(
                    self.client.QueryItems(
                        self.__container_link, query, options)
                    )
                # return a dict with a key and a StoreItem
                return {
                    r.get('realId'): self.__create_si(r) for r in results
                    }
            else:
                raise Exception('cosmosdb_storage.read(): \
provide at least one key')
        except TypeError as e:
            raise e

f"SELECT c.id, c.realId, c.document, c._etag \FROM c WHERE c.id in ({parameter_sequence})"

'cosmosdb_storage.read(): \provide at least one key'


async def write(self, changes: Dict[str, StoreItem]):
        """Save storeitems to storage.

        :param changes:
        :return:
        """
        try:
            # check if the database and container exists and if not create
            if not self.__container_exists:
                self.__create_db_and_container()
                # iterate over the changes
            for (key, change) in changes.items():
                # store the e_tag
                e_tag = change.e_tag
                # create the new document
                doc = {'id': self.__sanitize_key(key),
                       'realId': key,
                       'document': self.__create_dict(change)
                       }
                # the e_tag will be * for new docs so do an insert
                if (e_tag == '*' or not e_tag):
                    self.client.UpsertItem(
                        database_or_Container_link=self.__container_link,
                        document=doc,
                        options={'disableAutomaticIdGeneration': True}
                        )
                # if we have an etag, do opt. concurrency replace
                elif(len(e_tag) > 0):
                    access_condition = {'type': 'IfMatch', 'condition': e_tag}
                    self.client.ReplaceItem(
                        document_link=self.__item_link(
                            self.__sanitize_key(key)),
                        new_document=doc,
                        options={'accessCondition': access_condition}
                        )
                # error when there is no e_tag
                else:
                    raise Exception('cosmosdb_storage.write(): etag missing')
        except Exception as e:
            raise e


async def delete(self, keys: List[str]):
        """Remove storeitems from storage.

        :param keys:
        :return:
        """
        try:
            # check if the database and container exists and if not create
            if not self.__container_exists:
                self.__create_db_and_container()
            # call the function for each key
            for k in keys:
                self.client.DeleteItem(
                    document_link=self.__item_link(self.__sanitize_key(k)))
                # print(res)
        except cosmos_errors.HTTPFailure as h:
            # print(h.status_code)
            if h.status_code != 404:
                raise h
        except TypeError as e:
            raise e

async def delete ( self , keys : List [ str ] ) : try : if not self . __container_exists : self . __create_db_and_container ( ) for k in keys : self . client . DeleteItem ( document_link = self . __item_link ( self . __sanitize_key ( k ) ) ) except cosmos_errors . HTTPFailure as h : if h . status_code != 404 : raise h except TypeError as e : raise e


def __create_si(self, result) -> StoreItem:
        """Create a StoreItem from a result out of CosmosDB.

        :param result:
        :return StoreItem:
        """
        # get the document item from the result and turn into a dict
        doc = result.get('document')
        # readd the e_tag from Cosmos
        doc['e_tag'] = result.get('_etag')
        # create and return the StoreItem
        return StoreItem(**doc)

def __create_si ( self , result ) -> StoreItem : doc = result . get ( 'document' ) doc [ 'e_tag' ] = result . get ( '_etag' ) return StoreItem ( ** doc )

Create a StoreItem from a result out of CosmosDB .


def __create_dict(self, si: StoreItem) -> Dict:
        """Return the dict of a StoreItem.

        This eliminates non_magic attributes and the e_tag.

        :param si:
        :return dict:
        """
        # read the content
        non_magic_attr = ([attr for attr in dir(si)
                          if not attr.startswith('_') or attr.__eq__('e_tag')])
        # loop through attributes and write and return a dict
        return ({attr: getattr(si, attr)
                for attr in non_magic_attr})

def __create_dict ( self , si : StoreItem ) -> Dict : non_magic_attr = ( [ attr for attr in dir ( si ) if not attr . startswith ( '_' ) or attr . __eq__ ( 'e_tag' ) ] ) return ( { attr : getattr ( si , attr ) for attr in non_magic_attr } )


def __sanitize_key(self, key) -> str:
        """Return the sanitized key.

        Replace characters that are not allowed in keys in Cosmos.

        :param key:
        :return str:
        """
        # forbidden characters
        bad_chars = ['\\', '?', '/', '#', '\t', '\n', '\r']
        # replace those with with '*' and the
        # Unicode code point of the character and return the new string
        return ''.join(
            map(
                lambda x: '*'+str(ord(x)) if x in bad_chars else x, key
                )
            )

def __sanitize_key ( self , key ) -> str : bad_chars = [ '\\' , '?' , '/' , '#' , '\t' , '\n' , '\r' ] return '' . join ( map ( lambda x : '*' + str ( ord ( x ) ) if x in bad_chars else x , key ) )


def __create_db_and_container(self):
        """Call the get or create methods."""
        db_id = self.config.database
        container_name = self.config.container
        self.db = self.__get_or_create_database(self.client, db_id)
        self.container = self.__get_or_create_container(
            self.client, container_name
            )

def __create_db_and_container ( self ) : db_id = self . config . database container_name = self . config . container self . db = self . __get_or_create_database ( self . client , db_id ) self . container = self . __get_or_create_container ( self . client , container_name )


def __get_or_create_database(self, doc_client, id) -> str:
        """Return the database link.

        Check if the database exists or create the db.

        :param doc_client:
        :param id:
        :return str:
        """
        # query CosmosDB for a database with that name/id
        dbs = list(doc_client.QueryDatabases({
            "query": "SELECT * FROM r WHERE r.id=@id",
            "parameters": [
                {"name": "@id", "value": id}
            ]
        }))
        # if there are results, return the first (db names are unique)
        if len(dbs) > 0:
            return dbs[0]['id']
        else:
            # create the database if it didn't exist
            res = doc_client.CreateDatabase({'id': id})
            return res['id']

def
__get_or_create_database
(
self
,
doc_client
,
id
)
->
str
:
dbs
=
list
(
doc_client
.
QueryDatabases
(
{
"query"
:
"SELECT * FROM r WHERE r.id=@id"
,
"parameters"
:
[
{
"name"
:
"@id"
,
"value"
:
id
}
]
}
)
)
if
len
(
dbs
)
>
0
:
return
dbs
[
0
]
[
'id'
]
else
:
res
=
doc_client
.
CreateDatabase
(
{
'id'
:
id
}
)
return
res
[
'id'
]


def __get_or_create_container(self, doc_client, container) -> str:
        """Return the container link.

        Check if the container exists or create the container.

        :param doc_client:
        :param container:
        :return str:
        """
        # query CosmosDB for a container in the database with that name
        containers = list(doc_client.QueryContainers(
            self.__database_link,
            {
                "query": "SELECT * FROM r WHERE r.id=@id",
                "parameters": [
                    {"name": "@id", "value": container}
                ]
            }
        ))
        # if there are results, return the first (container names are unique)
        if len(containers) > 0:
            return containers[0]['id']
        else:
            # Create a container if it didn't exist
            res = doc_client.CreateContainer(
                self.__database_link, {'id': container})
            return res['id']

def
__get_or_create_container
(
self
,
doc_client
,
container
)
->
str
:
containers
=
list
(
doc_client
.
QueryContainers
(
self
.
__database_link
,
{
"query"
:
"SELECT * FROM r WHERE r.id=@id"
,
"parameters"
:
[
{
"name"
:
"@id"
,
"value"
:
container
}
]
}
)
)
if
len
(
containers
)
>
0
:
return
containers
[
0
]
[
'id'
]
else
:
res
=
doc_client
.
CreateContainer
(
self
.
__database_link
,
{
'id'
:
container
}
)
return
res
[
'id'
]


def fill_qna_event(
        self,
        query_results: [QueryResult],
        turn_context: TurnContext,
        telemetry_properties: Dict[str,str] = None,
        telemetry_metrics: Dict[str,float] = None
    ) -> EventData:
        """
        Fills the event properties and metrics for the QnaMessage event for telemetry.

        :return: A tuple of event data properties and metrics that will be sent to the BotTelemetryClient.track_event() method for the QnAMessage event. The properties and metrics returned the standard properties logged with any properties passed from the get_answers() method.

        :rtype: EventData
        """

        properties: Dict[str,str] = dict()
        metrics: Dict[str, float] = dict()

        properties[QnATelemetryConstants.knowledge_base_id_property] = self._endpoint.knowledge_base_id

        text: str = turn_context.activity.text
        userName: str = turn_context.activity.from_property.name

        # Use the LogPersonalInformation flag to toggle logging PII data; text and username are common examples.
        if self.log_personal_information:
            if text:
                properties[QnATelemetryConstants.question_property] = text

            if userName:
                properties[QnATelemetryConstants.username_property] = userName

        # Fill in Qna Results (found or not).
        if len(query_results) > 0:
            query_result = query_results[0]

            result_properties = {
                QnATelemetryConstants.matched_question_property: json.dumps(query_result.questions),
                QnATelemetryConstants.question_id_property: str(query_result.id),
                QnATelemetryConstants.answer_property: query_result.answer,
                QnATelemetryConstants.score_metric: query_result.score,
                QnATelemetryConstants.article_found_property: 'true'
            }

            properties.update(result_properties)
        else:
            no_match_properties = {
                QnATelemetryConstants.matched_question_property : 'No Qna Question matched',
                QnATelemetryConstants.question_id_property : 'No Qna Question Id matched',
                QnATelemetryConstants.answer_property : 'No Qna Answer matched',
                QnATelemetryConstants.article_found_property : 'false'
            }

            properties.update(no_match_properties)

        # Additional Properties can override "stock" properties.
        if telemetry_properties:
            properties.update(telemetry_properties)

        # Additional Metrics can override "stock" metrics.
        if telemetry_metrics:
            metrics.update(telemetry_metrics)

        return EventData(properties=properties, metrics=metrics)

def
fill_qna_event
(
self
,
query_results
:
[
QueryResult
]
,
turn_context
:
TurnContext
,
telemetry_properties
:
Dict
[
str
,
str
]
=
,
telemetry_metrics
:
Dict
[
str
,
float
]
=
)
->
EventData
:
properties
:
Dict
[
str
,
str
]
=
dict
(
)
metrics
:
Dict
[
str
,
float
]
=
dict
(
)
properties
[
QnATelemetryConstants
.
knowledge_base_id_property
]
=
self
.
_endpoint
.
knowledge_base_id
text
:
str
=
turn_context
.
activity
.
text
userName
:
str
=
turn_context
.
activity
.
from_property
.
name
if
self
.
log_personal_information
:
if
text
:
properties
[
QnATelemetryConstants
.
question_property
]
=
text
if
userName
:
properties
[
QnATelemetryConstants
.
username_property
]
=
userName
if
len
(
query_results
)
>
0
:
query_result
=
query_results
[
0
]
result_properties
=
{
QnATelemetryConstants
.
matched_question_property
:
json
.
dumps
(
query_result
.
questions
)
,
QnATelemetryConstants
.
question_id_property
:
str
(
query_result
.
id
)
,
QnATelemetryConstants
.
answer_property
:
query_result
.
answer
,
QnATelemetryConstants
.
score_metric
:
query_result
.
score
,
QnATelemetryConstants
.
article_found_property
:
'true'
}
properties
.
update
(
result_properties
)
else
:
no_match_properties
=
{
QnATelemetryConstants
.
matched_question_property
:
'No Qna Question matched'
,
QnATelemetryConstants
.
question_id_property
:
'No Qna Question Id matched'
,
QnATelemetryConstants
.
answer_property
:
'No Qna Answer matched'
,
QnATelemetryConstants
.
article_found_property
:
'false'
}
properties
.
update
(
no_match_properties
)
if
telemetry_properties
:
properties
.
update
(
telemetry_properties
)
if
telemetry_metrics
:
metrics
.
update
(
telemetry_metrics
)
return
EventData
(
properties
=
properties
,
metrics
=
metrics
)

Fills the event properties and metrics for the QnaMessage event for telemetry .


def get_conversation_reference(activity: Activity) -> ConversationReference:
        """
        Returns the conversation reference for an activity. This can be saved as a plain old JSON
        object and then later used to message the user proactively.

        Usage Example:
        reference = TurnContext.get_conversation_reference(context.request)
        :param activity:
        :return:
        """
        return ConversationReference(activity_id=activity.id,
                                     user=copy(activity.from_property),
                                     bot=copy(activity.recipient),
                                     conversation=copy(activity.conversation),
                                     channel_id=activity.channel_id,
                                     service_url=activity.service_url)

def get_conversation_reference ( activity : Activity ) -> ConversationReference : return ConversationReference ( activity_id = activity . id , user = copy ( activity . from_property ) , bot = copy ( activity . recipient ) , conversation = copy ( activity . conversation ) , channel_id = activity . channel_id , service_url = activity . service_url )

Returns the conversation reference for an activity . This can be saved as a plain old JSON object and then later used to message the user proactively .


def get_step_name(self, index: int) -> str:
        """
        Give the waterfall step a unique name
        """
        step_name = self._steps[index].__qualname__

        if not step_name or ">" in step_name :
            step_name = f"Step{index + 1}of{len(self._steps)}"

        return step_name

def
get_step_name
(
self
,
index
:
int
)
->
str
:
step_name
=
self
.
_steps
[
index
]
.
__qualname__
if
not
step_name
or
">"
in
step_name
:
step_name
=
f"Step{index + 1}of{len(self._steps)}"
return
step_name


def supports_suggested_actions(channel_id: str, button_cnt: int = 100) -> bool:
        """Determine if a number of Suggested Actions are supported by a Channel.

        Args:
            channel_id (str): The Channel to check the if Suggested Actions are supported in.
            button_cnt (int, optional): Defaults to 100. The number of Suggested Actions to check for the Channel.

        Returns:
            bool: True if the Channel supports the button_cnt total Suggested Actions, False if the Channel does not support that number of Suggested Actions.
        """

        max_actions = {
            # https://developers.facebook.com/docs/messenger-platform/send-messages/quick-replies
            Channels.facebook: 10,
            Channels.skype: 10,
            # https://developers.line.biz/en/reference/messaging-api/#items-object
            Channels.line: 13,
            # https://dev.kik.com/#/docs/messaging#text-response-object
            Channels.kik: 20,
            Channels.telegram: 100,
            Channels.slack: 100,
            Channels.emulator: 100,
            Channels.direct_line: 100,
            Channels.webchat: 100,
        }
        return button_cnt <= max_actions[channel_id] if channel_id in max_actions else False

def supports_suggested_actions ( channel_id : str , button_cnt : int = 100 ) -> bool : max_actions = { Channels . facebook : 10 , Channels . skype : 10 , Channels . line : 13 , Channels . kik : 20 , Channels . telegram : 100 , Channels . slack : 100 , Channels . emulator : 100 , Channels . direct_line : 100 , Channels . webchat : 100 , } return button_cnt <= max_actions [ channel_id ] if channel_id in max_actions else False

Determine if a number of Suggested Actions are supported by a Channel .


def supports_card_actions(channel_id: str, button_cnt: int = 100) -> bool:
        """Determine if a number of Card Actions are supported by a Channel.

        Args:
            channel_id (str): The Channel to check if the Card Actions are supported in.
            button_cnt (int, optional): Defaults to 100. The number of Card Actions to check for the Channel.

        Returns:
            bool: True if the Channel supports the button_cnt total Card Actions, False if the Channel does not support that number of Card Actions.
        """

        max_actions = {
            Channels.facebook: 3,
            Channels.skype: 3,
            Channels.ms_teams: 3,
            Channels.line: 99,
            Channels.slack: 100,
            Channels.emulator: 100,
            Channels.direct_line: 100,
            Channels.webchat: 100,
            Channels.cortana: 100,
        }
        return button_cnt <= max_actions[channel_id] if channel_id in max_actions else False

def supports_card_actions ( channel_id : str , button_cnt : int = 100 ) -> bool : max_actions = { Channels . facebook : 3 , Channels . skype : 3 , Channels . ms_teams : 3 , Channels . line : 99 , Channels . slack : 100 , Channels . emulator : 100 , Channels . direct_line : 100 , Channels . webchat : 100 , Channels . cortana : 100 , } return button_cnt <= max_actions [ channel_id ] if channel_id in max_actions else False

Determine if a number of Card Actions are supported by a Channel .


def get_channel_id(turn_context: TurnContext) -> str:
        """Get the Channel Id from the current Activity on the Turn Context.

        Args:
            turn_context (TurnContext): The Turn Context to retrieve the Activity's Channel Id from.

        Returns:
            str: The Channel Id from the Turn Context's Activity.
        """

        if turn_context.activity.channel_id is None:
            return ""
        else:
            return turn_context.activity.channel_id

def get_channel_id ( turn_context : TurnContext ) -> str : if turn_context . activity . channel_id is None : return "" else : return turn_context . activity . channel_id

Get the Channel Id from the current Activity on the Turn Context .


def is_token_from_emulator(auth_header: str) -> bool:
        """ Determines if a given Auth header is from the Bot Framework Emulator

        :param auth_header: Bearer Token, in the 'Bearer [Long String]' Format.
        :type auth_header: str

        :return: True, if the token was issued by the Emulator. Otherwise, false.
        """
        # The Auth Header generally looks like this:
        # "Bearer eyJ0e[...Big Long String...]XAiO"
        if not auth_header:
            # No token. Can't be an emulator token.
            return False

        parts = auth_header.split(' ')
        if len(parts) != 2:
            # Emulator tokens MUST have exactly 2 parts.
            # If we don't have 2 parts, it's not an emulator token
            return False

        auth_scheme = parts[0]
        bearer_token = parts[1]

        # We now have an array that should be:
        # [0] = "Bearer"
        # [1] = "[Big Long String]"
        if auth_scheme != 'Bearer':
            # The scheme from the emulator MUST be "Bearer"
            return False

        # Parse the Big Long String into an actual token.
        token = jwt.decode(bearer_token, verify=False)
        if not token:
            return False

        # Is there an Issuer?
        issuer = token['iss']
        if not issuer:
            # No Issuer, means it's not from the Emulator.
            return False

        # Is the token issues by a source we consider to be the emulator?
        issuer_list = EmulatorValidation.TO_BOT_FROM_EMULATOR_TOKEN_VALIDATION_PARAMETERS.issuer
        if issuer_list and not issuer in issuer_list:
            # Not a Valid Issuer. This is NOT a Bot Framework Emulator Token.
            return False

        # The Token is from the Bot Framework Emulator. Success!
        return True


def hero_card(card: HeroCard) -> Attachment:
        """
        Returns an attachment for a hero card. Will raise a TypeError if 'card' argument is not a HeroCard.

        Hero cards tend to have one dominant full width image and the cards text & buttons can
        usually be found below the image.
        :return:
        """
        if not isinstance(card, HeroCard):
            raise TypeError('CardFactory.hero_card(): `card` argument is not an instance of an HeroCard, '
                            'unable to prepare attachment.')

        return Attachment(content_type=CardFactory.content_types.hero_card,
                          content=card)

Returns an attachment for a hero card . Will raise a TypeError if card argument is not a HeroCard .


def params(self):
        """return instruction params"""
        # if params already defined don't attempt to get them from definition
        if self._definition and not self._params:
            self._params = []
            for sub_instr, _, _ in self._definition:
                self._params.extend(sub_instr.params)  # recursive call
            return self._params
        else:
            return self._params

def params ( self ) : if self . _definition and not self . _params : self . _params = [ ] for sub_instr , _ , _ in self . _definition : self . _params . extend ( sub_instr . params ) return self . _params else : return self . _params


def mirror(self):
        """For a composite instruction, reverse the order of sub-gates.

        This is done by recursively mirroring all sub-instructions.
        It does not invert any gate.

        Returns:
            Instruction: a fresh gate with sub-gates reversed
        """
        if not self._definition:
            return self.copy()

        reverse_inst = self.copy(name=self.name + '_mirror')
        reverse_inst.definition = []
        for inst, qargs, cargs in reversed(self._definition):
            reverse_inst._definition.append((inst.mirror(), qargs, cargs))
        return reverse_inst

def mirror ( self ) : if not self . _definition : return self . copy ( ) reverse_inst = self . copy ( name = self . name + '_mirror' ) reverse_inst . definition = [ ] for inst , qargs , cargs in reversed ( self . _definition ) : reverse_inst . _definition . append ( ( inst . mirror ( ) , qargs , cargs ) ) return reverse_inst

For a composite instruction reverse the order of sub - gates .


def inverse(self):
        """Invert this instruction.

        If the instruction is composite (i.e. has a definition),
        then its definition will be recursively inverted.

        Special instructions inheriting from Instruction can
        implement their own inverse (e.g. T and Tdg, Barrier, etc.)

        Returns:
            Instruction: a fresh instruction for the inverse

        Raises:
            QiskitError: if the instruction is not composite
                and an inverse has not been implemented for it.
        """
        if not self.definition:
            raise QiskitError("inverse() not implemented for %s." % self.name)
        inverse_gate = self.copy(name=self.name + '_dg')
        inverse_gate._definition = []
        for inst, qargs, cargs in reversed(self._definition):
            inverse_gate._definition.append((inst.inverse(), qargs, cargs))
        return inverse_gate

def
inverse
(
self
)
:
if
not
self
.
definition
:
raise
QiskitError
(
"inverse() not implemented for %s."
%
self
.
name
)
inverse_gate
=
self
.
copy
(
name
=
self
.
name
+
'_dg'
)
inverse_gate
.
_definition
=
[
]
for
inst
,
qargs
,
cargs
in
reversed
(
self
.
_definition
)
:
inverse_gate
.
_definition
.
append
(
(
inst
.
inverse
(
)
,
qargs
,
cargs
)
)
return
inverse_gate


def c_if(self, classical, val):
        """Add classical control on register classical and value val."""
        if not isinstance(classical, ClassicalRegister):
            raise QiskitError("c_if must be used with a classical register")
        if val < 0:
            raise QiskitError("control value should be non-negative")
        self.control = (classical, val)
        return self

Add classical control on register classical and value val .


def copy(self, name=None):
        """
        shallow copy of the instruction.

        Args:
          name (str): name to be given to the copied circuit,
            if None then the name stays the same

        Returns:
          Instruction: a shallow copy of the current instruction, with the name
            updated if it was provided
        """
        cpy = copy.copy(self)
        if name:
            cpy.name = name
        return cpy

def copy ( self , name = None ) : cpy = copy . copy ( self ) if name : cpy . name = name return cpy


def _qasmif(self, string):
        """Print an if statement if needed."""
        if self.control is None:
            return string
        return "if(%s==%d) " % (self.control[0].name, self.control[1]) + string

def
_qasmif
(
self
,
string
)
:
if
self
.
control
is
:
return
string
return
"if(%s==%d) "
%
(
self
.
control
[
0
]
.
name
,
self
.
control
[
1
]
)
+
string


def qasm(self):
        """Return a default OpenQASM string for the instruction.

        Derived instructions may override this to print in a
        different format (e.g. measure q[0] -> c[0];).
        """
        name_param = self.name
        if self.params:
            name_param = "%s(%s)" % (name_param, ",".join(
                [str(i) for i in self.params]))

        return self._qasmif(name_param)

def qasm ( self ) : name_param = self . name if self . params : name_param = "%s(%s)" % ( name_param , "," . join ( [ str ( i ) for i in self . params ] ) ) return self . _qasmif ( name_param )

Return a default OpenQASM string for the instruction .


def run(self, circuit):
        """Run all the passes on a QuantumCircuit

        Args:
            circuit (QuantumCircuit): circuit to transform via all the registered passes

        Returns:
            QuantumCircuit: Transformed circuit.
        """
        name = circuit.name
        dag = circuit_to_dag(circuit)
        del circuit
        for passset in self.working_list:
            for pass_ in passset:
                dag = self._do_pass(pass_, dag, passset.options)
        circuit = dag_to_circuit(dag)
        circuit.name = name
        return circuit

def run ( self , circuit ) : name = circuit . name dag = circuit_to_dag ( circuit ) del circuit for passset in self . working_list : for pass_ in passset : dag = self . _do_pass ( pass_ , dag , passset . options ) circuit = dag_to_circuit ( dag ) circuit . name = name return circuit


def _do_pass(self, pass_, dag, options):
        """Do a pass and its "requires".

        Args:
            pass_ (BasePass): Pass to do.
            dag (DAGCircuit): The dag on which the pass is ran.
            options (dict): PassManager options.
        Returns:
            DAGCircuit: The transformed dag in case of a transformation pass.
            The same input dag in case of an analysis pass.
        Raises:
            TranspilerError: If the pass is not a proper pass instance.
        """

        # First, do the requires of pass_
        if not options["ignore_requires"]:
            for required_pass in pass_.requires:
                dag = self._do_pass(required_pass, dag, options)

        # Run the pass itself, if not already run
        if pass_ not in self.valid_passes:
            if pass_.is_transformation_pass:
                pass_.property_set = self.fenced_property_set
                new_dag = pass_.run(dag)
                if not isinstance(new_dag, DAGCircuit):
                    raise TranspilerError("Transformation passes should return a transformed dag."
                                          "The pass %s is returning a %s" % (type(pass_).__name__,
                                                                             type(new_dag)))
                dag = new_dag
            elif pass_.is_analysis_pass:
                pass_.property_set = self.property_set
                pass_.run(FencedDAGCircuit(dag))
            else:
                raise TranspilerError("I dont know how to handle this type of pass")

            # update the valid_passes property
            self._update_valid_passes(pass_, options['ignore_preserves'])

        return dag


def passes(self):
        """
        Returns a list structure of the appended passes and its options.

        Returns (list): The appended passes.
        """
        ret = []
        for pass_ in self.working_list:
            ret.append(pass_.dump_passes())
        return ret

def passes ( self ) : ret = [ ] for pass_ in self . working_list : ret . append ( pass_ . dump_passes ( ) ) return ret

Returns a list structure of the appended passes and its options .


def dump_passes(self):
        """
        Fetches the passes added to this flow controller.

        Returns (dict): {'options': self.options, 'passes': [passes], 'type': type(self)}
        """
        ret = {'options': self.options, 'passes': [], 'type': type(self)}
        for pass_ in self._passes:
            if isinstance(pass_, FlowController):
                ret['passes'].append(pass_.dump_passes())
            else:
                ret['passes'].append(pass_)
        return ret

def dump_passes ( self ) : ret = { 'options' : self . options , 'passes' : [ ] , 'type' : type ( self ) } for pass_ in self . _passes : if isinstance ( pass_ , FlowController ) : ret [ 'passes' ] . append ( pass_ . dump_passes ( ) ) else : ret [ 'passes' ] . append ( pass_ ) return ret

Fetches the passes added to this flow controller .


def controller_factory(cls, passes, options, **partial_controller):
        """
        Constructs a flow controller based on the partially evaluated controller arguments.

        Args:
            passes (list[BasePass]): passes to add to the flow controller.
            options (dict): PassManager options.
            **partial_controller (dict): Partially evaluated controller arguments in the form
                `{name:partial}`

        Raises:
            TranspilerError: When partial_controller is not well-formed.

        Returns:
            FlowController: A FlowController instance.
        """
        if None in partial_controller.values():
            raise TranspilerError('The controller needs a condition.')

        if partial_controller:
            for registered_controller in cls.registered_controllers.keys():
                if registered_controller in partial_controller:
                    return cls.registered_controllers[registered_controller](passes, options,
                                                                             **partial_controller)
            raise TranspilerError("The controllers for %s are not registered" % partial_controller)
        else:
            return FlowControllerLinear(passes, options)

Constructs a flow controller based on the partially evaluated controller arguments .


def u_base(self, theta, phi, lam, q):
    """Apply U to q."""
    return self.append(UBase(theta, phi, lam), [q], [])

def u_base ( self , theta , phi , lam , q ) : return self . append ( UBase ( theta , phi , lam ) , [ q ] , [ ] )


def single_gate_params(gate, params=None):
    """Apply a single qubit gate to the qubit.

    Args:
        gate(str): the single qubit gate name
        params(list): the operation parameters op['params']
    Returns:
        tuple: a tuple of U gate parameters (theta, phi, lam)
    Raises:
        QiskitError: if the gate name is not valid
    """
    if gate in ('U', 'u3'):
        return params[0], params[1], params[2]
    elif gate == 'u2':
        return np.pi / 2, params[0], params[1]
    elif gate == 'u1':
        return 0, 0, params[0]
    elif gate == 'id':
        return 0, 0, 0
    raise QiskitError('Gate is not among the valid types: %s' % gate)

def
single_gate_params
(
gate
,
params
=
)
:
if
gate
in
(
'U'
,
'u3'
)
:
return
params
[
0
]
,
params
[
1
]
,
params
[
2
]
elif
gate
==
'u2'
:
return
np
.
pi
/
2
,
params
[
0
]
,
params
[
1
]
elif
gate
==
'u1'
:
return
0
,
0
,
params
[
0
]
elif
gate
==
'id'
:
return
0
,
0
,
0
raise
QiskitError
(
'Gate is not among the valid types: %s'
%
gate
)

Apply a single qubit gate to the qubit .


def single_gate_matrix(gate, params=None):
    """Get the matrix for a single qubit.

    Args:
        gate(str): the single qubit gate name
        params(list): the operation parameters op['params']
    Returns:
        array: A numpy array representing the matrix
    """

    # Converting sym to floats improves the performance of the simulator 10x.
    # This a is a probable a FIXME since it might show bugs in the simulator.
    (theta, phi, lam) = map(float, single_gate_params(gate, params))

    return np.array([[np.cos(theta / 2),
                      -np.exp(1j * lam) * np.sin(theta / 2)],
                     [np.exp(1j * phi) * np.sin(theta / 2),
                      np.exp(1j * phi + 1j * lam) * np.cos(theta / 2)]])

def single_gate_matrix ( gate , params = None ) : ( theta , phi , lam ) = map ( float , single_gate_params ( gate , params ) ) return np . array ( [ [ np . cos ( theta / 2 ) , - np . exp ( 1j * lam ) * np . sin ( theta / 2 ) ] , [ np . exp ( 1j * phi ) * np . sin ( theta / 2 ) , np . exp ( 1j * phi + 1j * lam ) * np . cos ( theta / 2 ) ] ] )


def einsum_matmul_index(gate_indices, number_of_qubits):
    """Return the index string for Numpy.eignsum matrix-matrix multiplication.

    The returned indices are to perform a matrix multiplication A.B where
    the matrix A is an M-qubit matrix, matrix B is an N-qubit matrix, and
    M <= N, and identity matrices are implied on the subsystems where A has no
    support on B.

    Args:
        gate_indices (list[int]): the indices of the right matrix subsystems
                                   to contract with the left matrix.
        number_of_qubits (int): the total number of qubits for the right matrix.

    Returns:
        str: An indices string for the Numpy.einsum function.
    """

    mat_l, mat_r, tens_lin, tens_lout = _einsum_matmul_index_helper(gate_indices,
                                                                    number_of_qubits)

    # Right indices for the N-qubit input and output tensor
    tens_r = ascii_uppercase[:number_of_qubits]

    # Combine indices into matrix multiplication string format
    # for numpy.einsum function
    return "{mat_l}{mat_r}, ".format(mat_l=mat_l, mat_r=mat_r) + \
           "{tens_lin}{tens_r}->{tens_lout}{tens_r}".format(tens_lin=tens_lin,
                                                            tens_lout=tens_lout,
                                                            tens_r=tens_r)

Return the index string for Numpy . eignsum matrix - matrix multiplication .


def einsum_vecmul_index(gate_indices, number_of_qubits):
    """Return the index string for Numpy.eignsum matrix-vector multiplication.

    The returned indices are to perform a matrix multiplication A.v where
    the matrix A is an M-qubit matrix, vector v is an N-qubit vector, and
    M <= N, and identity matrices are implied on the subsystems where A has no
    support on v.

    Args:
        gate_indices (list[int]): the indices of the right matrix subsystems
                                  to contract with the left matrix.
        number_of_qubits (int): the total number of qubits for the right matrix.

    Returns:
        str: An indices string for the Numpy.einsum function.
    """

    mat_l, mat_r, tens_lin, tens_lout = _einsum_matmul_index_helper(gate_indices,
                                                                    number_of_qubits)

    # Combine indices into matrix multiplication string format
    # for numpy.einsum function
    return "{mat_l}{mat_r}, ".format(mat_l=mat_l, mat_r=mat_r) + \
           "{tens_lin}->{tens_lout}".format(tens_lin=tens_lin,
                                            tens_lout=tens_lout)

Return the index string for Numpy . eignsum matrix - vector multiplication .


def _einsum_matmul_index_helper(gate_indices, number_of_qubits):
    """Return the index string for Numpy.eignsum matrix multiplication.

    The returned indices are to perform a matrix multiplication A.v where
    the matrix A is an M-qubit matrix, matrix v is an N-qubit vector, and
    M <= N, and identity matrices are implied on the subsystems where A has no
    support on v.

    Args:
        gate_indices (list[int]): the indices of the right matrix subsystems
                                   to contract with the left matrix.
        number_of_qubits (int): the total number of qubits for the right matrix.

    Returns:
        tuple: (mat_left, mat_right, tens_in, tens_out) of index strings for
        that may be combined into a Numpy.einsum function string.

    Raises:
        QiskitError: if the total number of qubits plus the number of
        contracted indices is greater than 26.
    """

    # Since we use ASCII alphabet for einsum index labels we are limited
    # to 26 total free left (lowercase) and 26 right (uppercase) indexes.
    # The rank of the contracted tensor reduces this as we need to use that
    # many characters for the contracted indices
    if len(gate_indices) + number_of_qubits > 26:
        raise QiskitError("Total number of free indexes limited to 26")

    # Indicies for N-qubit input tensor
    tens_in = ascii_lowercase[:number_of_qubits]

    # Indices for the N-qubit output tensor
    tens_out = list(tens_in)

    # Left and right indices for the M-qubit multiplying tensor
    mat_left = ""
    mat_right = ""

    # Update left indices for mat and output
    for pos, idx in enumerate(reversed(gate_indices)):
        mat_left += ascii_lowercase[-1 - pos]
        mat_right += tens_in[-1 - idx]
        tens_out[-1 - idx] = ascii_lowercase[-1 - pos]
    tens_out = "".join(tens_out)

    # Combine indices into matrix multiplication string format
    # for numpy.einsum function
    return mat_left, mat_right, tens_in, tens_out

Return the index string for Numpy . eignsum matrix multiplication .


def circuit_to_dag(circuit):
    """Build a ``DAGCircuit`` object from a ``QuantumCircuit``.

    Args:
        circuit (QuantumCircuit): the input circuit.

    Return:
        DAGCircuit: the DAG representing the input circuit.
    """
    dagcircuit = DAGCircuit()
    dagcircuit.name = circuit.name
    for register in circuit.qregs:
        dagcircuit.add_qreg(register)
    for register in circuit.cregs:
        dagcircuit.add_creg(register)

    for instruction, qargs, cargs in circuit.data:
        # Get arguments for classical control (if any)
        if instruction.control is None:
            control = None
        else:
            control = (instruction.control[0], instruction.control[1])

        dagcircuit.apply_operation_back(instruction.copy(),
                                        qargs, cargs, control)

    return dagcircuit

def circuit_to_dag ( circuit ) : dagcircuit = DAGCircuit ( ) dagcircuit . name = circuit . name for register in circuit . qregs : dagcircuit . add_qreg ( register ) for register in circuit . cregs : dagcircuit . add_creg ( register ) for instruction , qargs , cargs in circuit . data : if instruction . control is None : control = None else : control = ( instruction . control [ 0 ] , instruction . control [ 1 ] ) dagcircuit . apply_operation_back ( instruction . copy ( ) , qargs , cargs , control ) return dagcircuit

Build a DAGCircuit object from a QuantumCircuit .


def exp_fit_fun(x, a, tau, c):
    """Function used to fit the exponential decay."""
    # pylint: disable=invalid-name
    return a * np.exp(-x / tau) + c

def exp_fit_fun ( x , a , tau , c ) : return a * np . exp ( - x / tau ) + c

Function used to fit the exponential decay .


def osc_fit_fun(x, a, tau, f, phi, c):
    """Function used to fit the decay cosine."""
    # pylint: disable=invalid-name
    return a * np.exp(-x / tau) * np.cos(2 * np.pi * f * x + phi) + c

def osc_fit_fun ( x , a , tau , f , phi , c ) : return a * np . exp ( - x / tau ) * np . cos ( 2 * np . pi * f * x + phi ) + c


def plot_coherence(xdata, ydata, std_error, fit, fit_function, xunit, exp_str,
                   qubit_label):
    """Plot coherence data.

    Args:
        xdata
        ydata
        std_error
        fit
        fit_function
        xunit
        exp_str
        qubit_label
    Raises:
        ImportError: If matplotlib is not installed.
    """
    if not HAS_MATPLOTLIB:
        raise ImportError('The function plot_coherence needs matplotlib. '
                          'Run "pip install matplotlib" before.')
    plt.errorbar(xdata, ydata, std_error, marker='.',
                 markersize=9, c='b', linestyle='')
    plt.plot(xdata, fit_function(xdata, *fit), c='r', linestyle='--',
             label=(exp_str + '= %s %s' % (str(round(fit[1])), xunit)))
    plt.xticks(fontsize=14, rotation=70)
    plt.yticks(fontsize=14)
    plt.xlabel('time [%s]' % (xunit), fontsize=16)
    plt.ylabel('P(1)', fontsize=16)
    plt.title(exp_str + ' measurement of Q$_{%s}$' % (str(qubit_label)), fontsize=18)
    plt.legend(fontsize=12)
    plt.grid(True)
    plt.show()


def shape_rb_data(raw_rb):
    """Take the raw rb data and convert it into averages and std dev

    Args:
        raw_rb (numpy.array): m x n x l list where m is the number of seeds, n
            is the number of Clifford sequences and l is the number of qubits

    Return:
        numpy_array: 2 x n x l list where index 0 is the mean over seeds, 1 is
            the std dev overseeds
    """
    rb_data = []
    rb_data.append(np.mean(raw_rb, 0))
    rb_data.append(np.std(raw_rb, 0))

    return rb_data

def shape_rb_data ( raw_rb ) : rb_data = [ ] rb_data . append ( np . mean ( raw_rb , 0 ) ) rb_data . append ( np . std ( raw_rb , 0 ) ) return rb_data


def plot_rb_data(xdata, ydatas, yavg, yerr, fit, survival_prob, ax=None,
                 show_plt=True):
    """Plot randomized benchmarking data.

    Args:
        xdata (list): list of subsequence lengths
        ydatas (list): list of lists of survival probabilities for each
            sequence
        yavg (list): mean of the survival probabilities at each sequence
            length
        yerr (list): error of the survival
        fit (list): fit parameters
        survival_prob (callable): function that computes survival probability
        ax (Axes or None): plot axis (if passed in)
        show_plt (bool): display the plot.

    Raises:
        ImportError: If matplotlib is not installed.
    """
    # pylint: disable=invalid-name

    if not HAS_MATPLOTLIB:
        raise ImportError('The function plot_rb_data needs matplotlib. '
                          'Run "pip install matplotlib" before.')
    if ax is None:
        plt.figure()
        ax = plt.gca()

    # Plot the result for each sequence
    for ydata in ydatas:
        ax.plot(xdata, ydata, color='gray', linestyle='none', marker='x')
    # Plot the mean with error bars
    ax.errorbar(xdata, yavg, yerr=yerr, color='r', linestyle='--', linewidth=3)

    # Plot the fit
    ax.plot(xdata, survival_prob(xdata, *fit), color='blue', linestyle='-', linewidth=2)
    ax.tick_params(labelsize=14)
    # ax.tick_params(axis='x',labelrotation=70)

    ax.set_xlabel('Clifford Length', fontsize=16)
    ax.set_ylabel('Z', fontsize=16)
    ax.grid(True)

    if show_plt:
        plt.show()


def _split_runs_on_parameters(runs):
    """Finds runs containing parameterized gates and splits them into sequential
    runs excluding the parameterized gates.
    """

    def _is_dagnode_parameterized(node):
        return any(isinstance(param, Parameter) for param in node.op.params)

    out = []
    for run in runs:
        groups = groupby(run, _is_dagnode_parameterized)

        for group_is_parameterized, gates in groups:
            if not group_is_parameterized:
                out.append(list(gates))

    return out

def _split_runs_on_parameters ( runs ) : def _is_dagnode_parameterized ( node ) : return any ( isinstance ( param , Parameter ) for param in node . op . params ) out = [ ] for run in runs : groups = groupby ( run , _is_dagnode_parameterized ) for group_is_parameterized , gates in groups : if not group_is_parameterized : out . append ( list ( gates ) ) return out

Finds runs containing parameterized gates and splits them into sequential runs excluding the parameterized gates .


def compose_u3(theta1, phi1, lambda1, theta2, phi2, lambda2):
        """Return a triple theta, phi, lambda for the product.

        u3(theta, phi, lambda)
           = u3(theta1, phi1, lambda1).u3(theta2, phi2, lambda2)
           = Rz(phi1).Ry(theta1).Rz(lambda1+phi2).Ry(theta2).Rz(lambda2)
           = Rz(phi1).Rz(phi').Ry(theta').Rz(lambda').Rz(lambda2)
           = u3(theta', phi1 + phi', lambda2 + lambda')

        Return theta, phi, lambda.
        """
        # Careful with the factor of two in yzy_to_zyz
        thetap, phip, lambdap = Optimize1qGates.yzy_to_zyz((lambda1 + phi2), theta1, theta2)
        (theta, phi, lamb) = (thetap, phi1 + phip, lambda2 + lambdap)

        return (theta, phi, lamb)

def compose_u3 ( theta1 , phi1 , lambda1 , theta2 , phi2 , lambda2 ) : thetap , phip , lambdap = Optimize1qGates . yzy_to_zyz ( ( lambda1 + phi2 ) , theta1 , theta2 ) ( theta , phi , lamb ) = ( thetap , phi1 + phip , lambda2 + lambdap ) return ( theta , phi , lamb )

Return a triple theta phi lambda for the product .