Reputation: 871
We have an application (app-a) that is on python2.7 standard google app engine. We are attempting to do programmatic authentication to access another application (app-b) using service account based on the example here. App-b is on python3.7 standard google app engine.
When we do the iap authenticated call we get the following error in the logs of App-A.
resp = requests.request(
method, url,
headers={'Authorization': 'Bearer {}'.format(
google_open_id_connect_token)}, **kwargs)
AppEnginePlatformWarning: urllib3 is using URLFetch on Google App Engine sandbox instead of sockets. To use sockets directly instead of URLFetch see https://urllib3.readthedocs.io/en/latest/reference/urllib3.contrib.html.
AppEnginePlatformWarning: URLFetch does not support granular timeout settings, reverting to total or default URLFetch timeout.
The requests.request errors with
Exception("Bad response from application: 500 / {'content-type': 'text/html', 'x-cloud-trace-context':
In App-B we are trying to receive the data sent from app-a.
json.loads(request.data)
We get the following error in the logs of app-b.
in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) File "/opt/python3.7/lib/python3.7/json/decoder.py", line 355, in raw_decode raise JSONDecodeError("Expecting value", s, err.value) from None json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
This leads me to believe that app-a is able to call app-b successfully. But for some reason it is not able to pass the data. Please help.
UPDATE - Per suggestion to use HTTPlib we tried this.
payload = {
'test_data' : "data_test"
}
payload_json_dumps = json.dumps(payload)
conn = httplib.HTTPConnection(host)
conn.request("POST", path, payload_json_dumps, request_headers)
resp = conn.getresponse()
Added the following to app.yaml.
env_variables:
GAE_USE_SOCKETS_HTTPLIB : 'true'
In App-B we changed to
from flask import request
@app.route('url', methods = ['GET','POST'])
def content_from_client():
if (request.data):
data_received = request.get_json()
We are still not able to get the data on App-B. We get
AttributeError("'NoneType' object has no attribute 'get'")
UPDATE -
Changed the header formation and got it working.
request_headers = {
"Content-Type": 'application/json',
"follow_redirects": False,
"X-Appengine-Inbound-Appid": "app-A.appspot.com",
"Connection": "keep-alive",
'Authorization': 'Bearer {}'.format(google_open_id_connect_token)
}
Upvotes: 2
Views: 473
Reputation: 871
Per suggestion above the following helped solve the issue. Changed to httplib instead of urlfetch.
conn = httplib.HTTPConnection(host)
conn.request("POST", path, payload_json_dumps, request_headers)
resp = conn.getresponse()
Added the following to app.yaml -
env_variables:
GAE_USE_SOCKETS_HTTPLIB : 'true'
Changed header formation to -
request_headers = {
"Content-Type": 'application/json',
"follow_redirects": False,
"X-Appengine-Inbound-Appid": "app-A.appspot.com",
"Connection": "keep-alive",
'Authorization': 'Bearer {}'.format(google_open_id_connect_token)
}
Upvotes: 0
Reputation: 1321
AppEnginePlatformWarning
is raised by urllib3 which is used by the requests library.
Urllib3 provides a pool manager that uses URL Fetch API by default. Sometimes though may not be the best option for your use case. A solution is to use sockets instead. In order to do that you have to configure your app.yaml
and include the following field:
env_variables:
GAE_USE_SOCKETS_HTTPLIB : 'true'
You may also find this documented in Google documentation.
As of the error on your app-B I would use response.json() method, requests
builtin method instead of json.loads()
as it detects automatically which decoder to use.
Let me know if this was helpful.
Upvotes: 1