Exemple #1
0
def test_build_url():
    res = client.build_url('test', 125)
    assert res == 'test/125'

    res = client.build_url('test', 125, id='my_id')
    assert res == 'test/125?id=my_id'

    res = client.build_url('test', 125, id='my_id', value=123)
    assert res == 'test/125?id=my_id&value=123'
    def create(self, name, as_json=False):
        """Create new group.

        https://developers.mailerlite.com/v2/reference#create-group

        Parameters
        ----------
        name : str
            group name
        as_json : bool
            return result as json format

        Returns
        -------
        group: :class:Group
            group object

        """
        url = client.build_url('groups')
        data = {'name': name}
        _, res_json = client.post(url, body=data, headers=self.headers)

        if as_json or not res_json:
            return res_json

        return Group(**res_json)
    def update(self, group_id, name, as_json=False):
        """Update existing group.

        https://developers.mailerlite.com/v2/reference#rename-group

        Parameters
        ----------
        group_id : int
            group that you want to rename
        name : str
            group name
        as_json : bool
            return result as json format

        Returns
        -------
        group: :class:Group
            group object

        """
        url = client.build_url('groups', group_id)
        body = {
            "name": name,
        }
        _, res_json = client.put(url, body=body, headers=self.headers)

        if as_json or not res_json:
            return as_json

        return Group(**res_json)
    def get(self, webhook_id, as_json=False):
        """Get single field by ID from your account.

        https://developers.mailerlite.com/v2/reference#get-single-webhook

        Parameters
        ----------
        webhook_id : int
            ID of a webhook
        as_json : bool
            return result as json format

        Returns
        -------
        webhook: dict
            the desired webhook.

        """
        url = client.build_url('webhooks', webhook_id)
        _, res_json = client.get(url, headers=self.headers)

        if as_json or not res_json:
            return res_json

        webhook = Webhook(**res_json)
        return webhook
    def create(self, title, field_type='TEXT'):
        """Create new custom field in account.

        https://developers.mailerlite.com/v2/reference#create-field

        Parameters
        ----------
        title : str
            Title of field
        field_type: str
            Type of field. Available values: TEXT , NUMBER, DATE
            (default: TEXT)

        Returns
        -------
        field : :class:Field
            field object updated

        """
        if field_type.upper() not in ['TEXT', 'NUMBER', 'DATE']:
            raise ValueError('Incorrect field_type. Available values'
                             ' are: TEXT , NUMBER, DATE')
        url = client.build_url('fields')
        data = {'title': title, 'type': field_type.upper()}
        return client.post(url, body=data, headers=self.headers)
Exemple #6
0
    def update(self, data, as_json=False, **identifier):
        """Update single subscriber.

        https://developers.mailerlite.com/v2/reference#update-subscriber

        Parameters
        ----------
        data : dict
            subscriber object. only the email is required.
            you can use the following example:
            data = {'name'   : 'John',
                    'fields' : {'company': 'MailerLite'}
                    }
        as_json : bool
            return result as json format
        identifier : str
            should be subscriber id or email.
            e.g: id=1343965485 or email='*****@*****.**'

        Returns
        -------
        response : int
            response value
        content : dict
            The JSON output from the API

        Notes
        -----
        The email of a subscriber can not be updated

        """
        path = get_id_or_email_identifier(**identifier)
        if path is None:
            raise IOError('An identifier must be define')

        if 'email' in data.keys():
            raise ValueError("Subscriber email can not be updated. Please, "
                             "remove this field or create a new Subscriber. "
                             "For more informations, look at "
                             "http://help.mailerlite.com/article/show"
                             "/29233-how-to-edit-a-subscribers-data")

        optional_keys = ['name', 'type', 'fields', 'resend_autoresponders']
        unknown_keys = [
            d for d in data.keys() if d not in optional_keys
            if d not in ['groups', 'segments']
        ]
        if unknown_keys:
            raise ValueError(
                "The following keys are unknown: {}".format(unknown_keys))

        url = client.build_url('subscribers', path)
        res_code, res_json = client.put(url, body=data, headers=self.headers)

        if not res_json:
            return False

        res_json['fields'] = [Field(**res) for res in res_json['fields']]

        return Subscriber(**res_json)
Exemple #7
0
    def groups(self, as_json=False, **identifier):
        """Get groups subscriber belongs to.

        More informations:
        https://developers.mailerlite.com/v2/reference#groups-subscriber-belongs-to

        Parameters
        ----------
        identifier : str
            should be subscriber id or email.
            e.g: id=1343965485 or email='*****@*****.**'
        as_json : bool
            return result as json format

        Returns
        -------
        groups: list
            all groups that a subscriber belongs to. More informations :
            https://developers.mailerlite.com/v2/reference#groups
        """
        path = get_id_or_email_identifier(**identifier)
        if path is None:
            raise IOError('An identifier must be define')

        url = client.build_url('subscribers', path, 'groups')

        res_code, res_json = client.get(url, headers=self.headers)

        if as_json or not res_json:
            return res_json

        all_groups = [Group(**res) for res in res_json]
        return all_groups
Exemple #8
0
    def batch(self, batch_requests):
        """Execute a list of command. Dedicated for experts.

        https://developers.mailerlite.com/v2/reference#batch-api-requests

        Parameters
        ----------
        batch_requests : list of dict
            all you command. E.g:
            batch_requests = {"requests": [{"method":"GET",
                                            "path": "/api/v2/groups"
                                            },
                                            {"method":"POST",
                                             "path": "/api/v2/groups",
                                            "body": {"name": "New group"}
                                           }
                                          ]
                               }

        Returns
        -------
        results : list
            list of all desired object

        Notes
        -----
        * There is a limit of maximum 50 requests per single batch.
        * The order of response objects are the same as sent requests.
        * requests parameter should not be empty

        """
        url = client.build_url('batch')
        return client.post(url, body=batch_requests, headers=self.headers)
Exemple #9
0
    def cancel(self, campaign_id, as_json=False):
        """Cancel a campaign which is in outbox.

        https://developers.mailerlite.com/reference#campaign-actions-and-triggers

        Parameters
        ----------
        campaign_id : int
            campaign id
        as_json : bool
            return result as json format

        Returns
        -------
        content : dict
            The JSON output from the API

        """
        # TODO: Check if campaign is in Outbox otherwise raise an issue
        url = client.build_url('campaigns', campaign_id, "actions/cancel")
        code, res_json = client.post(url, headers=self.headers)

        # TODO: Check new attribute to campaign object.
        # if as_json or not res_json or code != 200:
        #     return res_json

        # res_json['opened'] = Stats(**res_json.pop('opened'))
        # res_json['clicked'] = Stats(**res_json.pop('clicked'))

        # return Campaign(**res_json)
        return code, res_json
    def update(self, field_id, title, as_json=False):
        """Update custom field in account.

        https://developers.mailerlite.com/v2/reference#update-field

        Parameters
        ----------
        field_id : int
            field id
        title : str
            Title of field

        Returns
        -------
        field : :class:Field
            field object updated

        """
        url = client.build_url('fields', field_id)
        body = {"title": title}
        res_code, res_json = client.put(url, body=body, headers=self.headers)

        if as_json or not res_json:
            return res_json

        return Field(**res_json)
    def get(self, id, as_json=False):
        """Get single field by ID from your account.

        look at https://developers.mailerlite.com/v2/reference#all-fields

        Parameters
        ----------
        id : int
            should be group id. e.g: id=1343965485
        as_json : bool
            return result as json format

        Returns
        -------
        Field: :class:Field
            a single field

        """
        url = client.build_url('fields', id)
        res_code, res_json = client.get(url, headers=self.headers)

        if as_json or not res_json:
            return res_json

        return Field(**res_json)
Exemple #12
0
    def get(self, as_json=False, **identifier):
        """Get a single subscriber from your account.

        https://developers.mailerlite.com/v2/reference#single-subscriber

        Parameters
        ----------
        identifier : str
            should be subscriber id or email.
            e.g: id=1343965485 or email='*****@*****.**'
        as_json : bool
            return result as json format
        Returns
        -------
        subscriber: :class:Subscriber
            a single subscriber
        """
        path = get_id_or_email_identifier(**identifier)
        if path is None:
            raise IOError('An identifier must be define')

        url = client.build_url('subscribers', path)
        res_code, res_json = client.get(url, headers=self.headers)

        if as_json or not res_json:
            return res_json

        res_json['fields'] = [Field(**res) for res in res_json['fields']]

        return Subscriber(**res_json)
    def subscriber(self, group_id, subscriber_id, as_json=False):
        """Get one subscriber in a specified group.

        https://developers.mailerlite.com/v2/reference#a-subscriber-of-a-group

        Parameters
        ----------
        group_id : int
            group id
        subscriber_id : int
            subscriber id
        as_json : bool
            return result as json format

        Returns
        -------
        subscriber: :class:Subscriber
            a single subscriber
        """
        url = client.build_url('groups', group_id, 'subscribers',
                               subscriber_id)
        _, res_json = client.get(url, headers=self.headers)

        if as_json or not res_json:
            return res_json

        res_json['fields'] = [Field(**res) for res in res_json['fields']]

        return Subscriber(**res_json)
    def all(self, limit=100, offset=0, gfilters='', as_json=False):
        """Get list of groups from your account.

        look at https://developers.mailerlite.com/v2/reference#groups

        Parameters
        ----------
        limit : int
            How many groups you want
        offset : int
            page index
        gfilters : str
            group filters
        as_json : bool
            return result as json format

        Returns
        -------
        groups: list
            all desired Groups. More informations :
            https://developers.mailerlite.com/v2/reference#groups

        """
        params = {'limit': limit, 'offset': offset, 'filters': gfilters}
        url = client.build_url('groups', **params)
        _, res_json = client.get(url, headers=self.headers)

        if as_json or not res_json:
            return res_json

        all_groups = [Group(**res) for res in res_json]
        return all_groups
    def add_subscribers(self,
                        group_id,
                        subscribers_data,
                        resubscribe=False,
                        autoresponders=False,
                        as_json=False):
        """Add one or many new subscribers to specified group at once.

        https://developers.mailerlite.com/v2/reference#add-single-subscriber
        https://developers.mailerlite.com/v2/reference#add-many-subscribers

        Parameters
        ----------
        group_id : int
            group id
        subscribers_data : dict, list of dict
            subscribers element that contains email and name
        resubscribe : bool
            reactivate subscriber if value is true (default False)
        autoresponders : bool
            autoresponders will be sent if value is true (default False)
        as_json : bool
            return result as json format

        Returns
        -------
        group: :class:Group
            group object

        """
        url = client.build_url('groups', group_id, 'subscribers', 'import')

        body = {'resubscribe': resubscribe, 'autoresponders': autoresponders}
        if isinstance(subscribers_data, dict):
            body['subscribers'] = [
                subscribers_data,
            ]
        elif isinstance(subscribers_data, list):
            body['subscribers'] = subscribers_data
        else:
            raise ValueError('subscribers_data should be a dict or a list of'
                             ' dict that contains the following keys: email,'
                             ' name')

        errors = [
            d for d in body['subscribers']
            if not {'email', 'name'}.issubset(d.keys())
        ]
        if errors:
            raise ValueError('All subscribers_data should contain the'
                             ' following keys: email, name')
        _, res_json = client.post(url, body=body, headers=self.headers)

        if as_json or not res_json:
            return res_json

        return [Subscriber(**subs) for subs in res_json['imported']]
Exemple #16
0
    def activity(self, as_json=False, atype=None, **identifier):
        """Get activities (clicks, opens, etc) of selected subscriber.

        More informations:
        https://developers.mailerlite.com/v2/reference#activity-of-single-subscriber

        Parameters
        ----------
        identifier : str
            should be subscriber id or email.
            e.g: id=1343965485 or email='*****@*****.**'
        as_json : bool
            return result as json format
        atype : str
            Define activity type: Here are the possible values:
            * None - All activities (default)
            * opens
            * clicks
            * bounces
            * junks
            * unsubscribes
            * forwards
            * sendings

        Returns
        -------
        activities: list
            all subscriber activities. More informations :
            https://developers.mailerlite.com/v2/reference#activity-of-single-subscriber
        """
        path = get_id_or_email_identifier(**identifier)
        if path is None:
            raise IOError('An identifier must be define')

        args = ['subscribers', path, 'activity']
        if atype:
            possible_atype = [
                'opens', 'clicks', 'junks', 'bounces', 'unsubscribes',
                'forwards', 'sendings'
            ]
            if atype not in possible_atype:
                raise ValueError('Incorrect value atype. Activity type should'
                                 ' be {0}'.format(possible_atype))
            args.append(atype)

        url = client.build_url(*args)

        res_code, res_json = client.get(url, headers=self.headers)

        if as_json or not res_json:
            return res_json

        all_activities = [Activity(**res) for res in res_json]
        return all_activities
Exemple #17
0
    def update(self, campaign_id, html, plain, auto_inline=True):
        r"""Upload your HTML template to created campaign.

        https://developers.mailerlite.com/v2/reference#put-custom-content-to-campaign

        Parameters
        ----------
        campaign_id : int
            the campaign id that you want to update
        html : str
            HTML template source
        plain : str
            Plain text of email
        auto_inline : bool, optional
            Defines if it is needed to convert available CSS to inline CSS
            (excluding media queries)

        Returns
        -------
        success : bool

        Examples
        --------
        >>> from mailerlite import MailerLiteApi
        >>> api = MailerLiteApi('my_keys')
        >>> html = '<head></head><body><h1>Title</h1><p>Content</p><p><small>'
        >>> html += '<a href=\"{$unsubscribe}\">Unsubscribe</a></small></p>'
        >>> html += '</body>'
        >>> plain = "Your email client does not support HTML emails. "
        >>> plain += "Open newsletter here: {$url}. If you do not want"
        >>> plain += " to receive emails from us, click here: {$unsubscribe}"
        >>> api.campaigns.update(campaign_id, html=html, plain=plain)
        True

        Notes
        -----
        * HTML template must contain body and head tag.
        * HTML template must contain a link for unsubscribe. It may look like
            this: <a href="{$unsubscribe}">Unsubscribe</a>
        * Some email clients do not support HTML emails so you need to set
            plain text email and it must contain these variables:
            * {$unsubscribe} - unsubscribe link
            * {$url} - URL to your HTML newsletter

        """
        url = client.build_url('campaigns', campaign_id, 'content')
        # Todo, Check html syntax
        body = {"html": html, "plain": plain}
        _, res_json = client.put(url, body=body, headers=self.headers)

        if not res_json:
            return False

        return res_json['success']
    def subscribers(self,
                    group_id,
                    limit=100,
                    offset=0,
                    stype=None,
                    as_json=False):
        """Get all subscribers in a specified group.

        https://developers.mailerlite.com/v2/reference#subscribers-in-a-group

        Parameters
        ----------
        group_id : int
            group id
        limit : int
            How many subscribers you want
        offset : int
            page index
        stype : str
            Define subscriber type: Here are the possible values:
            * None - All subscribers (default)
            * active
            * unsubscribed
            * bounced
            * junk
            * unconfirmed
        as_json : bool
            return result as json format

        Returns
        -------
        subscribers: list
            all desired Subscribers. More informations :
            https://developers.mailerlite.com/v2/reference#subscribers

        """
        params = {'limit': limit, 'offset': offset}
        if stype and stype.lower() in [
                'active', 'unsubscribed', 'bounced', 'junk', 'unconfirmed'
        ]:
            params.update({'type': stype})

        url = client.build_url('groups', group_id, 'subscribers', **params)
        _, res_json = client.get(url, headers=self.headers)

        if as_json or not res_json:
            return res_json

        for res in res_json:
            res['fields'] = [Field(**field) for field in res['fields']]

        all_subscribers = [Subscriber(**res) for res in res_json]
        return all_subscribers
Exemple #19
0
    def create(self, data, as_json=False):
        """Add new single subscriber.

        https://developers.mailerlite.com/v2/reference#create-a-subscriber

        Parameters
        ----------
        data : dict
            subscriber object. only the email is required.
            you can use the following example:
            data = {'name'   : 'John',
                    'email'  : '*****@*****.**',
                    'fields' : {'company': 'MailerLite'}
                    }
        as_json : bool
            return result as json format
        Returns
        -------
        subscriber: :class:Subscriber
            a single subscriber
        """
        if not isinstance(data, dict):
            raise ValueError('In data should be a dictionary.')
        required_keys = [
            'email',
        ]
        optional_keys = [
            'name', 'fields', 'resubscribe', 'type', 'signup_ip',
            'signup_timestamp', 'confirmation_ip', 'confirmation_timestamp'
        ]
        available_keys = required_keys + optional_keys

        errors = [rk for rk in required_keys if rk not in data.keys()]
        if errors:
            raise ValueError("The following keys are missing and they"
                             " are required : {}".format(errors))

        unknown_keys = [
            d for d in data.keys() if d not in available_keys
            if d not in ['groups', 'segments']
        ]
        if unknown_keys:
            raise ValueError(
                "The following keys are unknown: {}".format(unknown_keys))

        url = client.build_url('subscribers')
        res_code, res_json = client.post(url, body=data, headers=self.headers)

        if as_json or not res_json:
            return res_json

        return Subscriber(**res_json)
    def double_optin(self):
        """Retrieve the status double opt-in.

        https://developers.mailerlite.com/v2/reference#get-double-optin-status

        Returns
        -------
        success: bool
            deletion status

        """
        url = client.build_url('settings', 'double_optin')
        _, res_json = client.get(url, headers=self.headers)
        return res_json
Exemple #21
0
    def all(self):
        """Get list of Webhooks.

        https://developers.mailerlite.com/v2/reference#get-webhooks-list

        Returns
        -------
        webhooks: list of dict
            all webhooks.
        """
        url = client.build_url('webhooks')
        _, res_json = client.get(url, headers=self.headers)

        return res_json
Exemple #22
0
    def info(self):
        """Get account info.

        https://developers.mailerlite.com/v2/reference#account

        Returns
        -------
        info: dict
            all account information.

        """
        url = client.build_url('me')
        res_code, res_json = client.get(url, headers=self.headers)

        return res_json
Exemple #23
0
    def count(self):
        """Return the number of segments.

        More informations:
        https://developers.mailerlite.com/reference#section-segments-count

        Returns
        -------
        count: int
            number of segments

        """
        url = client.build_url('segments', 'count')
        _, res_json = client.get(url, headers=self.headers)
        return res_json['count']
Exemple #24
0
    def delete(self, subscriber_id):
        """Remove a subscribers.

        Parameters
        ----------
        subscriber_id : int
            subscribers id

        Returns
        -------
        success: bool
            deletion status
        """
        url = client.build_url('subscribers', subscriber_id)
        return client.delete(url, headers=self.headers)
Exemple #25
0
    def all(self,
            status='sent',
            limit=100,
            offset=0,
            order='asc',
            as_json=False):
        """Get paginated details of all campaigns from your account.

        look at https://developers.mailerlite.com/reference#campaigns-by-type

        Parameters
        ----------
        status : str
            Define campaigns type: Here are the possible values:
            * sent - campaigns which are sent already (default)
            * draft - campaigns which aren't completed or sent to subscribers
            * outbox - campaigns which are being sent right now or scheduled
        limit : int
            How many campaigns you want
        offset : int
            page index
        order : str
            pick the order. Here are the possible values: ASC (default) or DESC
        as_json : bool
            return result as json format

        Returns
        -------
        campaigns: list
            all desired campaign. More informations concerning campaign :
            https://developers.mailerlite.com/reference#section-response-body-parameters
        """
        if order.upper() not in ['ASC', 'DESC']:
            raise IOError("Incorrect order, please choose between ASC or DESC")

        params = {'limit': limit, 'offset': offset, 'order': order}
        url = client.build_url('campaigns', status, **params)
        _, res_json = client.get(url, headers=self.headers)

        if as_json or not res_json:
            return res_json

        for res in res_json:
            res['opened'] = Stats(**res.pop('opened'))
            res['clicked'] = Stats(**res.pop('clicked'))

        all_campaigns = [Campaign(**res) for res in res_json]
        return all_campaigns
Exemple #26
0
    def stats(self):
        """Get basic stats for of account, such as subscribers,
        open/click rates and so on.

        https://developers.mailerlite.com/v2/reference#stats

        Returns
        -------
        stats: dict
            account stats

        """
        url = client.build_url('stats')
        res_code, res_json = client.get(url, headers=self.headers)

        return res_json
    def add_single_subscriber(self,
                              group_id,
                              subscribers_data: dict,
                              resubscribe=False,
                              autoresponders=False,
                              as_json=False):
        """Add single new subscriber to specified group.

        https://developers.mailerlite.com/v2/reference#add-single-subscriber

        Parameters
        ----------
        group_id : int
            group id
        subscribers_data : dict,
            subscribers data
        resubscribe : bool
            reactivate subscriber if value is true (default False)
        autoresponders : bool
            autoresponders will be sent if value is true (default False)
        as_json : bool
            return result as json format

        Returns
        -------
        subscriber: :class:Subscriber
            subscriber object

        """
        url = client.build_url('groups', group_id, 'subscribers')

        body = {
            'resubscribe': resubscribe,
            'autoresponders': autoresponders,
            **subscribers_data
        }

        if not {'email', 'name'}.issubset(subscribers_data.keys()):
            raise ValueError('Subscribers_data should contain the'
                             ' following keys: email, name')

        _, res_json = client.post(url, body=body, headers=self.headers)

        if as_json or not res_json:
            return res_json

        return Subscriber(**res_json)
Exemple #28
0
    def delete(self, webhook_id):
        """Remove a webhook.

        https://developers.mailerlite.com/v2/reference#delete-a-webhook

        Parameters
        ----------
        webhook_id : int
            ID of a webhook

        Returns
        -------
        success: bool
            deletion status
        """
        url = client.build_url('webhooks', webhook_id)
        return client.delete(url, headers=self.headers)
Exemple #29
0
    def delete(self, campaign_id):
        """Remove a campaign.

        look at https://developers.mailerlite.com/reference#delete-campaign

        Parameters
        ----------
        campaign_id : int
            campaign id

        Returns
        -------
        success: bool
            deletion status
        """
        url = client.build_url('campaigns', campaign_id)
        return client.delete(url, headers=self.headers)
Exemple #30
0
    def search(self,
               search=None,
               limit=100,
               offset=0,
               minimized=True,
               as_json=False):
        """Get paginated details of all Subscribers from your account.

        look at https://developers.mailerlite.com/v2/reference#subscribers

        Parameters
        ----------
        search : str
            query parameter to search
        limit : int
            How many subscribers you want
        offset : int
            page index
        minimized : bool
            return minimized response with: id, email, type
            default: True
        as_json : bool
            return result as json format

        Returns
        -------
        subscribers: list
            all desired Subscribers. More informations :
            https://developers.mailerlite.com/v2/reference#subscribers
        """
        params = {'limit': limit, 'offset': offset, 'minimized': minimized}
        if search is not None:
            params.update({'query': search})
        url = client.build_url('subscribers', 'search', **params)

        res_code, res_json = client.get(url, headers=self.headers)

        if as_json or not res_json:
            return res_json

        if not minimized:
            for res in res_json:
                res['fields'] = [Field(**field) for field in res['fields']]

        all_subscribers = [Subscriber(**res) for res in res_json]
        return all_subscribers