Django and Dreamhost, Take 2
Comments Off After installing my own custom Python build, I went back and tweaked how Django ran on my Dreamhost account. My previous Django installation experience is still mostly valid. I just figured I could “upgrade” the installation to take advantage of Python 2.5 and eggs.
I installed three eggs to get Django running
# For Django
python ez_setup.py MySQL-python
python ez_setup.py http://www.saddi.com/software/flup/dist/flup-r2030.tar.gz
python ez_setup.py http://www.djangoproject.com/download/0.95/tarball/
The first was mySQL support; second was for Django’s built-in fcgi support; and finally Django itself.
I had a second goal in this upgrade. I wanted to partition off the “/-/” subtree (For example, http://example.com/-/admin/) for Django, instead of using the full subdomain. I had to make a couple of changes to the project’s urls.py file (to handle the ‘-’) and to the .htaccess file:
# urls.py change example for the admin application.
(r’^-/admin/’, include(‘django.contrib.admin.urls’)),
The .htaccess file:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^-$ /-/ [R]
RewriteRule ^-/(.*)$ /_/mysite.fcgi/-/$1 [QSA,L]
</IfModule mod_rewrite.c>
And finally, a new mysite.fcgi script found in the /_/ directory (notice that it’s an underscore, not a dash):
#!/home/user/bin/python/bin/python
import sys, os# Switch to the directory of your project. (Optional.)
# os.chdir(“/home/user/myproject”)# Set the DJANGO_SETTINGS_MODULE environment variable.
os.environ['DJANGO_SETTINGS_MODULE'] = “myproject.settings”from django.core.servers.fastcgi import runfastcgi
runfastcgi(["method=threaded", "daemonize=false"])
Python, Eggs and Dreamhost
3 Comments Dreamhost, my web host, does not yet support Python2.5, and one can’t install Python eggs into Dreamhost’s own Python installations. The solution? I just installed a custom build of Python2.5 into my $HOME/opt directory. The following is the script I created to automate that process:
# Obtain Python2.5 and unpack
mkdir $HOME/downloads/
cd $HOME/downloads/
wget http://www.python.org/ftp/python/2.5/Python-2.5.tgz
tar -zxvf Python-2.5.tgz# Creating the location under which python (and other apps) are to be installed.
mkdir $HOME/opt# Go into the Python2.5 directory, make && make install the thing
cd Python-2.5
./configure –prefix=$HOME/opt –enable-unicode=ucs4
make && make install# Create a bin directory for Python, and link the bin to the real executable
mkdir -p $HOME/bin/python/bin
ln -s $HOME/opt/bin/python $HOME/bin/python/bin/python
After the installation, I edited the bash_profile file to add the bin path:
export PATH=$HOME/bin/python/bin:$HOME/opt/bin:$PATH
Now with a custom installation of Python, I can use eggs to manage my Django projects’ library dependencies.
Python Conditional Expressions
2 Comments Python had lacked a C equivalent of the “condition ? true_value : false_value” expression. So we used a work around until now… conditional expressions finally made it in to Python’s 2.5 release.
In Python2.4:
x = ((condition) and true_value) or false_value
In Python2.5:
x = true_value if condition else false_value
Yeah, the statement looks better in Python2.5.
Map, Filter, and Reduce over Python Dictionaries
3 Comments I wanted to apply some Functional Programming ideas to solve a problem in some Python code I had, which involved manipulation of data found in a couple dictionaries. Unfortunately, the built in map, filter, reduce, and list composition methods can only be used over iterable lists.
Luckily, I remembered that equivalent dictionaries in LISP are all represented as a list-of-lists: ( (key1, val1), (key2, val2) ); python map & filter functions can then be used over this converted datastructure.
After a little digging, I found that it’s really easy to do this conversion in Python:
# Uses the list composition to make the key value pairs over a dictionary.
dict2list = lambda dic: [(k, v) for (k, v) in dic.iteritems()]# Use the built in dictionary constructor to convert the list.
list2dict = lambda lis: dict(lis)# Example Usage follows:
dict1 = { ‘a’:1, ‘b’:2, ‘c’:3, ‘d’:4 }
# Filter function
is_even = lambda item: item[1] % 2 == 0
# Map functions
add_two = lambda item: (item[0], item[1] + 2)
add_sss = lambda item: (“%s SSS” % item[0], item[1])
# Reduce function
add_all = lambda x, y: (“%s %s” % (x[0], y[0]), x[1] + y[1])# Make sure you have the [] around the reduce call.
list2dict([reduce(add_all, map(add_two, map(add_sss, filter(is_even, dict2list( dict1 )))))])
Too Many Usernames!
9 Comments I am generally tolerant of dumb tech hurdles because I’m a techie, but I don’t like having different usernames and passwords for every site I visit– Yahoo, Google, MSN, etc. Some big companies are trying to solve this problem– MSN Passport and the Liberty Alliance. But those solutions require huge budgets (and not K.I.S.S), and I personally don’t think that they can realistically solve the problem.
So, if I barely can handle this user account problem, how does a non-techie stand a chance?.
What can be done? For my part, I’ll be using OpenId (Authentication Scheme) and YADIS (Scheme/Service Discovery) in my Django projects. Why?
- They can give my users (and me) a single identity across the web.
- They already have good support (LiveJournal, Moveable Type, etc).
- They are Simple in design.
- They are Open.
- They are Federated. Power to the people, not any one mega-corp.
To do so, I wrote up a simple pluggable OpenId Authentication Django App that I can use in my projects. The app uses the OpenId Python library put out by the OpenId Enabled guys. I shot them email about contributing my code back to their project. This is in progress. If not, I’ll just release and host it myself.
Next step is to connect my OpenId App, YADIS and Django.
Django and TurboGears, Excitement
2 Comments My last post made the claim that Django hands down beats TurboGears. I know I may have sounded like a “fanboy” (I’m not), but I couldn’t contain the enthusiasm of what I saw.
I want to add the following: [edited: Not only do I currently think that Django is better, but also:] I am really really excited by the active development found in both projects.
Case in point:
- Adrian Holovaty commented (Comment section of my last post) that my pet peeves have been or are currently being addressed. Excellent!
- Thanks to Cliff Wells for pointing out that Catwalk is being added to the next version of TurboGears, correcting my statement about TurboGears lacking an admin interface. I will have to check it out!
- Both Projects have active mailing lists and blogging communities.
- Coding is active, and new releases are forthcoming.
I think this case of “sibling rivalry”, if they can be considered siblings, will be helpful in fostering the development of the python-web world. I’m currently seeing a growth in the perception that this area is really coming into its own with these really cool projects.
And finally, my opinion here isn’t fixed, so I’m looking forward to seeing what develops in the future (Let’s see if Cliff’s prediction about the TurboGears momentum will come true). I’ll definitely be making suggestions to both projects when they pop into my mind. And I will submit patches if I run across a bug or a feature idea as I work on my own projects. The future is chock-full of potential on all fronts.
Django is Rails
7 Comments The Django Project kicks the living crap out of Turbo Gears for python web application development. I went through the tutorials and documentation from both projects; messed around with writing up some toy applications. I have to say that I’d choose Django for my work.
What does Django Project have on Turbo Gears?
- Django has a more cohesive and streamlined feel.
- I can use Django on the Dreamhost servers with less hassle. (Installation instructions)
- Django comes with admin interface to manage data in the database.
- Django comes with a prebuilt RSS and Atom feed generation application.
- Django provides ready to go methods for handling 80% of what you need to do (I’m talking about Generic Views).
- The URL composition and decoupling allows one to make applications really RESTful.
- Much of the work only involves wiring up the URLs and the generic views to access the data. No coding.
- I’m writing less code than Turbo Gears, which is almost nothing at all.
But I have a few pet peeves about Django:
- The App’s url.py file isn’t truely decoupled from the project. You have to specify a view’s full package and name, which the project’s name is part of. But I got around that by declaring a BASE_APPS_PACKAGE settings.py string. Now, I can just copy apps around anywhere.
- I’m not sure if I like putting the URL generation logic in with the model (get_absolute_url). This can tie an app to the project. I added a BASE_URLS settings.py dictionary to map an application to its base url.
- The options on generic views don’t mesh up well. I needed to write up a custom archive_index view, so it wouldn’t return a 404 when no data is found. I wouldn’t have needed to if the original view implemented the allow_empty parameter as found on other views.
- The generic views only can take custom SQL parameters if they are predefined. I had to extend my custom archive_index view to handle extra parameters taken from a URL path.
I’m finding that I’m spending less time on the guts of glue work; I’m focusing on delivering the business solution; I can spend more time on the user interface.
FeedMesh Python Solution
Comments Off Ralph Meijer’s blog has a nice entry about connecting to the FeedMesh network, even with sample code.
This solution was exactly what I was looking for. The Twisted Framework is used for handling both the network connection and the XML streaming (Xish package).
However, I ran into a little problem when testing the code out. I found was that the XmlStreamFactory failed to instantiate. It required another parameter in its constructor. WTF?
Simple reason. Ralph has been making changes to remove all the Jabber specific stuff out of Xish. That parameter was for Jabber and Ralph’s changes haven’t made it out into a new release.
So, for those that already have Xish 0.1.0 installed, here are the following code changes:
auth = xmlstream.Authenticator('')
f = xmlstream.XmlStreamFactory(auth)