IronPython environment setup in NWSGI (IIS7)

Sep 11, 2012 at 12:04 AM
Edited Sep 11, 2012 at 12:05 AM

I'm a linux/python guy coming over into an IIS7 environment, so the answer might be a fundamental windows web/dev lack of understanding on my part.  That said...

I've installed IronPython 2.7.3 and NWSGI 2.1 (both via MSI installers).  I even got pip running, and installed flask, which I would like to use on my web page.

At the command-line, ipy -X:Frames gives me a python environment that will import flask, no problem.  But modifying the example hello.wsgi file that comes with NWSGI, trying to import flask fails with "No module named flask".

Which brings be to the first of several questions:

  • what is the accepted way to configure the environment in NWSGI? (I've tried setting PYTHONPATH and IRONPYTHONPATH, with no apparent effect)

So I gave up on that question for a bit and hacked the environment by directly inserting "c:\program files (x86)\ironpython 2.7\lib\site-packages and it's parent into sys.path, and found that it loaded flask just fine, but failed shortly afterwards with "ArgumentException: Illegal characters in path".

So, the second and third questions then are:

  • Where's that complaint coming from? (I imagined that the spaces in the path could be a problem, but copying the library files to \ipy\lib and changing the references to use the shorter path made no difference)
  • Is the exception I'm looking at even about the content of sys.path?  I reset sys.path back to it's original value after importing flask, and the problem remains.

Here's the Stack Trace:

[ArgumentException: Illegal characters in path.]   Microsoft.Scripting.Interpreter.MethodInfoCallInstruction.InvokeWorker(Object[] args) +7227998   Microsoft.Scripting.Interpreter.MethodInfoCallInstruction.Run(InterpretedFrame frame) +124   Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame) +7562087   Microsoft.Scripting.Interpreter.LightLambda.Run5(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) +428   System.Dynamic.UpdateDelegates.UpdateAndExecute4(CallSite site, T0 arg0, T1 arg1, T2 arg2, T3 arg3) +1097   IronPython.Runtime.Types.FastInitSite`1.CallTarget(CallSite site, CodeContext context, Object inst, T0 arg0) +118   System.Dynamic.UpdateDelegates.UpdateAndExecute3(CallSite site, T0 arg0, T1 arg1, T2 arg2) +1028   IronPython.Runtime.Types.FastTypeSite`1.CallTarget(CallSite site, CodeContext context, Object type, T0 arg0) +115   System.Dynamic.UpdateDelegates.UpdateAndExecute3(CallSite site, T0 arg0, T1 arg1, T2 arg2) +1028   <unnamed>$2.<unnamed>(CodeContext $globalContext, FunctionCode $functionCode) in C:\inetpub\wwwroot\HelloWorld\hello.wsgi:15   IronPython.Compiler.PythonScriptCode.RunWorker(CodeContext ctx) +240   IronPython.Compiler.RuntimeScriptCode.InvokeTarget(Scope scope) +422   NWSGI.WsgiHandler.GetApplicationInfo(String path, String callable) +243   NWSGI.WsgiHandler.GetApplicationCallable() +1103   NWSGI.WsgiHandler.ProcessRequest(HttpContext context) +106   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +625   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +270

Any clues would be greatly appreciated

--jeff

Coordinator
Sep 11, 2012 at 4:57 PM

You can add a pythonPaths element to web.config, like so:

<configuration>
	<configSections>
		<section name="wsgi" type="NWSGI.WsgiSection, NWSGI, Version=2.99.0.0, Culture=neutral, PublicKeyToken=41e64ddc1bf1fc86"/>
	</configSections>
	<wsgi enableExtensions="true">
		<pythonPaths>
			<path path="C:\Users\Jeff\Documents\Repositories\PythonLibs\paste"/>
		</pythonPaths>
		<wsgiEnviron>
			<variable name="CustomKey" value="CustomValue"/>
		</wsgiEnviron>
	</wsgi>
</configuration>
As for the illegal characters, check out this SO answer.

Sep 11, 2012 at 9:18 PM
Edited Sep 11, 2012 at 9:30 PM

Thanks for the quick response.  

I have inserted the following wsgi element into the <configuration> element in the HelloWorld application.  

<wsgi enableExtensions="true" frames="On" tracing="false">
    <pythonPaths>
        <path path="C:/Program Files (x86)/IronPython 2.7/Lib"/>
        <path path="C:/Program Files (x86)/IronPython 2.7/Lib/site-packages"/>
    </pythonPaths>
</wsgi>

That fixes issue #1 (getting flask to import), but leaves me with the "Illegal characters in path" exception.  

I am guessing that perhaps the spaces are a problem--and I see that your example has no spaces--but simply copying the lib directory to /ipy/lib and referencing that does not change the outcome.  I get the same stack trace as above.

For completeness sake, here's the current HelloWorld.wsgi:

import flask
app = flask.Flask(__name__)

@app.route("/")
def hello(): 
    return "Hello World!"

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

Coordinator
Sep 11, 2012 at 10:21 PM

Does it run from the command line? It's quite possible that flask is having issues on IronPython, and it would be good to pinpoint where.

Any chance you could but the whole project somewhere (dropbox or whatever)?

Sep 12, 2012 at 4:21 PM
Edited Sep 13, 2012 at 3:55 PM

Can't say it *works* at the command-line, but it does go further. It writes "* running on http://127.0.0.1:5000", and a deprecation warning about werkzeug.serving.new() no longer taking any arguments. It does service the port, but gets an exception when I visit the page:

Exception happened during processing of request from ('127.0.0.1', 52781)
Traceback (most recent call last):
File "C:\Program Files (x86)\IronPython 2.7\Lib\SocketServer.py", line 284, in _handle_request_noblock
self.process_request(request, client_address)
File "C:\Program Files (x86)\IronPython 2.7\Lib\SocketServer.py", line 310, in process_request
self.finish_request(request, client_address)
File "C:\Program Files (x86)\IronPython 2.7\Lib\SocketServer.py", line 323, in finish_request
self.RequestHandlerClass(request, client_address, self)
TypeError: object.__new__() takes no parameters
----
In any event, it gets much further at the command-line than under IIS, where I still have the "illegal characters" exception I started with.
The entire project right now is really just the modified HelloWorld.wsgi that I posted yesterday, and the default web.config created by IIS, modified as you suggested for passing the python-paths in, so I think the (NWSGI) problem comes down to installation somehow.
--jeff