Discussion on WSGI and possible way to make node.js server WSGI compliant
The beauty of Python web frameworks is that they are WSGI compliant and there are many servers that are also WSGI compliant like Gunicorn
, uWSGI
,mod_wsgi
etc. The full list can be found here.
This makes the whole system modular, a server that can talk WSGI can be replaced with any other WSGI-compatible servers. Similarly, a web framework that understands WSGI can be replaced with any other framework.
In the above diagram, you can see, you can replace any of the servers and any of the web frameworks.
So what is WSGI?
As described in PEP 333(3) “This PEP, therefore, proposes a simple and universal interface between web servers and web applications or frameworks: the Python Web Server Gateway Interface (WSGI).”
So, WSGI is noting but a set of protocols that a server and a webframework should follow.
Python currently boasts a wide variety of web application frameworks, such as Zope, Quixote, Webware, SkunkWeb, PSO, and Twisted Web — to name just a few [1]. This wide variety of choices can be a problem for new Python users, because generally speaking, their choice of web framework will limit their choice of usable web servers, and vice versa.
By contrast, although Java has just as many web application frameworks available, Java’s “servlet” API makes it possible for applications written with any Java web application framework to run in any web server that supports the servlet API.
for Web framework
For a web framework to be WSGI compliant it should have a callable object (a function or a class implementing __call__
) which should accept environ
— a python dictionary in which the request is stored in a parsed format in terms of headers and body.
This is a sample environ
dictionary passed by Gunicorn server. Any web framework should accept this dictionary and use it. Find the list of variables here.
It should accept a callable function that is used to set the headers. So the pseudo code for any web framework should look like —
for Servers
For a server to be WSGI compliant, it should send environment
variable to the framework and expose a function called start_response
or any name, which will be used to set headers.
Both of them is clearly described PEP 333(3).
Now that we know how WSGI works, if we can somehow make node.js server somehow WSGI compliant, then we can deploy Flask, Django on top of it.
This is a simple approach where I tried only with GET request i.e. I am not processing request body. I used PyNode
module to execute python code from node.js application. Read it here.
The app
object in Flask is the callable that we discussed. If we pass it (env, start_response) it will process it and send us the response.
In this dummy example, I created two route, one simple inde.html
page that is rendered via Flask app and one route to show that we can also parse query parameters.
There are surely many drawbacks like
- Every time you request a new instance of python created which means creating an all-new python interpreter every time. This can be solved by running for ex: 4–5 instances which do not exit like REPL and distribute the incoming request load in round-robin or any other way among those processed.
- I have not processed the incoming body. Also for big files, proper buffer & streaming should be implemented.
My objective was not to implement these but just to check the possibility of whether I can deploy Flask (or any) app on node.js or not, and it worked!
Find the GitHub link for this project here.