name = name.lower()<EOL>if name not in VALIDATORS:<EOL><INDENT>raise ValueError(<EOL>"<STR_LIT>".format(name))<EOL><DEDENT>valid = VALIDATORS[name](config_node)<EOL>if valid.name is None:  <EOL><INDENT>valid.name = name<EOL><DEDENT>if valid.config is None:  <EOL><INDENT>valid.config = config_node<EOL><DEDENT>return valid<EOL>

Parse a validator from configuration and use it


name = name.lower()<EOL>if name in VALIDATORS:<EOL><INDENT>raise Exception("<STR_LIT>".format(name))<EOL><DEDENT>VALIDATORS[name] = parse_function<EOL>

Registers a validator for use by this library
        Name is the string name for validator

        Parse function does parse(config_node) and returns a Validator object
        Validator functions have signature:
            validate(response_body, context=None) - context is a bindings.Context object

        Validators return true or false and optionally can return a Failure instead of false
        This allows for passing more details


if not isinstance(extractor_name, basestring):<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>if extractor_name.lower() == '<STR_LIT>':<EOL><INDENT>raise ValueError(<EOL>"<STR_LIT>")<EOL><DEDENT>elif extractor_name.lower() == '<STR_LIT:test>':<EOL><INDENT>raise ValueError(<EOL>"<STR_LIT>")<EOL><DEDENT>elif extractor_name.lower() == '<STR_LIT>':<EOL><INDENT>raise ValueError(<EOL>"<STR_LIT>")<EOL><DEDENT>elif extractor_name in EXTRACTORS:<EOL><INDENT>raise ValueError(<EOL>"<STR_LIT>".format(extractor_name))<EOL><DEDENT>EXTRACTORS[extractor_name] = parse_function<EOL>


if not isinstance(comparator_name, basestring):<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>elif comparator_name in COMPARATORS:<EOL><INDENT>raise ValueError(<EOL>"<STR_LIT>".format(comparator_name))<EOL><DEDENT>COMPARATORS[comparator_name] = comparator_function<EOL>

Register a new twpo-argument comparator function returning true or false


return False<EOL>

Failure objects test as False, simplifies coding with them


return False<EOL>


def extract_internal(self, query=None, body=None, headers=None, args=None):

pass<EOL>

Do extraction, query should be pre-templated


def extract(self, body=None, headers=None, context=None):

query = self.templated_query(context=context)<EOL>args = self.args<EOL>return self.extract_internal(query=query, body=body, headers=headers, args=self.args)<EOL>


query = self.templated_query(context=context)<EOL>output = '<STR_LIT>'.format(<EOL>self.extractor_type, query, self.is_templated)<EOL>args_string = None<EOL>if self.args:<EOL><INDENT>args_string = "<STR_LIT>" + str(self.args)<EOL>output = output + args_string<EOL><DEDENT>return output<EOL>

Print a human-readable version of the configuration


@classmethod<EOL><INDENT>def configure_base(cls, config, extractor_base):<DEDENT>

if isinstance(config, dict):<EOL><INDENT>try:<EOL><INDENT>config = config['<STR_LIT>']<EOL>extractor_base.is_templated = True<EOL>extractor_base.query = config<EOL><DEDENT>except KeyError:<EOL><INDENT>raise ValueError(<EOL>"<STR_LIT>")<EOL><DEDENT><DEDENT>elif isinstance(config, basestring):<EOL><INDENT>extractor_base.query = config<EOL>extractor_base.is_templated = False<EOL><DEDENT>else:<EOL><INDENT>raise TypeError(<EOL>"<STR_LIT>")<EOL><DEDENT>return extractor_base<EOL>

Parse config object and do basic config on an Extractor


@staticmethod<EOL><INDENT>def query_dictionary(query, dictionary, delimiter='<STR_LIT:.>'):<DEDENT>

<EOL>try:<EOL><INDENT>stripped_query = query.strip(delimiter)<EOL>if stripped_query:<EOL><INDENT>for x in stripped_query.split(delimiter):<EOL><INDENT>try:<EOL><INDENT>x = int(x)<EOL>dictionary = dictionary[x]<EOL><DEDENT>except ValueError:<EOL><INDENT>dictionary = dictionary[x]<EOL><DEDENT><DEDENT><DEDENT><DEDENT>except:<EOL><INDENT>return None<EOL><DEDENT>return dictionary<EOL>

Do an xpath-like query with dictionary, using a template if relevant


def validate(self, body=None, headers=None, context=None):

pass<EOL>

Run the validation function, return true or a Failure


string_frags = list()<EOL>string_frags.append(<EOL>"<STR_LIT>" + self.extractor.get_readable_config(context=context))<EOL>if isinstance(self.expected, AbstractExtractor):<EOL><INDENT>string_frags.append("<STR_LIT>" +<EOL>self.expected.get_readable_config(context=context))<EOL><DEDENT>elif self.isTemplateExpected:<EOL><INDENT>string_frags.append(<EOL>'<STR_LIT>'.format(self.expected))<EOL><DEDENT>return os.linesep.join(string_frags)<EOL>


output = ComparatorValidator()<EOL>config = parsing.lowercase_keys(parsing.flatten_dictionaries(config))<EOL>output.config = config<EOL>output.extractor = _get_extractor(config)<EOL>if output.extractor is None:<EOL><INDENT>raise ValueError(<EOL>"<STR_LIT>")<EOL><DEDENT>if '<STR_LIT>' not in config:  <EOL><INDENT>output.comparator_name = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>output.comparator_name = config['<STR_LIT>'].lower()<EOL><DEDENT>output.comparator = COMPARATORS[output.comparator_name]<EOL>if not output.comparator:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>try:<EOL><INDENT>expected = config['<STR_LIT>']<EOL><DEDENT>except KeyError:<EOL><INDENT>raise ValueError(<EOL>"<STR_LIT>")<EOL><DEDENT>if isinstance(expected, basestring) or isinstance(expected, (int, long, float, complex)):<EOL><INDENT>output.expected = expected<EOL><DEDENT>elif isinstance(expected, dict):<EOL><INDENT>expected = parsing.lowercase_keys(expected)<EOL>template = expected.get('<STR_LIT>')<EOL>if template:  <EOL><INDENT>if not isinstance(template, basestring):<EOL><INDENT>raise ValueError(<EOL>"<STR_LIT>")<EOL><DEDENT>output.isTemplateExpected = True<EOL>output.expected = template<EOL><DEDENT>else:  <EOL><INDENT>output.expected = _get_extractor(expected)<EOL>if not output.expected:<EOL><INDENT>raise ValueError(<EOL>"<STR_LIT>")<EOL><DEDENT><DEDENT><DEDENT>return output<EOL>

Create a validator that does an extract from body and applies a comparator,
            Then does comparison vs expected value
            Syntax sample:
              { jsonpath_mini: 'node.child',
                operator: 'eq',
                expected: 'myValue'
              }


return "<STR_LIT>" + self.extractor.get_readable_config(context=context)<EOL>


func.__doc__ = doc<EOL>


__import__(name)<EOL>return sys.modules[name]<EOL>

Import module, returning the module after the last dot.


setattr(_MovedItems, move.name, move)<EOL>


try:<EOL><INDENT>delattr(_MovedItems, name)<EOL><DEDENT>except AttributeError:<EOL><INDENT>try:<EOL><INDENT>del moves.__dict__[name]<EOL><DEDENT>except KeyError:<EOL><INDENT>raise AttributeError("<STR_LIT>" % (name,))<EOL><DEDENT><DEDENT>


<EOL>class metaclass(meta):<EOL><INDENT>def __new__(cls, name, this_bases, d):<EOL><INDENT>return meta(name, bases, d)<EOL><DEDENT><DEDENT>return type.__new__(metaclass, '<STR_LIT>', (), {})<EOL>


def wrapper(cls):<EOL><INDENT>orig_vars = cls.__dict__.copy()<EOL>slots = orig_vars.get('<STR_LIT>')<EOL>if slots is not None:<EOL><INDENT>if isinstance(slots, str):<EOL><INDENT>slots = [slots]<EOL><DEDENT>for slots_var in slots:<EOL><INDENT>orig_vars.pop(slots_var)<EOL><DEDENT><DEDENT>orig_vars.pop('<STR_LIT>', None)<EOL>orig_vars.pop('<STR_LIT>', None)<EOL>return metaclass(cls.__name__, cls.__bases__, orig_vars)<EOL><DEDENT>return wrapper<EOL>

Class decorator for creating a class with a metaclass.


if PY2:<EOL><INDENT>if '<STR_LIT>' not in klass.__dict__:<EOL><INDENT>raise ValueError("<STR_LIT>"<EOL>"<STR_LIT>" %<EOL>klass.__name__)<EOL><DEDENT>klass.__unicode__ = klass.__str__<EOL>klass.__str__ = lambda self: self.__unicode__().encode('<STR_LIT:utf-8>')<EOL><DEDENT>return klass<EOL>

A decorator that defines __unicode__ and __str__ methods under Python 2.
Under Python 3 it does nothing.

To support Python 2 and 3 with a single code base, define a __str__ method
returning text and apply this decorator to the class.


return hasattr(self.__get_module(fullname), "<STR_LIT>")<EOL>

Return true, if the named module is a package.

We need this method to get correct spec objects with
Python 3.4 (see PEP451)


self.__get_module(fullname)  <EOL>return None<EOL>

Return None

        Required, if is_package is implemented


return self.is_template_path or self.is_template_content<EOL>


if self.is_file:<EOL><INDENT>path = self.content<EOL>if self.is_template_path and context:<EOL><INDENT>path = string.Template(path).safe_substitute(<EOL>context.get_values())<EOL><DEDENT>data = None<EOL>with open(path, '<STR_LIT:r>') as f:<EOL><INDENT>data = f.read()<EOL><DEDENT>if self.is_template_content and context:<EOL><INDENT>return string.Template(data).safe_substitute(context.get_values())<EOL><DEDENT>else:<EOL><INDENT>return data<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if self.is_template_content and context:<EOL><INDENT>return safe_substitute_unicode_template(self.content, context.get_values())<EOL><DEDENT>else:<EOL><INDENT>return self.content<EOL><DEDENT><DEDENT>

Does all context binding and pathing to get content, templated out


if not self.is_file or self.is_template_path:<EOL><INDENT>return self<EOL><DEDENT>output = ContentHandler()<EOL>output.is_template_content = self.is_template_content<EOL>with open(self.content, '<STR_LIT:r>') as f:<EOL><INDENT>output.content = f.read()<EOL><DEDENT>return output<EOL>

Read file content if it is static and return content handler with no I/O


def setup(self, input, is_file=False, is_template_path=False, is_template_content=False):

if not isinstance(input, basestring):<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>if is_file:<EOL><INDENT>input = os.path.abspath(input)<EOL><DEDENT>self.content = input<EOL>self.is_file = is_file<EOL>self.is_template_path = is_template_path<EOL>self.is_template_content = is_template_content<EOL>

Self explanatory, input is inline content or file path.


<EOL>output = ContentHandler()<EOL>is_template_path = False<EOL>is_template_content = False<EOL>is_file = False<EOL>is_done = False<EOL>while (node and not is_done):  <EOL><INDENT>if isinstance(node, basestring):<EOL><INDENT>output.content = node<EOL>output.setup(node, is_file=is_file, is_template_path=is_template_path,<EOL>is_template_content=is_template_content)<EOL>return output<EOL><DEDENT>elif not isinstance(node, dict) and not isinstance(node, list):<EOL><INDENT>raise TypeError(<EOL>"<STR_LIT>")<EOL><DEDENT>is_done = True<EOL>flat = lowercase_keys(flatten_dictionaries(node))<EOL>for key, value in flat.items():<EOL><INDENT>if key == u'<STR_LIT>':<EOL><INDENT>if isinstance(value, basestring):<EOL><INDENT>if is_file:<EOL><INDENT>value = os.path.abspath(value)<EOL><DEDENT>output.content = value<EOL>is_template_content = is_template_content or not is_file<EOL>output.is_template_content = is_template_content<EOL>output.is_template_path = is_file<EOL>output.is_file = is_file<EOL>return output<EOL><DEDENT>else:<EOL><INDENT>is_template_content = True<EOL>node = value<EOL>is_done = False<EOL>break<EOL><DEDENT><DEDENT>elif key == '<STR_LIT:file>':<EOL><INDENT>if isinstance(value, basestring):<EOL><INDENT>output.content = os.path.abspath(value)<EOL>output.is_file = True<EOL>output.is_template_content = is_template_content<EOL>return output<EOL><DEDENT>else:<EOL><INDENT>is_file = True<EOL>node = value<EOL>is_done = False<EOL>break<EOL><DEDENT><DEDENT><DEDENT><DEDENT>raise Exception("<STR_LIT>")<EOL>

Parse content from input node and returns ContentHandler object
        it'll look like:

            - template:
                - file:
                    - temple: path

            or something


def generate_started_ids():<EOL><INDENT>val = starting_id<EOL>local_increment = increment<EOL>while(True):<EOL><INDENT>yield val<EOL>val += local_increment<EOL><DEDENT><DEDENT>return generate_started_ids<EOL>

Return function generator for ids starting at starting_id
        Note: needs to be called with () to make generator


return factory_generate_ids(<NUM_LIT:1>)()<EOL>


rand = random.Random()<EOL>while (True):<EOL><INDENT>yield random.randint(<NUM_LIT:0>, INT32_MAX_VALUE)<EOL><DEDENT>

Random integer generator for up to 32-bit signed ints


def factory_generate_text(legal_characters=string.ascii_letters, min_length=<NUM_LIT:8>, max_length=<NUM_LIT:8>):

def generate_text():<EOL><INDENT>local_min_len = min_length<EOL>local_max_len = max_length<EOL>rand = random.Random()<EOL>while(True):<EOL><INDENT>length = random.randint(local_min_len, local_max_len)<EOL>array = [random.choice(legal_characters)<EOL>for x in xrange(<NUM_LIT:0>, length)]<EOL>yield '<STR_LIT>'.join(array)<EOL><DEDENT><DEDENT>return generate_text<EOL>

Returns a generator function for text with given legal_characters string and length
        Default is ascii letters, length 8

        For hex digits, combine with string.hexstring, etc


def seq_generator():<EOL><INDENT>my_list = list(values)<EOL>i = <NUM_LIT:0><EOL>while(True):<EOL><INDENT>yield my_list[i]<EOL>if i == len(my_list):<EOL><INDENT>i = <NUM_LIT:0><EOL><DEDENT><DEDENT><DEDENT>return seq_generator<EOL>

Return a generator that runs through a list of values in order, looping after end


vals = config['<STR_LIT>']<EOL>if not vals:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>if not isinstance(vals, list):<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>return factory_fixed_sequence(vals)()<EOL>


def choice_generator():<EOL><INDENT>my_list = list(values)<EOL>rand = random.Random()<EOL>while(True):<EOL><INDENT>yield random.choice(my_list)<EOL><DEDENT><DEDENT>return choice_generator<EOL>

Return a generator that picks values from a list randomly


vals = config['<STR_LIT>']<EOL>if not vals:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>if not isinstance(vals, list):<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>return factory_choice_generator(vals)()<EOL>


def return_variable():<EOL><INDENT>variable_name = env_variable<EOL>while(True):<EOL><INDENT>yield os.environ.get(variable_name)<EOL><DEDENT><DEDENT>return return_variable<EOL>

Return a generator function that reads from an environment variable


def return_variable():<EOL><INDENT>my_input = env_string<EOL>while(True):<EOL><INDENT>yield os.path.expandvars(my_input)<EOL><DEDENT><DEDENT>return return_variable<EOL>

Return a generator function that uses OS expand path to expand environment variables in string


character_set = configuration.get(u'<STR_LIT>')<EOL>characters = None<EOL>if character_set:<EOL><INDENT>character_set = character_set.lower()<EOL>if character_set not in CHARACTER_SETS:<EOL><INDENT>raise ValueError(<EOL>"<STR_LIT>".format(character_set))<EOL><DEDENT>characters = CHARACTER_SETS[character_set]<EOL><DEDENT>else:  <EOL><INDENT>characters = str(configuration.get(u'<STR_LIT>'))<EOL><DEDENT>min_length = <NUM_LIT:8><EOL>max_length = <NUM_LIT:8><EOL>if configuration.get(u'<STR_LIT>'):<EOL><INDENT>min_length = int(configuration.get(u'<STR_LIT>'))<EOL><DEDENT>if configuration.get(u'<STR_LIT:max_length>'):<EOL><INDENT>max_length = int(configuration.get(u'<STR_LIT:max_length>'))<EOL><DEDENT>if configuration.get(u'<STR_LIT>'):<EOL><INDENT>length = int(configuration.get(u'<STR_LIT>'))<EOL>min_length = length<EOL>max_length = length<EOL><DEDENT>if characters:<EOL><INDENT>return factory_generate_text(legal_characters=characters, min_length=min_length, max_length=max_length)()<EOL><DEDENT>else:<EOL><INDENT>return factory_generate_text(min_length=min_length, max_length=max_length)()<EOL><DEDENT>

Parses configuration options for a random text generator


if not isinstance(typename, basestring):<EOL><INDENT>raise TypeError(<EOL>'<STR_LIT>'.format(typename))<EOL><DEDENT>if typename in GENERATOR_TYPES:<EOL><INDENT>raise ValueError(<EOL>'<STR_LIT>'.format(typename))<EOL><DEDENT>GENERATOR_TYPES.add(typename)<EOL>GENERATOR_PARSING[typename] = parse_function<EOL>

Register a new generator for use in testing
        typename is the new generator type name (must not already exist)
        parse_function will parse a configuration object (dict)


configuration = lowercase_keys(flatten_dictionaries(configuration))<EOL>gen_type = str(configuration.get(u'<STR_LIT:type>')).lower()<EOL>if gen_type not in GENERATOR_TYPES:<EOL><INDENT>raise ValueError(<EOL>'<STR_LIT>'.format(gen_type))<EOL><DEDENT>if gen_type == u'<STR_LIT>':<EOL><INDENT>return factory_env_variable(configuration[u'<STR_LIT>'])()<EOL><DEDENT>elif gen_type == u'<STR_LIT>':<EOL><INDENT>return factory_env_string(configuration[u'<STR_LIT:string>'])()<EOL><DEDENT>elif gen_type == u'<STR_LIT>':<EOL><INDENT>start = configuration.get('<STR_LIT:start>')<EOL>increment = configuration.get('<STR_LIT>')<EOL>if not start:<EOL><INDENT>start = <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>start = int(start)<EOL><DEDENT>if not increment:<EOL><INDENT>increment = <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>increment = int(increment)<EOL><DEDENT>return factory_generate_ids(start, increment)()<EOL><DEDENT>elif gen_type == u'<STR_LIT>':<EOL><INDENT>return generator_random_int32()<EOL><DEDENT>elif gen_type == u'<STR_LIT>':<EOL><INDENT>return parse_random_text_generator(configuration)<EOL><DEDENT>elif gen_type in GENERATOR_TYPES:<EOL><INDENT>return GENERATOR_PARSING[gen_type](configuration)<EOL><DEDENT>else:<EOL><INDENT>raise Exception("<STR_LIT>".format('<STR_LIT>'))<EOL><DEDENT>

Parses a configuration built from yaml and returns a generator
        Configuration should be a map


if not isinstance(my_string, basestring):<EOL><INDENT>my_string = repr(my_string)<EOL><DEDENT>if PYTHON_MAJOR_VERSION == <NUM_LIT:2>:<EOL><INDENT>if isinstance(my_string, str):<EOL><INDENT>return my_string<EOL><DEDENT>elif isinstance(my_string, unicode):<EOL><INDENT>return my_string.encode('<STR_LIT:utf-8>')<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if isinstance(my_string, str):<EOL><INDENT>return my_string.encode('<STR_LIT:utf-8>')<EOL><DEDENT>elif isinstance(my_string, bytes):<EOL><INDENT>return my_string<EOL><DEDENT><DEDENT>

Shim function, converts Unicode to UTF-8 encoded bytes regardless of the source format
        Intended for python 3 compatibility mode, and b/c PyCurl only takes raw bytes


if PYTHON_MAJOR_VERSION > <NUM_LIT:2>:  <EOL><INDENT>return string.Template(templated_string).safe_substitute(variable_map)<EOL><DEDENT>my_template = string.Template(encode_unicode_bytes(templated_string))<EOL>my_escaped_dict = dict(map(lambda x: (x[<NUM_LIT:0>], encode_unicode_bytes(x[<NUM_LIT:1>])), variable_map.items()))<EOL>templated = my_template.safe_substitute(my_escaped_dict)<EOL>return text_type(templated, '<STR_LIT:utf-8>')<EOL>

Perform string.Template safe_substitute on unicode input with unicode variable values by using escapes
        Catch: cannot accept unicode variable names, just values
        Returns a Unicode type output, if you want UTF-8 bytes, do encode_unicode_bytes on it


if isinstance(in_obj, bytearray):<EOL><INDENT>return str(in_obj)<EOL><DEDENT>if hasattr(in_obj, '<STR_LIT>'):<EOL><INDENT>return in_obj.__dict__<EOL><DEDENT>try:<EOL><INDENT>return str(in_obj)<EOL><DEDENT>except:<EOL><INDENT>return repr(in_obj)<EOL><DEDENT>

Safely get dict from object if present for json dumping


output = dict()<EOL>if isinstance(input, list):<EOL><INDENT>for map in input:<EOL><INDENT>output.update(map)<EOL><DEDENT><DEDENT>else:  <EOL><INDENT>output = input<EOL><DEDENT>return output<EOL>

Flatten a list of dictionaries into a single dictionary, to allow flexible YAML use
      Dictionary comprehensions can do this, but would like to allow for pre-Python 2.7 use
      If input isn't a list, just return it....


if not isinstance(input_dict, dict):<EOL><INDENT>return input_dict<EOL><DEDENT>safe = dict()<EOL>for key, value in input_dict.items():<EOL><INDENT>safe[str(key).lower()] = value<EOL><DEDENT>return safe<EOL>

Take input and if a dictionary, return version with keys all lowercase and cast to str


if isinstance(input, bool):<EOL><INDENT>return input<EOL><DEDENT>elif isinstance(input, basestring) and input.lower() == u'<STR_LIT:false>':<EOL><INDENT>return False<EOL><DEDENT>elif isinstance(input, basestring) and input.lower() == u'<STR_LIT:true>':<EOL><INDENT>return True<EOL><DEDENT>else:<EOL><INDENT>raise TypeError(<EOL>'<STR_LIT>')<EOL><DEDENT>

Safely convert user input to a boolean, throwing exception if not boolean or boolean-appropriate string
      For flexibility, we allow case insensitive string matching to false/true values
      If it's not a boolean or string that matches 'false' or 'true' when ignoring case, throws an exception


def run_configure(self, key, value, configurable, validator_func=None, converter_func=None, store_func=None, *args, **kwargs):

if validator_func and not validator(value):<EOL><INDENT>raise TypeError("<STR_LIT>".format(value))<EOL><DEDENT>storeable = value<EOL>if converter_func:<EOL><INDENT>storeable = converter_func(value)<EOL><DEDENT>if store_func:<EOL><INDENT>store_func(configurable, key, storeable)<EOL><DEDENT>else:<EOL><INDENT>configurable.setattr(configurable, key, value)<EOL><DEDENT>

Run a single configuration element
            Run a validator on the value, if supplied
            Run a converter_funct to turn the value into something to storeable:
                converter_func takes params (value) at least and throws exception if failed
            If a  store_func is supplied, use that to store the option
              store_func needs to take params (object, key, value, args, kwargs)
            If store_func NOT supplied we do a setattr on object


def configure(self, configs, configurable, handler, *args, **kwargs):

for key, value in configs.items():<EOL><INDENT>handler[key] = config_options<EOL>self.run_configure(value, configurable)<EOL><DEDENT>

Use the configs and configurable to parse


if isinstance(val, list):<EOL><INDENT>return [int(x) for x in val]<EOL><DEDENT>else:<EOL><INDENT>return [int(val)]<EOL><DEDENT>

If single value, try to parse as integer, else try to parse as list of integer


output = Test()<EOL>myvars = vars(self)<EOL>output.__dict__ = myvars.copy()<EOL>return output<EOL>

Optimization: limited copy of test object, for realize() methods
            This only copies fields changed vs. class, and keeps methods the same


def set_template(self, variable_name, template_string):

if self.templates is None:<EOL><INDENT>self.templates = dict()<EOL><DEDENT>self.templates[variable_name] = string.Template(template_string)<EOL>

Add a templating instance for variable given


if self.templates is not None and variable_name in self.templates:<EOL><INDENT>del self.templates[variable_name]<EOL><DEDENT>

Remove template instance, so we no longer use one for this test


def realize_template(self, variable_name, context):

val = None<EOL>if context is None or self.templates is None or variable_name not in self.templates:<EOL><INDENT>return None<EOL><DEDENT>return self.templates[variable_name].safe_substitute(context.get_values())<EOL>

Realize a templated value, using variables from context
            Returns None if no template is set for that variable


self._body = value<EOL>


if self._body is None:<EOL><INDENT>return None<EOL><DEDENT>elif isinstance(self._body, basestring):<EOL><INDENT>return self._body<EOL><DEDENT>else:<EOL><INDENT>return self._body.get_content(context=context)<EOL><DEDENT>

Read body from file, applying template if pertinent


def set_url(self, value, isTemplate=False):

if isTemplate:<EOL><INDENT>self.set_template(self.NAME_URL, value)<EOL><DEDENT>else:<EOL><INDENT>self.del_template(self.NAME_URL)<EOL><DEDENT>self._url = value<EOL>

Set URL, passing flag if using a template


val = self.realize_template(self.NAME_URL, context)<EOL>if val is None:<EOL><INDENT>val = self._url<EOL><DEDENT>return val<EOL>


def set_headers(self, value, isTemplate=False):

if isTemplate:<EOL><INDENT>self.set_template(self.NAME_HEADERS, '<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>self.del_template(self.NAME_HEADERS)<EOL><DEDENT>self._headers = value<EOL>

Set headers, passing flag if using a template


if not context or not self.templates or self.NAME_HEADERS not in self.templates:<EOL><INDENT>return self._headers<EOL><DEDENT>vals = context.get_values()<EOL>def template_tuple(tuple_input):<EOL><INDENT>return (string.Template(str(tuple_item)).safe_substitute(vals) for tuple_item in tuple_input)<EOL><DEDENT>return dict(map(template_tuple, self._headers.items()))<EOL>

Get headers, applying template if pertinent


if self.variable_binds:<EOL><INDENT>context.bind_variables(self.variable_binds)<EOL><DEDENT>if self.generator_binds:<EOL><INDENT>for key, value in self.generator_binds.items():<EOL><INDENT>context.bind_generator_next(key, value)<EOL><DEDENT><DEDENT>

Make pre-test context updates, by applying variable and generator updates


def update_context_after(self, response_body, headers, context):

if self.extract_binds:<EOL><INDENT>for key, value in self.extract_binds.items():<EOL><INDENT>result = value.extract(<EOL>body=response_body, headers=headers, context=context)<EOL>context.bind_variable(key, result)<EOL><DEDENT><DEDENT>

Run the extraction routines to update variables based on HTTP response body


return self.variable_binds or self.generator_binds or self.extract_binds<EOL>

Returns true if context can be modified by this test
            (disallows caching of templated test bodies)


if self.templates:<EOL><INDENT>return True<EOL><DEDENT>elif isinstance(self._body, ContentHandler) and self._body.is_dynamic():<EOL><INDENT>return True<EOL><DEDENT>return False<EOL>

Returns true if this test does templating


if not self.is_dynamic() or context is None:<EOL><INDENT>return self<EOL><DEDENT>else:<EOL><INDENT>selfcopy = self.ninja_copy()<EOL>selfcopy.templates = None<EOL>if isinstance(self._body, ContentHandler):<EOL><INDENT>selfcopy._body = self._body.get_content(context)<EOL><DEDENT>selfcopy._url = self.get_url(context=context)<EOL>selfcopy._headers = self.get_headers(context=context)<EOL>return selfcopy<EOL><DEDENT>

Return a fully-templated test object, for configuring curl
            Warning: this is a SHALLOW copy, mutation of fields will cause problems!
            Can accept a None context


if self.is_context_modifier():<EOL><INDENT>return self<EOL><DEDENT>elif self.is_dynamic():  <EOL><INDENT>return self.realize(context=context)<EOL><DEDENT>bod = self._body<EOL>newbod = None<EOL>if bod and isinstance(bod, ContentHandler) and bod.is_file and not bod.is_template_path:<EOL><INDENT>newbod = bod.create_noread_version()<EOL><DEDENT>output = self<EOL>if newbod:  <EOL><INDENT>output = copy.copy(self)<EOL>output._body = newbod<EOL><DEDENT>return output<EOL>

Attempt to template out what is static if possible, and load files.
            Used for performance optimization, in cases where a test is re-run repeatedly
            WITH THE SAME Context.


def configure_curl(self, timeout=DEFAULT_TIMEOUT, context=None, curl_handle=None):

if curl_handle:<EOL><INDENT>curl = curl_handle<EOL>try:  <EOL><INDENT>curl.getinfo(curl.HTTP_CODE)                <EOL>curl.reset()<EOL>curl.setopt(curl.COOKIELIST, "<STR_LIT>")<EOL><DEDENT>except pycurl.error:<EOL><INDENT>curl = pycurl.Curl()<EOL><DEDENT><DEDENT>else:<EOL><INDENT>curl = pycurl.Curl()<EOL><DEDENT>curl.setopt(curl.URL, str(self.url))<EOL>curl.setopt(curl.TIMEOUT, timeout)<EOL>is_unicoded = False<EOL>bod = self.body<EOL>if isinstance(bod, text_type):  <EOL><INDENT>bod = bod.encode('<STR_LIT>')<EOL>is_unicoded = True<EOL><DEDENT>if bod and len(bod) > <NUM_LIT:0>:<EOL><INDENT>curl.setopt(curl.READFUNCTION, MyIO(bod).read)<EOL><DEDENT>if self.auth_username and self.auth_password:<EOL><INDENT>curl.setopt(pycurl.USERPWD, <EOL>parsing.encode_unicode_bytes(self.auth_username) + b'<STR_LIT::>' + <EOL>parsing.encode_unicode_bytes(self.auth_password))<EOL>if self.auth_type:<EOL><INDENT>curl.setopt(pycurl.HTTPAUTH, self.auth_type)<EOL><DEDENT><DEDENT>if self.method == u'<STR_LIT:POST>':<EOL><INDENT>curl.setopt(HTTP_METHODS[u'<STR_LIT:POST>'], <NUM_LIT:1>)<EOL>if bod is not None:<EOL><INDENT>curl.setopt(pycurl.POSTFIELDSIZE, len(bod))<EOL><DEDENT>else:<EOL><INDENT>curl.setopt(pycurl.POSTFIELDSIZE, <NUM_LIT:0>)<EOL><DEDENT><DEDENT>elif self.method == u'<STR_LIT>':<EOL><INDENT>curl.setopt(HTTP_METHODS[u'<STR_LIT>'], <NUM_LIT:1>)<EOL>if bod is not None:<EOL><INDENT>curl.setopt(pycurl.INFILESIZE, len(bod))<EOL><DEDENT>else:<EOL><INDENT>curl.setopt(pycurl.INFILESIZE, <NUM_LIT:0>)<EOL><DEDENT><DEDENT>elif self.method == u'<STR_LIT>':<EOL><INDENT>curl.setopt(curl.POSTFIELDS, bod)<EOL>curl.setopt(curl.CUSTOMREQUEST, '<STR_LIT>')<EOL>if bod is not None:<EOL><INDENT>curl.setopt(pycurl.INFILESIZE, len(bod))<EOL><DEDENT>else:<EOL><INDENT>curl.setopt(pycurl.INFILESIZE, <NUM_LIT:0>)<EOL><DEDENT><DEDENT>elif self.method == u'<STR_LIT>':<EOL><INDENT>curl.setopt(curl.CUSTOMREQUEST, '<STR_LIT>')<EOL>if bod is not None:<EOL><INDENT>curl.setopt(pycurl.POSTFIELDS, bod)<EOL>curl.setopt(pycurl.POSTFIELDSIZE, len(bod))<EOL><DEDENT><DEDENT>elif self.method == u'<STR_LIT>':<EOL><INDENT>curl.setopt(curl.NOBODY, <NUM_LIT:1>)<EOL>curl.setopt(curl.CUSTOMREQUEST, '<STR_LIT>')<EOL><DEDENT>elif self.method and self.method.upper() != '<STR_LIT:GET>':  <EOL><INDENT>curl.setopt(curl.CUSTOMREQUEST, self.method.upper())<EOL>if bod is not None:<EOL><INDENT>curl.setopt(pycurl.POSTFIELDS, bod)<EOL>curl.setopt(pycurl.POSTFIELDSIZE, len(bod))<EOL><DEDENT><DEDENT>head = self.get_headers(context=context)<EOL>head = copy.copy(head)  <EOL>if is_unicoded and u'<STR_LIT>' in head.keys():<EOL><INDENT>content = head[u'<STR_LIT>']<EOL>if u'<STR_LIT>' not in content:<EOL><INDENT>head[u'<STR_LIT>'] = content + u'<STR_LIT>'<EOL><DEDENT><DEDENT>if head:<EOL><INDENT>headers = [str(headername) + '<STR_LIT::>' + str(headervalue)<EOL>for headername, headervalue in head.items()]<EOL><DEDENT>else:<EOL><INDENT>headers = list()<EOL><DEDENT>headers.append("<STR_LIT>")<EOL>headers.append("<STR_LIT>")<EOL>curl.setopt(curl.HTTPHEADER, headers)<EOL>if self.curl_options:<EOL><INDENT>filterfunc = lambda x: x[<NUM_LIT:0>] is not None and x[<NUM_LIT:1>] is not None  <EOL>for (key, value) in ifilter(filterfunc, self.curl_options.items()):<EOL><INDENT>curl.setopt(getattr(curl, key), value)<EOL><DEDENT><DEDENT>return curl<EOL>

Create and mostly configure a curl object for test, reusing existing if possible


super(MailChimp, self).__init__(*args, **kwargs)<EOL>self.root = self.api_root = Root(self)<EOL>self.authorized_apps = AuthorizedApps(self)<EOL>self.automations = Automations(self)<EOL>self.automations.actions = AutomationActions(self)<EOL>self.automations.emails = AutomationEmails(self)<EOL>self.automations.emails.actions = AutomationEmailActions(self)<EOL>self.automations.emails.queues = AutomationEmailQueues(self)<EOL>self.automations.removed_subscribers = AutomationRemovedSubscribers(self)<EOL>self.batches = self.batch_operations = BatchOperations(self)<EOL>self.batch_webhooks = BatchWebhooks(self)<EOL>self.campaign_folders = CampaignFolders(self)<EOL>self.campaigns = Campaigns(self)<EOL>self.campaigns.actions = CampaignActions(self)<EOL>self.campaigns.content = CampaignContent(self)<EOL>self.campaigns.feedback = CampaignFeedback(self)<EOL>self.campaigns.send_checklist = CampaignSendChecklist(self)<EOL>self.conversations = Conversations(self)<EOL>self.conversations.messages = ConversationMessages(self)<EOL>self.stores = self.ecommerce = Stores(self)<EOL>self.stores.carts = StoreCarts(self)<EOL>self.stores.carts.lines = StoreCartLines(self)<EOL>self.stores.customers = StoreCustomers(self)<EOL>self.stores.orders = StoreOrders(self)<EOL>self.stores.orders.lines = StoreOrderLines(self)<EOL>self.stores.products = StoreProducts(self)<EOL>self.stores.products.images = StoreProductImages(self)<EOL>self.stores.products.variants = StoreProductVariants(self)<EOL>self.stores.promo_rules = StorePromoRules(self)<EOL>self.stores.promo_codes = StorePromoCodes(self)<EOL>self.files = FileManagerFiles(self)<EOL>self.folders = FileManagerFolders(self)<EOL>self.lists = Lists(self)<EOL>self.lists.abuse_reports = ListAbuseReports(self)<EOL>self.lists.activity = ListActivity(self)<EOL>self.lists.clients = ListClients(self)<EOL>self.lists.growth_history = ListGrowthHistory(self)<EOL>self.lists.interest_categories = ListInterestCategories(self)<EOL>self.lists.interest_categories.interests = ListInterestCategoryInterest(self)<EOL>self.lists.members = ListMembers(self)<EOL>self.lists.members.activity = ListMemberActivity(self)<EOL>self.lists.members.goals = ListMemberGoals(self)<EOL>self.lists.members.notes = ListMemberNotes(self)<EOL>self.lists.members.tags = ListMemberTags(self)<EOL>self.lists.merge_fields = ListMergeFields(self)<EOL>self.lists.segments = ListSegments(self)<EOL>self.lists.segments.members = ListSegmentMembers(self)<EOL>self.lists.signup_forms = ListSignupForms(self)<EOL>self.lists.webhooks = ListWebhooks(self)<EOL>self.ping = Ping(self)<EOL>self.reports = Reports(self)<EOL>self.reports.abuse_reports = ReportCampaignAbuseReports(self)<EOL>self.reports.advice = ReportCampaignAdvice(self)<EOL>self.reports.click_details = ReportClickDetailReports(self)<EOL>self.reports.click_details.members = ReportClickDetailMembers(self)<EOL>self.reports.domain_performance = ReportDomainPerformance(self)<EOL>self.reports.eepurl = ReportEepURL(self)<EOL>self.reports.email_activity = ReportEmailActivity(self)<EOL>self.reports.locations = ReportLocations(self)<EOL>self.reports.sent_to = ReportSentTo(self)<EOL>self.reports.subreports = ReportSubReports(self)<EOL>self.reports.unsubscribes = ReportUnsubscribes(self)<EOL>self.reports.open_details = ReportOpenDetails(self)<EOL>self.reports.google_analytics = ReportGoogleAnalytics(self)<EOL>self.search_campaigns = SearchCampaigns(self)<EOL>self.search_members = SearchMembers(self)<EOL>self.template_folders = TemplateFolders(self)<EOL>self.templates = Templates(self)<EOL>self.templates.default_content = TemplateDefaultContent(self)<EOL>

Initialize the class with your api_key and user_id and attach all of
the endpoints


check_email(member_email)<EOL>member_email = member_email.lower().encode()<EOL>m = hashlib.md5(member_email)<EOL>return m.hexdigest()<EOL>

The MD5 hash of the lowercase version of the list member's email.
Used as subscriber_hash

:param member_email: The member's email address
:type member_email: :py:class:`str`
:returns: The MD5 hash in hex
:rtype: :py:class:`str`


if re.match(r"<STR_LIT>", potential_hash):<EOL><INDENT>return potential_hash<EOL><DEDENT>else:<EOL><INDENT>return get_subscriber_hash(potential_hash)<EOL><DEDENT>

Check the passed value to see if it matches a 32 character hex number that
MD5 generates as output, or compute that value assuming that the input is
an email address.

:param potential_hash: A value to be passed to any of the endpoints that
expect an MD5 of an email address
:type potential_hash: :py:class:`str`
:returns: A valid MD5 hash in hex
:rtype: :py:class:`str`


if not re.match(r"<STR_LIT>", email):<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>return<EOL>

Function that verifies that the string passed is a valid email address.

Regex for email validation based on MailChimp limits:
http://kb.mailchimp.com/accounts/management/international-characters-in-mailchimp

:param email: The potential email address
:type email: :py:class:`str`
:return: Nothing


Function that verifies that the string passed is a valid url.

Original regex author Diego Perini (http://www.iport.it)
regex ported to Python by adamrofer (https://github.com/adamrofer)
Used under MIT license.

:param url:
:return: Nothing


z = x.copy()<EOL>for key, value in y.items():<EOL><INDENT>if isinstance(value, list) and isinstance(z.get(key), list):<EOL><INDENT>z[key] += value<EOL><DEDENT>else:<EOL><INDENT>z[key] = value<EOL><DEDENT><DEDENT>return z<EOL>

Given two dicts, x and y, merge them into a new dict as a shallow copy.

The result only differs from `x.update(y)` in the way that it handles list
values when both x and y have list values for the same key. In which case
the returned dictionary, z, has a value according to:
  z[key] = x[key] + z[key]

:param x: The first dictionary
:type x: :py:class:`dict`
:param y: The second dictionary
:type y: :py:class:`dict`
:returns: The merged dictionary
:rtype: :py:class:`dict`


super(BaseApi, self).__init__()<EOL>self._mc_client = mc_client<EOL>self.endpoint = '<STR_LIT>'<EOL>

Initialize the class with you user_id and secret_key

:param mc_client: The mailchimp client connection
:type mc_client: :mod:`mailchimp3.mailchimpclient.MailChimpClient`


return '<STR_LIT:/>'.join(chain((self.endpoint,), map(str, args)))<EOL>

Build path with endpoint and args

:param args: Tokens in the endpoint URL
:type args: :py:class:`unicode`


<EOL>if '<STR_LIT>' in queryparams:<EOL><INDENT>if '<STR_LIT>' not in queryparams['<STR_LIT>'].split('<STR_LIT:U+002C>'):<EOL><INDENT>queryparams['<STR_LIT>'] += '<STR_LIT>'<EOL><DEDENT><DEDENT>queryparams.pop("<STR_LIT>", None)<EOL>queryparams.pop("<STR_LIT:count>", None)<EOL>result = self._mc_client._get(url=url, offset=<NUM_LIT:0>, count=<NUM_LIT:1000>, **queryparams)<EOL>total = result['<STR_LIT>']<EOL>if total > <NUM_LIT:1000>:<EOL><INDENT>for offset in range(<NUM_LIT:1>, int(total / <NUM_LIT:1000>) + <NUM_LIT:1>):<EOL><INDENT>result = merge_results(result, self._mc_client._get(<EOL>url=url,<EOL>offset=int(offset * <NUM_LIT:1000>),<EOL>count=<NUM_LIT:1000>,<EOL>**queryparams<EOL>))<EOL><DEDENT>return result<EOL><DEDENT>else:  <EOL><INDENT>return result<EOL><DEDENT>

Iterate over all pages for the given url. Feed in the result of self._build_path as the url.

:param url: The url of the endpoint
:type url: :py:class:`str`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []
queryparams['count'] = integer
queryparams['offset'] = integer


super(TemplateFolders, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.folder_id = None<EOL>


if '<STR_LIT:name>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>response = self._mc_client._post(url=self._build_path(), data=data)<EOL>if response is not None:<EOL><INDENT>self.folder_id = response['<STR_LIT:id>']<EOL><DEDENT>else:<EOL><INDENT>self.folder_id = None<EOL><DEDENT>return response<EOL>

Create a new template folder.

:param data: The request body parameters
:type data: :py:class:`dict`
data = {
    "name": string*
}


def all(self, get_all=False, **queryparams):

self.folder_id = None<EOL>if get_all:<EOL><INDENT>return self._iterate(url=self._build_path(), **queryparams)<EOL><DEDENT>else:<EOL><INDENT>return self._mc_client._get(url=self._build_path(), **queryparams)<EOL><DEDENT>

Get all folders used to organize templates.

:param get_all: Should the query get all results
:type get_all: :py:class:`bool`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []
queryparams['count'] = integer
queryparams['offset'] = integer


def get(self, folder_id, **queryparams):

self.folder_id = folder_id<EOL>return self._mc_client._get(url=self._build_path(folder_id), **queryparams)<EOL>

Get information about a specific folder used to organize templates.

:param folder_id: The unique id for the File Manager folder.
:type folder_id: :py:class:`str`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []


if '<STR_LIT:name>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>self.folder_id = folder_id<EOL>return self._mc_client._patch(url=self._build_path(folder_id), data=data)<EOL>

Update a specific folder used to organize templates.

:param folder_id: The unique id for the File Manager folder.
:type folder_id: :py:class:`str`
:param data: The request body parameters
:type data: :py:class:`dict`
data = {
    "name": string*
}


self.folder_id = folder_id<EOL>return self._mc_client._delete(url=self._build_path(folder_id))<EOL>

Delete a specific template folder, and mark all the templates in the
folder as ‘unfiled’.

:param folder_id: The unique id for the File Manager folder.
:type folder_id: :py:class:`str`


super(Automations, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.workflow_id = None<EOL>self.actions = AutomationActions(self)<EOL>self.emails = AutomationEmails(self)<EOL>self.removed_subscribers = AutomationRemovedSubscribers(self)<EOL>


self.workflow_id = None<EOL>if get_all:<EOL><INDENT>return self._iterate(url=self._build_path(), **queryparams)<EOL><DEDENT>else:<EOL><INDENT>return self._mc_client._get(url=self._build_path(), **queryparams)<EOL><DEDENT>

Get a summary of an account’s Automations.

:param get_all: Should the query get all results
:type get_all: :py:class:`bool`
:param queryparams: the query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []


def get(self, workflow_id, **queryparams):

self.workflow_id = workflow_id<EOL>return self._mc_client._get(url=self._build_path(workflow_id), **queryparams)<EOL>

Get a summary of an individual Automation workflow’s settings and
content. The trigger_settings object returns information for the first
email in the workflow.

:param workflow_id: The unique id for the Automation workflow
:type workflow_id: :py:class:`str`
:param queryparams: the query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []


super(AutomationEmails, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.workflow_id = None<EOL>self.email_id = None<EOL>self.actions = AutomationEmailActions(self)<EOL>self.queues = AutomationEmailQueues(self)<EOL>


def all(self, workflow_id, get_all=False, **queryparams):

self.workflow_id = workflow_id<EOL>self.email_id = None<EOL>if get_all:<EOL><INDENT>return self._iterate(url=self._build_path(workflow_id, '<STR_LIT>'), **queryparams)<EOL><DEDENT>else:<EOL><INDENT>return self._mc_client._get(url=self._build_path(workflow_id, '<STR_LIT>'), **queryparams)<EOL><DEDENT>

Get a summary of the emails in an Automation workflow.

:param workflow_id: The unique id for the Automation workflow.
:type workflow_id: :py:class:`str`
:param get_all: Should the query get all results
:type get_all: :py:class:`bool`
:param queryparams: the query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []


self.workflow_id = workflow_id<EOL>self.email_id = email_id<EOL>return self._mc_client._get(url=self._build_path(workflow_id, '<STR_LIT>', email_id))<EOL>

Get information about an individual Automation workflow email.

:param workflow_id: The unique id for the Automation workflow.
:type workflow_id: :py:class:`str`
:param email_id: The unique id for the Automation workflow email.
:type email_id: :py:class:`str`


super(AutomationEmailQueues, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.workflow_id = None<EOL>self.email_id = None<EOL>self.subscriber_hash = None<EOL>


def create(self, workflow_id, email_id, data):

self.workflow_id = workflow_id<EOL>self.email_id = email_id<EOL>if '<STR_LIT>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>check_email(data['<STR_LIT>'])<EOL>response = self._mc_client._post(<EOL>url=self._build_path(workflow_id, '<STR_LIT>', email_id, '<STR_LIT>'),<EOL>data=data<EOL>)<EOL>if response is not None:<EOL><INDENT>self.subscriber_hash = response['<STR_LIT:id>']<EOL><DEDENT>else:<EOL><INDENT>self.subscriber_hash = None<EOL><DEDENT>return response<EOL>

Manually add a subscriber to a workflow, bypassing the default trigger
settings. You can also use this endpoint to trigger a series of
automated emails in an API 3.0 workflow type or add subscribers to an
automated email queue that uses the API request delay type.

:param workflow_id: The unique id for the Automation workflow.
:type workflow_id: :py:class:`str`
:param email_id: The unique id for the Automation workflow email.
:type email_id: :py:class:`str`
:param data: The request body parameters
:type data: :py:class:`dict`
data = {
    "email_address": string*
}


self.workflow_id = workflow_id<EOL>self.email_id = email_id<EOL>self.subscriber_hash = None<EOL>return self._mc_client._get(url=self._build_path(workflow_id, '<STR_LIT>', email_id, '<STR_LIT>'))<EOL>

Get information about an Automation email queue.

:param workflow_id: The unique id for the Automation workflow.
:type workflow_id: :py:class:`str`
:param email_id: The unique id for the Automation workflow email.
:type email_id: :py:class:`str`


def get(self, workflow_id, email_id, subscriber_hash):

subscriber_hash = check_subscriber_hash(subscriber_hash)<EOL>self.workflow_id = workflow_id<EOL>self.email_id = email_id<EOL>self.subscriber_hash = subscriber_hash<EOL>return self._mc_client._get(url=self._build_path(workflow_id, '<STR_LIT>', email_id, '<STR_LIT>', subscriber_hash))<EOL>

Get information about a specific subscriber in an Automation email
queue.

:param workflow_id: The unique id for the Automation workflow.
:type workflow_id: :py:class:`str`
:param email_id: The unique id for the Automation workflow email.
:type email_id: :py:class:`str`
:param subscriber_hash: The MD5 hash of the lowercase version of the
  list member’s email address.
:type subscriber_hash: :py:class:`str`


super(SearchCampaigns, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>


return self._mc_client._get(url=self._build_path(), **queryparams)<EOL>

Search all campaigns for the specified query terms.

:param queryparams: The query string parameters
queryparams['fields'] = array
queryparams['exclude_fields'] = array
queryparams['query'] = string
queryparams['snip_start'] = string
queryparams['snip_end'] = string
queryparams['offset'] = integer


super(TemplateDefaultContent, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.template_id = None<EOL>


def all(self, template_id, **queryparams):

self.template_id = template_id<EOL>return self._mc_client._get(url=self._build_path(template_id, '<STR_LIT>'), **queryparams)<EOL>

Get the sections that you can edit in a template, including each
section’s default content.

:param template_id: The unique id for the template.
:type template_id: :py:class:`str`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []


super(Templates, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.template_id = None<EOL>self.default_content = TemplateDefaultContent(self)<EOL>


if '<STR_LIT:name>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT:html>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>response = self._mc_client._post(url=self._build_path(), data=data)<EOL>if response is not None:<EOL><INDENT>self.template_id = response['<STR_LIT:id>']<EOL><DEDENT>else:<EOL><INDENT>self.template_id = None<EOL><DEDENT>return response<EOL>

Create a new template for the account. Only Classic templates are
supported.

:param data: The request body parameters
:type data: :py:class:`dict`
data = {
    "name": string*,
    "html": string*
}


self.template_id = None<EOL>if get_all:<EOL><INDENT>return self._iterate(url=self._build_path(), **queryparams)<EOL><DEDENT>else:<EOL><INDENT>return self._mc_client._get(url=self._build_path(), **queryparams)<EOL><DEDENT>

Get a list of an account’s available templates.

:param get_all: Should the query get all results
:type get_all: :py:class:`bool`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []
queryparams['count'] = integer
queryparams['offset'] = integer
queryparams['created_by'] = string
queryparams['before_created_at'] = string
queryparams['since_created_at'] = string
queryparams['type'] = string
queryparams['folder_id'] = string


def get(self, template_id, **queryparams):

self.template_id = template_id<EOL>return self._mc_client._get(url=self._build_path(template_id), **queryparams)<EOL>

Get information about a specific template.

:param template_id: The unique id for the template.
:type template_id: :py:class:`str`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []


if '<STR_LIT:name>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT:html>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>self.template_id = template_id<EOL>return self._mc_client._patch(url=self._build_path(template_id), data=data)<EOL>

Update the name, HTML, or folder_id of an existing template.

:param template_id: The unique id for the template.
:type template_id: :py:class:`str`
:param data: The request body parameters
:type data: :py:class:`dict`
data = {
    "name": string*,
    "html": string*
}


self.template_id = template_id<EOL>return self._mc_client._delete(url=self._build_path(template_id))<EOL>

Delete a specific template.

:param template_id: The unique id for the template.
:type template_id: :py:class:`str`


super(ReportEepURL, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.campaign_id = None<EOL>


def all(self, campaign_id, **queryparams):

self.campaign_id = campaign_id<EOL>return self._mc_client._get(url=self._build_path(campaign_id, '<STR_LIT>'), **queryparams)<EOL>

Get a summary of social activity for the campaign, tracked by EepURL.

:param campaign_id: The unique id for the campaign.
:type campaign_id: :py:class:`str`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []


return self._mc_client._get(url=self._build_path(list_id, '<STR_LIT>'), **queryparams)<EOL>

returns the first 10 segments for a specific list.


return self._mc_client._get(url=self._build_path(list_id, '<STR_LIT>', segment_id))<EOL>


def update(self, list_id, segment_id, data):

return self._mc_client._patch(url=self._build_path(list_id, '<STR_LIT>', segment_id), data=data)<EOL>


return self._mc_client._delete(url=self._build_path(list_id, '<STR_LIT>', segment_id))<EOL>

removes an existing list segment from the list. This cannot be undone.


return self._mc_client._post(url=self._build_path(list_id, '<STR_LIT>'), data=data)<EOL>


super(FileManagerFiles, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.file_id = None<EOL>


if '<STR_LIT:name>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>response = self._mc_client._post(url=self._build_path(), data=data)<EOL>if response is not None:<EOL><INDENT>self.file_id = response['<STR_LIT:id>']<EOL><DEDENT>else:<EOL><INDENT>self.file_id = None<EOL><DEDENT>return response<EOL>

Upload a new image or file to the File Manager.

:param data: The request body parameters
:type data: :py:class:`dict`
data = {
    "name": string*,
    "file_data": string*
}


self.file_id = None<EOL>if get_all:<EOL><INDENT>return self._iterate(url=self._build_path(), **queryparams)<EOL><DEDENT>else:<EOL><INDENT>return self._mc_client._get(url=self._build_path(), **queryparams)<EOL><DEDENT>

Get a list of available images and files stored in the File Manager for the account.

:param get_all: Should the query get all results
:type get_all: :py:class:`bool`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []
queryparams['count'] = integer
queryparams['offset'] = integer
queryparams['type'] = string
queryparams['created_by'] = string
queryparams['before_created_at'] = string
queryparams['since_created_at'] = string
queryparams['sort_field'] = string
queryparams['sort_dir'] = string


self.file_id = file_id<EOL>return self._mc_client._get(url=self._build_path(file_id), **queryparams)<EOL>

Get information about a specific file in the File Manager.

:param file_id: The unique id for the File Manager file.
:type file_id: :py:class:`str`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []


self.file_id = file_id<EOL>if '<STR_LIT:name>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>return self._mc_client._patch(url=self._build_path(file_id), data=data)<EOL>

Update a file in the File Manager.

:param file_id: The unique id for the File Manager file.
:type file_id: :py:class:`str`
:param data: The request body parameters
:type data: :py:class:`dict`
data = {
    "name": string*,
    "file_data": string*
}


self.file_id = file_id<EOL>return self._mc_client._delete(url=self._build_path(file_id))<EOL>

Remove a specific file from the File Manager.

:param file_id: The unique id for the File Manager file.
:type file_id: :py:class:`str`


super(ListSegmentMembers, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.list_id = None<EOL>self.segment_id = None<EOL>self.subscriber_hash = None<EOL>


def create(self, list_id, segment_id, data):

self.list_id = list_id<EOL>self.segment_id = segment_id<EOL>if '<STR_LIT>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>check_email(data['<STR_LIT>'])<EOL>if '<STR_LIT:status>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if data['<STR_LIT:status>'] not in ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>']:<EOL><INDENT>raise ValueError('<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT>response = self._mc_client._post(url=self._build_path(list_id, '<STR_LIT>', segment_id, '<STR_LIT>'), data=data)<EOL>if response is not None:<EOL><INDENT>self.subscriber_hash = response['<STR_LIT:id>']<EOL><DEDENT>else:<EOL><INDENT>self.subscriber_hash = None<EOL><DEDENT>return response<EOL>

Add a member to a static segment.

The documentation does not currently elaborate on the path or request
body parameters. Looking at the example provided, it will be assumed
that email_address and status are required request body parameters and
they are documented and error-checked as such.

:param list_id: The unique id for the list.
:type list_id: :py:class:`str`
:param segment_id: The unique id for the segment.
:type segment_id: :py:class:`str`
:param data: The request body parameters
:type data: :py:class:`dict`
data = {
    "email_address": string*,
    "status": string* (Must be one of 'subscribed', 'unsubscribed', 'cleaned', or 'pending')
}


def all(self, list_id, segment_id, get_all=False, **queryparams):

self.list_id = list_id<EOL>self.segment_id = segment_id<EOL>self.subscriber_hash = None<EOL>if get_all:<EOL><INDENT>return self._iterate(url=self._build_path(list_id, '<STR_LIT>', segment_id, '<STR_LIT>'), **queryparams)<EOL><DEDENT>else:<EOL><INDENT>return self._mc_client._get(url=self._build_path(list_id, '<STR_LIT>', segment_id, '<STR_LIT>'), **queryparams)<EOL><DEDENT>

Get information about members in a saved segment.

:param list_id: The unique id for the list.
:type list_id: :py:class:`str`
:param segment_id: The unique id for the segment.
:type segment_id: :py:class:`str`
:param get_all: Should the query get all results
:type get_all: :py:class:`bool`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []
queryparams['count'] = integer
queryparams['offset'] = integer


def delete(self, list_id, segment_id, subscriber_hash):

subscriber_hash = check_subscriber_hash(subscriber_hash)<EOL>self.list_id = list_id<EOL>self.segment_id = segment_id<EOL>self.subscriber_hash = subscriber_hash<EOL>return self._mc_client._delete(<EOL>url=self._build_path(list_id, '<STR_LIT>', segment_id, '<STR_LIT>', subscriber_hash)<EOL>)<EOL>

Remove a member from the specified static segment.

:param list_id: The unique id for the list.
:type list_id: :py:class:`str`
:param segment_id: The unique id for the segment.
:type segment_id: :py:class:`str`
:param subscriber_hash: The MD5 hash of the lowercase version of the
  list member’s email address.
:type subscriber_hash: :py:class:`str`


super(ReportEmailActivity, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.campaign_id = None<EOL>self.subscriber_hash = None<EOL>


def all(self, campaign_id, get_all=False, **queryparams):

self.campaign_id = campaign_id<EOL>self.subscriber_hash = None<EOL>if get_all:<EOL><INDENT>return self._iterate(url=self._build_path(campaign_id, '<STR_LIT>'), **queryparams)<EOL><DEDENT>else:<EOL><INDENT>return self._mc_client._get(url=self._build_path(campaign_id, '<STR_LIT>'), **queryparams)<EOL><DEDENT>

Get a list of member’s subscriber activity in a specific campaign.

:param campaign_id: The unique id for the campaign.
:type campaign_id: :py:class:`str`
:param get_all: Should the query get all results
:type get_all: :py:class:`bool`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []
queryparams['count'] = integer
queryparams['offset'] = integer


def get(self, campaign_id, subscriber_hash, **queryparams):

subscriber_hash = check_subscriber_hash(subscriber_hash)<EOL>self.campaign_id = campaign_id<EOL>self.subscriber_hash = subscriber_hash<EOL>return self._mc_client._get(<EOL>url=self._build_path(campaign_id, '<STR_LIT>', subscriber_hash),<EOL>**queryparams<EOL>)<EOL>

Get a specific list member’s activity in a campaign including opens,
clicks, and bounces.

:param campaign_id: The unique id for the campaign.
:type campaign_id: :py:class:`str`
:param subscriber_hash: The MD5 hash of the lowercase version of the
  list member’s email address.
:type subscriber_hash: :py:class:`str`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []


super(BatchWebhooks, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.batch_webhook_id = None<EOL>


if '<STR_LIT:url>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>response = self._mc_client._post(url=self._build_path(), data=data)<EOL>if response is not None:<EOL><INDENT>self.batch_webhook_id = response['<STR_LIT:id>']<EOL><DEDENT>else:<EOL><INDENT>self.batch_webhook_id = None<EOL><DEDENT>return response<EOL>

Configure a webhook that will fire whenever any batch request
completes processing.

:param data: The request body parameters
:type data: :py:class:`dict`
data = {
    "url": string*
}


self.batch_webhook_id = None<EOL>if get_all:<EOL><INDENT>return self._iterate(url=self._build_path(), **queryparams)<EOL><DEDENT>else:<EOL><INDENT>return self._mc_client._get(url=self._build_path(), **queryparams)<EOL><DEDENT>

Get all webhooks that have been configured for batches.

:param get_all: Should the query get all results
:type get_all: :py:class:`bool`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []
queryparams['count'] = integer
queryparams['offset'] = integer


def get(self, batch_webhook_id, **queryparams):

self.batch_webhook_id = batch_webhook_id<EOL>return self._mc_client._get(url=self._build_path(batch_webhook_id), **queryparams)<EOL>

Get information about a specific batch webhook.

:param batch_webhook_id: The unique id for the batch webhook.
:type batch_webhook_id: :py:class:`str`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []


def update(self, batch_webhook_id, data):

self.batch_webhook_id = batch_webhook_id<EOL>if '<STR_LIT:url>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>return self._mc_client._patch(url=self._build_path(batch_webhook_id), data=data)<EOL>

Update a webhook that will fire whenever any batch request completes
processing.

:param batch_webhook_id: The unique id for the batch webhook.
:type batch_webhook_id: :py:class:`str`
:param data: The request body parameters
:type data: :py:class:`dict`
data = {
    "url": string*
}


self.batch_webhook_id = batch_webhook_id<EOL>return self._mc_client._delete(url=self._build_path(batch_webhook_id))<EOL>

Remove a batch webhook. Webhooks will no longer be sent to the given
URL.

:param batch_webhook_id: The unique id for the batch webhook.
:type batch_webhook_id: :py:class:`str`


super(ReportSubReports, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.campaign_id = None<EOL>


self.campaign_id = campaign_id<EOL>return self._mc_client._get(url=self._build_path(campaign_id, '<STR_LIT>'), **queryparams)<EOL>

Get a list of reports with child campaigns for a specific parent
campaign.

:param campaign_id: The unique id for the campaign.
:type campaign_id: :py:class:`str`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []


super(ListSignupForms, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.list_id = None<EOL>


self.list_id = list_id<EOL>response = self._mc_client._post(url=self._build_path(list_id, '<STR_LIT>'), data=data)<EOL>return response<EOL>

Create a customized list signup form.

No fields are listed as required in the documentation and the
description of the method does not indicate any required fields
either.

:param list_id: The unique id for the list.
:type list_id: :py:class:`str`
:param data: The request body parameters
:type data: :py:class:`dict`


self.list_id = list_id<EOL>return self._mc_client._get(url=self._build_path(list_id, '<STR_LIT>'))<EOL>

Get signup forms for a specific list.

:param list_id: The unique id for the list.
:type list_id: :py:class:`str`


super(ReportCampaignAbuseReports, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.campaign_id = None<EOL>self.report_id = None<EOL>


self.campaign_id = campaign_id<EOL>self.report_id = None<EOL>return self._mc_client._get(url=self._build_path(campaign_id, '<STR_LIT>'), **queryparams)<EOL>

Get a list of abuse complaints for a specific campaign.

:param campaign_id: The unique id for the campaign.
:type campaign_id: :py:class:`str`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []


def get(self, campaign_id, report_id, **queryparams):

self.campaign_id = campaign_id<EOL>self.report_id = report_id<EOL>return self._mc_client._get(url=self._build_path(campaign_id, '<STR_LIT>', report_id), **queryparams)<EOL>

Get information about a specific abuse report for a campaign.

:param campaign_id: The unique id for the campaign.
:type campaign_id: :py:class:`str`
:param report_id: The id for the abuse report.
:type report_id: :py:class:`str`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []


super(AuthorizedApps, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.app_id = None<EOL>


self.app_id = None<EOL>if '<STR_LIT>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>return self._mc_client._post(url=self._build_path(), data=data)<EOL>

Retrieve OAuth2-based credentials to associate API calls with your
application.

:param data: The request body parameters
:type data: :py:class:`dict`
data = {
    "client_id": string*,
    "client_secret": string*
}


def all(self, get_all=False, **queryparams):

self.app_id = None<EOL>if get_all:<EOL><INDENT>return self._iterate(url=self._build_path(), **queryparams)<EOL><DEDENT>else:<EOL><INDENT>return self._mc_client._get(url=self._build_path(), **queryparams)<EOL><DEDENT>

Get a list of an account’s registered, connected applications.

:param get_all: Should the query get all results
:type get_all: :py:class:`bool`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []
queryparams['count'] = integer
queryparams['offset'] = integer


self.app_id = app_id<EOL>return self._mc_client._get(url=self._build_path(app_id), **queryparams)<EOL>

Get information about a specific authorized application

:param app_id: The unique id for the connected authorized application
:type app_id: :py:class:`str`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []


super(ListAbuseReports, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.list_id = None<EOL>self.report_id = None<EOL>


def all(self, list_id, get_all=False, **queryparams):

self.list_id = list_id<EOL>self.report_id = None<EOL>if get_all:<EOL><INDENT>return self._iterate(url=self._build_path(list_id, '<STR_LIT>'), **queryparams)<EOL><DEDENT>else:<EOL><INDENT>return self._mc_client._get(url=self._build_path(list_id, '<STR_LIT>'), **queryparams)<EOL><DEDENT>

Get all abuse reports for a specific list.

:param list_id: The unique id for the list.
:type list_id: :py:class:`str`
:param get_all: Should the query get all results
:type get_all: :py:class:`bool`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []
queryparams['count'] = integer
queryparams['offset'] = integer


def get(self, list_id, report_id, **queryparams):

self.list_id = list_id<EOL>self.report_id = report_id<EOL>return self._mc_client._get(url=self._build_path(list_id, '<STR_LIT>', report_id), **queryparams)<EOL>

Get details about a specific abuse report.

:param list_id: The unique id for the list.
:type list_id: :py:class:`str`
:param report_id: The id for the abuse report.
:type report_id: :py:class:`str`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []
queryparams['count'] = integer
queryparams['offset'] = integer


super(Stores, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.store_id = None<EOL>self.carts = StoreCarts(self)<EOL>self.customers = StoreCustomers(self)<EOL>self.orders = StoreOrders(self)<EOL>self.products = StoreProducts(self)<EOL>


if '<STR_LIT:id>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT:name>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if not re.match(r"<STR_LIT>", data['<STR_LIT>']):<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>response = self._mc_client._post(url=self._build_path(), data=data)<EOL>if response is not None:<EOL><INDENT>self.store_id = response['<STR_LIT:id>']<EOL><DEDENT>else:<EOL><INDENT>self.store_id = None<EOL><DEDENT>return response<EOL>

Add a new store to your MailChimp account.

Error checking on the currency code verifies that it is in the correct
three-letter, all-caps format as specified by ISO 4217 but does not
check that it is a valid code as the list of valid codes changes over
time.

:param data: The request body parameters
:type data: :py:class:`dict`
data = {
    "id": string*,
    "list_id": string*,
    "name": string*,
    "currency_code": string*
}


self.store_id = None<EOL>if get_all:<EOL><INDENT>return self._iterate(url=self._build_path(), **queryparams)<EOL><DEDENT>else:<EOL><INDENT>return self._mc_client._get(url=self._build_path(), **queryparams)<EOL><DEDENT>

Get information about all stores in the account.

:param get_all: Should the query get all results
:type get_all: :py:class:`bool`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []
queryparams['count'] = integer
queryparams['offset'] = integer


self.store_id = store_id<EOL>return self._mc_client._get(url=self._build_path(store_id), **queryparams)<EOL>

Get information about a specific store.

:param store_id: The store id.
:type store_id: :py:class:`str`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []


self.store_id = store_id<EOL>return self._mc_client._patch(url=self._build_path(store_id), data=data)<EOL>

Update a store.

:param store_id: The store id.
:type store_id: :py:class:`str`
:param data: The request body parameters
:type data: :py:class:`dict`


self.store_id = store_id<EOL>return self._mc_client._delete(url=self._build_path(store_id))<EOL>

Delete a store. Deleting a store will also delete any associated
subresources, including Customers, Orders, Products, and Carts.

:param store_id: The store id.
:type store_id: :py:class:`str`


super(ReportClickDetailMembers, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.campaign_id = None<EOL>self.link_id = None<EOL>self.subscriber_hash = None<EOL>


def all(self, campaign_id, link_id, get_all=False, **queryparams):

self.campaign_id = campaign_id<EOL>self.link_id = link_id<EOL>self.subscriber_hash = None<EOL>if get_all:<EOL><INDENT>return self._iterate(url=self._build_path(campaign_id, '<STR_LIT>', link_id, '<STR_LIT>'), **queryparams)<EOL><DEDENT>else:<EOL><INDENT>return self._mc_client._get(<EOL>url=self._build_path(campaign_id, '<STR_LIT>', link_id, '<STR_LIT>'),<EOL>**queryparams<EOL>)<EOL><DEDENT>

Get information about list members who clicked on a specific link in a
campaign.

:param campaign_id: The unique id for the campaign.
:type campaign_id: :py:class:`str`
:param link_id: The id for the link.
:type link_id: :py:class:`str`
:param get_all: Should the query get all results
:type get_all: :py:class:`bool`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []
queryparams['count'] = integer
queryparams['offset'] = integer


def get(self, campaign_id, link_id, subscriber_hash, **queryparams):

subscriber_hash = check_subscriber_hash(subscriber_hash)<EOL>self.campaign_id = campaign_id<EOL>self.link_id = link_id<EOL>self.subscriber_hash = subscriber_hash<EOL>return self._mc_client._get(<EOL>url=self._build_path(campaign_id, '<STR_LIT>', link_id, '<STR_LIT>', subscriber_hash),<EOL>**queryparams<EOL>)<EOL>

Get information about a specific subscriber who clicked a link in a
specific campaign.

:param campaign_id: The unique id for the campaign.
:type campaign_id: :py:class:`str`
:param link_id: The id for the link.
:type link_id: :py:class:`str`
:param subscriber_hash: The MD5 hash of the lowercase version of the
  list member’s email address.
:type subscriber_hash: :py:class:`str`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []


super(StoreCarts, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.store_id = None<EOL>self.cart_id = None<EOL>self.lines = StoreCartLines(self)<EOL>


self.store_id = store_id<EOL>if '<STR_LIT:id>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT:id>' not in data['<STR_LIT>']:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if not re.match(r"<STR_LIT>", data['<STR_LIT>']):<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>for line in data['<STR_LIT>']:<EOL><INDENT>if '<STR_LIT:id>' not in line:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT>' not in line:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT>' not in line:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT>' not in line:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT>' not in line:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT><DEDENT>response = self._mc_client._post(url=self._build_path(store_id, '<STR_LIT>'), data=data)<EOL>if response is not None:<EOL><INDENT>self.cart_id = response['<STR_LIT:id>']<EOL><DEDENT>else:<EOL><INDENT>self.cart_id = None<EOL><DEDENT>return response<EOL>

Add a new cart to a store.

:param store_id: The store id.
:type store_id: :py:class:`str`
:param data: The request body parameters
:type data: :py:class:`dict`
data = {
    "id": string*,
    "customer": object*
    {
        "id": string*
    },
    "currency_code": string*,
    "order_total": number*,
    "lines": array*
    [
        {
            "id": string*,
            "product_id": string*,
            "product_variant_id": string*,
            "quantity": integer*,
            "price": number*
        }
    ]
}


def all(self, store_id, get_all=False, **queryparams):

self.store_id = store_id<EOL>self.cart_id = None<EOL>if get_all:<EOL><INDENT>return self._iterate(url=self._build_path(store_id, '<STR_LIT>'), **queryparams)<EOL><DEDENT>else:<EOL><INDENT>return self._mc_client._get(url=self._build_path(store_id, '<STR_LIT>'), **queryparams)<EOL><DEDENT>

Get information about a store’s carts.

:param store_id: The store id.
:type store_id: :py:class:`str`
:param get_all: Should the query get all results
:type get_all: :py:class:`bool`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []
queryparams['count'] = integer
queryparams['offset'] = integer


def get(self, store_id, cart_id, **queryparams):

self.store_id = store_id<EOL>self.cart_id = cart_id<EOL>return self._mc_client._get(url=self._build_path(store_id, '<STR_LIT>', cart_id), **queryparams)<EOL>

Get information about a specific cart.

:param store_id: The store id.
:type store_id: :py:class:`str`
:param cart_id: The id for the cart.
:type cart_id: :py:class:`str`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []


def update(self, store_id, cart_id, data):

self.store_id = store_id<EOL>self.cart_id = cart_id<EOL>return self._mc_client._patch(url=self._build_path(store_id, '<STR_LIT>', cart_id), data=data)<EOL>

Update a specific cart.

:param store_id: The store id.
:type store_id: :py:class:`str`
:param cart_id: The id for the cart.
:type cart_id: :py:class:`str`
:param data: The request body parameters
:type data: :py:class:`dict`


self.store_id = store_id<EOL>self.cart_id = cart_id<EOL>return self._mc_client._delete(url=self._build_path(store_id, '<STR_LIT>', cart_id))<EOL>

Delete a cart.

:param store_id: The store id.
:type store_id: :py:class:`str`
:param cart_id: The id for the cart.
:type cart_id: :py:class:`str`


super(Reports, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.campaign_id = None<EOL>self.abuse_reports = ReportCampaignAbuseReports(self)<EOL>self.advice = ReportCampaignAdvice(self)<EOL>self.click_details = ReportClickDetailReports(self)<EOL>self.domain_performance = ReportDomainPerformance(self)<EOL>self.eepurl = ReportEepURL(self)<EOL>self.email_activity = ReportEmailActivity(self)<EOL>self.locations = ReportLocations(self)<EOL>self.sent_to = ReportSentTo(self)<EOL>self.subreports = ReportSubReports(self)<EOL>self.unsubscribes = ReportUnsubscribes(self)<EOL>


self.campaign_id = None<EOL>if get_all:<EOL><INDENT>return self._iterate(url=self._build_path(), **queryparams)<EOL><DEDENT>else:<EOL><INDENT>return self._mc_client._get(url=self._build_path(), **queryparams)<EOL><DEDENT>

Get campaign reports.

.. note::
    The before_send_time and since_send_time queryparams expect times
    to be listed in the ISO 8601 format in UTC (ex.
    2015-10-21T15:41:36+00:00).

:param get_all: Should the query get all results
:type get_all: :py:class:`bool`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []
queryparams['count'] = integer
queryparams['offset'] = integer
queryparams['type'] = []
queryparams['before_send_time'] = string
queryparams['since_send_time'] = string


def get(self, campaign_id, **queryparams):

self.campaign_id = campaign_id<EOL>return self._mc_client._get(url=self._build_path(campaign_id), **queryparams)<EOL>

Get report details for a specific sent campaign.

:param campaign_id: The unique id for the campaign.
:type campaign_id: :py:class:`str`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []


super(StoreProducts, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.store_id = None<EOL>self.product_id = None<EOL>self.images = StoreProductImages(self)<EOL>self.variants = StoreProductVariants(self)<EOL>


self.store_id = store_id<EOL>if '<STR_LIT:id>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT:title>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>for variant in data['<STR_LIT>']:<EOL><INDENT>if '<STR_LIT:id>' not in variant:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT:title>' not in variant:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT><DEDENT>response = self._mc_client._post(url=self._build_path(store_id, '<STR_LIT>'), data=data)<EOL>if response is not None:<EOL><INDENT>self.product_id = response['<STR_LIT:id>']<EOL><DEDENT>else:<EOL><INDENT>self.product_id = None<EOL><DEDENT>return response<EOL>

Add a new product to a store.

:param store_id: The store id.
:type store_id: :py:class:`str`
:param data: The request body parameters
:type data: :py:class:`dict`
data = {
    "id": string*,
    "title": string*,
    "variants": array*
    [
        {
            "id": string*,
            "title": string*
        }
    ]
}


self.store_id = store_id<EOL>self.product_id = None<EOL>if get_all:<EOL><INDENT>return self._iterate(url=self._build_path(store_id, '<STR_LIT>'), **queryparams)<EOL><DEDENT>else:<EOL><INDENT>return self._mc_client._get(url=self._build_path(store_id, '<STR_LIT>'), **queryparams)<EOL><DEDENT>

Get information about a store’s products.

:param store_id: The store id.
:type store_id: :py:class:`str`
:param get_all: Should the query get all results
:type get_all: :py:class:`bool`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []
queryparams['count'] = integer
queryparams['offset'] = integer


def get(self, store_id, product_id, **queryparams):

self.store_id = store_id<EOL>self.product_id = product_id<EOL>return self._mc_client._get(url=self._build_path(store_id, '<STR_LIT>', product_id), **queryparams)<EOL>

Get information about a specific product.

:param store_id: The store id.
:type store_id: :py:class:`str`
:param product_id: The id for the product of a store.
:type product_id: :py:class:`str`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []


def update(self, store_id, product_id, data):

self.store_id = store_id<EOL>self.product_id = product_id<EOL>return self._mc_client._patch(<EOL>url=self._build_path(store_id, '<STR_LIT>', product_id),<EOL>data=data<EOL>)<EOL>

Update a product.

:param store_id: The store id.
:type store_id: :py:class:`str`
:param product_id: The id for the product of a store.
:type product_id: :py:class:`str`
:param data: The request body parameters
:type data: :py:class:`dict`


self.store_id = store_id<EOL>self.product_id = product_id<EOL>return self._mc_client._delete(url=self._build_path(store_id, '<STR_LIT>', product_id))<EOL>

Delete a product.

:param store_id: The store id.
:type store_id: :py:class:`str`
:param product_id: The id for the product of a store.
:type product_id: :py:class:`str`


super(ListGrowthHistory, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.list_id = None<EOL>self.month = None<EOL>


self.list_id = list_id<EOL>self.month = None<EOL>if get_all:<EOL><INDENT>return self._iterate(url=self._build_path(list_id, '<STR_LIT>'), **queryparams)<EOL><DEDENT>else:<EOL><INDENT>return self._mc_client._get(url=self._build_path(list_id, '<STR_LIT>'), **queryparams)<EOL><DEDENT>

Get a month-by-month summary of a specific list’s growth activity.

:param list_id: The unique id for the list.
:type list_id: :py:class:`str`
:param get_all: Should the query get all results
:type get_all: :py:class:`bool`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []
queryparams['count'] = integer
queryparams['offset'] = integer


def get(self, list_id, month, **queryparams):

self.list_id = list_id<EOL>self.month = month<EOL>return self._mc_client._get(url=self._build_path(list_id, '<STR_LIT>', month), **queryparams)<EOL>

Get a summary of a specific list’s growth activity for a specific month and year.

:param list_id: The unique id for the list.
:type list_id: :py:class:`str`
:param month: A specific month of list growth history.
:type month: :py:class:`str`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []


super(Conversations, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.conversation_id = None<EOL>self.messages = ConversationMessages(self)<EOL>


self.conversation_id = None<EOL>if get_all:<EOL><INDENT>return self._iterate(url=self._build_path(), **queryparams)<EOL><DEDENT>else:<EOL><INDENT>return self._mc_client._get(url=self._build_path(), **queryparams)<EOL><DEDENT>

Get a list of conversations for the account.

:param get_all: Should the query get all results
:type get_all: :py:class:`bool`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []
queryparams['count'] = integer
queryparams['offset'] = integer
queryparams['has_unread_messages'] = string
queryparams['list_id'] = string
queryparams['campaign_id'] = string


def get(self, conversation_id, **queryparams):

self.conversation_id = conversation_id<EOL>return self._mc_client._get(url=self._build_path(conversation_id), **queryparams)<EOL>

Get details about an individual conversation.

:param conversation_id: The unique id for the conversation.
:type conversation_id: :py:class:`str`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []


super(ListMemberTags, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.list_id = None<EOL>self.subscriber_hash = None<EOL>


def update(self, list_id, subscriber_hash, data):

subscriber_hash = check_subscriber_hash(subscriber_hash)<EOL>self.list_id = list_id<EOL>self.subscriber_hash = subscriber_hash<EOL>if '<STR_LIT>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>response = self._mc_client._post(url=self._build_path(list_id, '<STR_LIT>', subscriber_hash, '<STR_LIT>'), data=data)<EOL>return response<EOL>

Update tags for a specific subscriber.

The documentation lists only the tags request body parameter so it is
being documented and error-checked as if it were required based on the
description of the method.

The data list needs to include a "status" key. This determines if the
tag should be added or removed from the user:

data = {
    'tags': [
        {'name': 'foo', 'status': 'active'},
        {'name': 'bar', 'status': 'inactive'}
    ]
}

:param list_id: The unique id for the list.
:type list_id: :py:class:`str`
:param subscriber_hash: The MD5 hash of the lowercase version of the
  list member’s email address.
:type subscriber_hash: :py:class:`str`
:param data: The request body parameters
:type data: :py:class:`dict`
data = {
    "tags": list*
}


def all(self, list_id, subscriber_hash, **queryparams):

subscriber_hash = check_subscriber_hash(subscriber_hash)<EOL>self.list_id = list_id<EOL>self.subscriber_hash = subscriber_hash<EOL>return self._mc_client._get(url=self._build_path(list_id, '<STR_LIT>', subscriber_hash, '<STR_LIT>'), **queryparams)<EOL>

Get all tags for a specific list member.

:param list_id: The unique id for the list.
:type list_id: :py:class:`str`
:param subscriber_hash: The MD5 hash of the lowercase version of the
  list member’s email address.
:type subscriber_hash: :py:class:`str`


super(AutomationActions, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.workflow_id = None<EOL>


self.workflow_id = workflow_id<EOL>return self._mc_client._post(url=self._build_path(workflow_id, '<STR_LIT>'))<EOL>

Pause all emails in a specific Automation workflow.

:param workflow_id: The unique id for the Automation workflow.
:type workflow_id: :py:class:`str`


Start all emails in an Automation workflow.

:param workflow_id: The unique id for the Automation workflow.
:type workflow_id: :py:class:`str`


super(ListWebhooks, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.list_id = None<EOL>self.webhook_id = None<EOL>


self.list_id = list_id<EOL>if '<STR_LIT:url>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>check_url(data['<STR_LIT:url>'])<EOL>response = self._mc_client._post(url=self._build_path(list_id, '<STR_LIT>'), data=data)<EOL>if response is not None:<EOL><INDENT>self.webhook_id = response['<STR_LIT:id>']<EOL><DEDENT>else:<EOL><INDENT>self.webhook_id = None<EOL><DEDENT>return response<EOL>

Create a new webhook for a specific list.

The documentation does not include any required request body
parameters but the url parameter is being listed here as a required
parameter in documentation and error-checking based on the description
of the method

:param list_id: The unique id for the list.
:type list_id: :py:class:`str`
:param data: The request body parameters
:type data: :py:class:`dict`
data = {
    "url": string*
}


self.list_id = list_id<EOL>self.webhook_id = None<EOL>return self._mc_client._get(url=self._build_path(list_id, '<STR_LIT>'))<EOL>

Get information about all webhooks for a specific list.

:param list_id: The unique id for the list.
:type list_id: :py:class:`str`


self.list_id = list_id<EOL>self.webhook_id = webhook_id<EOL>return self._mc_client._get(url=self._build_path(list_id, '<STR_LIT>', webhook_id))<EOL>

Get information about a specific webhook.

:param list_id: The unique id for the list.
:type list_id: :py:class:`str`
:param webhook_id: The unique id for the webhook.
:type webhook_id: :py:class:`str`


def update(self, list_id, webhook_id, data):

self.list_id = list_id<EOL>self.webhook_id = webhook_id<EOL>return self._mc_client._patch(url=self._build_path(list_id, '<STR_LIT>', webhook_id), data=data)<EOL>

Update the settings for an existing webhook.

:param list_id: The unique id for the list
:type list_id: :py:class:`str`
:param webhook_id: The unique id for the webhook
:type webhook_id: :py:class:`str`


self.list_id = list_id<EOL>self.webhook_id = webhook_id<EOL>return self._mc_client._delete(url=self._build_path(list_id, '<STR_LIT>', webhook_id))<EOL>

Delete a specific webhook in a list.

:param list_id: The unique id for the list.
:type list_id: :py:class:`str`
:param webhook_id: The unique id for the webhook.
:type webhook_id: :py:class:`str`


super(ListClients, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.list_id = None<EOL>


self.list_id = list_id<EOL>return self._mc_client._get(url=self._build_path(list_id, '<STR_LIT>'), **queryparams)<EOL>

Get a list of the top email clients based on user-agent strings.

:param list_id: The unique id for the list.
:type list_id: :py:class:`str`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []


super(ReportLocations, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.campaign_id = None<EOL>


def all(self, campaign_id, get_all=False, **queryparams):

self.campaign_id = campaign_id<EOL>if get_all:<EOL><INDENT>return self._iterate(url=self._build_path(campaign_id, '<STR_LIT>'), **queryparams)<EOL><DEDENT>else:<EOL><INDENT>return self._mc_client._get(url=self._build_path(campaign_id, '<STR_LIT>'), **queryparams)<EOL><DEDENT>

Get top open locations for a specific campaign.

:param campaign_id: The unique id for the campaign.
:type campaign_id: :py:class:`str`
:param get_all: Should the query get all results
:type get_all: :py:class:`bool`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []
queryparams['count'] = integer
queryparams['offset'] = integer


super(ReportDomainPerformance, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.campaign_id = None<EOL>


def all(self, campaign_id, **queryparams):

self.campaign_id = campaign_id<EOL>return self._mc_client._get(url=self._build_path(campaign_id, '<STR_LIT>'), **queryparams)<EOL>

Get statistics for the top-performing email domains in a campaign.

:param campaign_id: The unique id for the campaign.
:type campaign_id: :py:class:`str`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []


super(StoreOrderLines, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.store_id = None<EOL>self.order_id = None<EOL>self.line_id = None<EOL>


def create(self, store_id, order_id, data):

self.store_id = store_id<EOL>self.order_id = order_id<EOL>if '<STR_LIT:id>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>response = self._mc_client._post(url=self._build_path(store_id, '<STR_LIT>', order_id, '<STR_LIT>'))<EOL>if response is not None:<EOL><INDENT>self.line_id = response['<STR_LIT:id>']<EOL><DEDENT>else:<EOL><INDENT>self.line_id = None<EOL><DEDENT>return response<EOL>

Add a new line item to an existing order.

:param store_id: The store id.
:type store_id: :py:class:`str`
:param order_id: The id for the order in a store.
:type order_id: :py:class:`str`
:param data: The request body parameters
:type data: :py:class:`dict`
data = {
    "id": string*,
    "product_id": string*,
    "product_variant_id": string*,
    "quantity": integer*,
    "price": number*
}


def all(self, store_id, order_id, get_all=False, **queryparams):

self.store_id = store_id<EOL>self.order_id = order_id<EOL>self.line_id = None<EOL>if get_all:<EOL><INDENT>return self._iterate(url=self._build_path(store_id, '<STR_LIT>', order_id, '<STR_LIT>'), **queryparams)<EOL><DEDENT>else:<EOL><INDENT>return self._mc_client._get(url=self._build_path(store_id, '<STR_LIT>', order_id, '<STR_LIT>'), **queryparams)<EOL><DEDENT>

Get information about an order’s line items.

:param store_id: The store id.
:type store_id: :py:class:`str`
:param order_id: The id for the order in a store.
:type order_id: :py:class:`str`
:param get_all: Should the query get all results
:type get_all: :py:class:`bool`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []
queryparams['count'] = integer
queryparams['offset'] = integer


def get(self, store_id, order_id, line_id, **queryparams):

self.store_id = store_id<EOL>self.order_id = order_id<EOL>self.line_id = line_id<EOL>return self._mc_client._get(url=self._build_path(store_id, '<STR_LIT>', order_id, '<STR_LIT>', line_id), **queryparams)<EOL>

Get information about a specific order line item.

:param store_id: The store id.
:type store_id: :py:class:`str`
:param order_id: The id for the order in a store.
:type order_id: :py:class:`str`
:param line_id: The id for the line item of a cart.
:type line_id: :py:class:`str`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []


def update(self, store_id, order_id, line_id, data):

self.store_id = store_id<EOL>self.order_id = order_id<EOL>self.line_id = line_id<EOL>return self._mc_client._patch(url=self._build_path(store_id, '<STR_LIT>', order_id, '<STR_LIT>', line_id), data=data)<EOL>

Update a specific order line item.

:param store_id: The store id.
:type store_id: :py:class:`str`
:param order_id: The id for the order in a store.
:type order_id: :py:class:`str`
:param line_id: The id for the line item of a cart.
:type line_id: :py:class:`str`
:param data: The request body parameters
:type data: :py:class:`dict`


def delete(self, store_id, order_id, line_id):

self.store_id = store_id<EOL>self.order_id = order_id<EOL>self.line_id = line_id<EOL>return self._mc_client._delete(url=self._build_path(store_id, '<STR_LIT>', order_id, '<STR_LIT>', line_id))<EOL>

Delete a specific order line item.

:param store_id: The store id.
:type store_id: :py:class:`str`
:param order_id: The id for the order in a store.
:type order_id: :py:class:`str`
:param line_id: The id for the line item of a cart.
:type line_id: :py:class:`str`


super(CampaignFeedback, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.campaign_id = None<EOL>self.feedback_id = None<EOL>


def create(self, campaign_id, data, **queryparams):

self.campaign_id = campaign_id<EOL>if '<STR_LIT:message>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>response = self._mc_client._post(url=self._build_path(campaign_id, '<STR_LIT>'), data=data, **queryparams)<EOL>if response is not None:<EOL><INDENT>self.feedback_id = response['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>self.feedback_id = None<EOL><DEDENT>return response<EOL>

Add feedback on a specific campaign.

:param campaign_id: The unique id for the campaign.
:type campaign_id: :py:class:`str`
:param data: The request body parameters
:type data: :py:class:`dict`
data = {
    "message": string*
}
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []


self.campaign_id = campaign_id<EOL>self.feedback_id = None<EOL>if get_all:<EOL><INDENT>return self._iterate(url=self._build_path(campaign_id, '<STR_LIT>'), **queryparams)<EOL><DEDENT>else:<EOL><INDENT>return self._mc_client._get(url=self._build_path(campaign_id, '<STR_LIT>'), **queryparams)<EOL><DEDENT>

Get team feedback while you’re working together on a MailChimp
campaign.

:param campaign_id: The unique id for the campaign.
:type campaign_id: :py:class:`str`
:param get_all: Should the query get all results
:type get_all: :py:class:`bool`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []


def get(self, campaign_id, feedback_id, **queryparams):

self.campaign_id = campaign_id<EOL>self.feedback_id = feedback_id<EOL>return self._mc_client._get(url=self._build_path(campaign_id, '<STR_LIT>', feedback_id), **queryparams)<EOL>

Get a specific feedback message from a campaign.

:param campaign_id: The unique id for the campaign.
:type campaign_id: :py:class:`str`
:param feedback_id: The unique id for the feedback message.
:type feedback_id: :py:class:`str`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []


def update(self, campaign_id, feedback_id, data):

self.campaign_id = campaign_id<EOL>self.feedback_id = feedback_id<EOL>if '<STR_LIT:message>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>return self._mc_client._patch(url=self._build_path(campaign_id, '<STR_LIT>', feedback_id), data=data)<EOL>

Update a specific feedback message for a campaign.

:param campaign_id: The unique id for the campaign.
:type campaign_id: :py:class:`str`
:param feedback_id: The unique id for the feedback message.
:type feedback_id: :py:class:`str`
:param data: The request body parameters
:type data: :py:class:`dict`
data = {
    "message": string*
}


def delete(self, campaign_id, feedback_id):

self.campaign_id = campaign_id<EOL>self.feedback_id = feedback_id<EOL>return self._mc_client._delete(url=self._build_path(campaign_id, '<STR_LIT>', feedback_id))<EOL>

Remove a specific feedback message for a campaign.

:param campaign_id: The unique id for the campaign.
:type campaign_id: :py:class:`str`
:param feedback_id: The unique id for the feedback message.
:type feedback_id: :py:class:`str`


super(OpenDetails, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.campaign_id = None<EOL>


def all(self, campaign_id, get_all=False,  **queryparams):

Get detailed information about any campaign emails that were opened by a list member.

:param campaign_id: The unique id for the campaign.
:type campaign_id: :py:class:`str`
:param get_all: Should the query get all results
:type get_all: :py:class:`bool`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []
queryparams['count'] = integer
queryparams['offset'] = integer
queryparams['since'] = str


super(ConversationMessages, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.conversation_id = None<EOL>self.message_id = None<EOL>


def create(self, conversation_id, data):

self.conversation_id = conversation_id<EOL>if '<STR_LIT>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>check_email(data['<STR_LIT>'])<EOL>if '<STR_LIT>' not in data:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if data['<STR_LIT>'] not in [True, False]:<EOL><INDENT>raise TypeError('<STR_LIT>')<EOL><DEDENT>response =  self._mc_client._post(url=self._build_path(conversation_id, '<STR_LIT>'), data=data)<EOL>if response is not None:<EOL><INDENT>self.message_id = response['<STR_LIT:id>']<EOL><DEDENT>else:<EOL><INDENT>self.message_id = None<EOL><DEDENT>return response<EOL>

Post a new message to a conversation.

:param conversation_id: The unique id for the conversation.
:type conversation_id: :py:class:`str`
:param data: The request body parameters
:type data: :py:class:`dict`
data = {
    "from_email": string*,
    "read": boolean*
}


def all(self, conversation_id, **queryparams):

self.conversation_id = conversation_id<EOL>self.message_id = None<EOL>return self._mc_client._get(url=self._build_path(conversation_id, '<STR_LIT>'), **queryparams)<EOL>

Get messages from a specific conversation.

This endpoint does not currently support count and offset, preventing
it from having the get_all parameter that most all() methods have

:param conversation_id: The unique id for the conversation.
:type conversation_id: :py:class:`str`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = p[
queryparams['is_read'] = string
queryparams['before_timestamp'] = string
queryparams['since_timestamp'] = string


def get(self, conversation_id, message_id, **queryparams):

self.conversation_id = conversation_id<EOL>self.message_id = message_id<EOL>return self._mc_client._get(url=self._build_path(conversation_id, '<STR_LIT>', message_id), **queryparams)<EOL>

Get an individual message in a conversation.

:param conversation_id: The unique id for the conversation.
:type conversation_id: :py:class:`str`
:param message_id: The unique id for the conversation message.
:type message_id: :py:class:`str`
:param queryparams: The query string parameters
queryparams['fields'] = []
queryparams['exclude_fields'] = []


super(StoreCustomers, self).__init__(*args, **kwargs)<EOL>self.endpoint = '<STR_LIT>'<EOL>self.store_id = None<EOL>self.customer_id = None<EOL>