Sunday, November 7, 2010

Writing a File Atomically from Python

I wanted to be able to write to a file, but there was a possibility that others could be reading from it while I was writing to it. So I came up with this code below (which I release as public domain) which should guarantee that the file gets written without anyone being able to read it until it is completely written to disk.

import os, os.path
import errno

def write(filename, data, mode=0600):
""" guarantees that noone can read filename with only partial data """
fd = None
seq = 1
dn = os.path.dirname(filename)
bn = os.path.basename(filename)
while fd == None:
try:
fn = os.path.join(dn,".%s.%d"%(bn,seq))
fd = os.open(fn, os.O_CREAT | os.O_EXCL | os.O_WRONLY, mode)
except OSError, e:
if e.errno == errno.EEXIST:
seq += 1
continue
else:
raise

# write data to temporary file
fo = os.fdopen(fd, "w")
fo.write(str(data))
fo.close
#os.close(fd)

# move file into place now that it is written
os.rename(fn, filename)

Outputting HTML5 via XML/XSLT

One of my web applications uses XSLT to transform some XML data into output. For a long time, I was convinced XHTML was the future. But now I've seen the light and HTML5 is the way to go. I want my app to be able to take advantage of all the HTML5 goodness while still retaining the content/view separation that using XML and XSLT has allowed me.

Content With Style had a good blog post highlighting this problem, but it seems that the doctype has since changed. The current HTML5 spec outlines the current accepted doctype including the doctype that XSLT-generated documents can use.

So here's the xsl:output string I needed to use:

<xsl:output method="html"
doctype-system="about:legacy-compat"
indent="yes"/>