mod_wsgi/python sys.path.exend problems - python

I'm working on a mod_wsgi script.. at the beginning is:
sys.path.extend(map(os.path.abspath, ['/media/server/www/webroot/']))
But I've noticed, that every time I update the script the sys.path var keeps growing with duplicates of this extension:
['/usr/lib64/python25.zip'
'/usr/lib64/python2.5'
'/usr/lib64/python2.5/plat-linux2'
'/usr/lib64/python2.5/lib-tk'
'/usr/lib64/python2.5/lib-dynload'
'/usr/lib64/python2.5/site-packages'
'/usr/lib64/python2.5/site-packages/Numeric'
'/usr/lib64/python2.5/site-packages/gtk-2.0'
'/usr/lib64/python2.5/site-packages/scim-0.1'
'/usr/lib/python2.5/site-packages'
'/media/server/www/webroot'
'/media/server/www/webroot'
'/media/server/www/webroot'
'/media/server/www/webroot']
It resets every time I restart apache.. is there any way to make sure this doesn't happen? I want the module path to be loaded only once..

No need to worry about checking or using abspath yourself. Use the ‘site’ module's built-in addsitedir function. It will take care of these issues and others (eg. pth files) automatically:
import site
site.addsitedir('/media/server/www/webroot/')
(This function is only documented in Python 2.6, but it has pretty much always existed.)

One fairly simple way to do this is to check to see if the path has already been extended before extending it::
path_extension = map(os.path.abspath,['/media/server/www/webroot/'])
if path_extension[0] not in sys.path:
sys.path.extend(path_extension)
This has the disadvantage, however, of always scanning through most of sys.path when checking to see if it's been extended. A faster, though more complex, version is below::
path_extension = map(os.path.abspath,['/media/server/www/webroot/'])
if path_extension[-1] not in reversed(sys.path):
sys.path.extend(path_extension)
A better solution, however, is probably to either add the path extensions to your PYTHONPATH environment variable or put a .pth file into your site-packages directory:
http://docs.python.org/install/index.html

The mod_wsgi documentation on code reloading covers this.

Related

How to pass any directory format (windows, linux, mac) to a function and use it os independently (python3)

You can make os independent a file-name with:
os.path.join(os.path.curdir, 'filename')
But I need something else. I want my function to take whatever path format (windows, linux, mac), to convert it to os independent format, in order to assign it at a variable and work with it at any os. Also, note that the filename is not necessarily at the curent directory.
example:
def magically_read_any_path_format_and_make_it_os_independent(input_file)
...
return os_independent_format
# my variable
file = magically_...(input_file)
P.S. I know I can check whether it is the one or the other os and make the corresponding conversions, but is there something more automated and pythonic? Something in os or pathlib or elsewhere?
Thank you
If you're using python > 3.4 you can use pathlib and it does exactly that. You create a Path object from your path and it handles everything for you.
On older versions of Python, as long as you use os.path for any path manipulations you need, and use the Unix format for any hard-coded constants together with os.path.normpath, it should work on any os.
Not sure exactly what you mean by os independent the docs state that "os.path module is always the path module suitable for the operating system Python is running on, and therefore usable for local paths" meaning it gives you what you need locally.
You may be able to
os.path.join(os.path.join(os.path.curdir, '') which is rather hacky
or
os.path.normpath(os.path.curdir) which may do more then you want, see the docs

Making a directory for a file

I was making a exercise generator algorithm for my friend, but I stumbled across a problem. It is a python program, and I wanted to generate a folder in a directory that was above the program's location (like, the python file is in 'C:\Documents\foo' and the folder should be created in 'C:\Documents') so that it could then store the file the program created. Is there a way to do this or should I try something else?
Use the path argument of the os.mkdir() function.
Getting the current script directory is not a built-in feature, but there are multiple hacks suggested here.
Once you get the current script directory, you can build a path based off of that.
Not super familiar with Python in a Windows environment, but this should be easily do-able. Here is a similar question that might be worth looking at: How to check if a directory exists and create it if necessary?
Looks like the pathlib module might do what you are looking for.
from pathlib import Path
path = Path("/my/directory/filename.txt")
try:
if not path.parent.exists():
path.parent.mkdir(parents=True)
except OSError:
# handle error; you can also catch specific errors like
# FileExistsError and so on.
Appears to work on Win 7 with Python 2.7.8 as described:
import os.path
createDir = '\\'.join((os.path.abspath(os.path.join(os.getcwd(), os.pardir)), 'Foo'))
if not os.path.exists(createDir):
os.makedirs(createDir)

how to access source tree in Twisted trial tests?

In my trial test case, I want to run scripts from my source tree. Trial changes the working directory, so simple relative paths don't work. In practice, Trial's temporary directory is inside the source tree, but assuming that to be the case seems suboptimal. I.e., I could do:
def source_file(p):
return os.path.join('..', p)
Is there a better way?
If you want to find a file next to your test and run it as a script, you can just do this:
from twisted.python.modules import getModule
script = getModule(__name__).filePath.path
# ...
reactor.spawnProcess(..., script, ...)
You can also use this to support storing your code in a zip file, although invoking it with Python becomes a little more difficult that way. Have you considered just using python -m?

Open a file from PYTHONPATH

In a program, and obviously being influenced by the way Java does things, I want to read a static file (a log configuration file, actually) from a directory within the interpreter's PYTHONPATH. I know I could do something like:
import foo
a = foo.__path__
conf = open(a[0] + "/logging.conf")
but I don't know if this is the "Pythonic" way of doing things. How could I distribute the logging configuration file in a way that my application does not need to be externally configured to read it?
In general, that's fine, though I'm not sure you want a[0] above (that will just give you the first character of the path), and you should use os.path.join instead of just appending / to be cross-platform compatible. You might consider making the path canonical, i.e. os.path.abspath(os.path.dirname(foo.__path__)). Note that it won't work if __path__ is in a zip file or other import trickery is in use, but I wouldn't worry about that (it's not normal to do so for the main program in Python, unlike Java).
If you do want to support zipped files, there's pkg_resources, but that's somewhat deprecated at this point (there's no corresponding API I could see in the new packaging module).
Here's a snippet based on the link Nix posted upthread but written in a more functional style:
def search_path(pathname_suffix):
cands = [os.path.join(d,pathname_suffix) for d in sys.path]
try:
return filter(os.path.exists, cands)[0]
except IndexError:
return None

How to get the current running module path/name

I've searched and this seems to be a simple question without a simple answer.
I have the file a/b/c.py which would be called with python -m a.b.c. I would like to obtain the value a.b.c in the module level.
USAGE = u'''\
Usage:
python -m %s -h
''' % (what_do_i_put_here,)
So when I receive the -h option, I display the USAGE without the need to actually write down the actual value in each and every script.
Do I really need to go through inspect to get the desired value?
Thanks.
EDIT: As said, there are answers (I've searched), but not simple answers. Either use inspect, use of traceback, or manipulate __file__ and __package__ and do some substring to get the answer. But nothing as simple as if I had a class in the module, I could just use myClass.__module__ and I would get the answer I want. The use of __name__ is (unfortunately) useless as it's always "__main__".
Also, this is in python 2.6 and I cannot use any other versions.
This works for me:
__loader__.fullname
Also if I do python -m b.c from a\ I get 'b.c' as expected.
Not entirely sure what the __loader__ attribute is so let me know if this is no good.
edit: It comes from PEP 302: http://www.python.org/dev/peps/pep-0302/
Interesting snippets from the link:
The load_module() method has a few responsibilities that it must
fulfill before it runs any code:
...
It should add an __loader__ attribute to the module, set to the
loader object. This is mostly for introspection, but can be used
for importer-specific extras, for example getting data associated
with an importer.
So it looks like it should work fine in all cases.
I think you're actually looking for the __name__ special variable. From the Python documentation:
Within a module, the module’s name (as a string) is available as the value of the global variable __name__.
If you run a file directly, this name will __main__. However, if you're in a module (as in the case where you're using the -m flag, or any other import), it will be the complete name of the module.
When run with -m, sys.path[0] contains the full path to the module. You could use that to build the name.
source: http://docs.python.org/using/cmdline.html#command-line
Another option may be the __package__ built in variable which is available within modules.
Number of options are there to get the path/name of the current module.
First be familiar with the use of __file__ in Python, Click here to see the usage.
It holds the name of currently loaded module.
Check/Try the following code, it will work on both Python2 & Python3.
» module_names.py
import os
print (__file__)
print (os.path.abspath(__file__))
print (os.path.realpath(__file__))
Output on MAC OS X:
MacBook-Pro-2:practice admin$ python module_names.py
module_names.py
/Users/admin/projects/Python/python-the-snake/practice/module_names.py
/Users/admin/projects/Python/python-the-snake/practice/module_names.py
So here we got the name of current module name and its absolute path.
The only way is to do path manipulation with os.getcwd(), os.path, file and whatnot, as you mentioned.
Actually, it could be a good patch to implement for optparse / argparse (which currently replace "%prog" in the usage string with os.path.basename(sys.argv[0]) -- you are using optparse, right? -- ), i.e. another special string like %module.
Why does nobody mentioned the .__module__?
When doing a self.__module__ you will get the module path.
You can also do this outside of the class:
Class A:
self.__module__ # gets module.filename
def get_module():
A.__module__ # also gets module.filename
One liner But OS dependent
it does not work in interpreter! since file is meaningless there in the interpreter and is not defined.
does not require os module to be imported.
modulename=__file__.split("\\")[-1].split('.')[0]
Explanation:
X:\apple\pythonabc.py | will output pythonabc.py
select the last element after splitting with slashes, then select the first element by splitting it with dot '.'. because first step gives module.py, second step gives 'module' only. __file__ is a unique variable and returns the filepath of current module.
Comment any flaws or has any other pitfalls.
you should hardcode a.b.c in your help, if you distribute the package as such then that's the way to call it regardless of where a is located in the filesystem, as long as it's on the PYTHONPATH it'll be imported.

Categories

Resources