0

I have a Python application that interfaces with a licensed Windows-based program, and I need to provide a web-based interface (using GET/POST requests) for this Python application. I am using IIS as the web server for this interface, because we already have web-based interfaces for other applications working through IIS.

In order to use this licensed Windows-based program, each instance must make a very resource intensive license check call, which then grants the license. Once the instance is done, I must make a very resource intensive license release call, which then releases the license back into the pool. In order to improve the speed of web application, I desire to only make each of these calls once: once when the web server starts (granting the license), and once when the server stops (releasing the license).

Based on my reading, I came to the conclusion that using a FastCGI (this may be wrong) would address the general design need of having a single-thread application within which I would maintain my license grant (as opposed to CGI, which would require the grant and release for every request). My application is very simple, so I selected Bottle as the framework to build my application. And I'm using wfastcgi to use Python WSGI with IIS.

In order to get the start/stop code working, I have created the following web.config and app.py files:

web.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <add key="WSGI_HANDLER" value="app.wsgi_app()"/>
    <add key="PYTHONPATH" value="C:\web\App"/>
    <add key="WSGI_LOG" value="C:\web\App\wfastcgi.log"/>
  </appSettings>
  <system.webServer>
    <handlers>
      <add name="PythonHandler" path="*" verb="*" modules="FastCgiModule" scriptProcessor="C:\python\Python37\python.exe|C:\python\Python37\lib\site-packages\wfastcgi.py" resourceType="Unspecified" requireAccess="Script"/>
    </handlers>
  </system.webServer>
</configuration>

app.py

from bottle import default_app, route
import atexit

import myapp

mylicense = None

def wsgi_app():
    global mylicense
    mylicense = myapp.get_license()

    return default_app()

@route('/app/<page>')
def mypage(page):
    return myapp.get_data(mylicense,page)

@atexit.register
def close_server():
    myapp.release_license(mylicense)

As far as I can tell, this works. However, I feel like my solution is kludgy to the extreme. I would assume that there is some clean way to register startup/shutdown code for WSGI. I also feel like my use of the global mylicense variable is terrible, and that I should be able to pass the license object into my route functions much more cleanly as well.

Can anyone suggest how I can do these better/cleaner/faster/stronger?

Nick2253
  • 329
  • 3
  • 12
  • Keep in mind that Microsoft no longer spends resources on Python on IIS via FastCGI. You might read https://stackoverflow.com/tags/wfastcgi/info for more details. That alone raises more concerns that your own analysis. – Lex Li Dec 23 '19 at 23:51
  • @LexLi Fortunately, the IIS publishing will only need to be supported for about a year, as a backwards-compatibility measure for the previous legacy system. A new pure-python interface has already been rolled out, and other systems are being upgraded to use that. – Nick2253 Dec 23 '19 at 23:59

0 Answers0