prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Error on adding modules to python datasource
  I'm trying to add a module to a python datasource, but it's failing with this traceback
  
  ```
  Traceback (most recent call last):
    File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1475, in full_dispatch_request
      rv = self.dispatch_request()
    File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1461, in dispatch_request
      return self.view_functions[rule.endpoint](**req.view_args)
    File "/usr/local/lib/python2.7/dist-packages/flask_restful/__init__.py", line 477, in wrapper
      resp = resource(*args, **kwargs)
    File "/usr/local/lib/python2.7/dist-packages/flask_login.py", line 792, in decorated_view
      return func(*args, **kwargs)
    File "/usr/local/lib/python2.7/dist-packages/flask/views.py", line 84, in view
      return self.dispatch_request(*args, **kwargs)
    File "/opt/redash/redash.0.9.2.b1536/redash/handlers/base.py", line 19, in dispatch_request
      return super(BaseResource, self).dispatch_request(*args, **kwargs)
    File "/usr/local/lib/python2.7/dist-packages/flask_restful/__init__.py", line 587, in dispatch_request
      resp = meth(*args, **kwargs)
    File "/opt/redash/redash.0.9.2.b1536/redash/permissions.py", line 40, in decorated
      return fn(*args, **kwargs)
    File "/opt/redash/redash.0.9.2.b1536/redash/handlers/data_sources.py", line 38, in post
      data_source.options.update(req['options'])
    File "/opt/redash/redash.0.9.2.b1536/redash/utils/configuration.py", line 56, in update
      if k in self.schema['secret'] and v == SECRET_PLACEHOLDER:
  KeyError: 'secret'
  ```
  
  
  </issue>
  <code>
  [start of redash/utils/configuration.py]
  1 import json
  2 import jsonschema
  3 from jsonschema import ValidationError
  4 
  5 SECRET_PLACEHOLDER = '--------'
  6 
  7 
  8 class ConfigurationContainer(object):
  9     def __init__(self, config, schema=None):
  10         self._config = config
  11         self.set_schema(schema)
  12 
  13     def set_schema(self, schema):
  14         self._schema = schema
  15 
  16     @property
  17     def schema(self):
  18         if self._schema is None:
  19             raise RuntimeError("Schema missing.")
  20 
  21         return self._schema
  22 
  23     def is_valid(self):
  24         try:
  25             self.validate()
  26         except (ValidationError, ValueError):
  27             return False
  28 
  29         return True
  30 
  31     def validate(self):
  32         jsonschema.validate(self._config, self._schema)
  33 
  34     def to_json(self):
  35         return json.dumps(self._config)
  36 
  37     def iteritems(self):
  38         return self._config.iteritems()
  39 
  40     def to_dict(self, mask_secrets=False):
  41         if (mask_secrets is False or 'secret' not in self.schema):
  42             return self._config
  43 
  44         config = self._config.copy()
  45         for key in config:
  46             if key in self.schema['secret']:
  47                 config[key] = SECRET_PLACEHOLDER
  48 
  49         return config
  50 
  51     def update(self, new_config):
  52         jsonschema.validate(new_config, self.schema)
  53 
  54         config = {}
  55         for k, v in new_config.iteritems():
  56             if k in self.schema['secret'] and v == SECRET_PLACEHOLDER:
  57                 config[k] = self[k]
  58             else:
  59                 config[k] = v
  60 
  61         self._config = config
  62 
  63     def get(self, *args, **kwargs):
  64         return self._config.get(*args, **kwargs)
  65 
  66     def __getitem__(self, item):
  67         if item in self._config:
  68             return self._config[item]
  69 
  70         raise KeyError(item)
  71 
  72     def __contains__(self, item):
  73         return item in self._config
  74 
  75     @classmethod
  76     def from_json(cls, config_in_json):
  77         return cls(json.loads(config_in_json))
  78
  [end of redash/utils/configuration.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/redash/utils/configuration.py b/redash/utils/configuration.py
  --- a/redash/utils/configuration.py
  +++ b/redash/utils/configuration.py
  @@ -38,7 +38,7 @@
           return self._config.iteritems()
   
       def to_dict(self, mask_secrets=False):
  -        if (mask_secrets is False or 'secret' not in self.schema):
  +        if mask_secrets is False or 'secret' not in self.schema:
               return self._config
   
           config = self._config.copy()
  @@ -53,7 +53,7 @@
   
           config = {}
           for k, v in new_config.iteritems():
  -            if k in self.schema['secret'] and v == SECRET_PLACEHOLDER:
  +            if k in self.schema.get('secret', []) and v == SECRET_PLACEHOLDER:
                   config[k] = self[k]
               else:
                   config[k] = v
  
verification_info: {"golden_diff": "diff --git a/redash/utils/configuration.py b/redash/utils/configuration.py\n--- a/redash/utils/configuration.py\n+++ b/redash/utils/configuration.py\n@@ -38,7 +38,7 @@\n         return self._config.iteritems()\n \n     def to_dict(self, mask_secrets=False):\n-        if (mask_secrets is False or 'secret' not in self.schema):\n+        if mask_secrets is False or 'secret' not in self.schema:\n             return self._config\n \n         config = self._config.copy()\n@@ -53,7 +53,7 @@\n \n         config = {}\n         for k, v in new_config.iteritems():\n-            if k in self.schema['secret'] and v == SECRET_PLACEHOLDER:\n+            if k in self.schema.get('secret', []) and v == SECRET_PLACEHOLDER:\n                 config[k] = self[k]\n             else:\n                 config[k] = v\n", "issue": "Error on adding modules to python datasource\nI'm trying to add a module to a python datasource, but it's failing with this traceback\n\n```\nTraceback (most recent call last):\n  File \"/usr/local/lib/python2.7/dist-packages/flask/app.py\", line 1475, in full_dispatch_request\n    rv = self.dispatch_request()\n  File \"/usr/local/lib/python2.7/dist-packages/flask/app.py\", line 1461, in dispatch_request\n    return self.view_functions[rule.endpoint](**req.view_args)\n  File \"/usr/local/lib/python2.7/dist-packages/flask_restful/__init__.py\", line 477, in wrapper\n    resp = resource(*args, **kwargs)\n  File \"/usr/local/lib/python2.7/dist-packages/flask_login.py\", line 792, in decorated_view\n    return func(*args, **kwargs)\n  File \"/usr/local/lib/python2.7/dist-packages/flask/views.py\", line 84, in view\n    return self.dispatch_request(*args, **kwargs)\n  File \"/opt/redash/redash.0.9.2.b1536/redash/handlers/base.py\", line 19, in dispatch_request\n    return super(BaseResource, self).dispatch_request(*args, **kwargs)\n  File \"/usr/local/lib/python2.7/dist-packages/flask_restful/__init__.py\", line 587, in dispatch_request\n    resp = meth(*args, **kwargs)\n  File \"/opt/redash/redash.0.9.2.b1536/redash/permissions.py\", line 40, in decorated\n    return fn(*args, **kwargs)\n  File \"/opt/redash/redash.0.9.2.b1536/redash/handlers/data_sources.py\", line 38, in post\n    data_source.options.update(req['options'])\n  File \"/opt/redash/redash.0.9.2.b1536/redash/utils/configuration.py\", line 56, in update\n    if k in self.schema['secret'] and v == SECRET_PLACEHOLDER:\nKeyError: 'secret'\n```\n\n", "before_files": [{"content": "import json\nimport jsonschema\nfrom jsonschema import ValidationError\n\nSECRET_PLACEHOLDER = '--------'\n\n\nclass ConfigurationContainer(object):\n    def __init__(self, config, schema=None):\n        self._config = config\n        self.set_schema(schema)\n\n    def set_schema(self, schema):\n        self._schema = schema\n\n    @property\n    def schema(self):\n        if self._schema is None:\n            raise RuntimeError(\"Schema missing.\")\n\n        return self._schema\n\n    def is_valid(self):\n        try:\n            self.validate()\n        except (ValidationError, ValueError):\n            return False\n\n        return True\n\n    def validate(self):\n        jsonschema.validate(self._config, self._schema)\n\n    def to_json(self):\n        return json.dumps(self._config)\n\n    def iteritems(self):\n        return self._config.iteritems()\n\n    def to_dict(self, mask_secrets=False):\n        if (mask_secrets is False or 'secret' not in self.schema):\n            return self._config\n\n        config = self._config.copy()\n        for key in config:\n            if key in self.schema['secret']:\n                config[key] = SECRET_PLACEHOLDER\n\n        return config\n\n    def update(self, new_config):\n        jsonschema.validate(new_config, self.schema)\n\n        config = {}\n        for k, v in new_config.iteritems():\n            if k in self.schema['secret'] and v == SECRET_PLACEHOLDER:\n                config[k] = self[k]\n            else:\n                config[k] = v\n\n        self._config = config\n\n    def get(self, *args, **kwargs):\n        return self._config.get(*args, **kwargs)\n\n    def __getitem__(self, item):\n        if item in self._config:\n            return self._config[item]\n\n        raise KeyError(item)\n\n    def __contains__(self, item):\n        return item in self._config\n\n    @classmethod\n    def from_json(cls, config_in_json):\n        return cls(json.loads(config_in_json))\n", "path": "redash/utils/configuration.py"}]}