I'm writing a web application in Python using web.py, spawn_fcgi and nginx.
Let's say that I have this configuration block in nginx:
location / {
include fastcgi.conf;
fastcgi_pass 127.0.0.1:9001;
}
If I then access, say, http://example.com/api/test
, then the FastCGI application receives /api/test
as its request location. The web.py framework will use this location when determining which class to execute. For example:
urls = ( "/api/.*", myClass )
The problem comes if I need to place this script in another location on the website. For example:
location /app {
include fastcgi.conf;
fastcgi_pass 127.0.0.1:9001;
}
Now, when I access http://example.com/app/api/test
, the FastCGI application gets /app/api/test
as its location.
It could of course be located just about anywhere: http://example.com/sloppy_admin/My%20Web%20Pages/app/api/test
for example. :-)
I would like the app to be relocatable, as installing it on other servers may necessitate this (e.g. it has to share the server with something else). It also seems a bit hardheaded to insist that every server place it in the same "virtual subdirectory".
Right now, my workaround has been to do something like this:
URL_PREFIX = "/app" # the same as the nginx location parameter
urls = ( URL_PREFIX+"/api/.*",myClass )
The problems here are 1) this means that the script still needs to be edited per site (not necessarily horrible but at the least inconvenient) and 2) that the URL_PREFIX
variable has to be globally accessible to the entire collection of scripts - because for example any class or function may need to access the location but it would need to not include the prefix.
I'm using custom python packages (e.g. directories containing init.py scripts) to simplify managing the different scripts that make up the app, but the problem is passing that URL_PREFIX parameter around. Example:
app.py:
from myapp import appclass
import web
URL_PREFIX = "/app" # the same as the nginx location parameter
urls = ( URL_PREFIX+"/api/.*",appclass.myClass )
app = web.application(urls,globals())
if __name__ == "__main__":
web.wsgi.runwsgi = lambda func, addr=None: web.wsgi.runfcgi(func, addr)
app.run()
myapp/appclass.py:
class myClass:
def GET(self):
global URL_PREFIX # this does not work!
return URL_PREFIX
Is there either an nginx parameter to cause the path sent to FastCGI to be relative to the location, or a more elegant way to handle this in web.py?
The fastcgi.conf
file should have all the configuration options you need. You might also want to look at the fastcgi_split_path_info
directive.