Reputation: 1937
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
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
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