[mod_python] Current Working Directory not set?

Sean Jamieson sean at barriescene.com
Fri Jan 27 17:41:15 EST 2006

Thanks for all the options Graham.

I've come up with the following code template, if anyone see anything 
obviously wrong/bad please let me know:
import os
import sys
from mod_python import apache, util
from kid import Template

# this file's current directory
__dir__ = os.path.dirname( __file__ )

# set the templates path under this file's directory
__templates__ = os.path.join( __dir__, "templates" )

def index( req ): _page='index'
    req.content_type = 'text/html'
    ## function body ##
    return Template( file=os.path.join( __templates__, '%s_%s.kid' % 
(__name__, _page) ), **vars() )

I'm expecting someone might say something about my use of **vars().
The overall result of my return Template(..) statement is that it will 
match [script's dir]/templates/[script name]_[function name].kid



Graham Dumpleton wrote:

> On 28/01/2006, at 6:53 AM, Sean Jamieson wrote:
>> Hello everybody,
>> I don't know if there's already been a discussion about this, it 
>> seems like a small but obvious issue.
> Many times. ;-)
>> The current working directory does not apear to be set when a 
>> mod_python.publisher script runs; or rather it's set to "/" which is 
>> not useful. This becomes quite a pain, as I'm forced to do many 
>> things to work around it.
> As someone else said, working directory can't be changed because of 
> multithreading
> abilities of mod_python.
>> i.e.
>> 1) I've started using kid templates, and I have to use:
>>     Template( file=req.document_root().'template.kid', ... )
>> or
>>    Template( 
>> file=req.document_root().'project_dir/templates/template.kid', ... )
>> rather then the more natural:
>>    Template( file='templates/template.kid )
>> this should find the 'templates' directory in the same directory as 
>> the running script
> Don't use req.document_root(). Instead, in that specific Python code 
> file,
> include at global scope:
>   import os
>   __here__ = os.path.dirname(__file__)
>   __templates__ = os.path.join(__here__,"templates")
> That will give you the directory that file is located in, in a handy 
> variable
> which you can then use.
>     Template( file=os.path.join(__templates__,"template.kid") )
> This is only useful though if all your publisher handlers are in the 
> one directory.
> If you have stuff spread over subdirectories, you start having to use 
> relative
> paths as appropriate in subdirectory handler files.
>   import os
>   __here__ = os.path.dirname(__file__)
>   __templates__ = os.path.join(__here__,"..","templates")
> Thus, you may be better off doing something like:
>   def _templates(req,path):
>     return os.path.join(req.hlist.directory,"templates",path)
>   ...
>     Template( file=_template("template.kid") )
> The req.hlist.directory variable will be set to the directory for 
> which PythonHandler
> is specified, thus giving you a root anchor point which you can use to 
> describe all
> paths relative to. Doing this means you have more flexibility as far 
> as moving code
> files around between directories without having to modify code.
> The other reference point you might use is:
>   def _templates(req,path):
>     directory = os.path.dirname(req.filename)
>     return os.path.join(directory,path)
>   ...
>     Template( file=_template("templates/template.kid") )
> The req.filename object is similar to using __file__ for most cases, 
> but getting the
> information from the request object instead.
> You might even create your own derived class from Kid's Template class 
> so you can
> pass it a 'req' object and relative template file path and have that 
> derived class
> constructor do the calculation of where the file is relative to 
> PythonHandler root
> or req.filename.
> In other words, to be more transparent, the template system would need 
> to know about
> the environment it is used in.
>> 2) I have to fully qualify imports from the document root, as the 
>> document root is added to sys.modules, but the current directory is 
>> not. So, if I'm in a subdirectory under the document root I have to do:
>>    import project_dir.subpackage.module
>> when the current directory is 'project_dir'. This is silly, I should 
>> be able to import something in, or under, the current working directory:
>>    import subpackage.module
> If these packages contain reusable code used across various pages and 
> don't have
> actual code in them for generating pages, it is not a good idea to put 
> them under
> your document root. This is because with the right URL they may be 
> able to be
> invoked by a remote user because of publishers automatic mapping. Thus 
> you need to
> be very careful.
> If they do contain code for generating pages, you should not be using 
> "import"
> to access them as at the same time they could be getting loaded by 
> publisher using
> a different module loading system which will cause various problems.
> As suggested by someone else, look at using "apache.import_module()".
>> I would have to do some hack involving seperating the dirname of 
>> __file__ and adding it to sys.modules
> I think you must have meant into sys.path. Same above, Modifying 
> sys.path directly
> in mod_python is not usually a good idea either. The use of 
> PythonHandler will
> automatically put that root directory in sys.path for you without 
> having to resort
> to using PythonPath. This all assumes you have already set PythonPath 
> explicitly
> and aren't using Location directive instead of Directory directive to 
> specify context
> in which mod_python is used.
> Graham

More information about the Mod_python mailing list