def _verify_time_range(payload_dict):
    """Verifies the issued at and expiration from a JWT payload.

    Makes sure the current time (in UTC) falls between the issued at and
    expiration for the JWT (with some skew allowed for via
    ``CLOCK_SKEW_SECS``).

    Args:
        payload_dict: dict, A dictionary containing a JWT payload.

    Raises:
        AppIdentityError: If there is no ``'iat'`` field in the payload
                          dictionary.
        AppIdentityError: If there is no ``'exp'`` field in the payload
                          dictionary.
        AppIdentityError: If the JWT expiration is too far in the future (i.e.
                          if the expiration would imply a token lifetime
                          longer than what is allowed.)
        AppIdentityError: If the token appears to have been issued in the
                          future (up to clock skew).
        AppIdentityError: If the token appears to have expired in the past
                          (up to clock skew).
    """
    # Get the current time to use throughout.
    now = int(time.time())

    # Make sure issued at and expiration are in the payload.
    issued_at = payload_dict.get('iat')
    if issued_at is None:
        raise AppIdentityError(
            'No iat field in token: {0}'.format(payload_dict))
    expiration = payload_dict.get('exp')
    if expiration is None:
        raise AppIdentityError(
            'No exp field in token: {0}'.format(payload_dict))

    # Make sure the expiration gives an acceptable token lifetime.
    if expiration >= now + MAX_TOKEN_LIFETIME_SECS:
        raise AppIdentityError(
            'exp field too far in future: {0}'.format(payload_dict))

    # Make sure (up to clock skew) that the token wasn't issued in the future.
    earliest = issued_at - CLOCK_SKEW_SECS
    if now < earliest:
        raise AppIdentityError('Token used too early, {0} < {1}: {2}'.format(
            now, earliest, payload_dict))
    # Make sure (up to clock skew) that the token isn't already expired.
    latest = expiration + CLOCK_SKEW_SECS
    if now > latest:
        raise AppIdentityError('Token used too late, {0} > {1}: {2}'.format(
            now, latest, payload_dict))

def
_verify_time_range
(
payload_dict
)
:
now
=
int
(
time
.
time
(
)
)
issued_at
=
payload_dict
.
get
(
'iat'
)
if
issued_at
is
:
raise
AppIdentityError
(
'No iat field in token: {0}'
.
format
(
payload_dict
)
)
expiration
=
payload_dict
.
get
(
'exp'
)
if
expiration
is
:
raise
AppIdentityError
(
'No exp field in token: {0}'
.
format
(
payload_dict
)
)
if
expiration
>=
now
+
MAX_TOKEN_LIFETIME_SECS
:
raise
AppIdentityError
(
'exp field too far in future: {0}'
.
format
(
payload_dict
)
)
earliest
=
issued_at
CLOCK_SKEW_SECS
if
now
<
earliest
:
raise
AppIdentityError
(
'Token used too early, {0} < {1}: {2}'
.
format
(
now
,
earliest
,
payload_dict
)
)
latest
=
expiration
+
CLOCK_SKEW_SECS
if
now
>
latest
:
raise
AppIdentityError
(
'Token used too late, {0} > {1}: {2}'
.
format
(
now
,
latest
,
payload_dict
)
)

Verifies the issued at and expiration from a JWT payload .


def verify_signed_jwt_with_certs(jwt, certs, audience=None):
    """Verify a JWT against public certs.

    See http://self-issued.info/docs/draft-jones-json-web-token.html.

    Args:
        jwt: string, A JWT.
        certs: dict, Dictionary where values of public keys in PEM format.
        audience: string, The audience, 'aud', that this JWT should contain. If
                  None then the JWT's 'aud' parameter is not verified.

    Returns:
        dict, The deserialized JSON payload in the JWT.

    Raises:
        AppIdentityError: if any checks are failed.
    """
    jwt = _helpers._to_bytes(jwt)

    if jwt.count(b'.') != 2:
        raise AppIdentityError(
            'Wrong number of segments in token: {0}'.format(jwt))

    header, payload, signature = jwt.split(b'.')
    message_to_sign = header + b'.' + payload
    signature = _helpers._urlsafe_b64decode(signature)

    # Parse token.
    payload_bytes = _helpers._urlsafe_b64decode(payload)
    try:
        payload_dict = json.loads(_helpers._from_bytes(payload_bytes))
    except:
        raise AppIdentityError('Can\'t parse token: {0}'.format(payload_bytes))

    # Verify that the signature matches the message.
    _verify_signature(message_to_sign, signature, certs.values())

    # Verify the issued at and created times in the payload.
    _verify_time_range(payload_dict)

    # Check audience.
    _check_audience(payload_dict, audience)

    return payload_dict


def get(self, template_id, **queryparams):
        """
        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'] = []
        """
        self.template_id = template_id
        return self._mc_client._get(url=self._build_path(template_id), **queryparams)

def get ( self , template_id , ** queryparams ) : self . template_id = template_id return self . _mc_client . _get ( url = self . _build_path ( template_id ) , ** queryparams )

Get information about a specific template .


def update(self, template_id, data):
        """
        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*
        }
        """
        if 'name' not in data:
            raise KeyError('The template must have a name')
        if 'html' not in data:
            raise KeyError('The template must have html')
        self.template_id = template_id
        return self._mc_client._patch(url=self._build_path(template_id), data=data)

def
update
(
self
,
template_id
,
data
)
:
if
'name'
not
in
data
:
raise
KeyError
(
'The template must have a name'
)
if
'html'
not
in
data
:
raise
KeyError
(
'The template must have html'
)
self
.
template_id
=
template_id
return
self
.
_mc_client
.
_patch
(
url
=
self
.
_build_path
(
template_id
)
,
data
=
data
)

Update the name HTML or folder_id of an existing template .


def delete(self, template_id):
        """
        Delete a specific template.

        :param template_id: The unique id for the template.
        :type template_id: :py:class:`str`
        """
        self.template_id = template_id
        return self._mc_client._delete(url=self._build_path(template_id))

def delete ( self , template_id ) : self . template_id = template_id return self . _mc_client . _delete ( url = self . _build_path ( template_id ) )


def get_subscriber_hash(member_email):
    """
    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`
    """
    check_email(member_email)
    member_email = member_email.lower().encode()
    m = hashlib.md5(member_email)
    return m.hexdigest()

def get_subscriber_hash ( member_email ) : check_email ( member_email ) member_email = member_email . lower ( ) . encode ( ) m = hashlib . md5 ( member_email ) return m . hexdigest ( )

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


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

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


def merge_results(x, y):
    """
    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`
    """
    z = x.copy()
    for key, value in y.items():
        if isinstance(value, list) and isinstance(z.get(key), list):
            z[key] += value
        else:
            z[key] = value
    return z

def merge_results ( x , y ) : z = x . copy ( ) for key , value in y . items ( ) : if isinstance ( value , list ) and isinstance ( z . get ( key ) , list ) : z [ key ] += value else : z [ key ] = value return z

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


def create(self, data):
        """
        Create a new list in your MailChimp account.

        :param data: The request body parameters
        :type data: :py:class:`dict`
        data = {
            "name": string*,
            "contact": object*
            {
                "company": string*,
                "address1": string*,
                "city": string*,
                "state": string*,
                "zip": string*,
                "country": string*
            },
            "permission_reminder": string*,
            "campaign_defaults": object*
            {
                "from_name": string*,
                "from_email": string*,
                "subject": string*,
                "language": string*
            },
            "email_type_option": boolean
        }
        """
        if 'name' not in data:
            raise KeyError('The list must have a name')
        if 'contact' not in data:
            raise KeyError('The list must have a contact')
        if 'company' not in data['contact']:
            raise KeyError('The list contact must have a company')
        if 'address1' not in data['contact']:
            raise KeyError('The list contact must have a address1')
        if 'city' not in data['contact']:
            raise KeyError('The list contact must have a city')
        if 'state' not in data['contact']:
            raise KeyError('The list contact must have a state')
        if 'zip' not in data['contact']:
            raise KeyError('The list contact must have a zip')
        if 'country' not in data['contact']:
            raise KeyError('The list contact must have a country')
        if 'permission_reminder' not in data:
            raise KeyError('The list must have a permission_reminder')
        if 'campaign_defaults' not in data:
            raise KeyError('The list must have a campaign_defaults')
        if 'from_name' not in data['campaign_defaults']:
            raise KeyError('The list campaign_defaults must have a from_name')
        if 'from_email' not in data['campaign_defaults']:
            raise KeyError('The list campaign_defaults must have a from_email')
        check_email(data['campaign_defaults']['from_email'])
        if 'subject' not in data['campaign_defaults']:
            raise KeyError('The list campaign_defaults must have a subject')
        if 'language' not in data['campaign_defaults']:
            raise KeyError('The list campaign_defaults must have a language')
        if 'email_type_option' not in data:
            raise KeyError('The list must have an email_type_option')
        if data['email_type_option'] not in [True, False]:
            raise TypeError('The list email_type_option must be True or False')
        response = self._mc_client._post(url=self._build_path(), data=data)
        if response is not None:
            self.list_id = response['id']
        else:
            self.list_id = None
        return response

Create a new list in your MailChimp account .


def update_members(self, list_id, data):
        """
        Batch subscribe or unsubscribe list members.

        Only the members array is required in the request body parameters.
        Within the members array, each member requires an email_address
        and either a status or status_if_new. The update_existing parameter
        will also be considered required to help prevent accidental updates
        to existing members and will default to false if not present.

        :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 = {
            "members": array*
            [
                {
                    "email_address": string*,
                    "status": string* (Must be one of 'subscribed', 'unsubscribed', 'cleaned', or 'pending'),
                    "status_if_new": string* (Must be one of 'subscribed', 'unsubscribed', 'cleaned', or 'pending')
                }
            ],
            "update_existing": boolean*
        }
        """
        self.list_id = list_id
        if 'members' not in data:
            raise KeyError('The update must have at least one member')
        else:
            if not len(data['members']) <= 500:
                raise ValueError('You may only batch sub/unsub 500 members at a time')
        for member in data['members']:
            if 'email_address' not in member:
                raise KeyError('Each list member must have an email_address')
            check_email(member['email_address'])
            if 'status' not in member and 'status_if_new' not in member:
                raise KeyError('Each list member must have either a status or a status_if_new')
            valid_statuses = ['subscribed', 'unsubscribed', 'cleaned', 'pending']
            if 'status' in member and member['status'] not in valid_statuses:
                raise ValueError('The list member status must be one of "subscribed", "unsubscribed", "cleaned", or '
                                 '"pending"')
            if 'status_if_new' in member and member['status_if_new'] not in valid_statuses:
                raise ValueError('The list member status_if_new must be one of "subscribed", "unsubscribed", '
                                 '"cleaned", or "pending"')
        if 'update_existing' not in data:
            data['update_existing'] = False
        return self._mc_client._post(url=self._build_path(list_id), data=data)

Batch subscribe or unsubscribe list members .


def update(self, list_id, data):
        """
        Update the settings for a specific list.

        :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 = {
            "name": string*,
            "contact": object*
            {
                "company": string*,
                "address1": string*,
                "city": string*,
                "state": string*,
                "zip": string*,
                "country": string*
            },
            "permission_reminder": string*,
            "campaign_defaults": object*
            {
                "from_name": string*,
                "from_email": string*,
                "subject": string*,
                "language": string*
            },
            "email_type_option": boolean
        }
        """
        self.list_id = list_id
        if 'name' not in data:
            raise KeyError('The list must have a name')
        if 'contact' not in data:
            raise KeyError('The list must have a contact')
        if 'company' not in data['contact']:
            raise KeyError('The list contact must have a company')
        if 'address1' not in data['contact']:
            raise KeyError('The list contact must have a address1')
        if 'city' not in data['contact']:
            raise KeyError('The list contact must have a city')
        if 'state' not in data['contact']:
            raise KeyError('The list contact must have a state')
        if 'zip' not in data['contact']:
            raise KeyError('The list contact must have a zip')
        if 'country' not in data['contact']:
            raise KeyError('The list contact must have a country')
        if 'permission_reminder' not in data:
            raise KeyError('The list must have a permission_reminder')
        if 'campaign_defaults' not in data:
            raise KeyError('The list must have a campaign_defaults')
        if 'from_name' not in data['campaign_defaults']:
            raise KeyError('The list campaign_defaults must have a from_name')
        if 'from_email' not in data['campaign_defaults']:
            raise KeyError('The list campaign_defaults must have a from_email')
        check_email(data['campaign_defaults']['from_email'])
        if 'subject' not in data['campaign_defaults']:
            raise KeyError('The list campaign_defaults must have a subject')
        if 'language' not in data['campaign_defaults']:
            raise KeyError('The list campaign_defaults must have a language')
        if 'email_type_option' not in data:
            raise KeyError('The list must have an email_type_option')
        if data['email_type_option'] not in [True, False]:
            raise TypeError('The list email_type_option must be True or False')
        return self._mc_client._patch(url=self._build_path(list_id), data=data)

Update the settings for a specific list .


def create(self, store_id, order_id, data):
        """
        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*
        }
        """
        self.store_id = store_id
        self.order_id = order_id
        if 'id' not in data:
            raise KeyError('The order line must have an id')
        if 'product_id' not in data:
            raise KeyError('The order line must have a product_id')
        if 'product_variant_id' not in data:
            raise KeyError('The order line must have a product_variant_id')
        if 'quantity' not in data:
            raise KeyError('The order line must have a quantity')
        if 'price' not in data:
            raise KeyError('The order line must have a price')
        response = self._mc_client._post(url=self._build_path(store_id, 'orders', order_id, 'lines'))
        if response is not None:
            self.line_id = response['id']
        else:
            self.line_id = None
        return response

Add a new line item to an existing order .


def get(self, **queryparams):
        """
        Get links to all other resources available in the API.

        :param queryparams: The query string parameters
        queryparams['fields'] = []
        queryparams['exclude_fields'] = []
        """
        return self._mc_client._get(url=self._build_path(), **queryparams)

def get ( self , ** queryparams ) : return self . _mc_client . _get ( url = self . _build_path ( ) , ** queryparams )

Get links to all other resources available in the API .


def create(self, data):
        """
        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*
        }
        """
        self.app_id = None
        if 'client_id' not in data:
            raise KeyError('The authorized app must have a client_id')
        if 'client_secret' not in data:
            raise KeyError('The authorized app must have a client_secret')
        return self._mc_client._post(url=self._build_path(), data=data)

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


def get(self, app_id, **queryparams):
        """
        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'] = []
        """
        self.app_id = app_id
        return self._mc_client._get(url=self._build_path(app_id), **queryparams)

def get ( self , app_id , ** queryparams ) : self . app_id = app_id return self . _mc_client . _get ( url = self . _build_path ( app_id ) , ** queryparams )


def create(self, store_id, data):
        """
        Add new promo rule 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,
            "description": string*,
            "starts_at": string,
            "ends_at": string,
            "amount": number*,
            "type": string*,
            "target": string*,
            "enabled": boolean,
            "created_at_foreign": string,
            "updated_at_foreign": string,
        }
        """
        self.store_id = store_id
        if 'id' not in data:
            raise KeyError('The promo rule must have an id')
        if 'description' not in data:
            raise KeyError('This promo rule must have a description')
        if 'amount' not in data:
            raise KeyError('This promo rule must have an amount')
        if 'target' not in data:
            raise KeyError('This promo rule must apply to a target (example per_item, total, or shipping')
        response = self._mc_client._post(url=self._build_path(store_id, 'promo-rules'), data=data)

        if response is not None:
            return response


def get(self, folder_id, **queryparams):
        """
        Get information about a specific folder used to organize campaigns.

        :param folder_id: The unique id for the campaign folder.
        :type folder_id: :py:class:`str`
        :param queryparams: The query string parameters
        queryparams['fields'] = []
        queryparams['exclude_fields'] = []
        """
        self.folder_id = folder_id
        return self._mc_client._get(url=self._build_path(folder_id), **queryparams)

def get ( self , folder_id , ** queryparams ) : self . folder_id = folder_id return self . _mc_client . _get ( url = self . _build_path ( folder_id ) , ** queryparams )

Get information about a specific folder used to organize campaigns .


def get(self, workflow_id, email_id):
        """
        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`
        """
        self.workflow_id = workflow_id
        self.email_id = email_id
        return self._mc_client._get(url=self._build_path(workflow_id, 'emails', email_id))

def get ( self , workflow_id , email_id ) : self . workflow_id = workflow_id self . email_id = email_id return self . _mc_client . _get ( url = self . _build_path ( workflow_id , 'emails' , email_id ) )

Get information about an individual Automation workflow email .


def create(self, data):
        """
        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*
        }
        """
        if 'name' not in data:
            raise KeyError('The file must have a name')
        if 'file_data' not in data:
            raise KeyError('The file must have file_data')
        response = self._mc_client._post(url=self._build_path(), data=data)
        if response is not None:
            self.file_id = response['id']
        else:
            self.file_id = None
        return response

def
create
(
self
,
data
)
:
if
'name'
not
in
data
:
raise
KeyError
(
'The file must have a name'
)
if
'file_data'
not
in
data
:
raise
KeyError
(
'The file must have file_data'
)
response
=
self
.
_mc_client
.
_post
(
url
=
self
.
_build_path
(
)
,
data
=
data
)
if
response
is
not
:
self
.
file_id
=
response
[
'id'
]
else
:
self
.
file_id
=
return
response

Upload a new image or file to the File Manager .


def get(self, file_id, **queryparams):
        """
        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
        return self._mc_client._get(url=self._build_path(file_id), **queryparams)

def get ( self , file_id , ** queryparams ) : self . file_id = file_id return self . _mc_client . _get ( url = self . _build_path ( file_id ) , ** queryparams )

Get information about a specific file in the File Manager .


def update(self, file_id, data):
        """
        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
        if 'name' not in data:
            raise KeyError('The file must have a name')
        if 'file_data' not in data:
            raise KeyError('The file must have file_data')
        return self._mc_client._patch(url=self._build_path(file_id), data=data)

def
update
(
self
,
file_id
,
data
)
:
self
.
file_id
=
file_id
if
'name'
not
in
data
:
raise
KeyError
(
'The file must have a name'
)
if
'file_data'
not
in
data
:
raise
KeyError
(
'The file must have file_data'
)
return
self
.
_mc_client
.
_patch
(
url
=
self
.
_build_path
(
file_id
)
,
data
=
data
)


def delete(self, file_id):
        """
        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`
        """
        self.file_id = file_id
        return self._mc_client._delete(url=self._build_path(file_id))

def delete ( self , file_id ) : self . file_id = file_id return self . _mc_client . _delete ( url = self . _build_path ( file_id ) )

Remove a specific file from the File Manager .


def _build_path(self, *args):
        """
        Build path with endpoint and args

        :param args: Tokens in the endpoint URL
        :type args: :py:class:`unicode`
        """
        return '/'.join(chain((self.endpoint,), map(str, args)))

def _build_path ( self , * args ) : return '/' . join ( chain ( ( self . endpoint , ) , map ( str , args ) ) )


def _iterate(self, url, **queryparams):
        """
        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
        """
        # fields as a query string parameter should be a string with
        # comma-separated substring values to pass along to
        # self._mc_client._get(). It should also contain total_items whenever
        # the parameter is employed, which is forced here.
        if 'fields' in queryparams:
            if 'total_items' not in queryparams['fields'].split(','):
                queryparams['fields'] += ',total_items'
        # Remove offset and count if provided in queryparams
        # to avoid 'multiple values for keyword argument' TypeError
        queryparams.pop("offset", None)
        queryparams.pop("count", None)
        # Fetch results from mailchimp, up to first 1000
        result = self._mc_client._get(url=url, offset=0, count=1000, **queryparams)
        total = result['total_items']
        # Fetch further results if necessary
        if total > 1000:
            for offset in range(1, int(total / 1000) + 1):
                result = merge_results(result, self._mc_client._get(
                    url=url,
                    offset=int(offset * 1000),
                    count=1000,
                    **queryparams
                ))
            return result
        else:  # Further results not necessary
            return result

def _iterate ( self , url , ** queryparams ) : if 'fields' in queryparams : if 'total_items' not in queryparams [ 'fields' ] . split ( ',' ) : queryparams [ 'fields' ] += ',total_items' queryparams . pop ( "offset" , None ) queryparams . pop ( "count" , None ) result = self . _mc_client . _get ( url = url , offset = 0 , count = 1000 , ** queryparams ) total = result [ 'total_items' ] if total > 1000 : for offset in range ( 1 , int ( total / 1000 ) + 1 ) : result = merge_results ( result , self . _mc_client . _get ( url = url , offset = int ( offset * 1000 ) , count = 1000 , ** queryparams ) ) return result else : return result

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


def all(self, workflow_id):
        """
        Get information about subscribers who were removed from an Automation
        workflow.

        :param workflow_id: The unique id for the Automation workflow.
        :type workflow_id: :py:class:`str`
        """
        self.workflow_id = workflow_id
        return self._mc_client._get(url=self._build_path(workflow_id, 'removed-subscribers'))

def all ( self , workflow_id ) : self . workflow_id = workflow_id return self . _mc_client . _get ( url = self . _build_path ( workflow_id , 'removed-subscribers' ) )

Get information about subscribers who were removed from an Automation workflow .


def create(self, list_id, data):
        """
        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
        if 'url' not in data:
            raise KeyError('The list webhook must have a url')
        check_url(data['url'])
        response = self._mc_client._post(url=self._build_path(list_id, 'webhooks'), data=data)
        if response is not None:
            self.webhook_id = response['id']
        else:
            self.webhook_id = None
        return response

def
create
(
self
,
list_id
,
data
)
:
self
.
list_id
=
list_id
if
'url'
not
in
data
:
raise
KeyError
(
'The list webhook must have a url'
)
check_url
(
data
[
'url'
]
)
response
=
self
.
_mc_client
.
_post
(
url
=
self
.
_build_path
(
list_id
,
'webhooks'
)
,
data
=
data
)
if
response
is
not
:
self
.
webhook_id
=
response
[
'id'
]
else
:
self
.
webhook_id
=
return
response

Create a new webhook for a specific list .


def get(self, list_id, webhook_id):
        """
        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`
        """
        self.list_id = list_id
        self.webhook_id = webhook_id
        return self._mc_client._get(url=self._build_path(list_id, 'webhooks', webhook_id))

def get ( self , list_id , webhook_id ) : self . list_id = list_id self . webhook_id = webhook_id return self . _mc_client . _get ( url = self . _build_path ( list_id , 'webhooks' , webhook_id ) )

Get information about a specific webhook .


def update(self, list_id, webhook_id, data):
        """
        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
        self.webhook_id = webhook_id
        return self._mc_client._patch(url=self._build_path(list_id, 'webhooks', webhook_id), data=data)

def update ( self , list_id , webhook_id , data ) : self . list_id = list_id self . webhook_id = webhook_id return self . _mc_client . _patch ( url = self . _build_path ( list_id , 'webhooks' , webhook_id ) , data = data )

Update the settings for an existing webhook .


def delete(self, list_id, webhook_id):
        """
        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`
        """
        self.list_id = list_id
        self.webhook_id = webhook_id
        return self._mc_client._delete(url=self._build_path(list_id, 'webhooks', webhook_id))

def delete ( self , list_id , webhook_id ) : self . list_id = list_id self . webhook_id = webhook_id return self . _mc_client . _delete ( url = self . _build_path ( list_id , 'webhooks' , webhook_id ) )


def all(self, list_id, **queryparams):
        """
        returns the first 10 segments for a specific list.
        """
        return self._mc_client._get(url=self._build_path(list_id, 'segments'), **queryparams)

def all ( self , list_id , ** queryparams ) : return self . _mc_client . _get ( url = self . _build_path ( list_id , 'segments' ) , ** queryparams )

returns the first 10 segments for a specific list .


def get(self, list_id, segment_id):
        """
        returns the specified list segment.
        """
        return self._mc_client._get(url=self._build_path(list_id, 'segments', segment_id))

def get ( self , list_id , segment_id ) : return self . _mc_client . _get ( url = self . _build_path ( list_id , 'segments' , segment_id ) )


def update(self, list_id, segment_id, data):
        """
        updates an existing list segment.
        """
        return self._mc_client._patch(url=self._build_path(list_id, 'segments', segment_id), data=data)

def update ( self , list_id , segment_id , data ) : return self . _mc_client . _patch ( url = self . _build_path ( list_id , 'segments' , segment_id ) , data = data )


def delete(self, list_id, segment_id):
        """
        removes an existing list segment from the list. This cannot be undone.
        """
        return self._mc_client._delete(url=self._build_path(list_id, 'segments', segment_id))

def delete ( self , list_id , segment_id ) : return self . _mc_client . _delete ( url = self . _build_path ( list_id , 'segments' , segment_id ) )

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


def create(self, list_id, data):
        """
        adds a new segment to the list.
        """
        return self._mc_client._post(url=self._build_path(list_id, 'segments'), data=data)

def create ( self , list_id , data ) : return self . _mc_client . _post ( url = self . _build_path ( list_id , 'segments' ) , data = data )


def _post(self, url, data=None):
        """
        Handle authenticated POST requests

        :param url: The url for the endpoint including path parameters
        :type url: :py:class:`str`
        :param data: The request body parameters
        :type data: :py:data:`none` or :py:class:`dict`
        :returns: The JSON output from the API or an error message
        """
        url = urljoin(self.base_url, url)
        try:
            r = self._make_request(**dict(
                method='POST',
                url=url,
                json=data,
                auth=self.auth,
                timeout=self.timeout,
                hooks=self.request_hooks,
                headers=self.request_headers
            ))
        except requests.exceptions.RequestException as e:
            raise e
        else:
            if r.status_code >= 400:
                # in case of a 500 error, the response might not be a JSON
                try:
                    error_data = r.json()
                except ValueError:
                    error_data = { "response": r }
                raise MailChimpError(error_data)
            if r.status_code == 204:
                return None
            return r.json()

def _post ( self , url , data = None ) : url = urljoin ( self . base_url , url ) try : r = self . _make_request ( ** dict ( method = 'POST' , url = url , json = data , auth = self . auth , timeout = self . timeout , hooks = self . request_hooks , headers = self . request_headers ) ) except requests . exceptions . RequestException as e : raise e else : if r . status_code >= 400 : try : error_data = r . json ( ) except ValueError : error_data = { "response" : r } raise MailChimpError ( error_data ) if r . status_code == 204 : return None return r . json ( )


def get_metadata(self):
        """
        Get the metadata returned after authentication
        """
        try:
            r = requests.get('https://login.mailchimp.com/oauth2/metadata', auth=self)
        except requests.exceptions.RequestException as e:
            raise e
        else:
            r.raise_for_status()
            output = r.json()
            if 'error' in output:
                raise requests.exceptions.RequestException(output['error'])
            return output


def update(self, campaign_id, data):
        """
        Set the content for a 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`
        """
        self.campaign_id = campaign_id
        return self._mc_client._put(url=self._build_path(campaign_id, 'content'), data=data)

def update ( self , campaign_id , data ) : self . campaign_id = campaign_id return self . _mc_client . _put ( url = self . _build_path ( campaign_id , 'content' ) , data = data )


def get(self, conversation_id, **queryparams):
        """
        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'] = []
        """
        self.conversation_id = conversation_id
        return self._mc_client._get(url=self._build_path(conversation_id), **queryparams)

def get ( self , conversation_id , ** queryparams ) : self . conversation_id = conversation_id return self . _mc_client . _get ( url = self . _build_path ( conversation_id ) , ** queryparams )

Get details about an individual conversation .


def all(self, campaign_id, get_all=False, **queryparams):
        """
        Get information about members who have unsubscribed from 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
        """
        self.campaign_id = campaign_id
        self.subscriber_hash = None
        if get_all:
            return self._iterate(url=self._build_path(campaign_id, 'unsubscribed'), **queryparams)
        else:
            return self._mc_client._get(url=self._build_path(campaign_id, 'unsubscribed'), **queryparams)

def all ( self , campaign_id , get_all = False , ** queryparams ) : self . campaign_id = campaign_id self . subscriber_hash = None if get_all : return self . _iterate ( url = self . _build_path ( campaign_id , 'unsubscribed' ) , ** queryparams ) else : return self . _mc_client . _get ( url = self . _build_path ( campaign_id , 'unsubscribed' ) , ** queryparams )

Get information about members who have unsubscribed from a specific campaign .


def create(self, workflow_id, email_id, data):
        """
        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
        self.email_id = email_id
        if 'email_address' not in data:
            raise KeyError('The automation email queue must have an email_address')
        check_email(data['email_address'])
        response = self._mc_client._post(
            url=self._build_path(workflow_id, 'emails', email_id, 'queue'),
            data=data
        )
        if response is not None:
            self.subscriber_hash = response['id']
        else:
            self.subscriber_hash = None
        return response

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 .


def all(self, workflow_id, email_id):
        """
        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`
        """
        self.workflow_id = workflow_id
        self.email_id = email_id
        self.subscriber_hash = None
        return self._mc_client._get(url=self._build_path(workflow_id, 'emails', email_id, 'queue'))

def all ( self , workflow_id , email_id ) : self . workflow_id = workflow_id self . email_id = email_id self . subscriber_hash = None return self . _mc_client . _get ( url = self . _build_path ( workflow_id , 'emails' , email_id , 'queue' ) )

Get information about an Automation email queue .


def get(self, workflow_id, email_id, subscriber_hash):
        """
        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`
        """
        subscriber_hash = check_subscriber_hash(subscriber_hash)
        self.workflow_id = workflow_id
        self.email_id = email_id
        self.subscriber_hash = subscriber_hash
        return self._mc_client._get(url=self._build_path(workflow_id, 'emails', email_id, 'queue', subscriber_hash))

def get ( self , workflow_id , email_id , subscriber_hash ) : subscriber_hash = check_subscriber_hash ( subscriber_hash ) self . workflow_id = workflow_id self . email_id = email_id self . subscriber_hash = subscriber_hash return self . _mc_client . _get ( url = self . _build_path ( workflow_id , 'emails' , email_id , 'queue' , subscriber_hash ) )

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


def cancel(self, campaign_id):
        """
        Cancel a Regular or Plain-Text Campaign after you send, before all of
        your recipients receive it. This feature is included with MailChimp
        Pro.

        :param campaign_id: The unique id for the campaign.
        :type campaign_id: :py:class:`str`
        """
        self.campaign_id = campaign_id
        return self._mc_client._post(url=self._build_path(campaign_id, 'actions/cancel-send'))

def cancel ( self , campaign_id ) : self . campaign_id = campaign_id return self . _mc_client . _post ( url = self . _build_path ( campaign_id , 'actions/cancel-send' ) )

Cancel a Regular or Plain - Text Campaign after you send before all of your recipients receive it . This feature is included with MailChimp Pro .


def pause(self, campaign_id):
        """
        Pause an RSS-Driven campaign.

        :param campaign_id: The unique id for the campaign.
        :type campaign_id: :py:class:`str`
        """
        self.campaign_id = campaign_id
        return self._mc_client._post(url=self._build_path(campaign_id, 'actions/pause'))

def pause ( self , campaign_id ) : self . campaign_id = campaign_id return self . _mc_client . _post ( url = self . _build_path ( campaign_id , 'actions/pause' ) )


def replicate(self, campaign_id):
        """
        Replicate a campaign in saved or send status.

        :param campaign_id: The unique id for the campaign.
        :type campaign_id: :py:class:`str`
        """
        self.campaign_id = campaign_id
        return self._mc_client._post(url=self._build_path(campaign_id, 'actions/replicate'))

def replicate ( self , campaign_id ) : self . campaign_id = campaign_id return self . _mc_client . _post ( url = self . _build_path ( campaign_id , 'actions/replicate' ) )

Replicate a campaign in saved or send status .


def resume(self, campaign_id):
        """
        Resume an RSS-Driven campaign.

        :param campaign_id: The unique id for the campaign.
        :type campaign_id: :py:class:`str`
        """
        self.campaign_id = campaign_id
        return self._mc_client._post(url=self._build_path(campaign_id, 'actions/resume'))

def resume ( self , campaign_id ) : self . campaign_id = campaign_id return self . _mc_client . _post ( url = self . _build_path ( campaign_id , 'actions/resume' ) )


def send(self, campaign_id):
        """
        Send a MailChimp campaign. For RSS Campaigns, the campaign will send
        according to its schedule. All other campaigns will send immediately.

        :param campaign_id: The unique id for the campaign.
        :type campaign_id: :py:class:`str`
        """
        self.campaign_id = campaign_id
        return self._mc_client._post(url=self._build_path(campaign_id, 'actions/send'))

def send ( self , campaign_id ) : self . campaign_id = campaign_id return self . _mc_client . _post ( url = self . _build_path ( campaign_id , 'actions/send' ) )

Send a MailChimp campaign . For RSS Campaigns the campaign will send according to its schedule . All other campaigns will send immediately .


def create(self, store_id, data):
        """
        Add a new customer 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*,
            "email_address": string*,
            "opt_in_status": boolean*
        }
        """
        self.store_id = store_id
        if 'id' not in data:
            raise KeyError('The store customer must have an id')
        if 'email_address' not in data:
            raise KeyError('The store customer must have an email_address')
        check_email(data['email_address'])
        if 'opt_in_status' not in data:
            raise KeyError('The store customer must have an opt_in_status')
        if data['opt_in_status'] not in [True, False]:
            raise TypeError('The opt_in_status must be True or False')
        response = self._mc_client._post(url=self._build_path(store_id, 'customers'), data=data)
        if response is not None:
            self.customer_id = response['id']
        else:
            self.customer_id = None
        return response


def get(self, store_id, customer_id, **queryparams):
        """
        Get information about a specific customer.

        :param store_id: The store id.
        :type store_id: :py:class:`str`
        :param customer_id: The id for the customer of a store.
        :type customer_id: :py:class:`str`
        :param queryparams: The query string parameters
        queryparams['fields'] = []
        queryparams['exclude_fields'] = []
        """
        self.store_id = store_id
        self.customer_id = customer_id
        return self._mc_client._get(url=self._build_path(store_id, 'customers', customer_id), **queryparams)

def get ( self , store_id , customer_id , ** queryparams ) : self . store_id = store_id self . customer_id = customer_id return self . _mc_client . _get ( url = self . _build_path ( store_id , 'customers' , customer_id ) , ** queryparams )

Get information about a specific customer .


def create_or_update(self, store_id, customer_id, data):
        """
        Add or update a customer.

        :param store_id: The store id.
        :type store_id: :py:class:`str`
        :param customer_id: The id for the customer of a store.
        :type customer_id: :py:class:`str`
        :param data: The request body parameters
        :type data: :py:class:`dict`
        data = {
            "id": string*,
            "email_address": string*,
            "opt_in_status": boolean
        }
        """
        self.store_id = store_id
        self.customer_id = customer_id
        if 'id' not in data:
            raise KeyError('The store customer must have an id')
        if 'email_address' not in data:
            raise KeyError('Each store customer must have an email_address')
        check_email(data['email_address'])
        if 'opt_in_status' not in data:
            raise KeyError('The store customer must have an opt_in_status')
        if data['opt_in_status'] not in [True, False]:
            raise TypeError('The opt_in_status must be True or False')
        return self._mc_client._put(url=self._build_path(store_id, 'customers', customer_id), data=data)


def create_or_update(self, store_id, product_id, variant_id, data):
        """
        Add or update a product variant.

        :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 variant_id: The id for the product variant.
        :type variant_id: :py:class:`str`
        :param data: The request body parameters
        :type data: :py:class:`dict`
        data = {
            "id": string*,
            "title": string*
        }
        """
        self.store_id = store_id
        self.product_id = product_id
        self.variant_id = variant_id
        if 'id' not in data:
             raise KeyError('The product variant must have an id')
        if 'title' not in data:
            raise KeyError('The product variant must have a title')
        return self._mc_client._put(
            url=self._build_path(store_id, 'products', product_id, 'variants', variant_id),
            data=data
        )

def
create_or_update
(
self
,
store_id
,
product_id
,
variant_id
,
data
)
:
self
.
store_id
=
store_id
self
.
product_id
=
product_id
self
.
variant_id
=
variant_id
if
'id'
not
in
data
:
raise
KeyError
(
'The product variant must have an id'
)
if
'title'
not
in
data
:
raise
KeyError
(
'The product variant must have a title'
)
return
self
.
_mc_client
.
_put
(
url
=
self
.
_build_path
(
store_id
,
'products'
,
product_id
,
'variants'
,
variant_id
)
,
data
=
data
)


def create(self, campaign_id, data, **queryparams):
        """
        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
        if 'message' not in data:
            raise KeyError('The campaign feedback must have a message')
        response = self._mc_client._post(url=self._build_path(campaign_id, 'feedback'), data=data, **queryparams)
        if response is not None:
            self.feedback_id = response['feedback_id']
        else:
            self.feedback_id = None
        return response


def update(self, campaign_id, feedback_id, data):
        """
        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*
        }
        """
        self.campaign_id = campaign_id
        self.feedback_id = feedback_id
        if 'message' not in data:
            raise KeyError('The campaign feedback must have a message')
        return self._mc_client._patch(url=self._build_path(campaign_id, 'feedback', feedback_id), data=data)

Update a specific feedback message for a campaign .


def create(self, list_id, data):
        """
        Add a new merge field for a specific list.

        :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 = {
            "name": string*,
            "type": string*
        }
        """
        self.list_id = list_id
        if 'name' not in data:
            raise KeyError('The list merge field must have a name')
        if 'type' not in data:
            raise KeyError('The list merge field must have a type')
        response = self._mc_client._post(url=self._build_path(list_id, 'merge-fields'), data=data)
        if response is not None:
            self.merge_id = response['merge_id']
        else:
            self.merge_id = None
        return response

def
create
(
self
,
list_id
,
data
)
:
self
.
list_id
=
list_id
if
'name'
not
in
data
:
raise
KeyError
(
'The list merge field must have a name'
)
if
'type'
not
in
data
:
raise
KeyError
(
'The list merge field must have a type'
)
response
=
self
.
_mc_client
.
_post
(
url
=
self
.
_build_path
(
list_id
,
'merge-fields'
)
,
data
=
data
)
if
response
is
not
:
self
.
merge_id
=
response
[
'merge_id'
]
else
:
self
.
merge_id
=
return
response

Add a new merge field for a specific list .


def get(self, list_id, merge_id):
        """
        Get information about a specific merge field in a list.

        :param list_id: The unique id for the list.
        :type list_id: :py:class:`str`
        :param merge_id: The id for the merge field.
        :type merge_id: :py:class:`str`
        """
        self.list_id = list_id
        self.merge_id = merge_id
        return self._mc_client._get(url=self._build_path(list_id, 'merge-fields', merge_id))

def get ( self , list_id , merge_id ) : self . list_id = list_id self . merge_id = merge_id return self . _mc_client . _get ( url = self . _build_path ( list_id , 'merge-fields' , merge_id ) )

Get information about a specific merge field in a list .


def get(self, batch_webhook_id, **queryparams):
        """
        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'] = []
        """
        self.batch_webhook_id = batch_webhook_id
        return self._mc_client._get(url=self._build_path(batch_webhook_id), **queryparams)

def get ( self , batch_webhook_id , ** queryparams ) : self . batch_webhook_id = batch_webhook_id return self . _mc_client . _get ( url = self . _build_path ( batch_webhook_id ) , ** queryparams )

Get information about a specific batch webhook .


def update(self, batch_webhook_id, data):
        """
        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
        if 'url' not in data:
            raise KeyError('The batch webhook must have a valid url')
        return self._mc_client._patch(url=self._build_path(batch_webhook_id), data=data)

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


def delete(self, batch_webhook_id):
        """
        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`
        """
        self.batch_webhook_id = batch_webhook_id
        return self._mc_client._delete(url=self._build_path(batch_webhook_id))

def delete ( self , batch_webhook_id ) : self . batch_webhook_id = batch_webhook_id return self . _mc_client . _delete ( url = self . _build_path ( batch_webhook_id ) )

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


def create(self, data):
        """
        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*
        }
        """
        if 'id' not in data:
            raise KeyError('The store must have an id')
        if 'list_id' not in data:
            raise KeyError('The store must have a list_id')
        if 'name' not in data:
            raise KeyError('The store must have a name')
        if 'currency_code' not in data:
            raise KeyError('The store must have a currency_code')
        if not re.match(r"^[A-Z]{3}$", data['currency_code']):
            raise ValueError('The currency_code must be a valid 3-letter ISO 4217 currency code')
        response = self._mc_client._post(url=self._build_path(), data=data)
        if response is not None:
            self.store_id = response['id']
        else:
            self.store_id = None
        return response

Add a new store to your MailChimp account .


def update(self, store_id, data):
        """
        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
        return self._mc_client._patch(url=self._build_path(store_id), data=data)

def update ( self , store_id , data ) : self . store_id = store_id return self . _mc_client . _patch ( url = self . _build_path ( store_id ) , data = data )


def create(self, store_id, product_id, data):
        """
        Add a new image to the 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`
        data = {
            "id": string*,
            "url": string*
        }
        """
        self.store_id = store_id
        self.product_id = product_id
        if 'id' not in data:
            raise KeyError('The product image must have an id')
        if 'title' not in data:
            raise KeyError('The product image must have a url')
        response = self._mc_client._post(url=self._build_path(store_id, 'products', product_id, 'images'), data=data)
        if response is not None:
            self.image_id = response['id']
        else:
            self.image_id = None
        return response

def
create
(
self
,
store_id
,
product_id
,
data
)
:
self
.
store_id
=
store_id
self
.
product_id
=
product_id
if
'id'
not
in
data
:
raise
KeyError
(
'The product image must have an id'
)
if
'title'
not
in
data
:
raise
KeyError
(
'The product image must have a url'
)
response
=
self
.
_mc_client
.
_post
(
url
=
self
.
_build_path
(
store_id
,
'products'
,
product_id
,
'images'
)
,
data
=
data
)
if
response
is
not
:
self
.
image_id
=
response
[
'id'
]
else
:
self
.
image_id
=
return
response


def get(self, store_id, product_id, image_id, **queryparams):
        """
        Get information about a specific product image.

        :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 image_id: The id for the product image.
        :type image_id: :py:class:`str`
        :param queryparams: The query string parameters
        queryparams['fields'] = []
        queryparams['exclude_fields'] = []
        """
        self.store_id = store_id
        self.product_id = product_id
        self.image_id = image_id
        return self._mc_client._post(
            url=self._build_path(store_id, 'products', product_id, 'images', image_id),
            **queryparams
        )

def get ( self , store_id , product_id , image_id , ** queryparams ) : self . store_id = store_id self . product_id = product_id self . image_id = image_id return self . _mc_client . _post ( url = self . _build_path ( store_id , 'products' , product_id , 'images' , image_id ) , ** queryparams )

Get information about a specific product image .


def create(self, conversation_id, data):
        """
        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*
        }
        """
        self.conversation_id = conversation_id
        if 'from_email' not in data:
            raise KeyError('The conversation message must have a from_email')
        check_email(data['from_email'])
        if 'read' not in data:
            raise KeyError('The conversation message must have a read')
        if data['read'] not in [True, False]:
            raise TypeError('The conversation message read must be True or False')
        response =  self._mc_client._post(url=self._build_path(conversation_id, 'messages'), data=data)
        if response is not None:
            self.message_id = response['id']
        else:
            self.message_id = None
        return response


def create(self, store_id, data):
        """
        Add a new order 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*
            },
            "curency_code": string*,
            "order_total": number*,
            "lines": array*
            [
                {
                    "id": string*,
                    "product_id": string*,
                    "product_variant_id": string*,
                    "quantity": integer*,
                    "price": number*
                }
            ]
        }
        """
        self.store_id = store_id
        if 'id' not in data:
            raise KeyError('The order must have an id')
        if 'customer' not in data:
            raise KeyError('The order must have a customer')
        if 'id' not in data['customer']:
            raise KeyError('The order customer must have an id')
        if 'currency_code' not in data:
            raise KeyError('The order must have a currency_code')
        if not re.match(r"^[A-Z]{3}$", data['currency_code']):
            raise ValueError('The currency_code must be a valid 3-letter ISO 4217 currency code')
        if 'order_total' not in data:
            raise KeyError('The order must have an order_total')
        if 'lines' not in data:
            raise KeyError('The order must have at least one order line')
        for line in data['lines']:
            if 'id' not in line:
                raise KeyError('Each order line must have an id')
            if 'product_id' not in line:
                raise KeyError('Each order line must have a product_id')
            if 'product_variant_id' not in line:
                raise KeyError('Each order line must have a product_variant_id')
            if 'quantity' not in line:
                raise KeyError('Each order line must have a quantity')
            if 'price' not in line:
                raise KeyError('Each order line must have a price')
        response = self._mc_client._post(url=self._build_path(store_id, 'orders'), data=data)
        if response is not None:
            self.order_id = response['id']
        else:
            self.order_id = None
        return response


def create(self, list_id, subscriber_hash, data):
        """
        Add a new note for a specific subscriber.

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

        :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 = {
            "note": string*
        }
        """
        subscriber_hash = check_subscriber_hash(subscriber_hash)
        self.list_id = list_id
        self.subscriber_hash = subscriber_hash
        if 'note' not in data:
            raise KeyError('The list member note must have a note')
        response = self._mc_client._post(url=self._build_path(list_id, 'members', subscriber_hash, 'notes'), data=data)
        if response is not None:
            self.note_id = response['id']
        else:
            self.note_id = None
        return response

def
create
(
self
,
list_id
,
subscriber_hash
,
data
)
:
subscriber_hash
=
check_subscriber_hash
(
subscriber_hash
)
self
.
list_id
=
list_id
self
.
subscriber_hash
=
subscriber_hash
if
'note'
not
in
data
:
raise
KeyError
(
'The list member note must have a note'
)
response
=
self
.
_mc_client
.
_post
(
url
=
self
.
_build_path
(
list_id
,
'members'
,
subscriber_hash
,
'notes'
)
,
data
=
data
)
if
response
is
not
:
self
.
note_id
=
response
[
'id'
]
else
:
self
.
note_id
=
return
response

Add a new note for a specific subscriber .


def update(self, list_id, subscriber_hash, data):
        """
        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*
        }
        """
        subscriber_hash = check_subscriber_hash(subscriber_hash)
        self.list_id = list_id
        self.subscriber_hash = subscriber_hash
        if 'tags' not in data:
            raise KeyError('The list member tags must have a tag')
        response = self._mc_client._post(url=self._build_path(list_id, 'members', subscriber_hash, 'tags'), data=data)
        return response

def
update
(
self
,
list_id
,
subscriber_hash
,
data
)
:
subscriber_hash
=
check_subscriber_hash
(
subscriber_hash
)
self
.
list_id
=
list_id
self
.
subscriber_hash
=
subscriber_hash
if
'tags'
not
in
data
:
raise
KeyError
(
'The list member tags must have a tag'
)
response
=
self
.
_mc_client
.
_post
(
url
=
self
.
_build_path
(
list_id
,
'members'
,
subscriber_hash
,
'tags'
)
,
data
=
data
)
return
response


def update(self, list_id, segment_id, data):
        """
        Update a specific segment in a list.

        :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 = {
            "name": string*
        }
        """
        self.list_id = list_id
        self.segment_id = segment_id
        if 'name' not in data:
            raise KeyError('The list segment must have a name')
        return self._mc_client._patch(url=self._build_path(list_id, 'segments', segment_id), data=data)

def
update
(
self
,
list_id
,
segment_id
,
data
)
:
self
.
list_id
=
list_id
self
.
segment_id
=
segment_id
if
'name'
not
in
data
:
raise
KeyError
(
'The list segment must have a name'
)
return
self
.
_mc_client
.
_patch
(
url
=
self
.
_build_path
(
list_id
,
'segments'
,
segment_id
)
,
data
=
data
)


def update(self, folder_id, data):
        """
        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*
        }
        """
        if 'name' not in data:
            raise KeyError('The template folder must have a name')
        self.folder_id = folder_id
        return self._mc_client._patch(url=self._build_path(folder_id), data=data)

def
update
(
self
,
folder_id
,
data
)
:
if
'name'
not
in
data
:
raise
KeyError
(
'The template folder must have a name'
)
self
.
folder_id
=
folder_id
return
self
.
_mc_client
.
_patch
(
url
=
self
.
_build_path
(
folder_id
)
,
data
=
data
)

Update a specific folder used to organize templates .


def create(self, list_id, data):
        """
        Add a new member to the list.

        :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 = {
            "status": string*, (Must be one of 'subscribed', 'unsubscribed', 'cleaned',
                'pending', or 'transactional')
            "email_address": string*
        }
        """
        self.list_id = list_id
        if 'status' not in data:
            raise KeyError('The list member must have a status')
        if data['status'] not in ['subscribed', 'unsubscribed', 'cleaned', 'pending', 'transactional']:
            raise ValueError('The list member status must be one of "subscribed", "unsubscribed", "cleaned", '
                             '"pending", or "transactional"')
        if 'email_address' not in data:
            raise KeyError('The list member must have an email_address')
        check_email(data['email_address'])
        response = self._mc_client._post(url=self._build_path(list_id, 'members'), data=data)
        if response is not None:
            self.subscriber_hash = response['id']
        else:
            self.subscriber_hash = None
        return response


def update(self, list_id, subscriber_hash, data):
        """
        Update information 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`
        :param data: The request body parameters
        :type data: :py:class:`dict`
        """
        subscriber_hash = check_subscriber_hash(subscriber_hash)
        self.list_id = list_id
        self.subscriber_hash = subscriber_hash
        return self._mc_client._patch(url=self._build_path(list_id, 'members', subscriber_hash), data=data)

def update ( self , list_id , subscriber_hash , data ) : subscriber_hash = check_subscriber_hash ( subscriber_hash ) self . list_id = list_id self . subscriber_hash = subscriber_hash return self . _mc_client . _patch ( url = self . _build_path ( list_id , 'members' , subscriber_hash ) , data = data )

Update information for a specific list member .


def create_or_update(self, list_id, subscriber_hash, data):
        """
        Add or update a 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`
        :param data: The request body parameters
        :type data: :py:class:`dict`
        data = {
            "email_address": string*,
            "status_if_new": string* (Must be one of 'subscribed',
                'unsubscribed', 'cleaned', 'pending', or 'transactional')
        }
        """
        subscriber_hash = check_subscriber_hash(subscriber_hash)
        self.list_id = list_id
        self.subscriber_hash = subscriber_hash
        if 'email_address' not in data:
            raise KeyError('The list member must have an email_address')
        check_email(data['email_address'])
        if 'status_if_new' not in data:
            raise KeyError('The list member must have a status_if_new')
        if data['status_if_new'] not in ['subscribed', 'unsubscribed', 'cleaned', 'pending', 'transactional']:
            raise ValueError('The list member status_if_new must be one of "subscribed", "unsubscribed", "cleaned", '
                             '"pending", or "transactional"')
        return self._mc_client._put(url=self._build_path(list_id, 'members', subscriber_hash), data=data)


def delete(self, list_id, subscriber_hash):
        """
        Delete a member from a list.

        :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`
        """
        subscriber_hash = check_subscriber_hash(subscriber_hash)
        self.list_id = list_id
        self.subscriber_hash = subscriber_hash
        return self._mc_client._delete(url=self._build_path(list_id, 'members', subscriber_hash))

def delete ( self , list_id , subscriber_hash ) : subscriber_hash = check_subscriber_hash ( subscriber_hash ) self . list_id = list_id self . subscriber_hash = subscriber_hash return self . _mc_client . _delete ( url = self . _build_path ( list_id , 'members' , subscriber_hash ) )


def delete_permanent(self, list_id, subscriber_hash):
        """
        Delete permanently a member from a list.

        :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`
        """
        subscriber_hash = check_subscriber_hash(subscriber_hash)
        self.list_id = list_id
        self.subscriber_hash = subscriber_hash
        return self._mc_client._post(url=self._build_path(list_id, 'members', subscriber_hash, 'actions', 'delete-permanent'))

def delete_permanent ( self , list_id , subscriber_hash ) : subscriber_hash = check_subscriber_hash ( subscriber_hash ) self . list_id = list_id self . subscriber_hash = subscriber_hash return self . _mc_client . _post ( url = self . _build_path ( list_id , 'members' , subscriber_hash , 'actions' , 'delete-permanent' ) )

Delete permanently a member from a list .


def pause(self, workflow_id, email_id):
        """
        Pause an automated 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`
        """
        self.workflow_id = workflow_id
        self.email_id = email_id
        return self._mc_client._post(url=self._build_path(workflow_id, 'emails', email_id, 'actions/pause'))

def pause ( self , workflow_id , email_id ) : self . workflow_id = workflow_id self . email_id = email_id return self . _mc_client . _post ( url = self . _build_path ( workflow_id , 'emails' , email_id , 'actions/pause' ) )


def start(self, workflow_id, email_id):
        """
        Start an automated 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`
        """
        self.workflow_id = workflow_id
        self.email_id = email_id
        return self._mc_client._post(url=self._build_path(workflow_id, 'emails', email_id, 'actions/start'))

def start ( self , workflow_id , email_id ) : self . workflow_id = workflow_id self . email_id = email_id return self . _mc_client . _post ( url = self . _build_path ( workflow_id , 'emails' , email_id , 'actions/start' ) )


def delete(self, workflow_id, email_id):
        """
        Removes 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`
        """

        self.workflow_id = workflow_id
        self.email_id = email_id
        return self._mc_client._delete(url=self._build_path(workflow_id, 'emails', email_id))

def delete ( self , workflow_id , email_id ) : self . workflow_id = workflow_id self . email_id = email_id return self . _mc_client . _delete ( url = self . _build_path ( workflow_id , 'emails' , email_id ) )

Removes an individual Automation workflow email .


def create(self, data):
        """
        Create a new MailChimp campaign.

        The ValueError raised by an invalid type in data does not mention
        'absplit' as a potential value because the documentation indicates
        that the absplit type has been deprecated.

        :param data: The request body parameters
        :type data: :py:class:`dict`
        data = {
            "recipients": object*
            {
                "list_id": string*
            },
            "settings": object*
            {
                "subject_line": string*,
                "from_name": string*,
                "reply_to": string*
            },
            "variate_settings": object* (Required if type is "variate")
            {
                "winner_criteria": string* (Must be one of "opens", "clicks", "total_revenue", or "manual")
            },
            "rss_opts": object* (Required if type is "rss")
            {
                "feed_url": string*,
                "frequency": string* (Must be one of "daily", "weekly", or "monthly")
            },
            "type": string* (Must be one of "regular", "plaintext", "rss", "variate", or "absplit")
        }
        """
        if 'recipients' not in data:
            raise KeyError('The campaign must have recipients')
        if 'list_id' not in data['recipients']:
            raise KeyError('The campaign recipients must have a list_id')
        if 'settings' not in data:
            raise KeyError('The campaign must have settings')
        if 'subject_line' not in data['settings']:
            raise KeyError('The campaign settings must have a subject_line')
        if 'from_name' not in data['settings']:
            raise KeyError('The campaign settings must have a from_name')
        if 'reply_to' not in data['settings']:
            raise KeyError('The campaign settings must have a reply_to')
        check_email(data['settings']['reply_to'])
        if 'type' not in data:
            raise KeyError('The campaign must have a type')
        if not data['type'] in ['regular', 'plaintext', 'rss', 'variate', 'abspilt']:
            raise ValueError('The campaign type must be one of "regular", "plaintext", "rss", or "variate"')
        if data['type'] == 'variate':
            if 'variate_settings' not in data:
                raise KeyError('The variate campaign must have variate_settings')
            if 'winner_criteria' not in data['variate_settings']:
                raise KeyError('The campaign variate_settings must have a winner_criteria')
            if data['variate_settings']['winner_criteria'] not in ['opens', 'clicks', 'total_revenue', 'manual']:
                raise ValueError('The campaign variate_settings '
                                 'winner_criteria must be one of "opens", "clicks", "total_revenue", or "manual"')
        if data['type'] == 'rss':
            if 'rss_opts' not in data:
                raise KeyError('The rss campaign must have rss_opts')
            if 'feed_url' not in data['rss_opts']:
                raise KeyError('The campaign rss_opts must have a feed_url')
            if not data['rss_opts']['frequency'] in ['daily', 'weekly', 'monthly']:
                raise ValueError('The rss_opts frequency must be one of "daily", "weekly", or "monthly"')
        response = self._mc_client._post(url=self._build_path(), data=data)
        if response is not None:
            self.campaign_id = response['id']
        else:
            self.campaign_id = None
        return response


def update(self, campaign_id, data):
        """
        Update some or all of the settings for 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 = {
            "settings": object*
            {
                "subject_line": string*,
                "from_name": string*,
                "reply_to": string*
            },
        }
        """
        self.campaign_id = campaign_id
        if 'settings' not in data:
            raise KeyError('The campaign must have settings')
        if 'subject_line' not in data['settings']:
            raise KeyError('The campaign settings must have a subject_line')
        if 'from_name' not in data['settings']:
            raise KeyError('The campaign settings must have a from_name')
        if 'reply_to' not in data['settings']:
            raise KeyError('The campaign settings must have a reply_to')
        check_email(data['settings']['reply_to'])
        return self._mc_client._patch(url=self._build_path(campaign_id), data=data)

Update some or all of the settings for a specific campaign .


def delete(self, campaign_id):
        """
        Remove a campaign from your MailChimp account.

        :param campaign_id: The unique id for the campaign.
        :type campaign_id: :py:class:`str`
        """
        self.campaign_id = campaign_id
        return self._mc_client._delete(url=self._build_path(campaign_id))

def delete ( self , campaign_id ) : self . campaign_id = campaign_id return self . _mc_client . _delete ( url = self . _build_path ( campaign_id ) )

Remove a campaign from your MailChimp account .


def delete(self, store_id, cart_id, line_id):
        """
        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`
        :param line_id: The id for the line item of a cart.
        :type line_id: :py:class:`str`
        """
        self.store_id = store_id
        self.cart_id = cart_id
        self.line_id = line_id
        return self._mc_client._delete(url=self._build_path(store_id, 'carts', cart_id, 'lines', line_id))

def delete ( self , store_id , cart_id , line_id ) : self . store_id = store_id self . cart_id = cart_id self . line_id = line_id return self . _mc_client . _delete ( url = self . _build_path ( store_id , 'carts' , cart_id , 'lines' , line_id ) )


def create(self, data):
        """
        Begin processing a batch operations request.

        :param data: The request body parameters
        :type data: :py:class:`dict`
        data = {
            "operations": array*
            [
                {
                    "method": string* (Must be one of "GET", "POST", "PUT", "PATCH", or "DELETE")
                    "path": string*,
                }
            ]
        }
        """
        if 'operations' not in data:
            raise KeyError('The batch must have operations')
        for op in data['operations']:
            if 'method' not in op:
                raise KeyError('The batch operation must have a method')
            if op['method'] not in ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']:
                raise ValueError('The batch operation method must be one of "GET", "POST", "PUT", "PATCH", '
                                 'or "DELETE", not {0}'.format(op['method']))
            if 'path' not in op:
                raise KeyError('The batch operation must have a path')
        return self._mc_client._post(url=self._build_path(), data=data)

Begin processing a batch operations request .


def all(self, get_all=False, **queryparams):
        """
        Get a summary of batch requests that have been made.

        :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.batch_id = None
        self.operation_status = None
        if get_all:
            return self._iterate(url=self._build_path(), **queryparams)
        else:
            return self._mc_client._get(url=self._build_path(), **queryparams)

def all ( self , get_all = False , ** queryparams ) : self . batch_id = None self . operation_status = None if get_all : return self . _iterate ( url = self . _build_path ( ) , ** queryparams ) else : return self . _mc_client . _get ( url = self . _build_path ( ) , ** queryparams )

Get a summary of batch requests that have been made .


def get(self, batch_id, **queryparams):
        """
        Get the status of a batch request.

        :param batch_id: The unique id for the batch operation.
        :type batch_id: :py:class:`str`
        :param queryparams: The query string parameters
        queryparams['fields'] = []
        queryparams['exclude_fields'] = []
        """
        self.batch_id = batch_id
        self.operation_status = None
        return self._mc_client._get(url=self._build_path(batch_id), **queryparams)

def get ( self , batch_id , ** queryparams ) : self . batch_id = batch_id self . operation_status = None return self . _mc_client . _get ( url = self . _build_path ( batch_id ) , ** queryparams )


def delete(self, batch_id):
        """
        Stops a batch request from running. Since only one batch request is
        run at a time, this can be used to cancel a long running request. The
        results of any completed operations will not be available after this
        call.

        :param batch_id: The unique id for the batch operation.
        :type batch_id: :py:class:`str`
        """
        self.batch_id = batch_id
        self.operation_status = None
        return self._mc_client._delete(url=self._build_path(batch_id))

def delete ( self , batch_id ) : self . batch_id = batch_id self . operation_status = None return self . _mc_client . _delete ( url = self . _build_path ( batch_id ) )

Stops a batch request from running . Since only one batch request is run at a time this can be used to cancel a long running request . The results of any completed operations will not be available after this call .


def _reformat_policy(policy):
    """
    Policies returned from boto3 are massive, ugly, and difficult to read.
    This method flattens and reformats the policy.

    :param policy: Result from invoking describe_load_balancer_policies(...)
    :return: Returns a tuple containing policy_name and the reformatted policy dict.
    """
    policy_name = policy['PolicyName']
    ret = {}
    ret['type'] = policy['PolicyTypeName']
    attrs = policy['PolicyAttributeDescriptions']

    if ret['type'] != 'SSLNegotiationPolicyType':
        return policy_name, ret

    attributes = dict()
    for attr in attrs:
        attributes[attr['AttributeName']] = attr['AttributeValue']

    ret['protocols'] = dict()
    ret['protocols']['sslv2'] = bool(attributes.get('Protocol-SSLv2'))
    ret['protocols']['sslv3'] = bool(attributes.get('Protocol-SSLv3'))
    ret['protocols']['tlsv1'] = bool(attributes.get('Protocol-TLSv1'))
    ret['protocols']['tlsv1_1'] = bool(attributes.get('Protocol-TLSv1.1'))
    ret['protocols']['tlsv1_2'] = bool(attributes.get('Protocol-TLSv1.2'))
    ret['server_defined_cipher_order'] = bool(attributes.get('Server-Defined-Cipher-Order'))
    ret['reference_security_policy'] = attributes.get('Reference-Security-Policy', None)

    non_ciphers = [
        'Server-Defined-Cipher-Order',
        'Protocol-SSLv2',
        'Protocol-SSLv3',
        'Protocol-TLSv1',
        'Protocol-TLSv1.1',
        'Protocol-TLSv1.2',
        'Reference-Security-Policy'
    ]

    ciphers = []
    for cipher in attributes:
        if attributes[cipher] == 'true' and cipher not in non_ciphers:
            ciphers.append(cipher)

    ciphers.sort()
    ret['supported_ciphers'] = ciphers

    return policy_name, ret

def _reformat_policy ( policy ) : policy_name = policy [ 'PolicyName' ] ret = { } ret [ 'type' ] = policy [ 'PolicyTypeName' ] attrs = policy [ 'PolicyAttributeDescriptions' ] if ret [ 'type' ] != 'SSLNegotiationPolicyType' : return policy_name , ret attributes = dict ( ) for attr in attrs : attributes [ attr [ 'AttributeName' ] ] = attr [ 'AttributeValue' ] ret [ 'protocols' ] = dict ( ) ret [ 'protocols' ] [ 'sslv2' ] = bool ( attributes . get ( 'Protocol-SSLv2' ) ) ret [ 'protocols' ] [ 'sslv3' ] = bool ( attributes . get ( 'Protocol-SSLv3' ) ) ret [ 'protocols' ] [ 'tlsv1' ] = bool ( attributes . get ( 'Protocol-TLSv1' ) ) ret [ 'protocols' ] [ 'tlsv1_1' ] = bool ( attributes . get ( 'Protocol-TLSv1.1' ) ) ret [ 'protocols' ] [ 'tlsv1_2' ] = bool ( attributes . get ( 'Protocol-TLSv1.2' ) ) ret [ 'server_defined_cipher_order' ] = bool ( attributes . get ( 'Server-Defined-Cipher-Order' ) ) ret [ 'reference_security_policy' ] = attributes . get ( 'Reference-Security-Policy' , None ) non_ciphers = [ 'Server-Defined-Cipher-Order' , 'Protocol-SSLv2' , 'Protocol-SSLv3' , 'Protocol-TLSv1' , 'Protocol-TLSv1.1' , 'Protocol-TLSv1.2' , 'Reference-Security-Policy' ] ciphers = [ ] for cipher in attributes : if attributes [ cipher ] == 'true' and cipher not in non_ciphers : ciphers . append ( cipher ) ciphers . sort ( ) ret [ 'supported_ciphers' ] = ciphers return policy_name , ret

Policies returned from boto3 are massive ugly and difficult to read . This method flattens and reformats the policy .


def get_load_balancer(load_balancer, flags=FLAGS.ALL ^ FLAGS.POLICY_TYPES, **conn):
    """
    Fully describes an ELB.

    :param loadbalancer: Could be an ELB Name or a dictionary. Likely the return value from a previous call to describe_load_balancers. At a minimum, must contain a key titled 'LoadBalancerName'.
    :param flags: Flags describing which sections should be included in the return value. Default is FLAGS.ALL minus FLAGS.POLICY_TYPES.
    :return: Returns a dictionary describing the ELB with the fields described in the flags parameter.
    """
    # Python 2 and 3 support:
    try:
        basestring
    except NameError as _:
        basestring = str

    if isinstance(load_balancer, basestring):
        load_balancer = dict(LoadBalancerName=load_balancer)

    return registry.build_out(flags, start_with=load_balancer, pass_datastructure=True, **conn)

def get_load_balancer ( load_balancer , flags = FLAGS . ALL ^ FLAGS . POLICY_TYPES , ** conn ) : try : basestring except NameError as _ : basestring = str if isinstance ( load_balancer , basestring ) : load_balancer = dict ( LoadBalancerName = load_balancer ) return registry . build_out ( flags , start_with = load_balancer , pass_datastructure = True , ** conn )


def get(self, key, delete_if_expired=True):
        """
        Retrieve key from Cache.

        :param key: key to look up in cache.
        :type key: ``object``

        :param delete_if_expired: remove value from cache if it is expired.
                                  Default is True.
        :type delete_if_expired: ``bool``

        :returns: value from cache or None
        :rtype: varies or None
        """
        self._update_cache_stats(key, None)

        if key in self._CACHE:
            (expiration, obj) = self._CACHE[key]
            if expiration > self._now():
                self._update_cache_stats(key, 'hit')
                return obj
            else:
                if delete_if_expired:
                    self.delete(key)
                    self._update_cache_stats(key, 'expired')
                    return None

        self._update_cache_stats(key, 'miss')
        return None

def get ( self , key , delete_if_expired = True ) : self . _update_cache_stats ( key , None ) if key in self . _CACHE : ( expiration , obj ) = self . _CACHE [ key ] if expiration > self . _now ( ) : self . _update_cache_stats ( key , 'hit' ) return obj else : if delete_if_expired : self . delete ( key ) self . _update_cache_stats ( key , 'expired' ) return None self . _update_cache_stats ( key , 'miss' ) return None


def insert(self, key, obj, future_expiration_minutes=15):
        """
        Insert item into cache.

        :param key: key to look up in cache.
        :type key: ``object``

        :param obj: item to store in cache.
        :type obj: varies

        :param future_expiration_minutes: number of minutes item is valid
        :type param: ``int``

        :returns: True
        :rtype: ``bool``
        """
        expiration_time = self._calculate_expiration(future_expiration_minutes)
        self._CACHE[key] = (expiration_time, obj)
        return True

def insert ( self , key , obj , future_expiration_minutes = 15 ) : expiration_time = self . _calculate_expiration ( future_expiration_minutes ) self . _CACHE [ key ] = ( expiration_time , obj ) return True


def _update_cache_stats(self, key, result):
        """
        Update the cache stats.

        If no cache-result is specified, we iniitialize the key.
        Otherwise, we increment the correct cache-result.

        Note the behavior for expired.  A client can be expired and the key
        still exists.
        """
        if result is None:
            self._CACHE_STATS['access_stats'].setdefault(key,
                                         {'hit': 0, 'miss': 0, 'expired': 0})
        else:
            self._CACHE_STATS['access_stats'][key][result] +=1

def _update_cache_stats ( self , key , result ) : if result is None : self . _CACHE_STATS [ 'access_stats' ] . setdefault ( key , { 'hit' : 0 , 'miss' : 0 , 'expired' : 0 } ) else : self . _CACHE_STATS [ 'access_stats' ] [ key ] [ result ] += 1

Update the cache stats . If no cache - result is specified we iniitialize the key . Otherwise we increment the correct cache - result .


def get_access_details(self, key=None):
        """Get access details in cache."""
        if key in self._CACHE_STATS:
            return self._CACHE_STATS['access_stats'][key]
        else:
            return self._CACHE_STATS['access_stats']

def get_access_details ( self , key = None ) : if key in self . _CACHE_STATS : return self . _CACHE_STATS [ 'access_stats' ] [ key ] else : return self . _CACHE_STATS [ 'access_stats' ]


def get_stats(self):
        """Get general stats for the cache."""
        expired = sum([x['expired'] for _, x in
                       self._CACHE_STATS['access_stats'].items()])
        miss = sum([x['miss'] for _, x in
                    self._CACHE_STATS['access_stats'].items()])

        hit = sum([x['hit'] for _, x in
                       self._CACHE_STATS['access_stats'].items()])
        return {
            'totals': {
                'keys': len(self._CACHE_STATS['access_stats']),
                'expired': expired,
                'miss': miss,
                'hit': hit,
                }
        }

def get_stats ( self ) : expired = sum ( [ x [ 'expired' ] for _ , x in self . _CACHE_STATS [ 'access_stats' ] . items ( ) ] ) miss = sum ( [ x [ 'miss' ] for _ , x in self . _CACHE_STATS [ 'access_stats' ] . items ( ) ] ) hit = sum ( [ x [ 'hit' ] for _ , x in self . _CACHE_STATS [ 'access_stats' ] . items ( ) ] ) return { 'totals' : { 'keys' : len ( self . _CACHE_STATS [ 'access_stats' ] ) , 'expired' : expired , 'miss' : miss , 'hit' : hit , } }


def get_vpc_flow_logs(vpc, **conn):
    """Gets the VPC Flow Logs for a VPC"""
    fl_result = describe_flow_logs(Filters=[{"Name": "resource-id", "Values": [vpc["id"]]}], **conn)

    fl_ids = []
    for fl in fl_result:
        fl_ids.append(fl["FlowLogId"])

    return fl_ids

def get_vpc_flow_logs ( vpc , ** conn ) : fl_result = describe_flow_logs ( Filters = [ { "Name" : "resource-id" , "Values" : [ vpc [ "id" ] ] } ] , ** conn ) fl_ids = [ ] for fl in fl_result : fl_ids . append ( fl [ "FlowLogId" ] ) return fl_ids