Tag Archive for 'python'

mod_python Project Configuration Files

April 30th, 2009 by peasleer

In my last post I brought up how to get around mod_python’s default inability to handle relative paths for imported modules. The next night after writing that, I faced a very similar issue with configuration files.

It is a sin to duplicate data in a project (except when caching), so most sane desktop applications will have a central store that contains the configuration parameters for the application (usually packaged as a resource with the application, or in the registry for Windows users). Mod_python can’t do this because, as was discussed in my last post, it views the current working directory of whatever script it is executing as the root directory of the filesystem (”/”). So where do you put the configuration file for your mod_python based project if you can’t refer to it relatively, don’t want to hardcode an absolute path, and want to distribute the configuration with the project?

The solution hit me like a bucket of cold water. Give up on the property or ini format file, and make your configuration a python dict object that you can directly import:

# config.py
#
# This is the project's configuration. Import it when a class needs to access
# project configuration variables.
#

_config = {
    # The name of my app so pathHack knows what string to look for
    'rootname': 'sampleWebApp',
    # Database options
    'db_host': 'localhost',
    'db_dbname': 'sampleWebApp',
    'db_user': 'sampleWebAppUser',
    'db_password': 's0m3p455w0rd',
    # Debug logfile path
    'debug_logfile': '/tmp/lostafollower.log'
    };



This file needs to live in your project’s root directory as far as mod_python is concerned. For more information, read my last post. If you’ve already read it, then you’ll understand when I say that config.py lives in the same folder as pathHack.py.

Once you can import it from your main source files, use it like this:

<%
# sample usage of config
from config import _config as _c
req.write(_c['rootname'])
%>


Tada! Extraordinarily simple configuration file that is easily accessible and can be distributed with your mod_python application. I’m pretty happy about it :)

Relative Import Paths Using Mod_Python

April 27th, 2009 by peasleer

A long while back (a year already? Jeeze!) David Brenner and I wrote a web application without using any frameworks, only mod_python and python server pages (PSP). We ran into a few problems along the way, one of which being that the import path mod_python used had to be composed of absolute paths. It isn’t a huge problem to just hard code a path to your project’s lib directory, but it is hardly portable and adds to the fragility of the system.

I’m now doing another project (more on that later), again using mod_python and psp. This time around however, I have a hack that gets around the absolute path problem. The solution looks like this:

# This file has only one function: to add directories to the path
# so we can import other python files/modules.

import sys

# Default directories to add to the path
_dirs = ["/src", "/lib"]
_applicationRoot = "sampleWebApp"

# Will go through the list and add the directories given relative to the
# lostafollower base path. Allows us to do paths relative to our installation
# instead of hard-coding absolute paths.
def addLibs( dirs ):

  # If [] was provided, just use the default.
  if not dirs:
    dirs = _dirs

  base = ""
  for entry in sys.path:
   if entry.find(_applicationRoot) != -1:
     base = entry
     break

  for dir in dirs:
    try:
      # Test if the path contains the path we want
      sys.path.index(base+dir)
    except:
      # The path doesn't already contain our path
      sys.path = sys.path+[base+dir]

The reason we normally can’t use relative paths when doing imports is because the mod_python handler considers the root (”/”) of the filesystem to be the current working directory of the application, regardless of where the application is actually running from. However, Apache will put whatever alias it has for your application’s directory [1] in the PYTHONPATH for mod_python, which is what allows us to do this hack. By finding the path that Apache has in the PYTHONPATH, we can add whatever paths we want relative to that. No .htaccess PythonPath directives, no hard coding of paths to your project’s module locations. Just:

  1. Put the above code in a file (I call it pathHack.py) in your application’s root directory (root as far as Apache is concerned) [1]
  2. import pathHack (or whatever you called it) in whichever file needs your other modules
  3. Call pathHack.addLibs([]) to add the defaults (/path/to/sampleWebApp/lib, etc), or pathHack.addLibs(”/lib/3rdParty”) to add /path/to/sampleWebApp/lib/3rdParty to your path
  4. import any python module in those newly added directories!

That is really it. Hard coded paths begone!

[1]

When I say “the alias it [Apache] has for your application’s directory,” what I mean is that even though, for example, my application runs out of /home/robertp/src/sampleApp/src, mod_python sees the root as being /home/robertp/src/sampleApp because of some unknown magic. It doesn’t really matter what the path is, in all honesty – when specifying a value for _applicationRoot in the solution code above, you are just looking for a string unique to the path to your application (just be sure to make all supplied paths relative from that base). Try just your project’s deployment folder for starters. If you are still having trouble finding it, create a quick psp file in the same folder as your other psp files, and do:

import sys
from mod_python import apache
req.write(str(sys.path))

That will just print out all the path elements to your browser window when visited. Pick out your application’s name or path from there, and set _applicationRoot to that. It isn’t completely ideal, but it is better than hard-coding ;)

Unsubstantiated Hype: Python and Web Development

March 8th, 2008 by peasleer

This past academic quarter I elected to do an independent study. A lot of hype has been surrounding web development over the past few years, and the python scripting language for even longer than that. Figuring it was time to immerse myself in both subjects and the technologies related to them, the independent study turned into a full four credit project aimed toward creating a web application for administering quizzes. Because I only had ten weeks to learn everything involved with developing a web application on top of the language, I coerced my good friend David Brenner into doing it with me. Development is done, and I now feel like I can talk intelligently about my experiences.

The project was developed using straight python, utilizing the mod python Apache module to serve Python Server Page (psp) files. Python isn’t my favorite language to code with, it is lacking some things that I’ve come to expect from a scripting language, and some things are just silly. Examples of lacking features include the ability to get an iterator for a collection. Iterators that grant references both to the next and previous element of a collection grant superior control and the ability to keep state while iterating. Python only allowing you to move forward through a collection with its “for x in collection:” construct really hurts while parsing large sequences of text, and having to revert to array notation and keep an index is much less human readable than just manipulating an iterator.

Annoyances with the language include python being a scripting language that doesn’t default to printing the string value of non-string objects, and using procedural style method calls intermixed with object-oriented style. For example, to print an object (say an array), you can’t just do print(“Array contents: “ + arrayName). You have to manually return the string value by using print(“Array contents:” + str(arrayName)) in order to avoid an error that print() was expecting an object of type string. I know python’s mantra is “explicit over implicit,” but languages are tools that you learn how to use. As I learn more, I expect to gain proficiency with the tool in order to save me time in the future. Python is easy to learn and easy to use, but I have yet to find any tricks with the language that save me time or make my job easier than it would be with another language. One last thing that I simply do not understand is the necessity to include a reference to “self” in method and constructor definitions. I strongly prefer the method signature to match the required call, python’s decision to branch from that convention is one that I can’t imagine will have a justification strong enough to alter my opinion of the practice.

As it goes with web development, we also used javascript, a MySQL database backed with InnoDB table engines, LDAP for authentication, HTML, and CSS. Development was utterly boring. Being a computer science student, I enjoy working on new things that present challenges and reward creative solutions. The most thought intensive part of this project was the parser run on imported quizzes using a format we decided on – and that was developed in the fourth week. Everything else was the brainless transfer of requirements to code. Some of the people I go to school with are attracted this kind of development, and I think I know why: frontend web dev is easy. Writing the backend logic isn’t bad, but the interface code and associated handlers could be composed by a high school student with some spare time and only rudimentary knowledge. The things learned in computer science definitely aren’t applied in that domain.

Finally, to wrap up loose ends: object relational database design is neat and very handy, javascript is odd at first but easy to pick up, dealing with web requests and forms is tedious, debugging web applications is a *bitch,* and Debian Linux with Apache, Subversion, screen, and vim makes for a great development and hosting environment.

Web development has its place, but it isn’t for me. I’m capable with python, but I’ll stick with ruby. And if you introduce yourself to me, try to be more descriptive than “I’m a web developer” so my experiences don’t tarnish my opinion of you – because I bet you are more skilled at writing code than that title would suggest.