brandones
brandones

Reputation: 1937

Workaround for dev_appserver.py inability to make SSL requests

Ran into this problem trying to call braintree.ClientToken.generate() from a Google App Engine app, running Flask on dev_appserver.py. dev_appserver.py can't currently make outgoing SSL connections. Making the above braintree call yields

ConnectionError: ('Connection aborted.', error(13, 'Permission denied'))

The call works on in a real GAE environment. It's used in one of my views, so it breaks my whole website flow with the above 500 error when it fails. How can I work around this so that I can continue developing in my local environment?

Upvotes: 2

Views: 1153

Answers (2)

agf
agf

Reputation: 176790

I work at Braintree. If you have more questions, you can always contact our support team

For help with the Braintree Python library on GAE, see this example on my GitHub. To answer your question, you can force the dev server to use the real Python socket library, so SSL connections work:

try:
    # This is needed to make local development work with SSL.
    # This must be done *before* you import the Braintree Python library.
    # See http://stackoverflow.com/a/24066819/500584
    # and https://code.google.com/p/googleappengine/issues/detail?id=9246 for more information.
    from google.appengine.tools.devappserver2.python import sandbox
    sandbox._WHITE_LIST_C_MODULES += ['_ssl', '_socket']

    import sys
    # this is socket.py copied from a standard python install
    import stdlib_socket
    sys.modules['socket'] = stdlib_socket
except ImportError as e:
    print(e)

Upvotes: 1

brandones
brandones

Reputation: 1937

If you have some variable global to your app that corresponds with when you're running in dev_appserver.py, you can create a mock of the failing method conditioned on that variable.

In my case, that variable is called env_conf.FLASK_CONF. I used the following code to mock the braintree generate call.

# Imports
import braintree
import env_conf
from flask import render_template

# Mock Braintree in DEV environment
if env_conf.FLASK_CONF == 'DEV':
    from functools import partial
    def mock_generate(self):
        return 'foobarbaz123'
    braintree.ClientToken.generate = partial(mock_generate, braintree.ClientToken())

# Add payment handler
def add_payment():
    token = braintree.ClientToken.generate()
    return render_template('add-payment.html',
                           braintree_client_token=token)

The idea generically is:

import problem_function
if DEV_ENVIRONMENT:
    def mock_problem_fcn():
        return 'expected response'
    problem_function = mock_problem_function

problem_function()

Upvotes: 1

Related Questions