Monthly Archives: June 2010

Win32 Python: getting user’s display name using ctypes

This post explains how you can obtain the user’s display name (a.k.a. “real name” or “full name”) in Windows, using Python’s ctypes module. However, it also serves as a mini tutorial/demonstration of ctypes.

First, a bit of background. I researched this while working on a patch for Jokosher. When you create a new project in Jokosher, it will prompt you with a dialog asking for the name of the project and so on. One of the fields in this dialog is the Author field, which by default should be filled with the logged-in user’s real name. While there are several ways to get the user’s login ID (a.k.a. “username”), there is no easy way to get their real name (display name) in Windows.

This is where ctypes and GetUserNameEx come in. ctypes is a Python library that lets you call C functions. GetUserNameEx is the C function in Win32 API that we want to call.

For the impatient, here is the full code. Continue reading if you want to know how it works and maybe learn a bit about ctypes. Otherwise, copy away. Note, however, that it does not have any error checking whatsoever.

import ctypes

def get_display_name():
	GetUserNameEx = ctypes.windll.secur32.GetUserNameExW
	NameDisplay = 3

	size = ctypes.pointer(ctypes.c_ulong(0))
	GetUserNameEx(NameDisplay, None, size)

	nameBuffer = ctypes.create_unicode_buffer(size.contents.value)
	GetUserNameEx(NameDisplay, nameBuffer, size)
	return nameBuffer.value

Continue reading

Advertisements

Using matplotlib in a Web application

matplotlib‘s FAQ has a section dealing with the exact topic of this post: using matplotlib in a web application server. The problem is that I couldn’t find it easily from my Web searches. What I’m doing here is adding my own twist to the answer, and hopefully making it slightly more search-friendly.

While testing a Web app that I was working on, I noticed that it would often hang. At first I dismissed it as a server problem, but it kept occuring on one particular page. A few hours and many head scratches later, I narrowed the problem down to matplotlib.

# Negative example; do not use.

import matplotlib.pyplot as plt

def callback():
	# ... (process data)
	fig = plt.figure()
	# ... (draw stuff)
	fig.savefile(path)

I used matplotlib to draw a plot and save it to a file. The code was quite long, but it involved steps similar to the above listing. The first time it ran, everything went OK. The second time, it always hung at the pyplot.figure call. This smelled like a threading / deadlock problem, so I tried to put a lock on the pyplot calls (which I should have done anyway, considering pyplot operates on a single plot at a time). Still, it didn’t work.

After some Web searches and more head scratching, I accidentally arrived at the FAQ entry mentioned earlier.

Here’s the gist of the available solutions.

First option: configure matplotlib to use the Anti-Grain Geometry backend. Continue using pyplot, carefully grouping its commands together and surrounding them with a lock.

from threading import Lock
lock = Lock()

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

def callback():
	# ... (process data)
	with lock:
		fig = pyplot.figure()
		# ... (draw stuff)
		fig.savefile(path)

Second, better option: dump pyplot and use matplotlib’s object-oriented API instead. For this one, you don’t need to care about threads or locking or whatever.

from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure

def callback():
	# ... (process data)
	fig = Figure()
	canvas = FigureCanvas(fig)
	# ... (draw stuff)
	canvas.print_figure(path)