Dirk van Oosterbosch, IR labs
labs at ixopusada.com
Mon Oct 30 20:14:06 EST 2006
Thanks, > Using current versions of mod_python available there is no way of > doing it except > perhaps by using the Vampire extensions for mod_python. > Alternatively, use > version 3.3 of mod_python out of Subversion repository or wait > until it is released. > > [...] > > This works even if 'from bar import bar' is used as they intercept > the 'import' > statement and when an import is performed from inside a module > which was > already imported using the module importer, it will use the module > importer for > the 'import' as well. Ie., no need to use apache.import_module() > explicitly. If the > module being imported using 'import' is in another directory > though, it is necessary > to specify an option declaring the search path for the modules. > This is a path which > is distinct from PythonPath as new importer will not use any module > in PythonPath > as a candidate for reloading as that causes lots of problems. Then, I guess it won't do it's magic for __import__(modulename) :-( The way I am building my system, I'll need to call module = __import__(modulename, globals(), locals(), [name]) since I don't know the name of the module (and of the object) until runtime. Will there be a cure for this too? (I wouldn't have a problem so much with issuing a special command to make mod_python reload all modules, if it just wasn't "apachectl stop ... apachectl start" ;) >>> Using '/' in the module name like this is not portable and is >>> dependent >>> on peculiarities of the behaviour of Python on a specific >>> platform. It will >>> not for example work on Mac OS X and also possibly not on Windows. >> >> I am working on a mac and also using slashes `/` to delimit my >> paths, so no problems there. (Didn't try from mod_python though & >> dunno what will happen on Windows). > > What version of Python are you using? I know for sure it didn't > work with > Python (2.3) on Panther. I also don't think it worked with Python > (2.3.5) > on Tiger. If you are using Python 2.4 or later which you installed > yourself, > it is entirely possible it may work. Indeed, python 2.4.1 >> I'm using os.path.join() > > Depending on the source of the path, one should actually use > posixpath functions > sometimes instead of os.path. This is especially the case of > working on req.uri and > sometimes on req.filename. This is because Apache supplies both of > them as > POSIXish style paths and using os.path functions on Windows can > screw things > up as it introduces back slashes. I am not planning to port, but thanks for the tip! Thanks again ... and mod_python 3.3 will be announced on this list won't it? ;-) dirk ----------------------------- Dirk van Oosterbosch de Wittenstraat 225 1052 AT Amsterdam the Netherlands http://labs.ixopusada.com ----------------------------- On 29-okt-2006, at 1:10, Graham Dumpleton wrote: > > On 29/10/2006, at 4:12 AM, Dirk van Oosterbosch, IR labs wrote: > >> Hi, >> >> I am also working on a "cms"-like website system, using mod_python >> and Cheetah, though I've not yet tied these both up together, to >> be fully functional. Still working on the smaller subparts of the >> system. >> So I follow this subject with great interest. >> >> It feels like the core of this discussion is about making sure the >> cheetah modules gets reloaded when they change. I didn't conduct >> any tests yet, still trying to grasp the exact mechanisms underneath. >> >>>> [...] >>>> Is this the best way to import template modules and then >>>> evaluate them? >>> >>> No, in as much as you are having to create a parallel hierarchy >>> of publisher >>> handlers for each Cheetah page. You would be better off using a >>> custom >>> handler which does the dispatch direct to the compiled Cheetah >>> template >>> classes. >> >> I'm not sure if this helps, but I've got a similar setup. There is >> one handler in a main.py that handles all requests. This main >> connects to a database, to find out which Cheetah template to use, >> and loads and fills this template. Also I've got a directory which >> hold all the python files directly necessary for the system (/var/ >> www/python) and an other directory to hold my templates. (/var/www/ >> python/templates) >> >> If inside this main.py I would use an `apache.import_module >> (fooTemplate)` instead of just `from fooTemplate import >> fooTemplate`, that would mean that the fooTemplate is reloaded if >> it changed, doesn't it? > > Probably not. See issue 8 in: > > http://www.dscpl.com.au/wiki/ModPython/Articles/ > ModuleImportingIsBroken > >> But would it also mean that all the other templates which are >> imported through their inheritance would be reloaded if they are >> changed? > > Again, probably not, for same reason. > >> Most of my templates are inheriting parent-templates using the >> Cheetah standard >> #from bar import bar >> #extends bar >> >> It's easy to create a whole directory with fresh modules, using >> the shell `cheetah compile *.tmpl`. But is there also a way to >> ensure me that apache is reloading them, if I do that? (i.e. an >> other way than restarting apache, which I have to do frequently >> while debugging this system :-( > > Using current versions of mod_python available there is no way of > doing it except > perhaps by using the Vampire extensions for mod_python. > Alternatively, use > version 3.3 of mod_python out of Subversion repository or wait > until it is released. > > Both Vampire and the new mod_python 3.3 implement a module importer > which > tracks child imports and will correctly import parent modules when > a child changes. > In fact it is the Vampire module importer which was used as basis > for 3.3 version. > > This works even if 'from bar import bar' is used as they intercept > the 'import' > statement and when an import is performed from inside a module > which was > already imported using the module importer, it will use the module > importer for > the 'import' as well. Ie., no need to use apache.import_module() > explicitly. If the > module being imported using 'import' is in another directory > though, it is necessary > to specify an option declaring the search path for the modules. > This is a path which > is distinct from PythonPath as new importer will not use any module > in PythonPath > as a candidate for reloading as that causes lots of problems. > > Anyway, end result is that with these module importers, you can > update a base > class template, regenerate Cheetah Python class and anything which > extends > from it will be automatically reloaded along with the base class. > >> And sometimes I am not importing a compiled template in main, but >> create a new template from a text/tmpl file >> `t = Template(file = "foobar.tmpl", searchList = [dict, obj])` >> What does creating a template on the fly like this, mean for >> reloading a changed inherited template? > > Not sure. Does Cheetah use a caching system of its own for this so > that it isn't > loading them from disk all the time and does it reload the tmpl > file if it has changed > on disk. I can't remember what it does and it may have changed > since when I > was more actively looking at it. > >>>> This second file only works if I add /var/www/app/templates to my >>>> PythonPath. And, due to (2) above, I then also have to add >>>> /var/www/app to PythonPath. Is this really necessary?= >>> >>> With the version of mod_python you are using, yes it is necessary. >> >> I am also adding the templates directory to my PythonPath, but >> since I am not yet running my code from Apache, I haven't yet >> discovered problems with loading the rest of my python modules >> from my /var/www/python. But if I hit those issues, I'll now know >> how to fix them, ;-) > > With new importers, you don't want to be setting PythonPath if you > want modules > to be reloadable. You will need to set the module importers own > search path. > >> BTW, (OT) >> >>>> templateModule = apache.import_module("templates/myTemplate") >>> >>> Using '/' in the module name like this is not portable and is >>> dependent >>> on peculiarities of the behaviour of Python on a specific >>> platform. It will >>> not for example work on Mac OS X and also possibly not on Windows. >> >> I am working on a mac and also using slashes `/` to delimit my >> paths, so no problems there. (Didn't try from mod_python though & >> dunno what will happen on Windows). > > What version of Python are you using? I know for sure it didn't > work with > Python (2.3) on Panther. I also don't think it worked with Python > (2.3.5) > on Tiger. If you are using Python 2.4 or later which you installed > yourself, > it is entirely possible it may work. > >> However I know of portability issues, so I am only using paths/ >> with/slashes in my configuration files, if I need to create a path >> in code I'm using os.path.join() > > Depending on the source of the path, one should actually use > posixpath functions > sometimes instead of os.path. This is especially the case of > working on req.uri and > sometimes on req.filename. This is because Apache supplies both of > them as > POSIXish style paths and using os.path functions on Windows can > screw things > up as it introduces back slashes. > >>> Things are a bit easier to manage and easier to predict when >>> mod_python 3.3 >>> can be used. Version 3.3 of mod_python hasn't been released yet, >>> but is quite >>> close. >> >> I am eagerly awaiting :-) >> best >> >> dirk >> >> >> >> ----------------------------- >> Dirk van Oosterbosch >> de Wittenstraat 225 >> 1052 AT Amsterdam >> the Netherlands >> >> http://labs.ixopusada.com >> ----------------------------- >> >> >> On 28-okt-2006, at 5:32, Graham Dumpleton wrote: >> >>> >>> On 28/10/2006, at 7:44 AM, Sebastian Celis wrote: >>> >>>> Hello, >>>> >>>> I am new to this list and have just recently begun to work on a >>>> project where I wish to use mod_python.publisher and cheetah to >>>> drive >>>> an entire web application. I apologize if the following topics >>>> have >>>> been discussed to death recently, but I have read through the >>>> documentation on both sites and have searched through the >>>> mailing-list >>>> archives and while I have seen similar discussions, I have yet >>>> to find >>>> definitive answers. I am able to get most things to work, >>>> however I >>>> can't help but feel that there are better ways of approaching >>>> some of >>>> my situations. >>>> >>>> First, I'll quickly describe my directory structure: >>>> >>>> /var/www/app -- The base directory to the web application. This >>>> will >>>> directly contain most of the python files that correspond >>>> directly to >>>> URLs. For example, index.py, login.py, etc. In this directory. >>>> /var/www/app/templates -- Contains all of my cheetah templates. >>>> /var/www/app/include -- Contains the python utility modules I am >>>> writing specifically for this application. >>>> >>>> Now, onto the questions. >>>> >>>> >>>> 1) Importing compiled cheetah templates >>>> >>>> Assume I have code like the following in /var/www/app/test1.py >>>> >>>> ###################################### >>>> from mod_python import apache >>>> from Cheetah.Template import Template >>>> >>>> def index(req): >>>> req.content_type = "text/html" >>>> >>>> dict = {'title': 'My Title!', 'message': 'Hello world!'} >>>> templateModule = apache.import_module("templates/myTemplate") >>> >>> Using '/' in the module name like this is not portable and is >>> dependent >>> on peculiarities of the behaviour of Python on a specific >>> platform. It will >>> not for example work on Mac OS X and also possibly not on Windows. >>> >>>> t = getattr(templateModule, "myTemplate")() >>>> searchList = t.searchList() >>>> searchList.insert(0, dict) >>>> >>>> return(t.respond()) >>>> ###################################### >>>> >>>> Is this the best way to import template modules and then >>>> evaluate them? >>> >>> No, in as much as you are having to create a parallel hierarchy >>> of publisher >>> handlers for each Cheetah page. You would be better off using a >>> custom >>> handler which does the dispatch direct to the compiled Cheetah >>> template >>> classes. See the mod_python handler described in: >>> >>> http://wiki.cheetahtemplate.org/cheetah-recipes.html >>> >>>> 2) Modifying PythonPath prevents modules from being imported >>>> >>>> Inside file /var/www/app/test2.py, I have the following code: >>>> >>>> import config >>>> (or) >>>> config = apache.import_module("config") >>>> >>>> Both of these commands load /var/www/app/config.py, and seem to >>>> work >>>> fine. However, if I add >>>> >>>> PythonPath "['/var/www/app/templates']+sys.path" >>>> >>>> to my apache configuration, I get an error next time I run >>>> test2.py. >>>> >>>> ### >>>> Mod_python error: "PythonHandler mod_python.publisher" >>>> >>>> Traceback (most recent call last): >>>> >>>> File "/usr/lib/python2.4/site-packages/mod_python/apache.py", line >>>> 299, in HandlerDispatch >>>> result = object(req) >>>> >>>> File "/usr/lib/python2.4/site-packages/mod_python/publisher.py", >>>> line 213, in handler >>>> published = publish_object(req, object) >>>> >>>> File "/usr/lib/python2.4/site-packages/mod_python/publisher.py", >>>> line 412, in publish_object >>>> return publish_object(req,util.apply_fs_data(object, >>>> req.form, req=req)) >>>> >>>> File "/usr/lib/python2.4/site-packages/mod_python/util.py", line >>>> 439, in apply_fs_data >>>> return object(**args) >>>> >>>> File "/var/www/app/test2.py", line 8, in index >>>> config = apache.import_module("config") >>>> >>>> File "/usr/lib/python2.4/site-packages/mod_python/apache.py", line >>>> 461, in import_module >>>> f, p, d = imp.find_module(parts[i], path) >>>> >>>> ImportError: No module named config >>>> ### >>>> >>>> Why does this initially work but then stop working once I add a >>>> directory to my path? I can fix it by adding '/var/www/app' to my >>>> PythonPath as well, but I don't understand why it didn't work >>>> before >>>> that. >>> >>> That is just how mod_python has always worked. Setting PythonPath >>> stops mod_python looking in the directory the handler was specified >>> for. Yes it is a pain. FWIW, this behaviour changes in mod_python >>> 3.3 >>> where the whole issue of module importing is dealt with a bit >>> differently >>> and is much more consistent and predictable. >>> >>> Current versions of mod_python have a lot of issues when it comes >>> to the module importer. You should really have a read of: >>> >>> http://www.dscpl.com.au/wiki/ModPython/Articles/ >>> ModuleImportingIsBroken >>> >>>> 3) Cheetah and #include >>>> >>>> I have read a lot about why mod_python sets the current working >>>> directory to '/', but this seems to be causing some larger problems >>>> when cheetah comes into play. (3) and (4) discuss two issues >>>> that I >>>> am having trouble with. >>>> >>>> Here is /var/www/app/templates/testPage.tmpl: >>>> ### >>>> #include 'header_include.tmpl' >>>> <head> >>>> <title>$title</title> >>>> </head> >>>> <body> >>>> <p>$message</p> >>>> </body> >>>> #include 'footer_include.tmpl' >>>> ### >>>> >>>> However, as this actually tries to load /header_include.tmpl and >>>> /footer_include.tmpl instead of the ones located in my templates >>>> directory, this will not work. >>> >>> If you are going to use compiled templates, you are possibly >>> better off using >>> a site page base class and have specific pages extend that page. >>> These >>> common blocks are then accessible through the base class. This >>> means you >>> get the benefit of compiled code for the included blocks as well, >>> instead of >>> it having to be interpreted each time. >>> >>>> I came up with two workarounds, >>>> however I don't really love either: >>>> >>>> a) >>>> >>>> ### >>>> #include os.path.join(os.path.dirname(__file__), >>>> 'header_include.tmpl') >>>> <head> >>>> <title>$title</title> >>>> </head> >>>> <body> >>>> <p>$message</p> >>>> </body> >>>> #include os.path.join(os.path.dirname(__file__), >>>> 'footer_include.tmpl') >>>> ### >>>> >>>> b) >>>> >>>> Actually pass $templatesDir into all of my templates and then >>>> instead call: >>>> >>>> ### >>>> #include os.path.join(templatesDir, 'header_include.tmpl') >>>> <head> >>>> <title>$title</title> >>>> </head> >>>> <body> >>>> <p>$message</p> >>>> </body> >>>> #include os.path.join(templatesDir, 'footer_include.tmpl') >>>> ### >>>> >>>> I guess I'm leaning toward (a), but both seem cumbersome and slower >>>> than necessary. Is there a better way to do this? >>> >>> If my memory of Cheetah is correct, then extending from a site >>> page which >>> has reusable bits like this as I describe above is better. >>> >>>> 4) Cheetah and inheritance >>>> >>>> Assume these two files: >>>> >>>> /var/www/app/templates/overall_base.tmpl >>>> ### >>>> <?xml version="1.0" encoding="UTF-8"?> >>>> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" >>>> "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> >>>> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> >>>> <head> >>>> <title>$title</title> >>>> </head> >>>> <body> >>>> $bodyContent >>>> </body> >>>> </html> >>>> ### >>>> >>>> /var/www/app/templates/overall_base_extender.tmpl >>>> ### >>>> #overall_base = apache.import_module("overall_base") >>>> (or) >>>> #from overall_base import overall_base >>>> >>>> #extends overall_base >>>> #def title >>>> Welcome to Foo >>>> #end def >>>> #def bodyContent >>>> Hello world! >>>> #end def >>>> >>>> This second file only works if I add /var/www/app/templates to my >>>> PythonPath. And, due to (2) above, I then also have to add >>>> /var/www/app to PythonPath. Is this really necessary?= >>> >>> With the version of mod_python you are using, yes it is necessary. >>> >>>> #overall_base = apache.import_module("overall_base", >>>> path=[os.path.dirname(__file__)]) >>>> >>>> doesn't seem to work inside the cheetah template file. Even >>>> >>>> #sys.path.append(os.path.dirname(__file__)) >>>> #overall_base = apache.import_module("overall_base") >>> >>> That one I am not sure about. You may be hitting one of the other >>> problems >>> with PythonPath based module importing which is you can't easily >>> have the >>> same name module in different directories and be sure you import >>> the one >>> you want. >>> >>> In general I wouldn't recommend using apache.import_module() within >>> Cheetah templates explicitly. >>> >>>> doesn't seem to work. Is there any way to get inheriting >>>> templates to >>>> work without modifying PythonPath to include all the directories >>>> where >>>> my base templates might be located? >>> >>> Not really. >>> >>>> I apologize for the huge length of this e-mail. I am still >>>> fairly new >>>> to mod_python and cheetah, but so far I really like what I see. I >>>> just feel like there are a few issues I need to wrap my head around >>>> before I can really dive into developing applications. Any >>>> pointers >>>> or help with these issues that you can provide would be greatly >>>> appreciated. >>> >>> Things are a bit easier to manage and easier to predict when >>> mod_python 3.3 >>> can be used. Version 3.3 of mod_python hasn't been released yet, >>> but is quite >>> close. If you want to try the source for mod_python out of the >>> Subversion >>> repository, then can suggest better ways of doing things. >>> >>> Graham >>> _______________________________________________ >>> Mod_python mailing list >>> Mod_python at modpython.org >>> http://mailman.modpython.org/mailman/listinfo/mod_python >>> >> >> >> >> >> >> _______________________________________________ >> Mod_python mailing list >> Mod_python at modpython.org >> http://mailman.modpython.org/mailman/listinfo/mod_python >
|