Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting 500 Internal Server Error when setting up Python and Flask with FastCgiModule on Windows

Anyone able to set up Python with IIS? Been trying to figure it out, but it's not working and it's driving me crazy. I see plenty of examples but I can not get it to work.


Here is my setup


  • Windows 2008R2
  • IIS 7.5 (7.5.7600.16385)
  • wfastcgi.py (2.2.0)
  • Flask (0.10.1)
  • Python (3.5.1)

Path of Python + Flask web app

C:\inetpub\wwwroot

Here are the steps I followed:

  1. Made sure the CGI windows feature was installed.
  2. In the IIS Manager, highlighted web server and in FastCGI Settings added an application with the values:

    Full Path: C:\python35\python.exe
    
    Arguments: C:\inetpub\wwwroot\wfastcgi.py
    
    Environment Variable Collection:
    
      PYTHONPATH: C:\inetpub\wwwroot\
      WSGI_HANDLER: app.app
      WSGI_LOG: C:\logs\app.txt
    
  3. Created a website called MyWebSite pointing to C:\inetpub\wwwroot

  4. In the handler mapping settings for web site, added a module mapping for FastCgiModule:

    Request path: *
    Module: FastCgiModule
    Executable: C:\python35\python.exe|C:\inetpub\wwwroot\wfastcgi.py
    Name: FlaskHandler
    

Simple Python app using Flask found on the web and added it to the web root folder. So at C:\inetpub\wwww there are just 3 files: app.py, web.config, and wfastcgi.py

web.config

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appSettings>
        <add key="PYTHONPATH" value="" />
        <add key="WSGI_HANDLER" value="app.app" />
        <add key="WSGI_RESTART_FILE_REGEX" value="(?i).*\.(py|cnf|config)$" />
    </appSettings>
    <system.webServer>
        <handlers>
            <add name="FlaskHandler" path="*" verb="*" modules="FastCgiModule" scriptProcessor="C:\python35\python.exe|C:\inetpub\wwwroot\wfastcgi.py" resourceType="Unspecified" requireAccess="Script" />
        </handlers>
    </system.webServer>
</configuration>

app.py

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello from FastCGI via IIS!"

if __name__ == "__main__":
    app.run()

applicationHost.config:

global module section:

<add name="FastCgiModule" image="%windir%\System32\inetsrv\iisfcgi.dll" />

module section:

<add name="FastCgiModule" lockItem="true" />

system webserver section:

<section name="fastCgi" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
...
<fastCgi>
    <application fullPath="C:\Python35\python.exe" arguments="C:\inetpub\wwwroot\wfastcgi.py">
        <environmentVariables>
            <environmentVariable name="PYTHONPATH" value="C:\inetpub\wwwroot\" />
            <environmentVariable name="WSGI_HANDLER" value="app.app" />
        <environmentVariable name="WSGI_LOG" value="c:\logs\my_log.txt" />
        </environmentVariables>
    </application>
</fastCgi>

So some reason it does not work as expected.

This is what I am experiencing:

HTTP Error 500.0 - Internal Server Error

C:\python35\python.exe - The FastCGI process exited unexpectedly

The things I've tried.

The scriptProcessor for the handler doesn't seem to be called correctly. It does seem to be called though because when I change the value to something else I get an error:

HTTP Error 500.0 - Internal Server Error
<handler> scriptProcessor could not be found in <fastCGI> application configuration

I thought it was a permissions thing so i made sure NETWORK SERVICE account has Read&Execute. I even gave everyone account Full control. I believe NETWORK SERVICE is the account that needs permission, I think.

I added logging to log out debug information in app.py. I did not get any logging information to be able to write out to log file. I am not sure how wfastcgi.py uses the IIS configurations, even if I added it to the web.config, to set up the location of the log file. Maybe that if the scriptProcessor is actually getting called, it will set it up eventually. But looking at the code it seems to using system environment variable, so I just added WSGI_LOG value as a OS environment variable. Still not logging debug info to the log file.

So I tried, running the python executable with the wfastcgi file as the argument straight on the command line, and it seems to work as expected, entering the wfastcgi while loop and waiting for a request. And it also logs the debug info to the log file.

python.exe c:\inetpub\wwwroot\wfastcgi.py

And when I run the python server it works when I navigate to localhost:8081 in the browser, so I suspect it is a configuration thing.

python app.py runserver 0.0.0.0:8081

So what is going on. I'm out of ideas. Any help would be appreciated.

Thanks! This is driving me nuts.

like image 582
JQ9 Avatar asked Apr 20 '16 12:04

JQ9


People also ask

How do I fix an internal server error on a flask?

Step 1 — Using The Flask Debugger. In this step, you'll create an application that has a few errors and run it without debug mode to see how the application responds. Then you'll run it with debug mode on and use the debugger to troubleshoot application errors.

How do I fix HTTP error 500 IIS?

The error 500.19 is an internal server error often occurring on a server using Microsoft IIS software. It indicates that the configuration data for the page is invalid. To solve the issue, delete the malformed XML element from the Web. config file or from the ApplicationHost.


3 Answers

It was permission issue in my case-

You need to have read and execute permissions on the whole python folder that has python.exe provided required permission by running below command from command prompt at folder location C:\Python36

icacls . /grant "NT AUTHORITY\IUSR:(OI)(CI)(RX)"

steps

2.pip install wfastcgi

3.Enable wfastcgi

4.create myapp.py

5.create web.config

----web.config------

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <add name="FlaskFastCGI" path="*" verb="*" modules="FastCgiModule" 
      scriptProcessor="C:\python\python36\python.exe|C:\python\python36\lib\site-packages\wfastcgi.py"
      resourceType="Unspecified" requireAccess="Script" />
    </handlers>
    <security> 
        <requestFiltering allowDoubleEscaping="true"></requestFiltering> 
    </security> 
  </system.webServer>

  <appSettings>
    <!-- Required settings -->
    <add key="WSGI_HANDLER" value="myapp.app" />
    <add key="PYTHONPATH" value="~/" />
  </appSettings>
</configuration>
like image 157
Atul Raut Avatar answered Sep 19 '22 20:09

Atul Raut


Based on the description, looks like you need some configuration changes on IIS. I have below configuration settings on IIS 7.5 and running Python Flask with FastCgiModule. Here are the steps you can take:

  1. Open IIS Manager. On left pane, Click on the "Server Name". Then on the middle pane double click "FastCGI Settings". You need to click on Actions >> Add from the right pane and have two settings. I have Python 2.7, for your case you have to enter path for Python 3.5

enter image description here

  1. On IIS "Add Web site" to publish the website. For the below screenshot, site name is "pyprojects" and contents are published to physical folder "C:\inetpub\wwwroot\pyprojects"

enter image description here

  1. Select the sitename on left and double click on Handler Mappings. On right pane under Actions, click "Add Module Mapping" and enter

    • Request Path: handler.fcgi
    • Module: FastCgiModule
    • Executable: C:\Python27\python.exe|C:\Python27\Scripts\wfastcgi.py (Python version specific path)
    • Name: Python FastCGI

enter image description here

  1. Again select the sitename on left. Now double click on Application Settings. For existing configurations %ROOTDIR% need to be replaced with the deployment directory for PYTHONPATH and WSGI_ALT_VIRTUALENV_ACTIVATE_THIS.

enter image description here

  1. Browse your website

Hope it will help you and save some time for those who encounters the same issue in future.

like image 8
gmsi Avatar answered Oct 17 '22 16:10

gmsi


I know that this question is some months old, but I think I need to share my solution. It really could help someone stuck in the same situation as I wasn't able to find a single person with this issue addressed. We were two inches close of giving up to an alternative server manager, as I spent no less than a complete day of work around this issue, crawling the entire internet in effort to find an explanation or any clue of a working solution.

It appeared that the input I had the issue with was:

Executable (optional): C:\Python27\python.exe | C:\Python27\Scripts\wfastcgi.py

What did it, was to remove the spacing around the paths in the "Executable (optional)" field. I was deeply assuming that such a field who carries two inputs was kind enough to trim the parsed values so I was doing exactly the same spacing each time. But I was wrong and my resulting configuration was a mapping with gamble dumble path with a whitespace before it and whatever. After removing all the whitespaces, which is very uncomfortable for me to look at, it worked as expected without even having to delete the handler and put it back. This kind of delete it and try again suggestions on IIS forums are polluting developer's mind with false belief that everything needs to be undone, when it really just needs good configurations.

Working input:

Executable (optional): C:\Python27\python.exe|C:\Python27\Scripts\wfastcgi.py

I hope this helps someone, and if a MS developper gets here by any chance, please remove this evil hack of double-input field, since afterwards it's divided in two distinct fields if you go in fastCgi Settings on the global level and it's just misleading to ask two inputs in one field somewhere else. At least trim both values so deep practitioners of input list padding don't crash against this issue ever again! It is extremely puzzling to face an issue where the error says that basically what you just entered is not there.

Update:

It is worth mentioning that in the end, you must expose the application object inside the python module to IIS and nothing more. This may seem obvious to some people, but it's not well documented and it will crash if the python module actually starts the app on his side too. It absolutely needs something like this to have a working dev environment as well:

Python - app.py

# <imports...>
# <routes...>
myApp.secret_key = 'this-is-a-secret-key'

if __name__ == '__main__':
   # start application in python

# IIS will get access to variable `myApp` and start it himself,
# without starting it twice because IIS won't run the script
# as `__main__`. In this scenario `WSGI_HANDLER` will be required
# to have `app.myApp` to reach your application.

Your app inside IIS will do its work. And you will still be able to start it in debug mode with python app.py.

like image 3
Frederik.L Avatar answered Oct 17 '22 16:10

Frederik.L