We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Notify (Pushbullet) Plugin Error.
Hi, since last week i have this error in my log. Up to this point everything worked without problems.
```
2019-11-13 10:30 ERROR    notify_entry  NexBox    'x-ratelimit-reset'
Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/flexget/components/notify/notify.py", line 104, in send_notification
    send_notification(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/flexget/components/notify/notification_framework.py", line 124, in send_notification
    title, message, rendered_config
  File "/usr/local/lib/python3.5/dist-packages/flexget/components/notify/notifiers/pushbullet.py", line 89, in notify
    self.send_push(key, title, message, config.get('url'), d, 'device_iden')
  File "/usr/local/lib/python3.5/dist-packages/flexget/components/notify/notifiers/pushbullet.py", line 130, in send_push
    int(response.headers['X-Ratelimit-Reset'])
  File "/usr/local/lib/python3.5/dist-packages/requests/structures.py", line 52, in __getitem__
    return self._store[key.lower()][1]
KeyError: 'x-ratelimit-reset'
```
Flexget: 2.21.32
API: 1.5.0

Same with Flexget 3.0.8 and Python 3.8
Notify (Pushbullet) Plugin Error.
Hi, since last week i have this error in my log. Up to this point everything worked without problems.
```
2019-11-13 10:30 ERROR    notify_entry  NexBox    'x-ratelimit-reset'
Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/flexget/components/notify/notify.py", line 104, in send_notification
    send_notification(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/flexget/components/notify/notification_framework.py", line 124, in send_notification
    title, message, rendered_config
  File "/usr/local/lib/python3.5/dist-packages/flexget/components/notify/notifiers/pushbullet.py", line 89, in notify
    self.send_push(key, title, message, config.get('url'), d, 'device_iden')
  File "/usr/local/lib/python3.5/dist-packages/flexget/components/notify/notifiers/pushbullet.py", line 130, in send_push
    int(response.headers['X-Ratelimit-Reset'])
  File "/usr/local/lib/python3.5/dist-packages/requests/structures.py", line 52, in __getitem__
    return self._store[key.lower()][1]
KeyError: 'x-ratelimit-reset'
```
Flexget: 2.21.32
API: 1.5.0

Same with Flexget 3.0.8 and Python 3.8

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `flexget/components/notify/notifiers/pushover.py`
Content:
```
1 import datetime
2 import logging
3 
4 from requests.exceptions import RequestException
5 
6 from flexget import plugin
7 from flexget.config_schema import one_or_more
8 from flexget.event import event
9 from flexget.plugin import PluginWarning
10 from flexget.utils.requests import Session as RequestSession
11 from flexget.utils.requests import TimedLimiter
12 
13 plugin_name = 'pushover'
14 log = logging.getLogger(plugin_name)
15 
16 PUSHOVER_URL = 'https://api.pushover.net/1/messages.json'
17 
18 requests = RequestSession(max_retries=3)
19 requests.add_domain_limiter(TimedLimiter('pushover.net', '5 seconds'))
20 
21 
22 class PushoverNotifier:
23     """
24     Example::
25 
26       notify:
27         entries:
28           via:
29             - pushover:
30                 user_key: <USER_KEY> (can also be a list of userkeys)
31                 token: <TOKEN>
32                 [device: <DEVICE_STRING>]
33                 [priority: <PRIORITY>]
34                 [url: <URL>]
35                 [url_title: <URL_TITLE>]
36                 [sound: <SOUND>]
37                 [retry]: <RETRY>]
38                 [expire]: <EXPIRE>]
39                 [callback]: <CALLBACK>]
40                 [html]: <HTML>]
41     """
42 
43     schema = {
44         'type': 'object',
45         'properties': {
46             'user_key': one_or_more({'type': 'string'}),
47             'api_key': {'type': 'string', 'default': 'aPwSHwkLcNaavShxktBpgJH4bRWc3m'},
48             'device': one_or_more({'type': 'string'}),
49             'priority': {
50                 'oneOf': [{'type': 'number', 'minimum': -2, 'maximum': 2}, {'type': 'string'}]
51             },
52             'url': {'type': 'string'},
53             'url_title': {'type': 'string'},
54             'sound': {'type': 'string'},
55             'retry': {'type': 'integer', 'minimum': 30},
56             'expire': {'type': 'integer', 'maximum': 86400},
57             'callback': {'type': 'string'},
58             'html': {'type': 'boolean'},
59         },
60         'required': ['user_key'],
61         'additionalProperties': False,
62     }
63 
64     def notify(self, title, message, config):
65         """
66         Sends a Pushover notification
67 
68         :param str title: the message's title
69         :param str message: the message to send
70         :param dict config: The pushover config
71         """
72         notification = {
73             'token': config.get('api_key'),
74             'message': message,
75             'title': title,
76             'device': config.get('device'),
77             'priority': config.get('priority'),
78             'url': config.get('url'),
79             'url_title': config.get('url_title'),
80             'sound': config.get('sound'),
81             'retry': config.get('retry'),
82             'expire': config.get('expire'),
83             'callback': config.get('callback'),
84         }
85 
86         # HTML parsing mode
87         if config.get('html'):
88             notification['html'] = 1
89 
90         # Support multiple devices
91         if isinstance(notification['device'], list):
92             notification['device'] = ','.join(notification['device'])
93 
94         # Special case, verify certain fields exists if priority is 2
95         priority = config.get('priority')
96         expire = config.get('expire')
97         retry = config.get('retry')
98         if priority == 2 and not all([expire, retry]):
99             log.warning(
100                 'Priority set to 2 but fields "expire" and "retry" are not both present.Lowering priority to 1'
101             )
102             notification['priority'] = 1
103 
104         if not isinstance(config['user_key'], list):
105             config['user_key'] = [config['user_key']]
106 
107         for user in config['user_key']:
108             notification['user'] = user
109             try:
110                 response = requests.post(PUSHOVER_URL, data=notification)
111             except RequestException as e:
112                 if e.response is not None:
113                     if e.response.status_code == 429:
114                         reset_time = datetime.datetime.fromtimestamp(
115                             int(e.response.headers['X-Limit-App-Reset'])
116                         ).strftime('%Y-%m-%d %H:%M:%S')
117                         error_message = (
118                             'Monthly pushover message limit reached. Next reset: %s' % reset_time
119                         )
120                     else:
121                         error_message = e.response.json()['errors'][0]
122                 else:
123                     error_message = str(e)
124                 raise PluginWarning(error_message)
125 
126             reset_time = datetime.datetime.fromtimestamp(
127                 int(response.headers['X-Limit-App-Reset'])
128             ).strftime('%Y-%m-%d %H:%M:%S')
129             remaining = response.headers['X-Limit-App-Remaining']
130             log.debug(
131                 'Pushover notification sent. Notifications remaining until next reset: %s. '
132                 'Next reset at: %s',
133                 remaining,
134                 reset_time,
135             )
136 
137 
138 @event('plugin.register')
139 def register_plugin():
140     plugin.register(PushoverNotifier, plugin_name, api_ver=2, interfaces=['notifiers'])
141
```
--- 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/flexget/components/notify/notifiers/pushover.py b/flexget/components/notify/notifiers/pushover.py
--- a/flexget/components/notify/notifiers/pushover.py
+++ b/flexget/components/notify/notifiers/pushover.py
@@ -111,12 +111,15 @@
             except RequestException as e:
                 if e.response is not None:
                     if e.response.status_code == 429:
-                        reset_time = datetime.datetime.fromtimestamp(
-                            int(e.response.headers['X-Limit-App-Reset'])
-                        ).strftime('%Y-%m-%d %H:%M:%S')
-                        error_message = (
-                            'Monthly pushover message limit reached. Next reset: %s' % reset_time
-                        )
+                        app_reset = e.response.headers.get('X-Limit-App-Reset')
+                        if app_reset:
+                            reset_time = datetime.datetime.fromtimestamp(int(app_reset)).strftime(
+                                '%Y-%m-%d %H:%M:%S'
+                            )
+                            error_message = (
+                                f'Monthly pushover message limit reached. Next reset: {reset_time}'
+                            )
+
                     else:
                         error_message = e.response.json()['errors'][0]
                 else:

{"golden_diff": "diff --git a/flexget/components/notify/notifiers/pushover.py b/flexget/components/notify/notifiers/pushover.py\n--- a/flexget/components/notify/notifiers/pushover.py\n+++ b/flexget/components/notify/notifiers/pushover.py\n@@ -111,12 +111,15 @@\n             except RequestException as e:\n                 if e.response is not None:\n                     if e.response.status_code == 429:\n-                        reset_time = datetime.datetime.fromtimestamp(\n-                            int(e.response.headers['X-Limit-App-Reset'])\n-                        ).strftime('%Y-%m-%d %H:%M:%S')\n-                        error_message = (\n-                            'Monthly pushover message limit reached. Next reset: %s' % reset_time\n-                        )\n+                        app_reset = e.response.headers.get('X-Limit-App-Reset')\n+                        if app_reset:\n+                            reset_time = datetime.datetime.fromtimestamp(int(app_reset)).strftime(\n+                                '%Y-%m-%d %H:%M:%S'\n+                            )\n+                            error_message = (\n+                                f'Monthly pushover message limit reached. Next reset: {reset_time}'\n+                            )\n+\n                     else:\n                         error_message = e.response.json()['errors'][0]\n                 else:\n", "issue": "Notify (Pushbullet) Plugin Error.\nHi, since last week i have this error in my log. Up to this point everything worked without problems.\r\n```\r\n2019-11-13 10:30 ERROR    notify_entry  NexBox    'x-ratelimit-reset'\r\nTraceback (most recent call last):\r\n  File \"/usr/local/lib/python3.5/dist-packages/flexget/components/notify/notify.py\", line 104, in send_notification\r\n    send_notification(*args, **kwargs)\r\n  File \"/usr/local/lib/python3.5/dist-packages/flexget/components/notify/notification_framework.py\", line 124, in send_notification\r\n    title, message, rendered_config\r\n  File \"/usr/local/lib/python3.5/dist-packages/flexget/components/notify/notifiers/pushbullet.py\", line 89, in notify\r\n    self.send_push(key, title, message, config.get('url'), d, 'device_iden')\r\n  File \"/usr/local/lib/python3.5/dist-packages/flexget/components/notify/notifiers/pushbullet.py\", line 130, in send_push\r\n    int(response.headers['X-Ratelimit-Reset'])\r\n  File \"/usr/local/lib/python3.5/dist-packages/requests/structures.py\", line 52, in __getitem__\r\n    return self._store[key.lower()][1]\r\nKeyError: 'x-ratelimit-reset'\r\n```\r\nFlexget: 2.21.32\r\nAPI: 1.5.0\r\n\r\nSame with Flexget 3.0.8 and Python 3.8\nNotify (Pushbullet) Plugin Error.\nHi, since last week i have this error in my log. Up to this point everything worked without problems.\r\n```\r\n2019-11-13 10:30 ERROR    notify_entry  NexBox    'x-ratelimit-reset'\r\nTraceback (most recent call last):\r\n  File \"/usr/local/lib/python3.5/dist-packages/flexget/components/notify/notify.py\", line 104, in send_notification\r\n    send_notification(*args, **kwargs)\r\n  File \"/usr/local/lib/python3.5/dist-packages/flexget/components/notify/notification_framework.py\", line 124, in send_notification\r\n    title, message, rendered_config\r\n  File \"/usr/local/lib/python3.5/dist-packages/flexget/components/notify/notifiers/pushbullet.py\", line 89, in notify\r\n    self.send_push(key, title, message, config.get('url'), d, 'device_iden')\r\n  File \"/usr/local/lib/python3.5/dist-packages/flexget/components/notify/notifiers/pushbullet.py\", line 130, in send_push\r\n    int(response.headers['X-Ratelimit-Reset'])\r\n  File \"/usr/local/lib/python3.5/dist-packages/requests/structures.py\", line 52, in __getitem__\r\n    return self._store[key.lower()][1]\r\nKeyError: 'x-ratelimit-reset'\r\n```\r\nFlexget: 2.21.32\r\nAPI: 1.5.0\r\n\r\nSame with Flexget 3.0.8 and Python 3.8\n", "before_files": [{"content": "import datetime\nimport logging\n\nfrom requests.exceptions import RequestException\n\nfrom flexget import plugin\nfrom flexget.config_schema import one_or_more\nfrom flexget.event import event\nfrom flexget.plugin import PluginWarning\nfrom flexget.utils.requests import Session as RequestSession\nfrom flexget.utils.requests import TimedLimiter\n\nplugin_name = 'pushover'\nlog = logging.getLogger(plugin_name)\n\nPUSHOVER_URL = 'https://api.pushover.net/1/messages.json'\n\nrequests = RequestSession(max_retries=3)\nrequests.add_domain_limiter(TimedLimiter('pushover.net', '5 seconds'))\n\n\nclass PushoverNotifier:\n    \"\"\"\n    Example::\n\n      notify:\n        entries:\n          via:\n            - pushover:\n                user_key: <USER_KEY> (can also be a list of userkeys)\n                token: <TOKEN>\n                [device: <DEVICE_STRING>]\n                [priority: <PRIORITY>]\n                [url: <URL>]\n                [url_title: <URL_TITLE>]\n                [sound: <SOUND>]\n                [retry]: <RETRY>]\n                [expire]: <EXPIRE>]\n                [callback]: <CALLBACK>]\n                [html]: <HTML>]\n    \"\"\"\n\n    schema = {\n        'type': 'object',\n        'properties': {\n            'user_key': one_or_more({'type': 'string'}),\n            'api_key': {'type': 'string', 'default': 'aPwSHwkLcNaavShxktBpgJH4bRWc3m'},\n            'device': one_or_more({'type': 'string'}),\n            'priority': {\n                'oneOf': [{'type': 'number', 'minimum': -2, 'maximum': 2}, {'type': 'string'}]\n            },\n            'url': {'type': 'string'},\n            'url_title': {'type': 'string'},\n            'sound': {'type': 'string'},\n            'retry': {'type': 'integer', 'minimum': 30},\n            'expire': {'type': 'integer', 'maximum': 86400},\n            'callback': {'type': 'string'},\n            'html': {'type': 'boolean'},\n        },\n        'required': ['user_key'],\n        'additionalProperties': False,\n    }\n\n    def notify(self, title, message, config):\n        \"\"\"\n        Sends a Pushover notification\n\n        :param str title: the message's title\n        :param str message: the message to send\n        :param dict config: The pushover config\n        \"\"\"\n        notification = {\n            'token': config.get('api_key'),\n            'message': message,\n            'title': title,\n            'device': config.get('device'),\n            'priority': config.get('priority'),\n            'url': config.get('url'),\n            'url_title': config.get('url_title'),\n            'sound': config.get('sound'),\n            'retry': config.get('retry'),\n            'expire': config.get('expire'),\n            'callback': config.get('callback'),\n        }\n\n        # HTML parsing mode\n        if config.get('html'):\n            notification['html'] = 1\n\n        # Support multiple devices\n        if isinstance(notification['device'], list):\n            notification['device'] = ','.join(notification['device'])\n\n        # Special case, verify certain fields exists if priority is 2\n        priority = config.get('priority')\n        expire = config.get('expire')\n        retry = config.get('retry')\n        if priority == 2 and not all([expire, retry]):\n            log.warning(\n                'Priority set to 2 but fields \"expire\" and \"retry\" are not both present.Lowering priority to 1'\n            )\n            notification['priority'] = 1\n\n        if not isinstance(config['user_key'], list):\n            config['user_key'] = [config['user_key']]\n\n        for user in config['user_key']:\n            notification['user'] = user\n            try:\n                response = requests.post(PUSHOVER_URL, data=notification)\n            except RequestException as e:\n                if e.response is not None:\n                    if e.response.status_code == 429:\n                        reset_time = datetime.datetime.fromtimestamp(\n                            int(e.response.headers['X-Limit-App-Reset'])\n                        ).strftime('%Y-%m-%d %H:%M:%S')\n                        error_message = (\n                            'Monthly pushover message limit reached. Next reset: %s' % reset_time\n                        )\n                    else:\n                        error_message = e.response.json()['errors'][0]\n                else:\n                    error_message = str(e)\n                raise PluginWarning(error_message)\n\n            reset_time = datetime.datetime.fromtimestamp(\n                int(response.headers['X-Limit-App-Reset'])\n            ).strftime('%Y-%m-%d %H:%M:%S')\n            remaining = response.headers['X-Limit-App-Remaining']\n            log.debug(\n                'Pushover notification sent. Notifications remaining until next reset: %s. '\n                'Next reset at: %s',\n                remaining,\n                reset_time,\n            )\n\n\n@event('plugin.register')\ndef register_plugin():\n    plugin.register(PushoverNotifier, plugin_name, api_ver=2, interfaces=['notifiers'])\n", "path": "flexget/components/notify/notifiers/pushover.py"}], "after_files": [{"content": "import datetime\nimport logging\n\nfrom requests.exceptions import RequestException\n\nfrom flexget import plugin\nfrom flexget.config_schema import one_or_more\nfrom flexget.event import event\nfrom flexget.plugin import PluginWarning\nfrom flexget.utils.requests import Session as RequestSession\nfrom flexget.utils.requests import TimedLimiter\n\nplugin_name = 'pushover'\nlog = logging.getLogger(plugin_name)\n\nPUSHOVER_URL = 'https://api.pushover.net/1/messages.json'\n\nrequests = RequestSession(max_retries=3)\nrequests.add_domain_limiter(TimedLimiter('pushover.net', '5 seconds'))\n\n\nclass PushoverNotifier:\n    \"\"\"\n    Example::\n\n      notify:\n        entries:\n          via:\n            - pushover:\n                user_key: <USER_KEY> (can also be a list of userkeys)\n                token: <TOKEN>\n                [device: <DEVICE_STRING>]\n                [priority: <PRIORITY>]\n                [url: <URL>]\n                [url_title: <URL_TITLE>]\n                [sound: <SOUND>]\n                [retry]: <RETRY>]\n                [expire]: <EXPIRE>]\n                [callback]: <CALLBACK>]\n                [html]: <HTML>]\n    \"\"\"\n\n    schema = {\n        'type': 'object',\n        'properties': {\n            'user_key': one_or_more({'type': 'string'}),\n            'api_key': {'type': 'string', 'default': 'aPwSHwkLcNaavShxktBpgJH4bRWc3m'},\n            'device': one_or_more({'type': 'string'}),\n            'priority': {\n                'oneOf': [{'type': 'number', 'minimum': -2, 'maximum': 2}, {'type': 'string'}]\n            },\n            'url': {'type': 'string'},\n            'url_title': {'type': 'string'},\n            'sound': {'type': 'string'},\n            'retry': {'type': 'integer', 'minimum': 30},\n            'expire': {'type': 'integer', 'maximum': 86400},\n            'callback': {'type': 'string'},\n            'html': {'type': 'boolean'},\n        },\n        'required': ['user_key'],\n        'additionalProperties': False,\n    }\n\n    def notify(self, title, message, config):\n        \"\"\"\n        Sends a Pushover notification\n\n        :param str title: the message's title\n        :param str message: the message to send\n        :param dict config: The pushover config\n        \"\"\"\n        notification = {\n            'token': config.get('api_key'),\n            'message': message,\n            'title': title,\n            'device': config.get('device'),\n            'priority': config.get('priority'),\n            'url': config.get('url'),\n            'url_title': config.get('url_title'),\n            'sound': config.get('sound'),\n            'retry': config.get('retry'),\n            'expire': config.get('expire'),\n            'callback': config.get('callback'),\n        }\n\n        # HTML parsing mode\n        if config.get('html'):\n            notification['html'] = 1\n\n        # Support multiple devices\n        if isinstance(notification['device'], list):\n            notification['device'] = ','.join(notification['device'])\n\n        # Special case, verify certain fields exists if priority is 2\n        priority = config.get('priority')\n        expire = config.get('expire')\n        retry = config.get('retry')\n        if priority == 2 and not all([expire, retry]):\n            log.warning(\n                'Priority set to 2 but fields \"expire\" and \"retry\" are not both present.Lowering priority to 1'\n            )\n            notification['priority'] = 1\n\n        if not isinstance(config['user_key'], list):\n            config['user_key'] = [config['user_key']]\n\n        for user in config['user_key']:\n            notification['user'] = user\n            try:\n                response = requests.post(PUSHOVER_URL, data=notification)\n            except RequestException as e:\n                if e.response is not None:\n                    if e.response.status_code == 429:\n                        app_reset = e.response.headers.get('X-Limit-App-Reset')\n                        if app_reset:\n                            reset_time = datetime.datetime.fromtimestamp(int(app_reset)).strftime(\n                                '%Y-%m-%d %H:%M:%S'\n                            )\n                            error_message = (\n                                f'Monthly pushover message limit reached. Next reset: {reset_time}'\n                            )\n\n                    else:\n                        error_message = e.response.json()['errors'][0]\n                else:\n                    error_message = str(e)\n                raise PluginWarning(error_message)\n\n            reset_time = datetime.datetime.fromtimestamp(\n                int(response.headers['X-Limit-App-Reset'])\n            ).strftime('%Y-%m-%d %H:%M:%S')\n            remaining = response.headers['X-Limit-App-Remaining']\n            log.debug(\n                'Pushover notification sent. Notifications remaining until next reset: %s. '\n                'Next reset at: %s',\n                remaining,\n                reset_time,\n            )\n\n\n@event('plugin.register')\ndef register_plugin():\n    plugin.register(PushoverNotifier, plugin_name, api_ver=2, interfaces=['notifiers'])\n", "path": "flexget/components/notify/notifiers/pushover.py"}]}