We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
DNSimple crash with team member that does not have a plan
Here's the error I get (I have redacted my account number, domain and auth token)

```sh
$ lexicon dnsimple --auth-token REDACTED list REDACTED A
Traceback (most recent call last):
  File "/usr/local/bin/lexicon", line 11, in <module>
    sys.exit(main())
  File "/usr/local/lib/python2.7/dist-packages/lexicon/cli.py", line 117, in main
    results = client.execute()
  File "/usr/local/lib/python2.7/dist-packages/lexicon/client.py", line 64, in execute
    self.provider.authenticate()
  File "/usr/local/lib/python2.7/dist-packages/lexicon/providers/dnsimple.py", line 43, in authenticate
    '/{0}/domains'.format(account['id']), query_params={'name_like': self.domain})
  File "/usr/local/lib/python2.7/dist-packages/lexicon/providers/base.py", line 87, in _get
    return self._request('GET', url, query_params=query_params)
  File "/usr/local/lib/python2.7/dist-packages/lexicon/providers/dnsimple.py", line 189, in _request
    r.raise_for_status()
  File "/usr/lib/python2.7/dist-packages/requests/models.py", line 935, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 402 Client Error: Payment Required for url: https://api.dnsimple.com/v2/REDACTED/domains?name_like=REDACTED
```

I believe that this happens because of the way the domain I have is configured. We have a domain configured with a team. There is one account that has a professional plan (with our domain) and we have other users as team members of that account. The only account that has a plan is the one mentioned. Other users have personal accounts by default but they don't have a plan configured at all.

I believe that the code responsible is this: https://github.com/AnalogJ/lexicon/blob/master/lexicon/providers/dnsimple.py#L37-L52

The dnsimple provider iterates through all accounts that the token has access to and tried to see if they have a domain similar to the one specified. When it tries to do this on an account that is not configured it will crash with the http error `402 Client Error: Payment Required for url: ...`.

This is consistent with the documentation from dnsimple: https://developer.dnsimple.com/v2/#response-codes

> `402 Payment Required` - Your account is not subscribed or not in good standing.

I think that it's possible to figure out if an account is not configured by using the `GET /accounts` endpoint. Accounts that are not configured have their `plan_identifier` set to `null`. This does not seem to be documented in the API references tho.

When I do this request I get the following json as output

```json
{
    "data": [
        {
            "created_at": "2018-06-05T19:23:59Z",
            "email": "REDACTED",
            "id": "REDACTED",
            "plan_identifier": "dnsimple-professional",
            "updated_at": "2019-01-06T21:16:40Z"
        },
        {
            "created_at": "2018-06-08T19:48:59Z",
            "email": "REDACTED",
            "id": "REDACTED",
            "plan_identifier": null,
            "updated_at": "2018-06-08T19:48:59Z"
        }
    ]
}
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `lexicon/providers/dnsimple.py`
Content:
```
1 """Module provider for DNS Simple"""
2 from __future__ import absolute_import
3 import json
4 import logging
5 
6 import requests
7 from lexicon.providers.base import Provider as BaseProvider
8 
9 
10 LOGGER = logging.getLogger(__name__)
11 
12 NAMESERVER_DOMAINS = ['dnsimple.com']
13 
14 
15 def provider_parser(subparser):
16     """Configure provider parser for DNS Simple"""
17     subparser.add_argument(
18         "--auth-token", help="specify api token for authentication")
19     subparser.add_argument(
20         "--auth-username", help="specify email address for authentication")
21     subparser.add_argument(
22         "--auth-password", help="specify password for authentication")
23     subparser.add_argument(
24         "--auth-2fa",
25         help="specify two-factor auth token (OTP) to use with email/password authentication")
26 
27 
28 class Provider(BaseProvider):
29     """Provider class for DNS Simple"""
30     def __init__(self, config):
31         super(Provider, self).__init__(config)
32         self.domain_id = None
33         self.account_id = None
34         self.api_endpoint = self._get_provider_option(
35             'api_endpoint') or 'https://api.dnsimple.com/v2'
36 
37     def _authenticate(self):
38 
39         payload = self._get('/accounts')
40 
41         if not payload[0]['id']:
42             raise Exception('No account id found')
43 
44         for account in payload:
45             dompayload = self._get(
46                 '/{0}/domains'.format(account['id']), query_params={'name_like': self.domain})
47             if dompayload and dompayload[0]['id']:
48                 self.account_id = account['id']
49                 self.domain_id = dompayload[0]['id']
50 
51         if not self.account_id:
52             raise Exception('No domain found like {}'.format(self.domain))
53 
54     # Create record. If record already exists with the same content, do nothing
55 
56     def _create_record(self, rtype, name, content):
57         # check if record already exists
58         existing_records = self._list_records(rtype, name, content)
59         if len(existing_records) == 1:
60             return True
61 
62         record = {
63             'type': rtype,
64             'name': self._relative_name(name),
65             'content': content
66         }
67         if self._get_lexicon_option('ttl'):
68             record['ttl'] = self._get_lexicon_option('ttl')
69         if self._get_lexicon_option('priority'):
70             record['priority'] = self._get_lexicon_option('priority')
71         if self._get_provider_option('regions'):
72             record['regions'] = self._get_provider_option('regions')
73 
74         payload = self._post(
75             '/{0}/zones/{1}/records'.format(self.account_id, self.domain), record)
76 
77         LOGGER.debug('create_record: %s', 'id' in payload)
78         return 'id' in payload
79 
80     # List all records. Return an empty list if no records found
81     # type, name and content are used to filter records.
82     # If possible filter during the query, otherwise filter after response is received.
83     def _list_records(self, rtype=None, name=None, content=None):
84         filter_query = {}
85         if rtype:
86             filter_query['type'] = rtype
87         if name:
88             filter_query['name'] = self._relative_name(name)
89         payload = self._get(
90             '/{0}/zones/{1}/records'.format(self.account_id, self.domain),
91             query_params=filter_query)
92 
93         records = []
94         for record in payload:
95             processed_record = {
96                 'type': record['type'],
97                 'name': '{}'.format(
98                     self.domain) if record['name'] == "" else '{0}.{1}'.format(
99                         record['name'],
100                         self.domain),
101                 'ttl': record['ttl'],
102                 'content': record['content'],
103                 'id': record['id']}
104             if record['priority']:
105                 processed_record['priority'] = record['priority']
106             records.append(processed_record)
107 
108         if content:
109             records = [
110                 record for record in records if record['content'] == content]
111 
112         LOGGER.debug('list_records: %s', records)
113         return records
114 
115     # Create or update a record.
116     def _update_record(self, identifier, rtype=None, name=None, content=None):
117 
118         data = {}
119 
120         if identifier is None:
121             records = self._list_records(rtype, name, content)
122             identifiers = [record["id"] for record in records]
123         else:
124             identifiers = [identifier]
125 
126         if name:
127             data['name'] = self._relative_name(name)
128         if content:
129             data['content'] = content
130         if self._get_lexicon_option('ttl'):
131             data['ttl'] = self._get_lexicon_option('ttl')
132         if self._get_lexicon_option('priority'):
133             data['priority'] = self._get_lexicon_option('priority')
134         if self._get_provider_option('regions'):
135             data['regions'] = self._get_provider_option('regions')
136 
137         for one_identifier in identifiers:
138             self._patch('/{0}/zones/{1}/records/{2}'
139                         .format(self.account_id, self.domain, one_identifier), data)
140             LOGGER.debug('update_record: %s', one_identifier)
141 
142         LOGGER.debug('update_record: %s', True)
143         return True
144 
145     # Delete an existing record.
146     # If record does not exist, do nothing.
147     def _delete_record(self, identifier=None, rtype=None, name=None, content=None):
148         delete_record_id = []
149         if not identifier:
150             records = self._list_records(rtype, name, content)
151             delete_record_id = [record['id'] for record in records]
152         else:
153             delete_record_id.append(identifier)
154 
155         LOGGER.debug('delete_records: %s', delete_record_id)
156 
157         for record_id in delete_record_id:
158             self._delete(
159                 '/{0}/zones/{1}/records/{2}'.format(self.account_id, self.domain, record_id))
160 
161         # is always True at this point; if a non 2xx response is returned, an error is raised.
162         LOGGER.debug('delete_record: True')
163         return True
164 
165     # Helpers
166 
167     def _request(self, action='GET', url='/', data=None, query_params=None):
168         if data is None:
169             data = {}
170         if query_params is None:
171             query_params = {}
172         default_headers = {
173             'Accept': 'application/json',
174             'Content-Type': 'application/json'
175         }
176         default_auth = None
177 
178         if self._get_provider_option('auth_token'):
179             default_headers['Authorization'] = "Bearer {0}".format(
180                 self._get_provider_option('auth_token'))
181         elif (self._get_provider_option('auth_username')
182               and self._get_provider_option('auth_password')):
183             default_auth = (self._get_provider_option(
184                 'auth_username'), self._get_provider_option('auth_password'))
185             if self._get_provider_option('auth_2fa'):
186                 default_headers['X-Dnsimple-OTP'] = self._get_provider_option(
187                     'auth_2fa')
188         else:
189             raise Exception('No valid authentication mechanism found')
190 
191         response = requests.request(action, self.api_endpoint + url, params=query_params,
192                                     data=json.dumps(data),
193                                     headers=default_headers,
194                                     auth=default_auth)
195         # if the request fails for any reason, throw an error.
196         response.raise_for_status()
197         if response.text and response.json()['data'] is None:
198             raise Exception('No data returned')
199 
200         return response.json()['data'] if response.text else None
201 
202     def _patch(self, url='/', data=None, query_params=None):
203         return self._request('PATCH', url, data=data, query_params=query_params)
204
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/lexicon/providers/dnsimple.py b/lexicon/providers/dnsimple.py
--- a/lexicon/providers/dnsimple.py
+++ b/lexicon/providers/dnsimple.py
@@ -42,6 +42,13 @@
             raise Exception('No account id found')
 
         for account in payload:
+            if account['plan_identifier'] is None:
+                logging.warning(
+                    'Skipping unconfigured account %s (%d). ' \
+                    'To use this account, you must select a plan.',
+                    account['email'], account['id'])
+                continue
+
             dompayload = self._get(
                 '/{0}/domains'.format(account['id']), query_params={'name_like': self.domain})
             if dompayload and dompayload[0]['id']:

{"golden_diff": "diff --git a/lexicon/providers/dnsimple.py b/lexicon/providers/dnsimple.py\n--- a/lexicon/providers/dnsimple.py\n+++ b/lexicon/providers/dnsimple.py\n@@ -42,6 +42,13 @@\n             raise Exception('No account id found')\n \n         for account in payload:\n+            if account['plan_identifier'] is None:\n+                logging.warning(\n+                    'Skipping unconfigured account %s (%d). ' \\\n+                    'To use this account, you must select a plan.',\n+                    account['email'], account['id'])\n+                continue\n+\n             dompayload = self._get(\n                 '/{0}/domains'.format(account['id']), query_params={'name_like': self.domain})\n             if dompayload and dompayload[0]['id']:\n", "issue": "DNSimple crash with team member that does not have a plan\nHere's the error I get (I have redacted my account number, domain and auth token)\r\n\r\n```sh\r\n$ lexicon dnsimple --auth-token REDACTED list REDACTED A\r\nTraceback (most recent call last):\r\n  File \"/usr/local/bin/lexicon\", line 11, in <module>\r\n    sys.exit(main())\r\n  File \"/usr/local/lib/python2.7/dist-packages/lexicon/cli.py\", line 117, in main\r\n    results = client.execute()\r\n  File \"/usr/local/lib/python2.7/dist-packages/lexicon/client.py\", line 64, in execute\r\n    self.provider.authenticate()\r\n  File \"/usr/local/lib/python2.7/dist-packages/lexicon/providers/dnsimple.py\", line 43, in authenticate\r\n    '/{0}/domains'.format(account['id']), query_params={'name_like': self.domain})\r\n  File \"/usr/local/lib/python2.7/dist-packages/lexicon/providers/base.py\", line 87, in _get\r\n    return self._request('GET', url, query_params=query_params)\r\n  File \"/usr/local/lib/python2.7/dist-packages/lexicon/providers/dnsimple.py\", line 189, in _request\r\n    r.raise_for_status()\r\n  File \"/usr/lib/python2.7/dist-packages/requests/models.py\", line 935, in raise_for_status\r\n    raise HTTPError(http_error_msg, response=self)\r\nrequests.exceptions.HTTPError: 402 Client Error: Payment Required for url: https://api.dnsimple.com/v2/REDACTED/domains?name_like=REDACTED\r\n```\r\n\r\nI believe that this happens because of the way the domain I have is configured. We have a domain configured with a team. There is one account that has a professional plan (with our domain) and we have other users as team members of that account. The only account that has a plan is the one mentioned. Other users have personal accounts by default but they don't have a plan configured at all.\r\n\r\nI believe that the code responsible is this: https://github.com/AnalogJ/lexicon/blob/master/lexicon/providers/dnsimple.py#L37-L52\r\n\r\nThe dnsimple provider iterates through all accounts that the token has access to and tried to see if they have a domain similar to the one specified. When it tries to do this on an account that is not configured it will crash with the http error `402 Client Error: Payment Required for url: ...`.\r\n\r\nThis is consistent with the documentation from dnsimple: https://developer.dnsimple.com/v2/#response-codes\r\n\r\n> `402 Payment Required` - Your account is not subscribed or not in good standing.\r\n\r\nI think that it's possible to figure out if an account is not configured by using the `GET /accounts` endpoint. Accounts that are not configured have their `plan_identifier` set to `null`. This does not seem to be documented in the API references tho.\r\n\r\nWhen I do this request I get the following json as output\r\n\r\n```json\r\n{\r\n    \"data\": [\r\n        {\r\n            \"created_at\": \"2018-06-05T19:23:59Z\",\r\n            \"email\": \"REDACTED\",\r\n            \"id\": \"REDACTED\",\r\n            \"plan_identifier\": \"dnsimple-professional\",\r\n            \"updated_at\": \"2019-01-06T21:16:40Z\"\r\n        },\r\n        {\r\n            \"created_at\": \"2018-06-08T19:48:59Z\",\r\n            \"email\": \"REDACTED\",\r\n            \"id\": \"REDACTED\",\r\n            \"plan_identifier\": null,\r\n            \"updated_at\": \"2018-06-08T19:48:59Z\"\r\n        }\r\n    ]\r\n}\r\n```\n", "before_files": [{"content": "\"\"\"Module provider for DNS Simple\"\"\"\nfrom __future__ import absolute_import\nimport json\nimport logging\n\nimport requests\nfrom lexicon.providers.base import Provider as BaseProvider\n\n\nLOGGER = logging.getLogger(__name__)\n\nNAMESERVER_DOMAINS = ['dnsimple.com']\n\n\ndef provider_parser(subparser):\n    \"\"\"Configure provider parser for DNS Simple\"\"\"\n    subparser.add_argument(\n        \"--auth-token\", help=\"specify api token for authentication\")\n    subparser.add_argument(\n        \"--auth-username\", help=\"specify email address for authentication\")\n    subparser.add_argument(\n        \"--auth-password\", help=\"specify password for authentication\")\n    subparser.add_argument(\n        \"--auth-2fa\",\n        help=\"specify two-factor auth token (OTP) to use with email/password authentication\")\n\n\nclass Provider(BaseProvider):\n    \"\"\"Provider class for DNS Simple\"\"\"\n    def __init__(self, config):\n        super(Provider, self).__init__(config)\n        self.domain_id = None\n        self.account_id = None\n        self.api_endpoint = self._get_provider_option(\n            'api_endpoint') or 'https://api.dnsimple.com/v2'\n\n    def _authenticate(self):\n\n        payload = self._get('/accounts')\n\n        if not payload[0]['id']:\n            raise Exception('No account id found')\n\n        for account in payload:\n            dompayload = self._get(\n                '/{0}/domains'.format(account['id']), query_params={'name_like': self.domain})\n            if dompayload and dompayload[0]['id']:\n                self.account_id = account['id']\n                self.domain_id = dompayload[0]['id']\n\n        if not self.account_id:\n            raise Exception('No domain found like {}'.format(self.domain))\n\n    # Create record. If record already exists with the same content, do nothing\n\n    def _create_record(self, rtype, name, content):\n        # check if record already exists\n        existing_records = self._list_records(rtype, name, content)\n        if len(existing_records) == 1:\n            return True\n\n        record = {\n            'type': rtype,\n            'name': self._relative_name(name),\n            'content': content\n        }\n        if self._get_lexicon_option('ttl'):\n            record['ttl'] = self._get_lexicon_option('ttl')\n        if self._get_lexicon_option('priority'):\n            record['priority'] = self._get_lexicon_option('priority')\n        if self._get_provider_option('regions'):\n            record['regions'] = self._get_provider_option('regions')\n\n        payload = self._post(\n            '/{0}/zones/{1}/records'.format(self.account_id, self.domain), record)\n\n        LOGGER.debug('create_record: %s', 'id' in payload)\n        return 'id' in payload\n\n    # List all records. Return an empty list if no records found\n    # type, name and content are used to filter records.\n    # If possible filter during the query, otherwise filter after response is received.\n    def _list_records(self, rtype=None, name=None, content=None):\n        filter_query = {}\n        if rtype:\n            filter_query['type'] = rtype\n        if name:\n            filter_query['name'] = self._relative_name(name)\n        payload = self._get(\n            '/{0}/zones/{1}/records'.format(self.account_id, self.domain),\n            query_params=filter_query)\n\n        records = []\n        for record in payload:\n            processed_record = {\n                'type': record['type'],\n                'name': '{}'.format(\n                    self.domain) if record['name'] == \"\" else '{0}.{1}'.format(\n                        record['name'],\n                        self.domain),\n                'ttl': record['ttl'],\n                'content': record['content'],\n                'id': record['id']}\n            if record['priority']:\n                processed_record['priority'] = record['priority']\n            records.append(processed_record)\n\n        if content:\n            records = [\n                record for record in records if record['content'] == content]\n\n        LOGGER.debug('list_records: %s', records)\n        return records\n\n    # Create or update a record.\n    def _update_record(self, identifier, rtype=None, name=None, content=None):\n\n        data = {}\n\n        if identifier is None:\n            records = self._list_records(rtype, name, content)\n            identifiers = [record[\"id\"] for record in records]\n        else:\n            identifiers = [identifier]\n\n        if name:\n            data['name'] = self._relative_name(name)\n        if content:\n            data['content'] = content\n        if self._get_lexicon_option('ttl'):\n            data['ttl'] = self._get_lexicon_option('ttl')\n        if self._get_lexicon_option('priority'):\n            data['priority'] = self._get_lexicon_option('priority')\n        if self._get_provider_option('regions'):\n            data['regions'] = self._get_provider_option('regions')\n\n        for one_identifier in identifiers:\n            self._patch('/{0}/zones/{1}/records/{2}'\n                        .format(self.account_id, self.domain, one_identifier), data)\n            LOGGER.debug('update_record: %s', one_identifier)\n\n        LOGGER.debug('update_record: %s', True)\n        return True\n\n    # Delete an existing record.\n    # If record does not exist, do nothing.\n    def _delete_record(self, identifier=None, rtype=None, name=None, content=None):\n        delete_record_id = []\n        if not identifier:\n            records = self._list_records(rtype, name, content)\n            delete_record_id = [record['id'] for record in records]\n        else:\n            delete_record_id.append(identifier)\n\n        LOGGER.debug('delete_records: %s', delete_record_id)\n\n        for record_id in delete_record_id:\n            self._delete(\n                '/{0}/zones/{1}/records/{2}'.format(self.account_id, self.domain, record_id))\n\n        # is always True at this point; if a non 2xx response is returned, an error is raised.\n        LOGGER.debug('delete_record: True')\n        return True\n\n    # Helpers\n\n    def _request(self, action='GET', url='/', data=None, query_params=None):\n        if data is None:\n            data = {}\n        if query_params is None:\n            query_params = {}\n        default_headers = {\n            'Accept': 'application/json',\n            'Content-Type': 'application/json'\n        }\n        default_auth = None\n\n        if self._get_provider_option('auth_token'):\n            default_headers['Authorization'] = \"Bearer {0}\".format(\n                self._get_provider_option('auth_token'))\n        elif (self._get_provider_option('auth_username')\n              and self._get_provider_option('auth_password')):\n            default_auth = (self._get_provider_option(\n                'auth_username'), self._get_provider_option('auth_password'))\n            if self._get_provider_option('auth_2fa'):\n                default_headers['X-Dnsimple-OTP'] = self._get_provider_option(\n                    'auth_2fa')\n        else:\n            raise Exception('No valid authentication mechanism found')\n\n        response = requests.request(action, self.api_endpoint + url, params=query_params,\n                                    data=json.dumps(data),\n                                    headers=default_headers,\n                                    auth=default_auth)\n        # if the request fails for any reason, throw an error.\n        response.raise_for_status()\n        if response.text and response.json()['data'] is None:\n            raise Exception('No data returned')\n\n        return response.json()['data'] if response.text else None\n\n    def _patch(self, url='/', data=None, query_params=None):\n        return self._request('PATCH', url, data=data, query_params=query_params)\n", "path": "lexicon/providers/dnsimple.py"}], "after_files": [{"content": "\"\"\"Module provider for DNS Simple\"\"\"\nfrom __future__ import absolute_import\nimport json\nimport logging\n\nimport requests\nfrom lexicon.providers.base import Provider as BaseProvider\n\n\nLOGGER = logging.getLogger(__name__)\n\nNAMESERVER_DOMAINS = ['dnsimple.com']\n\n\ndef provider_parser(subparser):\n    \"\"\"Configure provider parser for DNS Simple\"\"\"\n    subparser.add_argument(\n        \"--auth-token\", help=\"specify api token for authentication\")\n    subparser.add_argument(\n        \"--auth-username\", help=\"specify email address for authentication\")\n    subparser.add_argument(\n        \"--auth-password\", help=\"specify password for authentication\")\n    subparser.add_argument(\n        \"--auth-2fa\",\n        help=\"specify two-factor auth token (OTP) to use with email/password authentication\")\n\n\nclass Provider(BaseProvider):\n    \"\"\"Provider class for DNS Simple\"\"\"\n    def __init__(self, config):\n        super(Provider, self).__init__(config)\n        self.domain_id = None\n        self.account_id = None\n        self.api_endpoint = self._get_provider_option(\n            'api_endpoint') or 'https://api.dnsimple.com/v2'\n\n    def _authenticate(self):\n\n        payload = self._get('/accounts')\n\n        if not payload[0]['id']:\n            raise Exception('No account id found')\n\n        for account in payload:\n            if account['plan_identifier'] is None:\n                logging.warning(\n                    'Skipping unconfigured account %s (%d). ' \\\n                    'To use this account, you must select a plan.',\n                    account['email'], account['id'])\n                continue\n\n            dompayload = self._get(\n                '/{0}/domains'.format(account['id']), query_params={'name_like': self.domain})\n            if dompayload and dompayload[0]['id']:\n                self.account_id = account['id']\n                self.domain_id = dompayload[0]['id']\n\n        if not self.account_id:\n            raise Exception('No domain found like {}'.format(self.domain))\n\n    # Create record. If record already exists with the same content, do nothing\n\n    def _create_record(self, rtype, name, content):\n        # check if record already exists\n        existing_records = self._list_records(rtype, name, content)\n        if len(existing_records) == 1:\n            return True\n\n        record = {\n            'type': rtype,\n            'name': self._relative_name(name),\n            'content': content\n        }\n        if self._get_lexicon_option('ttl'):\n            record['ttl'] = self._get_lexicon_option('ttl')\n        if self._get_lexicon_option('priority'):\n            record['priority'] = self._get_lexicon_option('priority')\n        if self._get_provider_option('regions'):\n            record['regions'] = self._get_provider_option('regions')\n\n        payload = self._post(\n            '/{0}/zones/{1}/records'.format(self.account_id, self.domain), record)\n\n        LOGGER.debug('create_record: %s', 'id' in payload)\n        return 'id' in payload\n\n    # List all records. Return an empty list if no records found\n    # type, name and content are used to filter records.\n    # If possible filter during the query, otherwise filter after response is received.\n    def _list_records(self, rtype=None, name=None, content=None):\n        filter_query = {}\n        if rtype:\n            filter_query['type'] = rtype\n        if name:\n            filter_query['name'] = self._relative_name(name)\n        payload = self._get(\n            '/{0}/zones/{1}/records'.format(self.account_id, self.domain),\n            query_params=filter_query)\n\n        records = []\n        for record in payload:\n            processed_record = {\n                'type': record['type'],\n                'name': '{}'.format(\n                    self.domain) if record['name'] == \"\" else '{0}.{1}'.format(\n                        record['name'],\n                        self.domain),\n                'ttl': record['ttl'],\n                'content': record['content'],\n                'id': record['id']}\n            if record['priority']:\n                processed_record['priority'] = record['priority']\n            records.append(processed_record)\n\n        if content:\n            records = [\n                record for record in records if record['content'] == content]\n\n        LOGGER.debug('list_records: %s', records)\n        return records\n\n    # Create or update a record.\n    def _update_record(self, identifier, rtype=None, name=None, content=None):\n\n        data = {}\n\n        if identifier is None:\n            records = self._list_records(rtype, name, content)\n            identifiers = [record[\"id\"] for record in records]\n        else:\n            identifiers = [identifier]\n\n        if name:\n            data['name'] = self._relative_name(name)\n        if content:\n            data['content'] = content\n        if self._get_lexicon_option('ttl'):\n            data['ttl'] = self._get_lexicon_option('ttl')\n        if self._get_lexicon_option('priority'):\n            data['priority'] = self._get_lexicon_option('priority')\n        if self._get_provider_option('regions'):\n            data['regions'] = self._get_provider_option('regions')\n\n        for one_identifier in identifiers:\n            self._patch('/{0}/zones/{1}/records/{2}'\n                        .format(self.account_id, self.domain, one_identifier), data)\n            LOGGER.debug('update_record: %s', one_identifier)\n\n        LOGGER.debug('update_record: %s', True)\n        return True\n\n    # Delete an existing record.\n    # If record does not exist, do nothing.\n    def _delete_record(self, identifier=None, rtype=None, name=None, content=None):\n        delete_record_id = []\n        if not identifier:\n            records = self._list_records(rtype, name, content)\n            delete_record_id = [record['id'] for record in records]\n        else:\n            delete_record_id.append(identifier)\n\n        LOGGER.debug('delete_records: %s', delete_record_id)\n\n        for record_id in delete_record_id:\n            self._delete(\n                '/{0}/zones/{1}/records/{2}'.format(self.account_id, self.domain, record_id))\n\n        # is always True at this point; if a non 2xx response is returned, an error is raised.\n        LOGGER.debug('delete_record: True')\n        return True\n\n    # Helpers\n\n    def _request(self, action='GET', url='/', data=None, query_params=None):\n        if data is None:\n            data = {}\n        if query_params is None:\n            query_params = {}\n        default_headers = {\n            'Accept': 'application/json',\n            'Content-Type': 'application/json'\n        }\n        default_auth = None\n\n        if self._get_provider_option('auth_token'):\n            default_headers['Authorization'] = \"Bearer {0}\".format(\n                self._get_provider_option('auth_token'))\n        elif (self._get_provider_option('auth_username')\n              and self._get_provider_option('auth_password')):\n            default_auth = (self._get_provider_option(\n                'auth_username'), self._get_provider_option('auth_password'))\n            if self._get_provider_option('auth_2fa'):\n                default_headers['X-Dnsimple-OTP'] = self._get_provider_option(\n                    'auth_2fa')\n        else:\n            raise Exception('No valid authentication mechanism found')\n\n        response = requests.request(action, self.api_endpoint + url, params=query_params,\n                                    data=json.dumps(data),\n                                    headers=default_headers,\n                                    auth=default_auth)\n        # if the request fails for any reason, throw an error.\n        response.raise_for_status()\n        if response.text and response.json()['data'] is None:\n            raise Exception('No data returned')\n\n        return response.json()['data'] if response.text else None\n\n    def _patch(self, url='/', data=None, query_params=None):\n        return self._request('PATCH', url, data=data, query_params=query_params)\n", "path": "lexicon/providers/dnsimple.py"}]}