0

I am trying to serve Flask app from IIS Web Application under Default Web Site, but am not able to get it working. Here are the details:

OS: Windows Server 2016 DataCenter Edition
IIS: Installed with all options including CGI
IIS Rewrite Module: Version 2 installed

Steps I've taken:

  1. Install IIS with all components (with CGI)
  2. Install Python 2.7.14
  3. Add Python in the PATH variable
  4. pip install wfastcgi
  5. wfastcgi-enable
  6. pip install flask
  7. iisreset
  8. Create Directory: C:\inetpub\wwwroot\flask-demo
  9. Click Convert to Application in IIS for above directory.
  10. Create C:\inetpub\wwwroot\flask-demo\myapp.py with following content:
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'

if __name__ == "__main__":
    app.run()
  1. Create C:\inetpub\wwwroot\flask-demo\web.config with following content:
<configuration>
  <system.webServer>
    <handlers>
      <remove name="Python FastCGI" />
      <add name="Python FastCGI"
           path="*"
           verb="*"
           modules="FastCgiModule"
           scriptProcessor="C:\Python27\python.exe|C:\Python27\Lib\site-packages\wfastcgi.pyc"
           resourceType="Unspecified"
           requireAccess="Script" />
    </handlers>
   <rewrite>
 <rules>
 <rule name="asset-url-rewrite" stopProcessing="true">
 <match url="static" />
 <conditions>
 </conditions>
 <action type="Rewrite" url="flask-demo/{R:0}" />
 </rule>
 <rule name="app-url-rewrite" stopProcessing="true">
 <match url="[a-zA-Z]+" />
 <conditions>
 </conditions>
 <action type="Rewrite" url="flask-demo/" />
 </rule>
 </rules>
 </rewrite>
  </system.webServer>
  <appSettings>
    <add key="WSGI_HANDLER" value="myapp.app" />
    <add key="PYTHONPATH" value="C:\inetpub\wwwroot\flask-demo" />
  </appSettings>
</configuration>

Problem

When I try to access page as http://localhost/flask-demo, am getting 404. But if I change 2nd line in myapp.py from @app.route('/') to @app.route('/flask-demo') where flask-demo is the name of the IIS web application where Python files are placed, it works.

I wish to serve Python web page without writing flask-demo / name of IIS web application where Python flask app is placed. Am not able to do that.

I tried to use app.config['APPLICATION_ROOT'] = '/flask-demo', but it didn't worked.

What is the best way to get this working? Followed article https://medium.com/@bilalbayasut/deploying-python-web-app-flask-in-windows-server-iis-using-fastcgi-6c1873ae0ad8 but it didn't helped.

Sanket Tarun Shah
  • 637
  • 10
  • 28
  • You can't connect more than one service to the same port! Please check the error logs. Please also check network or loopback access permissions. – dsgdfg Mar 09 '18 at 08:53
  • It's IIS hosting and there should not be any problem for serving multiple web applications from same port. It should work (and it works well for ASP.NET applications). It's something that is wrong in my code / approach above where I need help. – Sanket Tarun Shah Mar 09 '18 at 08:59
  • Which port does flask broadcast? `It's IIS hosting and there should not be any problem for serving multiple web applications` totally wrong idea(without any rule), ! Do not confuse CGI and SERVER(service) terms. If `ISS` service is run, you can't listen `80` port ! – dsgdfg Mar 09 '18 at 09:09
  • There is no broadcast. If you medium.com link - it says this should work. In my case, IIS is talking to Python via Fast CGI. – Sanket Tarun Shah Mar 09 '18 at 09:13
  • 1- Try a CGI script without aplication 2-Check file permissions 3-Check the application to be triggered(python, what is python ?) 4- The ISS cannot follow the system path, it requires special authorization to get out of the given directories. 5-Main broadcast service address forwarding (ISS processed address block >> CGI Script) No idea which is missed. – dsgdfg Mar 12 '18 at 06:48

2 Answers2

0

The URL includes flask-demo so it is normal that Flask see it, and it use it.

There are some workarounds, e.g.:

Add a prefix to all Flask routes (on this site).

In general: what to you want? The URL is much more important than the underling technology (and URL should be stable, also when you change implementation). I recomment not to have flask-demo in the URL (and NEVER something with test and demo, anyway, demo are made to remain forever, unfortunately). So I would modify ISS so that it will redirect all dynamic pages to flask-demo.

Giacomo Catenazzi
  • 8,519
  • 2
  • 24
  • 32
  • I did tried that solution and it is also not working. Have mentioned that in my original question too. `APPLICATION_ROOT` is simply ignored. – Sanket Tarun Shah Mar 09 '18 at 08:57
  • Read the link again. It say that `APPLICATION_ROOT` handle the cockies and so on. Your WSGI (and similar) should handle the URL, They should remove the route prefix (for URL). So this part (and configuration) is on IIS side. – Giacomo Catenazzi Mar 09 '18 at 09:05
  • Apparently, I've tried that too. It didn't worked. Just enabled correct visualization for my web.config in the question. Any pointers on the mistake? – Sanket Tarun Shah Mar 09 '18 at 09:10
  • https://stackoverflow.com/questions/47253/how-do-you-set-up-a-python-wsgi-server-under-iis – Giacomo Catenazzi Mar 09 '18 at 09:13
  • Not of any help. Tried the original extension, tested and reverted back to Fast CGI (wfastcgi). – Sanket Tarun Shah Mar 09 '18 at 09:22
0

After multiple tries, I've reached out to following solution.

Solution Caveat

This assumes that Python application is hosted only at first depth level of IIS website. Solution below does not support 2nd level dept.

New myapp.py

from flask import Flask
import os
app = Flask(__name__)

ROOT_PREFIX = '/' + os.path.dirname(os.path.realpath(__file__)).rsplit('\\', 1)[-1]

@app.route(ROOT_PREFIX  + '/')
def hello_world():
    return 'Hello, World!'

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

New web.config

<configuration>
    <system.webServer>
        <modules>
            <remove name="WebDAVModule" />
        </modules>
        <handlers>
            <remove name="WebDAV" />
            <add name="Python FastCGI"
                        path="*"
                        verb="*"
                        modules="FastCgiModule"
                        scriptProcessor="C:\Python27\python.exe|C:\Python27\Lib\site-packages\wfastcgi.pyc"
                        resourceType="Unspecified"
                        requireAccess="Script" />
        </handlers>
    </system.webServer>
    <appSettings>
        <add key="WSGI_HANDLER" value="myapp.app" />
        <add key="PYTHONPATH" value="C:\inetpub\wwwroot\flask-demo" />
    </appSettings>
</configuration>
Sanket Tarun Shah
  • 637
  • 10
  • 28