Flask-socketio: Monkey-patching ssl after ssl has already been imported may lead to errors

Created on 10 Apr 2019  Β·  8Comments  Β·  Source: miguelgrinberg/Flask-SocketIO

I am using Python-3.7 and Flask-SocketIO-3.3.2 on Ubuntu 19.04 (beta). I got the following message error while trying to execute python3.7 app.py:

MonkeyPatchWarning: Monkey-patching ssl after ssl has already been imported may lead to errors, including RecursionError on Python 3.6. It may also silently lead to incorrect behaviour on Python 3.7. Please monkey-patch earlier. See https://github.com/gevent/gevent/issues/1016.

In order to run the example app.py without any error message (on standard error) I did two things:

  1. Added two lines as first statements in file app.py to avoid gevent issue #1016

    #!/usr/bin/env python
    
    import gevent.monkey
    gevent.monkey.patch_all()
    
    from threading import Lock
    from flask import Flask, render_template, session, request
    from flask_socketio import SocketIO, emit, join_room, leave_room, \
        close_room, rooms, disconnect
    
  2. Compared to requirements.txt I have updated the module six==1.12.0 and installed module gevent.

Using pipenv I provide below more details on dependencies:

$ python3.7 -m pipenv graph
Flask-Login==0.4.1
  - Flask [required: Any, installed: 0.12.4]
    - click [required: >=2.0, installed: 7.0]
    - itsdangerous [required: >=0.21, installed: 0.24]
    - Jinja2 [required: >=2.4, installed: 2.7.3]
      - markupsafe [required: Any, installed: 0.23]
    - Werkzeug [required: >=0.7, installed: 0.12.2]
Flask-Session==0.3.1
  - Flask [required: >=0.8, installed: 0.12.4]
    - click [required: >=2.0, installed: 7.0]
    - itsdangerous [required: >=0.21, installed: 0.24]
    - Jinja2 [required: >=2.4, installed: 2.7.3]
      - markupsafe [required: Any, installed: 0.23]
    - Werkzeug [required: >=0.7, installed: 0.12.2]
Flask-SocketIO==3.3.2
  - Flask [required: >=0.9, installed: 0.12.4]
    - click [required: >=2.0, installed: 7.0]
    - itsdangerous [required: >=0.21, installed: 0.24]
    - Jinja2 [required: >=2.4, installed: 2.7.3]
      - markupsafe [required: Any, installed: 0.23]
    - Werkzeug [required: >=0.7, installed: 0.12.2]
  - python-socketio [required: >=2.1.0,<4, installed: 3.1.2]
    - python-engineio [required: >=3.2.0, installed: 3.5.1]
      - six [required: >=1.9.0, installed: 1.12.0]
    - six [required: >=1.9.0, installed: 1.12.0]
gevent==1.4.0
  - greenlet [required: >=0.4.14, installed: 0.4.15]
$ python3.7 -m pipenv run pip freeze
Click==7.0
Flask==0.12.4
Flask-Login==0.4.1
Flask-Session==0.3.1
Flask-SocketIO==3.3.2
gevent==1.4.0
greenlet==0.4.15
itsdangerous==0.24
Jinja2==2.7.3
MarkupSafe==0.23
python-engineio==3.5.1
python-socketio==3.1.2
six==1.12.0
Werkzeug==0.12.2
$ cat Pipfile
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]
flask = "~=0.12.2"
flask-login = "~=0.4.0"
flask-session = "~=0.3.1"
flask-socketio = "~=3.3.2"
itsdangerous = "~=0.24"
jinja2 = "~=2.7.3"
markupsafe = "~=0.23"
werkzeug = "~=0.12.2"
gevent = "*"

[requires]
python_version = "3.7"
question

Most helpful comment

the solution to this problem is to intall pyopenssl library

All 8 comments

Did you actually see the infinite recursion error? Because that happens when SSL is used. This application does not use SSL.

Sorry, you are right.
I have removed my added lines about gevent.monkey and it works fine with the following:

$ cat Pipfile
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]
flask = "~=0.12.2"
flask-login = "~=0.4.0"
flask-session = "~=0.3.1"
flask-socketio = "~=3.3.2"
itsdangerous = "~=0.24"
jinja2 = "~=2.7.3"
markupsafe = "~=0.23"
werkzeug = "~=0.12.2"
# gevent = "*"
# gevent-websocket = "*"
# wsaccel = "*"
# ujson = "*"

[requires]
python_version = "3.7"
$ python3.7 -m pipenv run python3.7 app.py
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 266-034-648

Played with localhost:5000 web page producing following output, then Ctrl + C.

Client disconnected 84c7130fcaed44f1a8bcb9171afe2762
^CKeyboardInterrupt
KeyboardInterrupt
2019-04-11T09:02:22Z
2019-04-11T09:02:22Z

I did a complete test by first resetting my virtualenv:

$ python3.7 -m pipenv --rm
Removing virtualenv (/home/olibre/.local/share/virtualenvs/example-wxZDQ4eh)…
$ python3.7 -m pipenv --python 3.7
Creating a virtualenv for this project…
Pipfile: /home/olibre/dev/Flask-SocketIO/example/Pipfile
Using /usr/bin/python3.7m (3.7.3) to create virtualenv…
β ¦ Creating virtual environment...Using base prefix '/usr'
New python executable in /home/olibre/.local/share/virtualenvs/example-wxZDQ4eh/bin/python3.7m
Also creating executable in /home/olibre/.local/share/virtualenvs/example-wxZDQ4eh/bin/python
Installing setuptools, pip, wheel...
done.
Running virtualenv with interpreter /usr/bin/python3.7m
βœ” Successfully created virtual environment!
Virtualenv location: /home/olibre/.local/share/virtualenvs/example-wxZDQ4eh
$ python3.7 -m pipenv install
Installing dependencies from Pipfile.lock (e5ae1f)…
  🐍   β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰ 12/12 β€” 00:00:01
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
$ python3.7 -m pipenv graph
Flask-Login==0.4.1
  - Flask [required: Any, installed: 0.12.4]
    - click [required: >=2.0, installed: 7.0]
    - itsdangerous [required: >=0.21, installed: 0.24]
    - Jinja2 [required: >=2.4, installed: 2.7.3]
      - markupsafe [required: Any, installed: 0.23]
    - Werkzeug [required: >=0.7, installed: 0.12.2]
Flask-Session==0.3.1
  - Flask [required: >=0.8, installed: 0.12.4]
    - click [required: >=2.0, installed: 7.0]
    - itsdangerous [required: >=0.21, installed: 0.24]
    - Jinja2 [required: >=2.4, installed: 2.7.3]
      - markupsafe [required: Any, installed: 0.23]
    - Werkzeug [required: >=0.7, installed: 0.12.2]
Flask-SocketIO==3.3.2
  - Flask [required: >=0.9, installed: 0.12.4]
    - click [required: >=2.0, installed: 7.0]
    - itsdangerous [required: >=0.21, installed: 0.24]
    - Jinja2 [required: >=2.4, installed: 2.7.3]
      - markupsafe [required: Any, installed: 0.23]
    - Werkzeug [required: >=0.7, installed: 0.12.2]
  - python-socketio [required: >=2.1.0,<4, installed: 3.1.2]
    - python-engineio [required: >=3.2.0, installed: 3.5.1]
      - six [required: >=1.9.0, installed: 1.9.0]
    - six [required: >=1.9.0, installed: 1.9.0]

See below the warning about the missing module eventlet or modules gevent and gevent-websocket:

$ python3.7 -m pipenv run python3.7 app.py
WebSocket transport not available. Install eventlet or gevent and gevent-websocket for improved performance.
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with stat
WebSocket transport not available. Install eventlet or gevent and gevent-websocket for improved performance.
 * Debugger is active!
 * Debugger PIN: 235-710-757
127.0.0.1 - - [11/Apr/2019 11:20:57] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [11/Apr/2019 11:20:57] "GET /favicon.ico HTTP/1.1" 404 -
127.0.0.1 - - [11/Apr/2019 11:20:57] "GET /socket.io/?EIO=3&transport=polling&t=1554974457260-0 HTTP/1.1" 200 -
127.0.0.1 - - [11/Apr/2019 11:20:57] "POST /socket.io/?EIO=3&transport=polling&t=1554974457274-1&sid=086c507acedd4030afdc265b5fc2ba55 HTTP/1.1" 200 -
127.0.0.1 - - [11/Apr/2019 11:20:57] "GET /socket.io/?EIO=3&transport=polling&t=1554974457276-2&sid=086c507acedd4030afdc265b5fc2ba55 HTTP/1.1" 200 -
[...]
127.0.0.1 - - [11/Apr/2019 11:21:11] "POST /socket.io/?EIO=3&transport=polling&t=1554974471403-44&sid=086c507acedd4030afdc265b5fc2ba55 HTTP/1.1" 200 -
127.0.0.1 - - [11/Apr/2019 11:21:11] "GET /socket.io/?EIO=3&transport=polling&t=1554974471394-43&sid=086c507acedd4030afdc265b5fc2ba55 HTTP/1.1" 200 -
^C

Adding dependencies gevent and gevent-websocket:

$ vim Pipfile
$  python3.7 -m pipenv install
Pipfile.lock (f7a84d) out of date, updating to (e5ae1f)…
Locking [dev-packages] dependencies…
Locking [packages] dependencies…
βœ” Success!
Updated Pipfile.lock (f7a84d)!
Installing dependencies from Pipfile.lock (f7a84d)…
  🐍   β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰ 15/15 β€” 00:00:01
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
$ python3.7 -m pipenv graph
Flask-Login==0.4.1
  - Flask [required: Any, installed: 0.12.4]
    - click [required: >=2.0, installed: 7.0]
    - itsdangerous [required: >=0.21, installed: 0.24]
    - Jinja2 [required: >=2.4, installed: 2.7.3]
      - markupsafe [required: Any, installed: 0.23]
    - Werkzeug [required: >=0.7, installed: 0.12.2]
Flask-Session==0.3.1
  - Flask [required: >=0.8, installed: 0.12.4]
    - click [required: >=2.0, installed: 7.0]
    - itsdangerous [required: >=0.21, installed: 0.24]
    - Jinja2 [required: >=2.4, installed: 2.7.3]
      - markupsafe [required: Any, installed: 0.23]
    - Werkzeug [required: >=0.7, installed: 0.12.2]
Flask-SocketIO==3.3.2
  - Flask [required: >=0.9, installed: 0.12.4]
    - click [required: >=2.0, installed: 7.0]
    - itsdangerous [required: >=0.21, installed: 0.24]
    - Jinja2 [required: >=2.4, installed: 2.7.3]
      - markupsafe [required: Any, installed: 0.23]
    - Werkzeug [required: >=0.7, installed: 0.12.2]
  - python-socketio [required: >=2.1.0,<4, installed: 3.1.2]
    - python-engineio [required: >=3.2.0, installed: 3.5.1]
      - six [required: >=1.9.0, installed: 1.9.0]
    - six [required: >=1.9.0, installed: 1.9.0]
gevent-websocket==0.10.1
  - gevent [required: Any, installed: 1.4.0]
    - greenlet [required: >=0.4.14, installed: 0.4.15]
$ python3.7 -m pipenv run python3.7 app.py
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 266-034-648
Client disconnected 274b91a2f487433c8396a0dd72512cfd
^CKeyboardInterrupt
KeyboardInterrupt
2019-04-11T09:32:56Z
2019-04-11T09:32:56Z

@olibre can you clarify what is the issue that you are reporting? Is it the warning about eventlet/gevent missing? Because that is done on purpose, this package supports several web servers. The base installation uses the Flask development web server, you can then install a better one for production, and you have a lot of choices there: eventlet, gevent, gunicorn, uwsgi.

Hi

TL DR: There is no issue, it works fine, I close the issue, thank you for your work :+1:

I had initially opened this issue because of the following error message:

Monkey-patching ssl after ssl has already been imported may lead to errors

After your first reply, I had re-checked and saw I was wrong. I said the following and closed the issue.

Sorry, you are right.
I have removed my added lines about gevent.monkey and it works fine

Finally I continued my testing and shared my results with you...
... but when submitting my comment I clicked on the wrong button and reopened the issue by mistake :-/

Cheers ;-)

the solution to this problem is to intall pyopenssl library

Thank you @PasserByYao πŸ‘

Thank you @PasserByYao

Was this page helpful?
0 / 5 - 0 ratings