prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Azure - c7n-Mailer Errors
  About 50% of the time mailer runs, the following error results and messages aren't picked up, delivered:
  ```
  Traceback (most recent call last):
    File "/usr/local/bin/c7n-mailer", line 10, in <module>
      sys.exit(main())
    File "/usr/local/lib/python3.7/site-packages/c7n_mailer/cli.py", line 227, in main
      processor.run()
    File "/usr/local/lib/python3.7/site-packages/c7n_mailer/azure/azure_queue_processor.py", line 62, in run
      if (self.process_azure_queue_message(queue_message) or
    File "/usr/local/lib/python3.7/site-packages/c7n_mailer/azure/azure_queue_processor.py", line 89, in process_azure_queue_message
      SendGridDelivery(self.config, self.logger))
    File "/usr/local/lib/python3.7/site-packages/c7n_mailer/azure/sendgrid_delivery.py", line 29, in __init__
      sendgrid.SendGridAPIClient(apikey=self.config.get('sendgrid_api_key', ''))
  TypeError: __init__() got an unexpected keyword argument 'apikey'
  ```
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `tools/c7n_mailer/c7n_mailer/azure/sendgrid_delivery.py`
  Content:
  ```
  1 # Copyright 2018 Capital One Services, LLC
  2 #
  3 # Licensed under the Apache License, Version 2.0 (the "License");
  4 # you may not use this file except in compliance with the License.
  5 # You may obtain a copy of the License at
  6 #
  7 # http://www.apache.org/licenses/LICENSE-2.0
  8 #
  9 # Unless required by applicable law or agreed to in writing, software
  10 # distributed under the License is distributed on an "AS IS" BASIS,
  11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12 # See the License for the specific language governing permissions and
  13 # limitations under the License.
  14 
  15 import sendgrid
  16 import six
  17 from c7n_mailer.utils import (get_message_subject, get_rendered_jinja)
  18 from c7n_mailer.utils_email import is_email
  19 from python_http_client import exceptions
  20 from sendgrid.helpers.mail import Email, Content, Mail
  21 
  22 
  23 class SendGridDelivery(object):
  24 
  25     def __init__(self, config, logger):
  26         self.config = config
  27         self.logger = logger
  28         self.sendgrid_client = \
  29             sendgrid.SendGridAPIClient(apikey=self.config.get('sendgrid_api_key', ''))
  30 
  31     def get_to_addrs_sendgrid_messages_map(self, queue_message):
  32         # eg: { ('milton@initech.com', 'peter@initech.com'): [resource1, resource2, etc] }
  33         to_addrs_to_resources_map = self.get_email_to_addrs_to_resources_map(queue_message)
  34 
  35         to_addrs_to_content_map = {}
  36         for to_addrs, resources in six.iteritems(to_addrs_to_resources_map):
  37             to_addrs_to_content_map[to_addrs] = self.get_message_content(
  38                 queue_message,
  39                 resources,
  40                 list(to_addrs)
  41             )
  42         # eg: { ('milton@initech.com', 'peter@initech.com'): message }
  43         return to_addrs_to_content_map
  44 
  45     # this function returns a dictionary with a tuple of emails as the key
  46     # and the list of resources as the value. This helps ensure minimal emails
  47     # are sent, while only ever sending emails to the respective parties.
  48     def get_email_to_addrs_to_resources_map(self, queue_message):
  49         email_to_addrs_to_resources_map = {}
  50         targets = queue_message['action']['to']
  51 
  52         for resource in queue_message['resources']:
  53             # this is the list of emails that will be sent for this resource
  54             resource_emails = []
  55 
  56             for target in targets:
  57                 if target.startswith('tag:') and 'tags' in resource:
  58                     tag_name = target.split(':', 1)[1]
  59                     result = resource.get('tags', {}).get(tag_name, None)
  60                     if is_email(result):
  61                         resource_emails.append(result)
  62                 elif is_email(target):
  63                     resource_emails.append(target)
  64 
  65             resource_emails = tuple(sorted(set(resource_emails)))
  66 
  67             if resource_emails:
  68                 email_to_addrs_to_resources_map.setdefault(resource_emails, []).append(resource)
  69 
  70         if email_to_addrs_to_resources_map == {}:
  71             self.logger.debug('Found no email addresses, sending no emails.')
  72         # eg: { ('milton@initech.com', 'peter@initech.com'): [resource1, resource2, etc] }
  73         return email_to_addrs_to_resources_map
  74 
  75     def get_message_content(self, queue_message, resources, to_addrs):
  76         return get_rendered_jinja(
  77             to_addrs, queue_message, resources, self.logger,
  78             'template', 'default', self.config['templates_folders'])
  79 
  80     def sendgrid_handler(self, queue_message, to_addrs_to_email_messages_map):
  81         self.logger.info("Sending account:%s policy:%s %s:%s email:%s to %s" % (
  82             queue_message.get('account', ''),
  83             queue_message['policy']['name'],
  84             queue_message['policy']['resource'],
  85             str(len(queue_message['resources'])),
  86             queue_message['action'].get('template', 'default'),
  87             to_addrs_to_email_messages_map))
  88 
  89         from_email = Email(self.config.get('from_address', ''))
  90         subject = get_message_subject(queue_message)
  91         email_format = queue_message['action'].get('template_format', None)
  92         if not email_format:
  93             email_format = queue_message['action'].get(
  94                 'template', 'default').endswith('html') and 'html' or 'plain'
  95 
  96         for email_to_addrs, email_content in six.iteritems(to_addrs_to_email_messages_map):
  97             for to_address in email_to_addrs:
  98                 to_email = Email(to_address)
  99                 content = Content("text/" + email_format, email_content)
  100                 mail = Mail(from_email, subject, to_email, content)
  101                 try:
  102                     self.sendgrid_client.client.mail.send.post(request_body=mail.get())
  103                 except (exceptions.UnauthorizedError, exceptions.BadRequestsError) as e:
  104                     self.logger.warning(
  105                         "\n**Error \nPolicy:%s \nAccount:%s \nSending to:%s \n\nRequest body:"
  106                         "\n%s\n\nRequest headers:\n%s\n\n mailer.yml: %s" % (
  107                             queue_message['policy'],
  108                             queue_message.get('account', ''),
  109                             email_to_addrs,
  110                             e.body,
  111                             e.headers,
  112                             self.config
  113                         )
  114                     )
  115                     return False
  116         return True
  117
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/tools/c7n_mailer/c7n_mailer/azure/sendgrid_delivery.py b/tools/c7n_mailer/c7n_mailer/azure/sendgrid_delivery.py
  --- a/tools/c7n_mailer/c7n_mailer/azure/sendgrid_delivery.py
  +++ b/tools/c7n_mailer/c7n_mailer/azure/sendgrid_delivery.py
  @@ -26,7 +26,7 @@
           self.config = config
           self.logger = logger
           self.sendgrid_client = \
  -            sendgrid.SendGridAPIClient(apikey=self.config.get('sendgrid_api_key', ''))
  +            sendgrid.SendGridAPIClient(self.config.get('sendgrid_api_key', ''))
   
       def get_to_addrs_sendgrid_messages_map(self, queue_message):
           # eg: { ('milton@initech.com', 'peter@initech.com'): [resource1, resource2, etc] }
  
verification_info: {"golden_diff": "diff --git a/tools/c7n_mailer/c7n_mailer/azure/sendgrid_delivery.py b/tools/c7n_mailer/c7n_mailer/azure/sendgrid_delivery.py\n--- a/tools/c7n_mailer/c7n_mailer/azure/sendgrid_delivery.py\n+++ b/tools/c7n_mailer/c7n_mailer/azure/sendgrid_delivery.py\n@@ -26,7 +26,7 @@\n         self.config = config\n         self.logger = logger\n         self.sendgrid_client = \\\n-            sendgrid.SendGridAPIClient(apikey=self.config.get('sendgrid_api_key', ''))\n+            sendgrid.SendGridAPIClient(self.config.get('sendgrid_api_key', ''))\n \n     def get_to_addrs_sendgrid_messages_map(self, queue_message):\n         # eg: { ('milton@initech.com', 'peter@initech.com'): [resource1, resource2, etc] }\n", "issue": "Azure - c7n-Mailer Errors\nAbout 50% of the time mailer runs, the following error results and messages aren't picked up, delivered:\r\n```\r\nTraceback (most recent call last):\r\n  File \"/usr/local/bin/c7n-mailer\", line 10, in <module>\r\n    sys.exit(main())\r\n  File \"/usr/local/lib/python3.7/site-packages/c7n_mailer/cli.py\", line 227, in main\r\n    processor.run()\r\n  File \"/usr/local/lib/python3.7/site-packages/c7n_mailer/azure/azure_queue_processor.py\", line 62, in run\r\n    if (self.process_azure_queue_message(queue_message) or\r\n  File \"/usr/local/lib/python3.7/site-packages/c7n_mailer/azure/azure_queue_processor.py\", line 89, in process_azure_queue_message\r\n    SendGridDelivery(self.config, self.logger))\r\n  File \"/usr/local/lib/python3.7/site-packages/c7n_mailer/azure/sendgrid_delivery.py\", line 29, in __init__\r\n    sendgrid.SendGridAPIClient(apikey=self.config.get('sendgrid_api_key', ''))\r\nTypeError: __init__() got an unexpected keyword argument 'apikey'\r\n```\r\n\n", "before_files": [{"content": "# Copyright 2018 Capital One Services, LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport sendgrid\nimport six\nfrom c7n_mailer.utils import (get_message_subject, get_rendered_jinja)\nfrom c7n_mailer.utils_email import is_email\nfrom python_http_client import exceptions\nfrom sendgrid.helpers.mail import Email, Content, Mail\n\n\nclass SendGridDelivery(object):\n\n    def __init__(self, config, logger):\n        self.config = config\n        self.logger = logger\n        self.sendgrid_client = \\\n            sendgrid.SendGridAPIClient(apikey=self.config.get('sendgrid_api_key', ''))\n\n    def get_to_addrs_sendgrid_messages_map(self, queue_message):\n        # eg: { ('milton@initech.com', 'peter@initech.com'): [resource1, resource2, etc] }\n        to_addrs_to_resources_map = self.get_email_to_addrs_to_resources_map(queue_message)\n\n        to_addrs_to_content_map = {}\n        for to_addrs, resources in six.iteritems(to_addrs_to_resources_map):\n            to_addrs_to_content_map[to_addrs] = self.get_message_content(\n                queue_message,\n                resources,\n                list(to_addrs)\n            )\n        # eg: { ('milton@initech.com', 'peter@initech.com'): message }\n        return to_addrs_to_content_map\n\n    # this function returns a dictionary with a tuple of emails as the key\n    # and the list of resources as the value. This helps ensure minimal emails\n    # are sent, while only ever sending emails to the respective parties.\n    def get_email_to_addrs_to_resources_map(self, queue_message):\n        email_to_addrs_to_resources_map = {}\n        targets = queue_message['action']['to']\n\n        for resource in queue_message['resources']:\n            # this is the list of emails that will be sent for this resource\n            resource_emails = []\n\n            for target in targets:\n                if target.startswith('tag:') and 'tags' in resource:\n                    tag_name = target.split(':', 1)[1]\n                    result = resource.get('tags', {}).get(tag_name, None)\n                    if is_email(result):\n                        resource_emails.append(result)\n                elif is_email(target):\n                    resource_emails.append(target)\n\n            resource_emails = tuple(sorted(set(resource_emails)))\n\n            if resource_emails:\n                email_to_addrs_to_resources_map.setdefault(resource_emails, []).append(resource)\n\n        if email_to_addrs_to_resources_map == {}:\n            self.logger.debug('Found no email addresses, sending no emails.')\n        # eg: { ('milton@initech.com', 'peter@initech.com'): [resource1, resource2, etc] }\n        return email_to_addrs_to_resources_map\n\n    def get_message_content(self, queue_message, resources, to_addrs):\n        return get_rendered_jinja(\n            to_addrs, queue_message, resources, self.logger,\n            'template', 'default', self.config['templates_folders'])\n\n    def sendgrid_handler(self, queue_message, to_addrs_to_email_messages_map):\n        self.logger.info(\"Sending account:%s policy:%s %s:%s email:%s to %s\" % (\n            queue_message.get('account', ''),\n            queue_message['policy']['name'],\n            queue_message['policy']['resource'],\n            str(len(queue_message['resources'])),\n            queue_message['action'].get('template', 'default'),\n            to_addrs_to_email_messages_map))\n\n        from_email = Email(self.config.get('from_address', ''))\n        subject = get_message_subject(queue_message)\n        email_format = queue_message['action'].get('template_format', None)\n        if not email_format:\n            email_format = queue_message['action'].get(\n                'template', 'default').endswith('html') and 'html' or 'plain'\n\n        for email_to_addrs, email_content in six.iteritems(to_addrs_to_email_messages_map):\n            for to_address in email_to_addrs:\n                to_email = Email(to_address)\n                content = Content(\"text/\" + email_format, email_content)\n                mail = Mail(from_email, subject, to_email, content)\n                try:\n                    self.sendgrid_client.client.mail.send.post(request_body=mail.get())\n                except (exceptions.UnauthorizedError, exceptions.BadRequestsError) as e:\n                    self.logger.warning(\n                        \"\\n**Error \\nPolicy:%s \\nAccount:%s \\nSending to:%s \\n\\nRequest body:\"\n                        \"\\n%s\\n\\nRequest headers:\\n%s\\n\\n mailer.yml: %s\" % (\n                            queue_message['policy'],\n                            queue_message.get('account', ''),\n                            email_to_addrs,\n                            e.body,\n                            e.headers,\n                            self.config\n                        )\n                    )\n                    return False\n        return True\n", "path": "tools/c7n_mailer/c7n_mailer/azure/sendgrid_delivery.py"}], "after_files": [{"content": "# Copyright 2018 Capital One Services, LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport sendgrid\nimport six\nfrom c7n_mailer.utils import (get_message_subject, get_rendered_jinja)\nfrom c7n_mailer.utils_email import is_email\nfrom python_http_client import exceptions\nfrom sendgrid.helpers.mail import Email, Content, Mail\n\n\nclass SendGridDelivery(object):\n\n    def __init__(self, config, logger):\n        self.config = config\n        self.logger = logger\n        self.sendgrid_client = \\\n            sendgrid.SendGridAPIClient(self.config.get('sendgrid_api_key', ''))\n\n    def get_to_addrs_sendgrid_messages_map(self, queue_message):\n        # eg: { ('milton@initech.com', 'peter@initech.com'): [resource1, resource2, etc] }\n        to_addrs_to_resources_map = self.get_email_to_addrs_to_resources_map(queue_message)\n\n        to_addrs_to_content_map = {}\n        for to_addrs, resources in six.iteritems(to_addrs_to_resources_map):\n            to_addrs_to_content_map[to_addrs] = self.get_message_content(\n                queue_message,\n                resources,\n                list(to_addrs)\n            )\n        # eg: { ('milton@initech.com', 'peter@initech.com'): message }\n        return to_addrs_to_content_map\n\n    # this function returns a dictionary with a tuple of emails as the key\n    # and the list of resources as the value. This helps ensure minimal emails\n    # are sent, while only ever sending emails to the respective parties.\n    def get_email_to_addrs_to_resources_map(self, queue_message):\n        email_to_addrs_to_resources_map = {}\n        targets = queue_message['action']['to']\n\n        for resource in queue_message['resources']:\n            # this is the list of emails that will be sent for this resource\n            resource_emails = []\n\n            for target in targets:\n                if target.startswith('tag:') and 'tags' in resource:\n                    tag_name = target.split(':', 1)[1]\n                    result = resource.get('tags', {}).get(tag_name, None)\n                    if is_email(result):\n                        resource_emails.append(result)\n                elif is_email(target):\n                    resource_emails.append(target)\n\n            resource_emails = tuple(sorted(set(resource_emails)))\n\n            if resource_emails:\n                email_to_addrs_to_resources_map.setdefault(resource_emails, []).append(resource)\n\n        if email_to_addrs_to_resources_map == {}:\n            self.logger.debug('Found no email addresses, sending no emails.')\n        # eg: { ('milton@initech.com', 'peter@initech.com'): [resource1, resource2, etc] }\n        return email_to_addrs_to_resources_map\n\n    def get_message_content(self, queue_message, resources, to_addrs):\n        return get_rendered_jinja(\n            to_addrs, queue_message, resources, self.logger,\n            'template', 'default', self.config['templates_folders'])\n\n    def sendgrid_handler(self, queue_message, to_addrs_to_email_messages_map):\n        self.logger.info(\"Sending account:%s policy:%s %s:%s email:%s to %s\" % (\n            queue_message.get('account', ''),\n            queue_message['policy']['name'],\n            queue_message['policy']['resource'],\n            str(len(queue_message['resources'])),\n            queue_message['action'].get('template', 'default'),\n            to_addrs_to_email_messages_map))\n\n        from_email = Email(self.config.get('from_address', ''))\n        subject = get_message_subject(queue_message)\n        email_format = queue_message['action'].get('template_format', None)\n        if not email_format:\n            email_format = queue_message['action'].get(\n                'template', 'default').endswith('html') and 'html' or 'plain'\n\n        for email_to_addrs, email_content in six.iteritems(to_addrs_to_email_messages_map):\n            for to_address in email_to_addrs:\n                to_email = Email(to_address)\n                content = Content(\"text/\" + email_format, email_content)\n                mail = Mail(from_email, subject, to_email, content)\n                try:\n                    self.sendgrid_client.client.mail.send.post(request_body=mail.get())\n                except (exceptions.UnauthorizedError, exceptions.BadRequestsError) as e:\n                    self.logger.warning(\n                        \"\\n**Error \\nPolicy:%s \\nAccount:%s \\nSending to:%s \\n\\nRequest body:\"\n                        \"\\n%s\\n\\nRequest headers:\\n%s\\n\\n mailer.yml: %s\" % (\n                            queue_message['policy'],\n                            queue_message.get('account', ''),\n                            email_to_addrs,\n                            e.body,\n                            e.headers,\n                            self.config\n                        )\n                    )\n                    return False\n        return True\n", "path": "tools/c7n_mailer/c7n_mailer/azure/sendgrid_delivery.py"}]}