Problems with Stripe, Django and Cartridge / Mezzanine - python-2.7

My It is a cartridge/mezzanine app and is running fine with https set up properly. Its working fine until I get to the end of the checkout process, I get the following debug error in the browser:
Exception Type: AuthenticationError
Exception Value:
No API key provided. (HINT: set your API key using "stripe.api_key = "). You can generate API keys from the Stripe web interface. See https://stripe.com/api for details, or email support#stripe.com if you have any questions.
Exception Location: /home/jamesgilbert/lib/python2.7/stripe/api_requestor.py in request_raw, line 183
Traceback:
File "/home/johnsmith/webapps/cartridgeshop/lib/python2.7/Django-1.8.4-py2.7.egg/django/core/handlers/base.py" in get_response
132. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/johnsmith/webapps/cartridgeshop/lib/python2.7/Django-1.8.4-py2.7.egg/django/views/decorators/cache.py" in _wrapped_view_func
57. response = view_func(request, *args, **kwargs)
File "/home/johnsmith/lib/python2.7/cartridge/shop/views.py" in checkout_steps
282. transaction_id = payment_handler(request, form, order)
File "/home/johnsmith/lib/python2.7/cartridge_stripe/init.py" in payment_handler
34. description=order)
File "/home/johnsmith/lib/python2.7/stripe/resource.py" in create
344. response, api_key = requestor.request('post', url, params, headers)
File "/home/johnsmith/lib/python2.7/stripe/api_requestor.py" in request
140. method.lower(), url, params, headers)
File "/home/johnsmith/lib/python2.7/stripe/api_requestor.py" in request_raw
183. 'No API key provided. (HINT: set your API key using '
I then got the following in the apache error logs:
/home/johnsmith/lib/python2.7/cartridge/shop/views.py:226:
UserWarning: The SHOP_CHECKOUT_FORM_CLASS setting is deprecated - please define your own urlpattern for the checkout_steps view, passing in your own form_class argument.
I have the correct stripe api keys in the settings and everything set up as it should be, I have looked in other places and coming to a dead end?
Many Thanks

You need to add the Stripe API key to your settings.py file (which you said you had already done). Something like the following line but with your own API key from the Stripe developer web site.
STRIPE_API_KEY="sk_test_XXXXXXXXXXXXXXXXXXXXXXXX"
You also need to reference the python interface file (which you must have been doing to get this error message).
SHOP_HANDLER_PAYMENT = "cartridge.shop.payment.stripe_api.process"
And, you need to install the strip-python module.
Seems like you did all this so I'm not sure if this will help but maybe it will trigger something to get you over this.

Cartridge-stripe doesn't seem to be maintained. I'd advise using the stripe payment handler built into cartridge, which will be documented in cartridge's next docs release (PR).

Related

Django easypost buy returns malformed syntax when using test api key but insufficient funds with production

Using the easypost python library I call the buy function passing in the rate like the documentation says but it returns an error.
Can you use your test api key with buy for easypost or not? I didn't see anything in the documentation with it. It might seem to work with production but I am not able to test that yet so I was wondering if I could test it with the test api key?
The code is:
import easypost
def get_shipment(shipment_id):
return easypost.Shipment.retrieve(shipment_id)
......
shipment = get_shipment(shipment_id)
try:
shipment.buy(rate=shipment.lowest_rate())
except Exception as e:
raise ValidationError({'detail': e.message})
The error message I get with test key
Traceback (most recent call last):
File "/app/returns/serializers.py", line 237, in handle_shipment_purchase
shipment.buy(rate=shipment.lowest_rate())
File "/usr/local/lib/python3.6/dist-packages/easypost/__init__.py", line 725, in buy
response, api_key = requestor.request('post', url, params)
File "/usr/local/lib/python3.6/dist-packages/easypost/__init__.py", line 260, in request
response = self.interpret_response(http_body, http_status)
File "/usr/local/lib/python3.6/dist-packages/easypost/__init__.py", line 321, in interpret_response
self.handle_api_error(http_status, http_body, response)
File "/usr/local/lib/python3.6/dist-packages/easypost/__init__.py", line 383, in handle_api_error
raise Error(error.get('message', ''), http_status, http_body)
easypost.Error: The request could not be understood by the server due to malformed syntax.
I got the same issue with Python though my shipment id and API_KEY are correct. with the EasyPost python exception message, it will not show the root cause of the exception. Try to do request with curl or inside exception check e.json_body and raise ValidationError accordingly.
try:
shipment.buy(rate=shipment.lowest_rate())
except Exception as e:
# Put debugger here and Check exception e.json_body
e.json_body
raise ValidationError({'detail': e.http_body})
Yes, you can buy shipments with your TEST API key. From the code you shared, I don't see any obvious problems, but you'll obviously want to double check that your shipment_id is being set correctly and that your API key is as well. Beyond that, write to us as support#easypost.com and we can actually look into our system logs to see what may be coming in "malformed".

httplib2.ServerNotFoundError: Unable to find the server at www.googleapis.com

When i try to fetch the details of gmail using google-api's (googleapiclient,oauth2client), i am getting below error:
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/site-packages/google_api_python_client-1.7.8-py2.7.egg/googleapiclient/_helpers.py", line 130, in positional_wrapper
File "/usr/local/lib/python2.7/site-packages/google_api_python_client-1.7.8-py2.7.egg/googleapiclient/discovery.py", line 224, in build
File "/usr/local/lib/python2.7/site-packages/google_api_python_client-1.7.8-py2.7.egg/googleapiclient/discovery.py", line 274, in _retrieve_discovery_doc
File "/usr/local/lib/python2.7/site-packages/httplib2-0.12.1-py2.7.egg/httplib2/__init__.py", line 2135, in request
cachekey,
File "/usr/local/lib/python2.7/site-packages/httplib2-0.12.1-py2.7.egg/httplib2/__init__.py", line 1796, in _request
conn, request_uri, method, body, headers
File "/usr/local/lib/python2.7/site-packages/httplib2-0.12.1-py2.7.egg/httplib2/__init__.py", line 1707, in _conn_request
raise ServerNotFoundError("Unable to find the server at %s" % conn.host)
httplib2.ServerNotFoundError: Unable to find the server at www.googleapis.com
but it is working fine in my pc but not from remote location.
code:
from googleapiclient.discovery import build
from oauth2client.service_account import ServiceAccountCredentials
credentials = ServiceAccountCredentials.from_json_keyfile_name(
"quickstart-1551349397232-e8bcb3368ae1.json", scopes=
['https://www.googleapis.com/auth/admin.directory.group', 'https://www.googleapis.com/auth/admin.directory.user', 'https://www.googleapis.com/auth/admin.directory.domain', 'https://www.googleapis.com/auth/gmail.readonly'])
delegated_credentials = credentials.create_delegated('jango#carbonitedepot.com')
DIRECOTORY = build('admin', 'directory_v1', credentials=delegated_credentials)
try:
results = DIRECOTORY.users().list(customer='my_customer').execute()
users = results.get('users', [])
res = []
for info in users:
print(info)
res.append(info.get("primaryEmail"))
print(res)
except Exception as e:
print(e)
Any help would be much appreciated.
Thanks in advance.
I had the same issue and I searched a lot to get it fixed, turns out I was at fault here.
I don't know from where there was podman installed instead of docker and that caused the problem.
I suggest you check your docker version and make sure the latest is running at the server, otherwise, the library works fine! Please let me know if you still face this issue, would like to dig deep!
The httplib2 is likely scanning through network interface DHCP DNS nameservers (in your registry or visible to docker) and then trying to connect through a stale DNS or possible an IPv6. Patching your socket in the main routine may solve it:
# Monkey patch to force IPv4, since FB seems to hang on IPv6
import socket
old_getaddrinfo = socket.getaddrinfo
def new_getaddrinfo(*args, **kwargs):
responses = old_getaddrinfo(*args, **kwargs)
return [response
for response in responses
if response[0] == socket.AF_INET]
socket.getaddrinfo = new_getaddrinfo

How to use service account with private key file and impersonated user (DWD) in Google App Engine and local development server?

Application: Google App Engine Python standard environment
Purpose: Access Google APIs (not Cloud APIs) through the google-api-python-client, e.g. Sheets API v4, by using a service account and impersonate a user, because the app is supposed to act on behalf of this user. (2-legged auth, the user won't be asked to grant access)
I've got a setup running in production environment, but it runs only on the local development server (dev_appserver.py) for testing if a certain environment variable would be removed. I'm looking for a solution that would work without adding/removing the environment variable.
The service account was created for the app and configured with domain-wide delegation DWD in Admin Console. Sheets API is turned on for this project.
Of the many quick-starts, samples, and references available, it was only after reading the Google Auth Library for Python documentation (google-auth) that I've noticed the missing parts (an environment variable and the SSL library) and finally got the code running on production.
The app code will use the private key JSON file that was downloaded from Cloud Console IAM.
requirements.txt
# as suggested by almost all docs, but this isn't everything we need:
google-api-python-client==1.6.5
google-auth==1.4.0
google-auth-httplib2==0.0.3
app.yaml
env_variables:
# enable socket support of paid app, needed for OAuth2 service-accounts
# see google-auth documentation, v1.4.1, chapter 1.2.4
GAE_USE_SOCKETS_HTTPLIB : true
# some other stuff
libraries:
# to make HTTPS calls to other services, needed for OAuth2 service-accounts
# see google-auth documentation, v1.4.1, chapter 1.2.4
- name: ssl
version: latest
appengine_config.py (partial sample for Sheets API v4 access)
from google.oauth2 import service_account
SCOPES = ["https://www.googleapis.com/auth/spreadsheets"]
APP_ROOT_DIR = os.path.abspath(os.path.dirname(__file__))
SERVICE_ACCOUNT_FILE = "service-account-private-key.json"
import googleapiclient.discovery
credentials = service_account.Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES)
# impersonate as user#example.com (G Suite domain account)
credentials = credentials.with_subject('user#example.com')
service = googleapiclient.discovery.build('sheets', 'v4', credentials=credentials)
# until here, the code works in production and local dev server
result = service.spreadsheets().values().get(spreadsheetId="DOC-ID-HERE", range="A1:C5").execute()
# execute() will work only in production,
# on local dev, it will raise an ResponseNotReady exception
traceback
ERROR 2018-03-05 16:32:03,183 wsgi.py:263]
Traceback (most recent call last):
File "/Users/user/google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 240, in Handle
handler = _config_handle.add_wsgi_middleware(self._LoadHandler())
File "/Users/user/google-cloud-sdk/platform/google_appengine/google/appengine/api/lib_config.py", line 351, in __getattr__
self._update_configs()
File "/Users/user/google-cloud-sdk/platform/google_appengine/google/appengine/api/lib_config.py", line 287, in _update_configs
self._registry.initialize()
File "/Users/user/google-cloud-sdk/platform/google_appengine/google/appengine/api/lib_config.py", line 160, in initialize
import_func(self._modname)
File "/Users/user/git/project/gae/appengine_config.py", line 143, in <module>
spreadsheetId=spreadsheetId, range=rangeName).execute()
File "/Users/user/git/project/gae/_lib/oauth2client/_helpers.py", line 133, in positional_wrapper
return wrapped(*args, **kwargs)
File "/Users/user/git/project/gae/_lib/googleapiclient/http.py", line 839, in execute
method=str(self.method), body=self.body, headers=self.headers)
File "/Users/user/git/project/gae/_lib/googleapiclient/http.py", line 166, in _retry_request
resp, content = http.request(uri, method, *args, **kwargs)
File "/Users/user/git/project/gae/_lib/google_auth_httplib2.py", line 187, in request
self._request, method, uri, request_headers)
File "/Users/user/git/project/gae/_lib/google/auth/credentials.py", line 121, in before_request
self.refresh(request)
File "/Users/user/git/project/gae/_lib/google/oauth2/service_account.py", line 322, in refresh
request, self._token_uri, assertion)
File "/Users/user/git/project/gae/_lib/google/oauth2/_client.py", line 145, in jwt_grant
response_data = _token_endpoint_request(request, token_uri, body)
File "/Users/user/git/project/gae/_lib/google/oauth2/_client.py", line 106, in _token_endpoint_request
method='POST', url=token_uri, headers=headers, body=body)
File "/Users/user/git/project/gae/_lib/google_auth_httplib2.py", line 116, in __call__
url, method=method, body=body, headers=headers, **kwargs)
File "/Users/user/git/project/gae/_lib/httplib2/__init__.py", line 1659, in request
(response, content) = self._request(conn, authority, uri, request_uri, method, body, headers, redirections, cachekey)
File "/Users/user/git/project/gae/_lib/httplib2/__init__.py", line 1399, in _request
(response, content) = self._conn_request(conn, request_uri, method, body, headers)
File "/Users/user/git/project/gae/_lib/httplib2/__init__.py", line 1355, in _conn_request
response = conn.getresponse()
File "/Users/user/google-cloud-sdk/platform/google_appengine/google/appengine/dist27/python_std_lib/httplib.py", line 1121, in getresponse
raise ResponseNotReady()
I have figured out that if I delete GAE_USE_SOCKETS_HTTPLIB from app.yaml's env_variables list, the code will work on local development server (but not in production anymore).
Am I doing something wrong here? Could I use the same code (maybe with a small switch) for both environments, without manually adding/removing the variable from app.yaml?
Purpose: Access Google APIs (not Cloud APIs) through the google-api-python-client, e.g. Sheets API v4, ….
Here they explain that:
Private, broadcast, multicast, and Google IP ranges (except those whitelisted below), are blocked:
Google Public DNS: 8.8.8.8, 8.8.4.4, 2001:4860:4860::8888, 2001:4860:4860::8844 port 53
Gmail SMTPS: smtp.gmail.com port 465 and 587
Gmail POP3S: pop.gmail.com port 995
Gmail IMAPS: imap.gmail.com port 993
I have figured out that if I delete GAE_USE_SOCKETS_HTTPLIB from app.yaml's env_variables list, the code will work on local development server (but not in production anymore).
This is explained here:
Using sockets with the development server
You can run and test code
using sockets on the development server, without using any special
command line parameters.
Finally, this question and the accepted answer describe a similar scenario.
Hope this helps you :-)

linkedin api - python - get_connections()

I am working on a simple python scraping script, I am trying to get connections from LinkedIn using their API without a redirect_uri. I worked once with some APIs, that don't require the redirect url or just https://localhost. I got the consumer_key, consumer_secret, user_secret, consumer_secret. Here's the code i am using from https://github.com/ozgur/python-linkedin:
RETURN_URL = ''
url = 'https://api.linkedin.com/v1/people/~'
# Instantiate the developer authentication class
authentication = linkedin.LinkedInDeveloperAuthentication(CONSUMER_KEY, CONSUMER_SECRET,
USER_TOKEN, USER_SECRET,
RETURN_URL, linkedin.PERMISSIONS.enums.values())
# Pass it in to the app...
application = linkedin.LinkedInApplication(authentication)
print application.get_profile() # works
print application.get_connections()
And here's the error I get:
Traceback (most recent call last):
File "getContacts.py", line 20, in <module>
print application.get_connections()
File "/home/imane/Projects/prjL/env/local/lib/python2.7/site-packages/linkedin/linkedin.py", line 219, in get_connections
raise_for_error(response)
File "/home/imane/Projects/prjL/env/local/lib/python2.7/site-packages/linkedin/utils.py", line 63, in raise_for_error
raise LinkedInError(message)
linkedin.exceptions.LinkedInError: 403 Client Error: Forbidden for url: https://api.linkedin.com/v1/people/~/connections: Unknown Error
This is my first question here, so excuse me if I didn't make it clear enough, and thank you for helping me out.
Here's what i tried with python_oauth2:
import oauth2 as oauth
import requests
url = 'https://api.linkedin.com/v1/people/~'
params = {}
token = oauth.Token(key=USER_TOKEN, secret=USER_SECRET)
consumer = oauth.Consumer(key=CONSUMER_KEY, secret=CONSUMER_SECRET)
# Set our token/key parameters
params['oauth_token'] = token.key
params['oauth_consumer_key'] = consumer.key
oauth_request = oauth.Request(method="GET", url=url, parameters=params)
oauth_request.sign_request(oauth.SignatureMethod_HMAC_SHA1(), consumer, token)
signed_url = oauth_request.to_url()
response = requests.get(signed_url)
Connections API calls are a restricted endpoint as of March, 2015. It's possible you're using sample code/documentation that was written at a time when anyone could access those endpoints. You are receiving a 403 response because your application legitimately does not have the permission required to make that request.

Google Python Admin SDK using Oauth2 for a Service Account (Education Edition)-"oauth2client.client.AccessTokenRefreshError: access_denied" exception

I have been trying to get the Service Account authentication working for the Google Admin SDK for a few days now to no avail. I am using the google-api-python-client-1.2 library freshly installed from Google.
I have been following Google's documentation on the topic. Links are here:
htps://developers.google.com/accounts/docs/OAuth2ServiceAccount
htps://developers.google.com/api-client-library/python/guide/aaa_oauth
htp://google-api-python-client.googlecode.com/hg/docs/epy/oauth2client.client.SignedJwtAssertionCredentials-class.html
And have the tasks.py Service Account example working which you can be found here:
htp://code.google.com/p/google-api-python-client/source/browse/samples/service_account/tasks.py?r=c21573904a2df1334d13b4380f63463c94c8d0e8
And have been closely studying these two Stack Overflow threads on a related topic here:
google admin sdk directory api 403 python
Google Admin API using Oauth2 for a Service Account (Education Edition) - 403 Error
And have studied the relevant code in gam.py (Dito GAM).
Yet I'm still missing something as I am getting an 'oauth2client.client.AccessTokenRefreshError: access_denied' exception in nearly every test case I write.
Here is a concise example of a test authentication:
import httplib2
from apiclient.discovery import build
from oauth2client.client import SignedJwtAssertionCredentials
f = file('myKey.p12', 'rb')
key = f.read()
f.close()
credentials = SignedJwtAssertionCredentials(
'myServiceAdmin#developer.gserviceaccount.com',
key,
sub='myAdminUser#my.googleDomain.edu',
scope = ['https://www.googleapis.com/auth/admin.directory.user',])
http = httplib2.Http()
http = credentials.authorize(http)
service = build('admin', 'directory_v1', http=http)
When I run the above code I get this stack dump and exception:
Traceback (most recent call last):
File "./test.py", line 17, in <module>
service = build('admin', 'directory_v1', http=http)
File "/usr/lib/python2.7/dist-packages/oauth2client/util.py", line 132, in positional_wrapper
return wrapped(*args, **kwargs)
File "/usr/lib/python2.7/dist-packages/apiclient/discovery.py", line 192, in build resp, content = http.request(requested_url)
File "/usr/lib/python2.7/dist-packages/oauth2client/util.py", line 132, in positional_wrapper
return wrapped(*args, **kwargs)
File "/usr/lib/python2.7/dist-packages/oauth2client/client.py", line 475, in new_request
self._refresh(request_orig)
File "/usr/lib/python2.7/dist-packages/oauth2client/client.py", line 653, in _refresh
self._do_refresh_request(http_request)
File "/usr/lib/python2.7/dist-packages/oauth2client/client.py", line 710, in _do_refresh_request
raise AccessTokenRefreshError(error_msg)
oauth2client.client.AccessTokenRefreshError: access_denied
I've tried multiple super user accounts, service accounts, and keys and always end up with the same exception. If I add sub to the tasks.py example I end up with the same error. Replacing sub with prn also generates this exception and adding private_key_password='notasecret' does nothing (it is the default). The Admin SDK is activated in the Google Developers Console and the target accounts have super user privileges. This makes me think something is missing on the Google domain side but I cannot think of anything else to check.
Any one have an idea what I am doing wrong?
Have you granted the third party client access in your Admin Console for your service account?
My to go instruction when it comes to setting up Service Account is the instruction Google has for Drive Api.
https://developers.google.com/drive/web/delegation
Take a look at the "Delegate domain-wide authority to your service account" part and see if you have completed those steps.
Maybe not OP's problem, but I had this same error and my issue was that I was setting the sub field in the credentials object
credentials = SignedJwtAssertionCredentials(SERVICE_ACCOUNT_EMAIL, key,
scope=SCOPES, sub=**<DON'T SET ME>**)
If you're using domain-wide delegation, you need to not set a sub (because your "user" is the domain administrator.) The docs are a bit confusing on this point. I just removed the sub field and it worked for me.