Sunday, February 17, 2008

Twisted's filepath Module

Glyph recently blogged about some of the buried treasure in Twisted, the filepath module in particular. Since working at Divmod, I've made use of this module quite a bit, and thought I'd share some of the features that I've found most useful (and intuitively nice to use).

Assuming you've got Twisted installed, let's fire up a python interpreter and import the FilePath class and instantiate it with /tmp and test some basic operations:

>>> from twisted.python.filepath import FilePath
>>> tmp = FilePath('/tmp')
>>> tmp.exists()
True
>>> bogus = tmp.child('bogus')
>>> bogus.exists()
False

Isn't that nice? I love not having to import and use the os.path.exists function; it's a method on the object representing a file or a path, as it should be. I also enjoy the convenience FilePath offers when it comes to creating paths:

>>> mydir = tmp.child('notbogus').child('anotherdir').child('mydir')
>>> mydir.exists()
False
>>> mydir.makedirs()
>>> mydir.restat()
>>> mydir.exists()
True

We had to call restat() so that the object would check the file system again (since we just made some changes). Now, for some files:

>>> for filename in ['test1.txt', 'test2.txt', 'test3.tst']:
... mydir.child(filename).touch()
...
>>> mydir.listdir()
['test1.txt', 'test2.txt', 'test3.tst']

And if you don't believe that, we can switch to shell:

lorien:oubiwann 20:51:58 $ ls -al /tmp/notbogus/anotherdir/mydir/
total 0
drwxr-xr-x 2 oubiwann wheel 170 Feb 17 20:51 .
drwxr-xr-x 3 oubiwann wheel 102 Feb 17 20:46 ..
-rw-r--r-- 1 oubiwann wheel 0 Feb 17 20:51 test1.txt
-rw-r--r-- 1 oubiwann wheel 0 Feb 17 20:51 test2.txt
-rw-r--r-- 1 oubiwann wheel 0 Feb 17 20:51 test3.tst
view raw 04-stdout.txt hosted with ❤ by GitHub

Reading and writing operations are the same as usual:

>>> myfile = mydir.child(filename)
>>> myfile.isdir()
False
>>> myfile.islink()
False
>>> myfile.isfile()
True
>>> fh = myfile.open('w+')
>>> fh.write('do the usual thing')
>>> fh.close()
>>> myfile.getsize()
18L
>>> myfile.open().read()
'do the usual thing'

But you can use shortcuts like this, too:

>>> myfile.getContent()
'do the usual thing'
>>> myfile.setContent('and now for something completely different...')
>>> myfile.getContent()
'and now for something completely different...'

Let's get the path and recheck the file size, just to make sure:

>>> myfile.path
'/tmp/notbogus/anotherdir/mydir/test3.tst'
>>> myfile.restat()
>>> myfile.getsize()
45L

Or, again from shell:

lorien:oubiwann 20:52:06 $ ls -al /tmp/notbogus/anotherdir/mydir/
total 8
drwxr-xr-x 2 oubiwann wheel 170 Feb 17 20:58 .
drwxr-xr-x 3 oubiwann wheel 102 Feb 17 20:46 ..
-rw-r--r-- 1 oubiwann wheel 0 Feb 17 20:51 test1.txt
-rw-r--r-- 1 oubiwann wheel 0 Feb 17 20:51 test2.txt
-rw-r--r-- 1 oubiwann wheel 45 Feb 17 20:58 test3.tst
view raw 08-stdout.txt hosted with ❤ by GitHub

Hmm... for some reason, I really like this file and want to keep it. What do I do?

>>> docs = FilePath('/Users/oubiwann/Documents')
>>> myfile.moveTo(docs.child('special_file.txt'))

That's it! Nice, eh? Of course, we're careful, so we check to make sure it happened:

>>> myfile.exists()
False
>>> newfile = docs.child('special_file.txt')
>>> newfile.exists()
True
>>> newfile.path
'/Users/oubiwann/Documents/special_file.txt'
>>> newfile.getsize()
45L
>>> newfile.getContent()
'and now for somethibg completely different...'

To see more, check out the source, or at least do dir(FilePath) to see what other goodies this class has to offer, and enjoy :-)


Technorati Tags: , ,

No comments: