skip to Main Content

I have a VPS Hosting in cPanel, and a Flask-App.
I followed the instructions of How to install WSGI Application in cPanel.

Everything is working fine, when I run the application using the terminal, but when I open the App URL, it shows the following error:

Traceback (most recent call last):
  File "/opt/cpanel/ea-ruby24/root/usr/share/passenger/helper-scripts/wsgi-loader.py", line 369, in <module>
    app_module = load_app()
  File "/opt/cpanel/ea-ruby24/root/usr/share/passenger/helper-scripts/wsgi-loader.py", line 76, in load_app
    return imp.load_source('passenger_wsgi', startup_file)
  File "/home/qsemh/Maidan/passenger_wsgi.py", line 8, in <module>
    wsgi = imp.load_source('wsgi', 'wsgi.py')
  File "wsgi.py", line 1, in <module>
    from flaskr import create_app
  File "/home/qsemh/Maidan/flaskr/__init__.py", line 133
    print(f"Validate {len(users)} Users At {current_time}")
                                                         ^
SyntaxError: invalid syntax

So I’ve decided to create a simpler app in order to detect the issue, the app is as following :

passenger_wsgi.py

#!/usr/bin/env python3
import sys
from flask import Flask

application = Flask(__name__)

application.route("/")
def index():
    return sys.version

When I run this simple Application Using the URL it shows the following as a respond :

2.7.5 (default, Apr 2 2020, 13:16:51) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]

even though I’ve used the shebang #!/usr/bin/env python3 at the start of the file, and when I run it using the terminal, it works as if it using python3.

I’ve tried changing the shebang to the following formats :

#!/usr/bin/python3

#!/usr/bin/env 'python3'

but they gave the same result.

What is the problem here, and How can I solve it?

2

Answers


  1. Chosen as BEST ANSWER

    I've found the Correct approach to solve this issue;

    Basically, I only needed to add the following lines at the beginning of my passenger_wsgi.py file :

    import os
    INTERP = "/usr/bin/python3"
    if sys.executable != INTERP: os.execl(INTERP, INTERP, *sys.argv)
    

    so the final result would be :

    passenger_wsgi.py

    
    #!/usr/bin/env python3
    import sys
    import os
    
    # Solution
    INTERP = "/usr/bin/python3"
    if sys.executable != INTERP: os.execl(INTERP, INTERP, *sys.argv)
    
    from flask import Flask
    
    application = Flask(__name__)
    
    application.route("/")
    def index():
        return sys.version
    
    

    and the respond is correctly as I intended in the first place:

    3.6.8 (default, Apr  2 2020, 13:34:55) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
    

  2. This answer might be for some cPanel users. My cPanel is using passenger and wsgi, and even though my cPanel Python application is set to use python 3.9. it was running 2.7.5. Worse, it set all the 2.7 folders in the path.

    So I ended up with this helper script called from
    passenger_wsgi.py. I’m moved all the code out of this file into an import because this file may get blown away and re-created in some cases. It’s not safe to rely on code in this file surviving. It’s an auto generated file.

    Put set_python_environment.py file in the same directory as passenger_wsgi.py

    set_python_environment.py

    # -*- coding: UTF-8 -*-
    
    # insert these lines into passenger_wsgi.py if that file is rebuilt:
    # import set_python_environment
    # set_python_environment.upgrade_python()
    
    import sys
    import os
    
    def upgrade_python():
        try:
                python_interpreter = "/home/username/virtualenv/YourApplicationPath/3.9/bin/python3.9_bin"
            if sys.executable != python_interpreter: 
                print('switching from ' + sys.version + ' to ' + python_interpreter + '...')
        
                print('directory: ' + os.path.dirname(__file__))
                print('file: ' + __file__)
                print('arg 0: ' + sys.argv[0])
        
                # rebuild the env path variable
                print('old system path:n' + "n".join(str(x) for x in sys.path))
                print('n')
                for x in sys.path:
                    sys.path.remove(x)
        
                sys.path.append('/opt/cpanel/ea-ruby24/root/usr/share/passenger/helper-scripts')
                # App 3956 output: /usr/lib/python2.7/site-packages/pyzor-1.0.0-py2.7.egg
                # App 3956 output: /usr/lib64/python27.zip
                # App 3956 output: /usr/lib64/python2.7
                sys.path.append('/home/username/virtualenv/YourApplicationPath/3.9/lib64/python3.9')
                # App 3956 output: /usr/lib64/python2.7/plat-linux2
                # App 3956 output: /usr/lib64/python2.7/lib-tk
                # App 3956 output: /usr/lib64/python2.7/lib-old
                # App 3956 output: /usr/lib64/python2.7/lib-dynload
                # App 3956 output: /home/username/.local/lib/python2.7/site-packages
                # App 3956 output: /usr/lib64/python2.7/site-packages
                sys.path.append('/home/username/virtualenv/YourApplicationPath/3.9/lib64/python3.9/site-packages')
                # App 3956 output: /usr/lib64/python2.7/site-packages/gtk-2.0
                # App 3956 output: /usr/lib/python2.7/site-packages
                sys.path.append('/home/username/virtualenv/YourApplicationPath/3.9/lib/python3.9/site-packages')
                sys.path.append('/home/username/virtualenv/YourApplicationPath/3.9/bin')
                print('new system path:n' + "n".join(str(x) for x in sys.path))
                print('n')
                
                os.execl(python_interpreter, python_interpreter, *sys.argv)
            else:
                print('...continuing with ' + sys.executable)
    
        except Exception as e:
            print(str(e))
            
    

    Modified passenger_wsgi.py

    # -*- coding: UTF-8 -*-
    
    import sys
    import os
    import imp
    
    import set_python_environment
    set_python_environment.upgrade_python()
    
    sys.path.insert(0, os.path.dirname(__file__))
    wsgi = imp.load_source('wsgi', 'app.py')
    application = wsgi.app
            
    

    In order to get the right path, I typed whereis python in the ssh environment after running the source command given on the python application page, to find the location of all the python versions, and the one ending in bin turned out to be the one which actually works.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search