Friday, May 6, 2011

mod_python publisher and pretty URLs

Hi all,

I am new to Python (I am getting out of PHP because of how increasingly broken it is), and I am racing through porting my old code. One thing:

I have a file /foo.py with functions index() and bar(), so, with the publisher I can access http://domain/foo/bar and http://domain/foo as the documentation suggests.

How can I have it such that I can do:

http://domain/foo/bar/a1/a2/a3/an/...

Such that the publisher launches bar() and then I can access the URL to obtain /a1/a2/... All I get is Forbidden :) (I don't want to use mod_rewrite on everything)

Oh, im on 2.5.2 Thanks in advance

UPDATE: The ideal solution would be for the publisher to launch the furthest-right resolution in the URL it can, and simply make a1/a2/a3.. accessible through the apache module. Maybe a combination of an apache directive and publisher?

SOLVED (ish): The answer of the magic call() method and so on is juicy! Although I think I will modify the publisher or write my own to inspect objects in a similar way using furthest-right matching, then allowing the furthest-right to access the URL using apache module. Thanks all!

From stackoverflow
  • You would have to have an object bar.a1.a2.a3.an defined within your foo.py module. Basically, the publisher handler replaces the slashes in the URL with dots, and tries to find some Python object with that name.

    You would have to have an object bar.a1.a2.a3.an defined within your foo.py module. Basically, the publisher handler replaces the slashes in the URL with dots, and tries to find some Python object with that name.

    Here's something wacky you could try: in foo.py:

    class _barclass(object):
        def __init__(self, parent, name):
            if parent and name:
                self.path = parent.path + '/' + name
                setattr(parent, name, self)
            else:
                self.path = ''
        def __getattr__(self, name):
            return _barclass(self, name)
        def __call__(self):
            # do your processing here
            # url path is contained in self.path
    
    bar = _barclass(None, None)
    

    Although this is kind of straining the bounds of what the publisher is meant to do - you might be better off writing your own handlers from scratch. (Or using something like Django.)

    David Zaslavsky : You didn't wait for my edit ;-)
    David Zaslavsky : I know what you mean, Python has a lot of tricks that take some time to get used to. (I've been at it for a year and a half now.)
    David Zaslavsky : Well, stick with it! I also converted my website from PHP to Python, back in December, and I've never regretted it.
  • I believe this is beyond the capabilities of the publishing algorithm, as far as I know. (The documentation certainly doesn't mention it.) You could write your own mod_python handler (example here) that extends the publishing algorithm to do so, however.

    A better solution would be to look into mod_wsgi and build your web application as an WSGI application instead. You would benefit from the shelves and shelves of WSGI middleware, but in particular you'd be able to use routing software like Routes, which are specifically designed to handle these cases where object publishing isn't strong enough. But I don't know your deadlines, so this may or may not be feasible.

    David Zaslavsky : @NewToPython: Sounds like you're thinking of PATH_INFO - you can use that in Python too but but with the publisher handler.
    Jarret Hardie : Mod_Python's implementation is actually pretty bulky. You'd probably find that WSGI + Routes (or something else) might actually be faster and lighter.
    Jarret Hardie : And I'd point out that the url explosion approach, with Apache "just running" the resulting file is representative of one of the underlying aspects of the PHP culture that has led to you thinking it is broken :-)
    Jarret Hardie : @NewToPython: lol... no worries. You asked a great question.

0 comments:

Post a Comment