Announcing FS 0.1.0, a Python file-system

This is something I have been hacking together for a while now; FS is a file-system abstraction for Python. It has reached a stable state and is worthy of an official (0.1.0) release.

First, a brief history of the project. A while back, I was working mainly with desktop applications in wxPython. I found that I had a number of sources for files; there were read-only resources such as images, per-user files and per-installation config files. The location of these files would change depending on whether I was debugging or building a release version. The logic required to manage all this was pretty ugly and error-prone. So I wrote a collection of classes to bring all these disparate locations for files under a single virtual file-system. For example, to open a config file I could just read 'user/settings.cfg', and to open an image resource I could just read from 'resources/logo.png' and the virtual file-system would do the right thing and return a file-like object.

This turned out to be insanely useful, and I used it for a number of projects. I also used it while working for ICC, and I had the opportunity to enhance it based on feedback from colleagues. In the last few months I have re-written it from scratch, because I wanted to avoid any copyright issues, but mainly because I could make a better job of it the second time around.

Getting Started

You can install FS with the command 'easy_install fs', or manually by downloading the latest release from (http://code.google.com/p/pyfilesystem/downloads/list) and running 'python setup.py install'. FS has been checked on Linux and Windows, but should run anywhere since ultimately it uses the standard library. There is no documentation other than the docstrings at the moment, so this post will have to suffice till I write up the API.

The main module is called fs, and there are a number of sub-modules:

fs.osfs Contains the class OSFS, which is a simple layer around the operating systems own file-system.

Contains the class OSFS, which is a simple layer around the operating systems own file-system. fs.memoryfs Contains the class MemoryFS, which is a file-system that exists only in memory.

Contains the class MemoryFS, which is a file-system that exists only in memory. fs.mountfs Contains the class MountFS which can be used to mount other file-systems at various places in the directory structure.

Contains the class MountFS which can be used to mount other file-systems at various places in the directory structure. fs.multifs Contains the class MultiFS which creates a file-system from other file-systems which are tried in-order till a file operation succeeds.

Contains the class MultiFS which creates a file-system from other file-systems which are tried in-order till a file operation succeeds. fs.zipfs Contains the class ZipFS which creates a file-system from a zip file.

Contains the class ZipFS which creates a file-system from a zip file. fs.tempfs Contains the class TempFS which create a temporary file-sytem that can be automatically cleaned up.

Contains the class TempFS which create a temporary file-sytem that can be automatically cleaned up. fs.utils Contains a number of functions for dealing with FS objects.

Contains a number of functions for dealing with FS objects. fs.browsewin Contains the 'browse' function which opens a tree view of the file-system passed to it. This is mainly a debugging aid. Requires wxPython.

Examples

In lieu of documentation, I'm just going to run through an interactive session that shows a few features.

>>> from fs import * >>> home = osfs . OSFS ( '~/' ) >>> from fs.browsewin import browse >>> browse ( home )

This creates an object called 'home' which represents your home directory (use a different path if you are on a non-linux system). You can use it to open files, list directory contents, copy files etc. But it can never access files that aren't under your home directory, so it could be considered a sand box view on to the underlaying file-system of the OS. The root of the home object is re-positioned, so the path "/readme.txt" would map to "~/home/readme.txt". Most of the methods of an FS object are pretty self-explanatory, but there are a few that require explanation. Try the following for example:

>>> projects = home . opendir ( 'projects' ) # Assumes there is a directory called ~/projects >>> projects <SubFS: /projects in <OSFS: /home/will>> >>> browse ( projects )

There is no concept of a working directory for FS objects. Rather than something like 'chdir' there is an opendir method that returns a new FS object representing everything under the sub-directory root. So if you were to do projects.open("test.py"), it would return a file object for "~/projects/test.py".

Have you ever wondered how much space the .py files take up in your home directory? Give this a try:

>>> print sum ( home . getsize ( path ) for path in home . walkfiles ( wildcard = "*.py" ))

Here's how you could use ZipFS to archive your projects folder:

>>> projects_archive = zipfs . ZipFS ( 'projects.zip' , 'w' ) >>> from fs.utils import copydir >>> copydir ( projects , projects_archive ) >>> projects_archive . close ()

If you are interested in learning more, have a look at the docstrings in base.py, or just ask me. I promise to get proper documentation up soon.

FS is politeware, you can use it for any purpose you like, as long as you say thanks!