Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ValueError: set_wakeup_fd only works in main thread on Windows on Python 3.8 with Django 3.0.2 or Flask 2.0.0

When I run my Django Web application with Apache2.4.41 + Python 3.8.1 + Django 3.0.2 + MySQL 8.0.19 on Windows 10 Professional version it throws Value Error at /. set_wakeup_fd only works in main thread.

This issue was a result of regression in Python 3.8 and was fixed in November in later builds of Python. For more details - https://bugs.python.org/issue38563.

Stacktrace of the error is as follows -

Environment:

Request Method: GET
Request URL: http://127.0.0.1/

Django Version: 3.0.2
Python Version: 3.8.1
Installed Applications:
['Analysis.apps.AnalysisConfig',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.humanize']


Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback (most recent call last):
  File "c:\python38\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
    response = get_response(request)
  File "c:\python38\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "c:\python38\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "F:\IndianMarketAnalysis\ISMA\Analysis\views.py", line 8, in home
    date_list = dict(d.date_list())
  File "F:\IndianMarketAnalysis\ISMA\Analysis\models.py", line 7, in date_list
    with connection.cursor() as cursor:
  File "c:\python38\lib\site-packages\django\utils\asyncio.py", line 19, in inner
    event_loop = asyncio.get_event_loop()
  File "c:\python38\lib\asyncio\events.py", line 636, in get_event_loop
    self.set_event_loop(self.new_event_loop())
  File "c:\python38\lib\asyncio\events.py", line 656, in new_event_loop
    return self._loop_factory()
  File "c:\python38\lib\asyncio\windows_events.py", line 310, in __init__
    super().__init__(proactor)
  File "c:\python38\lib\asyncio\proactor_events.py", line 632, in __init__
    signal.set_wakeup_fd(self._csock.fileno())

Exception Type: ValueError at /
Exception Value: set_wakeup_fd only works in main thread

Further, this application works very well on local Development Environment using - python manage.py runserver.

Please suggest the next steps to move forward.


The same issue happens on Flask 2.0.0 (pip install --pre flask):

@app.get('/')
async def say_hello():
    return {'message': 'Hello!'}
> flask run
Traceback (most recent call last):
  File "c:\users\greyli\...\venv\lib\site-packages\flask\app.py", line 1953, in wsgi_app
    response = self.full_dispatch_request()
  File "c:\users\greyli\...\venv\lib\site-packages\flask\app.py", line 1454, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "c:\users\greyli\...\venv\lib\site-packages\flask\app.py", line 1452, in full_dispatch_request
    rv = self.dispatch_request()
  File "c:\users\greyli\...\app.py", line 318, in dispatch_request
    return self.view_functions[rule.endpoint](*req.view_args.values())
  File "c:\users\greyli\...\venv\lib\site-packages\flask\helpers.py", line 781, in outer
    return async_to_sync(inner)(*args, **kwargs)
  File "c:\users\...\venv\lib\site-packages\asgiref\sync.py", line 203, in __call__
    loop_future.result()
  File "C:\Users\greyli\.pyenv\pyenv-win\versions\3.8.0\lib\concurrent\futures\_base.py", line 432, in result
    return self.__get_result()
  File "C:\Users\greyli\.pyenv\pyenv-win\versions\3.8.0\lib\concurrent\futures\_base.py", line 388, in __get_result
    raise self._exception
  File "C:\Users\greyli\.pyenv\pyenv-win\versions\3.8.0\lib\concurrent\futures\thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "c:\users\greyli\...\venv\lib\site-packages\asgiref\sync.py", line 256, in _run_event_loop
    loop.close()
  File "C:\Users\greyli\.pyenv\pyenv-win\versions\3.8.0\lib\asyncio\proactor_events.py", line 679, in 
close
    signal.set_wakeup_fd(-1)
ValueError: set_wakeup_fd only works in main thread
like image 991
Siddharth Agarwal Avatar asked Feb 23 '20 04:02

Siddharth Agarwal


3 Answers

I have exactly the same bug. I opened the issue.

If you want to stay on the current Python version I have found the temporal solution which is to add following lines to asgiref\__init__.py (as it was suggested in issue):

if sys.platform == "win32" and sys.version_info >= (3, 8, 0):
    asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
like image 98
Denis B Avatar answered Nov 05 '22 07:11

Denis B


Not only Django, but you will also meet this error with Flask since Flask 2.0.0 uses asgiref to support async.

This bug was fixed in Python 3.9, so there are two solutions:

  • Upgrade to Python 3.9
  • Add the temp fix as follows (based on Dennis B's answer) to your entry script, for example, Flask's app.py or Django's manager.py:
# top of the file
import sys, asyncio

if sys.platform == "win32" and (3, 8, 0) <= sys.version_info < (3, 9, 0):
    asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
like image 2
Grey Li Avatar answered Nov 05 '22 06:11

Grey Li


upgraded to python 3.8.2 , worked fine on my windows server.

release notes https://docs.python.org/release/3.8.2/whatsnew/changelog.html#python-3-8-2-final

issue bpo-34679: fixed asynci.ProactorEventLoop.close() now only calls signal.set_wakeup_fd() in the main thread.

like image 1
Marcon Avatar answered Nov 05 '22 06:11

Marcon