Urrlib3/Requests: HTTPS problems on Google App Engine - python

Hi I am trying to make an HTTPS connection using requests on App Engine but I get the following error
NameError: name 'CERT_NONE' is not defined
It seems that urrlib3 cannot import ssl. Any ideas?
Update: The problem is that ssl on App Engine is missing the following
from ssl import wrap_socket, CERT_NONE, SSLError

This problem was fixed by t-8ch as you can see on this call https://github.com/shazow/urllib3/pull/130 at urllib3 github repository.
They have not done the merge to master branch yet, but you can get the available package from the fixed branch of t-8ch here: https://github.com/t-8ch/urllib3/tree/unify_ssl_api
I have tested and this is working well.

The fix mentioned by maxcnunes appears to have been merged into requests-1.2.0. Looks like it's working on my dev_appserver at least.

Are you using the latest urllib3? They recently added support for GAE. I seem to recall you need to use the urlfetch API, rather than SSL directly.

Related

Swagger-codegen flask generated server locally doesn't works

I have generated a simple API server example using swaggerhub, and downloaded python-flask generated server locally.
Unfortunately, it seems to not work at all. Every time I try to access the indicated url, that is
http://localhost:8080/data/2.5//ui/
it returns me a 404 error.
I've tried all the solutions reported on:
Python connexion not displaying Swagger UI
but with no success. What am I missing?
A very simple detail that made all work: after executing pip install 'connexion[swagger-ui]' and pip install pathlib swagger_ui_bundle (though I am not sure the last is strictly needed...), the server worked only with an invalidate cache and restart command on PyCharm.

Python connexion not displaying Swagger UI

I've built a Python/Flask based REST API using the connexion module. This working well as defining the REST API with with swagger.yml file works very well. The application is running, but when I navigate to /ui all I get in my browser is this:
I haven't disabled the UI, so I'm not sure what's going on and why the UI isn't being displayed. My application doesn't have a /static folder (it's only an API), so the app isn't serving any static files, not sure if that's related to the problem or not.
Any suggestions, pointers or hints about what I'm doing wrong would be most appreciated!
Here is a simplified example of my code:
# 3rd party libraries
from flask_cors import CORS
import connexion
def create_app(config_key, instance_config=None):
# create the connexion instance
connex_app = connexion.FlaskApp(__name__, specification_dir='./files/swagger/')
connex_app.server = 'gevent'
# get the Flask app instance
app = connex_app.app
# configure the application
app.config.from_object(config_key)
# add CORS support to application
CORS(app)
# define the API with the SWAGGER API definition YAML file
connex_app.add_api('line_controller_api.yml',
base_path='{url_prefix}'.format(url_prefix=app.config.get('URL_PREFIX', '/')),
resolver=AppResolver())
return connex_app
def production_app(instance_config=None):
app = create_app('api_config.ProductionConfig', instance_config)
return app
if __name__ == '__main__':
app = create_app('api_config.DevelopmentConfig')
port = 5001
logger.info('Line Controller API running on port %s', port)
app.run(host='0.0.0.0', port=port)
Thanks in advance,
Doug
connexion from 2.0.1 version onward don't have swagger-ui bundled inside it. You have install it explicitly using the below command (note the quotes)
pip install 'connexion[swagger-ui]'
Once you install it. swagger will work with connexion. In the earlier version swagger used to work with /ui added to your url at the end http(s)://host:port
But in 2.0.x onward use http(s)://host:port/<basepath>/ui
My stackoverflow reputation is too low for me to comment on Ashraff Ali Wahab's answer above but I just found out that I can edit it myself. Suffice it to say that it fixed the problem for me after I understood that the shell syntax, as presented, is wrong which was pointed out by Pablo Marin-Garcia. This is the shell syntax you need in Unix/Linux to properly install the swagger-ui plugin:
pip install 'connexion[swagger-ui]'
Any matched quotes will do. Note well that without the quotes, the pip command will run successfully but it won't install the swagger-ui component as you expect it to. Furthermore, I spent a lot of time scratching my head on this one because I did this in a virtualenv. I also searched the virtualenv for the swagger-ui component with find and I found some stub installed. So, if you are new to python or you are in a hurry, this can be easy to miss.
At the end of the day, I decided to add a local_requirement.txt file listing the correct version of Werzueg, connexion, and "connexion[swagger-ui]" which I install before using the stock requirements.txt because it seems like the Flask API code generated by the SmartBear tools is a little dated.
I had the same problem. I solved it with
pip install pathlib swagger_ui_bundle
It's caused by missing trailing slash. Just add slash at the end of your url and it will work.
Related issue https://github.com/zalando/connexion/issues/346.

Flask, Python 3, and WebSockets

How can I serve a websockets endpoint from Flask running on Python 3? This seems near impossible. Note, I do not want SocketsIO or anything like that. Just want to be able, from plain JavaScript following the very simple HTML5 standard, connect to to a Flask endpoint and upgrade it to a Websocket for bidirectional communication. Example JS below
var ws = new WebSocket("ws://localhost:5000/echo");
I assumed this would be a simple matter of pip installing the right module, but no. Any ideas? Should I write my own Python module for this?
Unfortunately this is currently not supported. Possible workarounds below
Go node.js.
Go python2
Fix the existing flask-sockets module, issue here.
Take it on yourself to write a python3 aware python module

Google App Engine/Cloud SQL/Django syncdb database backend error

I've been successfully able to run syncdb's on my django project for the past weeks, but something must have happened and I'm not sure what.
I always get this error:
No module named google.appengine.ext.django.backends.rdbms.base
I'm not sure why it's just kind of started. Shortly after getting this error, I tried updating my project on app engine and was prompted to download a new app engine launcher SDK, which I have done, but this error still exists. Not sure if maybe something is wrong with my PYTHONPATH?
From your description, this sounds like it could possibly be an issue, not intended behaviour. It sounds crazy, but perhaps something changed with the default Django installation. I suggest you attach a basic reproducing app to a new issue thread in the Public Issue Tracker
You may need to authorize your IP address. If that doesn't work, try using the standard MySQL driver instead of the Google App Engine one as described in our docs.

python requests not working with google app engine

I'm trying to fetch a page using python requests with this code in views.py:
s = requests.Session()
r = s.get("https://www.23andme.com/")
I get the error Exceeded 30 redirects. My app is a Google App Engine Django app. I've gotten this code to work in the python console and a django server on pythonanywhere.com, but for some reason it isn't working on google app engine. What could be causing this? Thanks
Edit: It seems like there is another issue with the Requests module in my app. I have this code to add an email to a mailchimp list:
m = mailchimp.Mailchimp(MAILCHIMP_API_KEY)
list_response = m.lists.list()
but if fails with the error HTTPS/SSL is required
Try installing urllib3 (and other stuff, see below).
See, historically there were tons of issues for requests with google app engine (and see issue #498). Those were mostly resolved with urllib3 support for GAE that came with v1.3. It came out a long time ago (the current release is 1.7), so its probably not the issue, however when you initially install requests, it includes urllib3 in a folder called packages and maybe it doesn't include the entirey of it.
I also tried searching the source code for requests and found this interesting:
# Attempt to enable urllib3's SNI support, if possible
try:
from requests.packages.urllib3.contrib import pyopenssl
pyopenssl.inject_into_urllib3()
except ImportError:
pass
Going deeper, the contrib package includes a pyopenssl.py script which requires:
SSL with SNI-support for Python 2.
This needs the following packages installed:
pyOpenSSL (tested with 0.13)
ndg-httpsclient (tested with 0.3.2)
pyasn1 (tested with 0.1.6)
So, to sum up:
Install urllib3 and other SSL packages mentioned above, then try running that request you're doing again and see if anything has changed. My guess is that this will (at the very least) help with the mailchimp as it's also complaining about SSL/HTTPS issues.
If that doesn't work, try using urllib3 api instead of requests to do the same task and see if that's working. If so, the problem is specifically with the packaged urllib3 that requests is using, which might need some patching.
import urllib3
http = urllib3.PoolManager()
r = http.request('GET', 'https://www.23andme.com/')
Sorry this isn't a definite solution, hopefully one of my suggestions will help. Update me as to the progress I'll try and help out as much as I can
According to this discussion, the issue is with netrc on Google App Engine. I was able to work around the problem by using an older version of Requests (1.2.3 in my case, but others may work too.)
Edit: According to this answer, Requests 2.1.0 should work as well.

Categories