<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Mouse Vs. The Python &#187; Windows</title>
	<atom:link href="http://www.blog.pythonlibrary.org/category/windows/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.blog.pythonlibrary.org</link>
	<description>Python Programming from the Frontlines</description>
	<lastBuildDate>Sun, 08 Jan 2012 12:45:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Python 101: Setting up Python on Windows</title>
		<link>http://www.blog.pythonlibrary.org/2011/11/24/python-101-setting-up-python-on-windows/</link>
		<comments>http://www.blog.pythonlibrary.org/2011/11/24/python-101-setting-up-python-on-windows/#comments</comments>
		<pubDate>Thu, 24 Nov 2011 15:32:38 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[PyWin32]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=2052</guid>
		<description><![CDATA[Python is pretty easy to install on Windows, but sometimes you need to do a few extra tweaks to really get the most our your development environment. In this article, we will try to cover all the common things you might want to do or install to get an ideal Python Windows development workspace set [...]]]></description>
			<content:encoded><![CDATA[<div class="socialize-in-content" style="float:left;"><div class="socialize-in-button socialize-in-button-left"><a href="http://twitter.com/share" class="twitter-share-button" data-counturl="http://www.blog.pythonlibrary.org/2011/11/24/python-101-setting-up-python-on-windows/" data-url="http://bit.ly/tTCkmJ" data-text="Python 101: Setting up Python on Windows" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-left"><iframe src="http://www.facebook.com/plugins/like.php?href=http://www.blog.pythonlibrary.org/2011/11/24/python-101-setting-up-python-on-windows/&amp;layout=button_count&amp;show_faces=true&amp;width=100&amp;action=like&amp;font=arial&amp;colorscheme=light&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px !important; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-left"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.blog.pythonlibrary.org/2011/11/24/python-101-setting-up-python-on-windows/";
			reddit_title = "Python 101: Setting up Python on Windows";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-left"><g:plusone size="small" href="http://www.blog.pythonlibrary.org/2011/11/24/python-101-setting-up-python-on-windows/"></g:plusone></div></div><p>Python is pretty easy to install on Windows, but sometimes you need to do a few extra tweaks to really get the most our your development environment. In this article, we will try to cover all the common things you might want to do or install to get an ideal Python Windows development workspace set up. Some of you might think that all you need to do is install Python and you&#8217;re done, but if you&#8217;re going to do Windows development, then you&#8217;ll need a few other packages to make it nicer.<span id="more-2052"></span></p>
<h2>Installing and Configuring Python</h2>
<p>Download <a href="http://www.python.org" target="_blank">Python</a> and run the installer. Make sure you got the version you want (i.e. Python 2.7 or 3.x). You&#8217;ll also want to make sure you get the bit type you want as there&#8217;s a 32-bit and a 64-bit version. <em>Note: The 32-bit Python will run just fine on a 64-bit system, but not vice versa!</em> Once you&#8217;ve got that installed, we&#8217;ll move on.</p>
<p>Now we’re going to make sure Python is set up right. Open a command window by going to Start –> Run and then typing “cmd” and pressing <strong>enter </strong>or <strong>return</strong>. Try typing “python” (without the quotes) in there and hitting your enter key. If you see the Python shell, then we’re halfway there. It should look something like this:</p>
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2011/11/python_shell.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2011/11/python_shell-300x148.png" alt="" title="python_shell" width="300" height="148" class="aligncenter size-medium wp-image-2069" /></a></p>
<p>If you don’t, then we need to modify some settings.</p>
<h3>Modifying Your Path</h3>
<p>On Windows, it can help a LOT to modify your Path settings by adding your Python path and the path to the Scripts folder to your System Path. Here&#8217;s one way that you can do it:</p>
<ol>
<li>Right-Click &#8220;My Computer&#8221; and choose <strong>Properties </strong>(Windows XP) or you may have to go digging in Control Panel on Windows 7 and do a &#8220;Show All Control Panel Items&#8221; from the path bar and look for <strong>System</strong>. You should see something like this:
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2011/08/system_properties_xp.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2011/08/system_properties_xp.png" alt="" title="system_properties_xp" width="419" height="479" class="aligncenter size-full wp-image-1891" /></a></p>
</li>
<li>Go to the <strong>Advanced</strong> tab and press the <strong>Environmental Variable</strong> button to see something like the following:
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2011/08/environment_vars_xp.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2011/08/environment_vars_xp.png" alt="" title="environment_vars_xp" width="384" height="423" class="aligncenter size-full wp-image-1894" /></a>
</li>
<li>You will see two types of variables here. In the bottom section are <strong>System Variables</strong>. Scroll down to the one labeled <strong>Path</strong> and at the end of that, add the following two lines: ;C:\Python26;C:\Python26\Scripts  (adjust as necessary according to your version of Python and its location) Note that each entry is separated by a semi-colon, so make sure you do that too or this will not work!</li>
</ol>
<p>Now you should be able to run Python from the command line. Not only that, you&#8217;ll also be able to run the special scripts that were in Python&#8217;s Scripts folder. Why would you care? Well, if you install easy_install / SetupTools or pip, they will install stuff in the Scripts folder that you can run. Speaking of which, since you now have a brand new installation of Python, let&#8217;s take a moment to show you how to install a 3rd party package.</p>
<h2>How to Install a Package on Windows</h2>
<p>We will use pip as our example. It is used for the easy installation of Python packages from the Python Packages Index (PyPI, not to be confused with PyPy). Anyway, you&#8217;ll need to go <a href="http://pypi.python.org/pypi/pip" target="_blank">here</a> to download it. The pip package is in a tarred and gzipped download at the bottom of the page. You&#8217;ll probably need something like <a href="http://www.izarc.org/" target="_blank">IZArc</a> or <a href="http://www.filzip.com/" target="_blank">Filzip</a> to unzip it since Windows doesn&#8217;t unzip tar files natively.</p>
<p>Open up a command line window as you did before. Now you will need to use the &#8220;cd&#8221; command to change directories to the location that you unzipped the files to. This can take some practice. On my machine, I usually unzip to my desktop and just cd there and then into the unzipped package. Once you&#8217;re in the folder that has the <strong>setup.py</strong> file in it, all you need to do to install it is to type the following:</p>
<p><code><br />
python setup.py install<br />
</code></p>
<p>Most of the time, this works great and the package is installed correctly. Occasionally, you will run into certain packages that complain that they need a compiler. If you don&#8217;t have one installed (like Visual Studio or MingW), then you won&#8217;t be able to install the package this way. You will have to find a pre-packaged installer for it. On my machine, I usually have easy_install installed too. For some reason, the package is called <a href="http://pypi.python.org/pypi/setuptools" target="_blank">SetupTools </a>. Anyway, the main reason that you used to need easy_install was that it was the defacto standard for install Python Eggs, which you can read about <a href="http://mrtopf.de/blog/en/a-small-introduction-to-python-eggs/" target="_blank">here</a> or <a href="http://packages.python.org/distribute/easy_install.html" target="_blank">here</a>. Now you can use pip or <a href="http://pypi.python.org/pypi/distribute" target="_blank">distribute</a> to do the same thing. All three can also install packages that are in compressed archives. Normally, all you have to do to install a package with one of these utilities is something like this:</p>
<p><code><br />
easy_install PackageName<br />
pip install PackageName<br />
</code></p>
<p>Read their respective docs for more information though.</p>
<h2>Other Handy Packages for Windows Developers</h2>
<p>If you are a serious Windows developer who will need access to Windows APIs, then you will require the <a href="http://sourceforge.net/projects/pywin32/" target="_blank">PyWin32</a> package. You&#8217;ll want to become familiar with <a href="http://docs.python.org/library/ctypes.html" target="_blank">ctypes </a>too, but that&#8217;s been included with Python since version 2.5. PyWin32 is a lightweight wrapper around the Windows APIs. You can actually look on MSDN for the API documentation and almost directly translate it into Python. The ctypes package put on an even lower level and can be used to interact with DLLs directly, among many other things.</p>
<p>Another common need when programming on Windows is access to Window Management Instrumentation (WMI). Fortunately, Tim Golden has written a nice <a href="http://timgolden.me.uk/python/wmi/index.html" target="_blank">wmi module</a>. You can usually get the same information using PyWin32, but it&#8217;s more convoluted than just using WMI. Tim Golden has also written several other utilities:</p>
<ul>
<li><a href="http://timgolden.me.uk/python/winsys/index.html" target="_blank">WinSys</a> &#8211; Python tools for the Windows Administrator</li>
<li><a href="http://timgolden.me.uk/python/winshell.html" target="_blank">winshell</a> &#8211; a utility for getting Windows paths easily</li>
<li>An <a href="http://timgolden.me.uk/python/active_directory.html" target="_blank">Active Directory</a> wrapper</li>
</ul>
<p>You should also check out his awesome &#8220;<a href="http://timgolden.me.uk/python/win32_how_do_i.html" target="_blank">How Do I</a>&#8221; series of tutorials. </p>
<p>Finally, Python includes a module called <strong>_winreg</strong> that you can use to gain access to the Windows Registry. It&#8217;s a very powerful tool that&#8217;s very useful if you do a lot of administrative scripting on Windows.</p>
<h2>Other Python Installations for Windows</h2>
<p>The comments section started filling up with people mentioning the special Python installations you can get that actually include PyWin32 and other packages all wrapped up in one installer. That is also an option. Here are a few of those:</p>
<ul>
<li>PythonXY &#8211; This one includes a TON of other packages, including PyWin32, SciPy, wxPython, NumPy and dozens of others. It looks like a jack of all trades. I have not used this one, but it sounds interesting.</li>
<li>The <a href="http://www.enthought.com/products/getepd.php" target="_blank">Enthought Python Distribution</a> &#8211; That link is their paid version, but there&#8217;s also a <a href="http://enthought.com/products/epd_free.php" target="_blank">lightweight free version</a> available too.</li>
<li><a href="http://www.activestate.com/activepython/downloads" target="_blank">ActivePython </a>from ActiveState &#8211; this one has been around for a long time and includes the PyWin32 documentation and various other tools.</li>
</ul>
<h2>Wrapping Up</h2>
<p>You should now have all the tools you need to be an effective Windows developer with Python. If you need help, the PyWin32 and ctypes mailing lists are active and they have experts there that can answer just about anything you&#8217;d want to know about those packages.</p>
<h2>Further Reading</h2>
<ul>
<li>A Python Windows Registry <a href="http://www.blog.pythonlibrary.org/2010/03/20/pythons-_winreg-editing-the-windows-registry/" target="_blank">tutorial</a></li>
<li>Some other article on MvP about <a href="http://www.blog.pythonlibrary.org/tag/windows/" target="_blank">Windows and Python</a></li>
<li>Official <a href="http://docs.python.org/using/windows.html" target="_blank">Python documentation</a> on Windows</li>
<li>Another tutorial on <a href="http://www.imladris.com/Scripts/PythonForWindows.html" target="_blank">Python on Windows</a></li>
<li>PyWin32 <a href="http://docs.activestate.com/activepython/2.7/pywin32/PyWin32.HTML" target="_blank">documentation </a>from ActiveState</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2011/11/24/python-101-setting-up-python-on-windows/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>TurboGears 2: Setting up on Windows</title>
		<link>http://www.blog.pythonlibrary.org/2011/08/14/turbogears-2-setting-up-on-windows/</link>
		<comments>http://www.blog.pythonlibrary.org/2011/08/14/turbogears-2-setting-up-on-windows/#comments</comments>
		<pubDate>Sun, 14 Aug 2011 17:51:09 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[TurboGears]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Web Framework]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Python Web Frameworks]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=1885</guid>
		<description><![CDATA[TurboGears is one of several web frameworks for Python that are available. The most popular by far is Django. Where I work, we chose TurboGears because of its integration with SQLAlchemy which supports composite keys. At that time, Django did not support that feature and I am not sure if it does yet. Anyway, I [...]]]></description>
			<content:encoded><![CDATA[<div class="socialize-in-content" style="float:left;"><div class="socialize-in-button socialize-in-button-left"><a href="http://twitter.com/share" class="twitter-share-button" data-counturl="http://www.blog.pythonlibrary.org/2011/08/14/turbogears-2-setting-up-on-windows/" data-url="http://bit.ly/tE5Abk" data-text="TurboGears 2: Setting up on Windows" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-left"><iframe src="http://www.facebook.com/plugins/like.php?href=http://www.blog.pythonlibrary.org/2011/08/14/turbogears-2-setting-up-on-windows/&amp;layout=button_count&amp;show_faces=true&amp;width=100&amp;action=like&amp;font=arial&amp;colorscheme=light&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px !important; height:65px;" allowTransparency="true"></iframe></div></div><p>TurboGears is one of several web frameworks for Python that are available. The most popular by far is Django. Where I work, we chose TurboGears because of its integration with SQLAlchemy which supports composite keys. At that time, Django did not support that feature and I am not sure if it does yet. Anyway, I develop almost exclusively on a Windows box and have found the TurboGears&#8217; documentation on the subject a little confusing. So here&#8217;s how I do it. </p>
<p><em>Note: We&#8217;ll be using TurboGears 2.1 in this tutorial</em><span id="more-1885"></span></p>
<h2>Getting Started</h2>
<p>We&#8217;re going to make sure Python is set up right first. Open a command window by going to <strong>Start &#8211;> Run</strong> and then typing &#8220;cmd&#8221; and pressing <strong>enter</strong>. Try typing &#8220;python&#8221; (without the quotes) in there and hitting your enter. If you see the Python shell, then we&#8217;re halfway there. If you don&#8217;t, then we need to modify some settings.</p>
<h3>Modifying Your Path</h3>
<p>On Windows, I have found that it helps a LOT to modify my Path settings by adding my Python path and the path to the Scripts folder to my Path. Here&#8217;s how you do it:</p>
<ol>
<li>Right-Click &#8220;My Computer&#8221; and choose <strong>Properties </strong>(Windows XP) or you may have to go digging in Control Panel on Windows 7 and do a &#8220;Show All Control Panel Items&#8221; from the path bar and look for <strong>System</strong>. You should see something like this:
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2011/08/system_properties_xp.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2011/08/system_properties_xp.png" alt="" title="system_properties_xp" width="419" height="479" class="aligncenter size-full wp-image-1891" /></a></p>
</li>
<li>Go to the <strong>Advanced</strong> tab and press the <strong>Environmental Variable</strong> button to see something like the following:
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2011/08/environment_vars_xp.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2011/08/environment_vars_xp.png" alt="" title="environment_vars_xp" width="384" height="423" class="aligncenter size-full wp-image-1894" /></a>
</li>
<li>You will see two types of variables here. In the bottom section are <strong>System Variables</strong>. Scroll down to the one labeled <strong>Path</strong> and at the end of that, add the following two lines: ;C:\Python26;C:\Python26\Scripts  (adjust as necessary according to your version of Python and its location) Note that each entry is separated by a semi-colon, so make sure you do that too or this will not work!</li>
</ol>
<p><strong><br />
<h3>Installing Prerequisites</h3>
<p></strong></p>
<p>Once that&#8217;s done, we need to make sure you have SetupTools installed. Go to the Python Package Index and <a href="http://pypi.python.org/pypi/setuptools" target="_blank">download </a>it if you know you don&#8217;t already have it as SetupTools will install a little script known as easy_install that will make getting TurboGears setup a breeze. Just scroll to the end of the page and pick the exe that corresponds to your Python version. You cannot install an egg unless you already have this installed, so I don&#8217;t know why they have eggs on there to begin with.</p>
<p>Once that&#8217;s done, open a new command window and try typing in the following: easy_install. You should receive an error like this: &#8220;error: No urls, filenames, or requirements specified (see &#8211;help)&#8221; If you do, then you&#8217;ve got it installed and on your path. Good job! </p>
<p>The TurboGears people recommend installing virtualenv to help keep your primary Python installation (PyPI) as pristine as possible. It also helps when you need to experiment with different versions of software that you don&#8217;t want to break current projects. How does this work? Well, virtualenv creates a little virtual workspace for you on your machine where it puts a copy of Python and installs all the software into that virtual place for you to play with. It&#8217;s a development sandbox! Since you now have easy_install, we&#8217;ll use that to install it. In your command window, type: easy_install virtualenv</p>
<p>That will cause easy_install to go out on the internet and try to download and install virtualenv from PyPI. It should look something like this:</p>
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2011/08/install_virtualenv.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2011/08/install_virtualenv.png" alt="" title="install_virtualenv" width="572" height="323" class="aligncenter size-full wp-image-1895" /></a></p>
<p>If it completed successfully, then we&#8217;re ready to create a virtual environment for our TurboGears install. Change directories to a location that you&#8217;d like to do this in. On Windows 7, you&#8217;ll probably have security issues if you try to do this outside of your Documents or similar Collections folders, so you should stick with one of those. For this tutorial, we&#8217;ll create it in <strong>My Documents</strong>.</p>
<p>Once you&#8217;re there, type the following: virtualenv &#8211;no-site-packages example</p>
<p>This will create a folder that&#8217;s labeled &#8220;example&#8221; with several folders inside it. You should see the following on your screen:</p>
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2011/08/virtualenv_example.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2011/08/virtualenv_example.png" alt="" title="virtualenv_example" width="440" height="156" class="aligncenter size-full wp-image-1902" /></a></p>
<p>The &#8211;no-site-packages command will prevent the virtual environment from inheriting anything from the system Python&#8217;s site-packages folder. Now change directory into your example folder in the command window and type the following: Scripts\activate.bat  (see screenshot below)</p>
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2011/08/virtualenv_activate.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2011/08/virtualenv_activate.png" alt="" title="virtualenv_activate" width="544" height="276" class="aligncenter size-full wp-image-1898" /></a></p>
<h2>Installing &#038; Setting Up TurboGears</h2>
<p>Now your virtual environment is active and ready to rock. You can tell because each line is now prefixed with the name of the folder you&#8217;re in, which in this case is &#8220;example&#8221;. You can install Turbogears at this point as your virtual environment also has Setup Tools installed. However, this install is a little different as we will be specifying a specific URL. Type the following (you may want to check the TurboGears website to see if the URL has been updated since the writing of this post):</p>
<p><code><br />
easy_install.exe -i http://www.turbogears.org/2.1/downloads/current/index tg.devtools<br />
</code></p>
<p>Depending on the speed of your PC and your connection, this will take a while. TurboGears is a mashup of a large number of 3rd party Python packages. You can watch it install or you can go get a drink or make a phone call while you wait. Once that&#8217;s finished, we&#8217;re nearly done. </p>
<p><em>Note: All the packages should be installing to your virtual space&#8217;s <strong>lib</strong> folder, NOT your default Python&#8217;s. If the latter is happening, you probably don&#8217;t have the virtual environment activated<br />
</em></p>
<p><strong><br />
<h3>Creating a TurboGears Workspace</h3>
<p></strong></p>
<p>One of the packages we installed earlier was Python Paste. TurboGears uses this package to bootstrap a new TurboGears application. So in your activated virtual environment, type the following command:</p>
<p><code><br />
paster quickstart example<br />
</code></p>
<p><em>Note: If your path to the &#8220;example&#8221; folder has a space in it, you will receive an error about needing the PyWin32 library installed. Very annoying.</em></p>
<p>When you run this, you will need to answer 3 questions. The first is what to name the project. The default is the same name as the folder. Note that the project name has to be in lowercase. Then it asks if you&#8217;d like to use <a href="http://www.makotemplates.org/" target="_blank">Mako templates</a>. What it doesn&#8217;t say is that if you choose no (which is the default), you will get <a href="http://genshi.edgewall.org/" target="_blank">Genshi templates</a> instead. That&#8217;s up to you. Mako looks and feels more &#8220;pythonic&#8221; from what I&#8217;ve seen of it, so I&#8217;d recommend it unless you already know Genshi or something like Genshi. The last question is whether or not you want authentication, which will give you a simple admin interface that you can login to, the default of which is &#8220;yes&#8221;. You can experiment with these or just take the defaults.</p>
<p>The next step is to change directories into your new project directory and then type the following in at the command line:</p>
<p><code><br />
python setup.py develop<br />
</code></p>
<p>This adds your project to the virtual environment and also downloads a few packages to install alongside it that might be useful in your development. I don&#8217;t really know how these help you, but it seems to be a requirement of sorts according to <a href="http://turbogears.org/2.1/docs/main/DownloadInstall.html" target="_blank">TurboGear&#8217;s documentation</a>.</p>
<p>The next to last step is to input the following into your command line window:</p>
<p><code><br />
paster setup-app development.ini<br />
</code></p>
<p>This will initiate your database, which is basically just creating and populating with some default information for the security / authentication you agreed to. If you didn&#8217;t install that stuff or don&#8217;t want to run this step, you don&#8217;t have to. But you won&#8217;t be able to login unless you do.</p>
<p>Finally, you need to type the following:</p>
<p><code><br />
paster serve development.ini<br />
</code></p>
<p>Now you will have a fully functioning website that&#8217;s running on <a href="http://localhost:8080/ " target="_blank">http://localhost:8080/ (or http://127.0.0.1:8080) </a>. If you load up your browser and navigate to that you should see something like this:</p>
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2011/08/default_tg_web.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2011/08/default_tg_web-300x198.png" alt="" title="default_tg_web" width="300" height="198" class="aligncenter size-medium wp-image-1904" /></a></p>
<h2>Wrapping Up</h2>
<p>Now you should know how to install and setup a TurboGears web application. The sky&#8217;s the limit after all that work. You&#8217;ll need to start reading the documentation, add a dash of javascript and a bit of CSS and you&#8217;ll have a cool website in no time. Good luck and have fun!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2011/08/14/turbogears-2-setting-up-on-windows/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PyWin32: adodbapi and MS Access</title>
		<link>http://www.blog.pythonlibrary.org/2011/02/01/pywin32-adodbapi-and-ms-access/</link>
		<comments>http://www.blog.pythonlibrary.org/2011/02/01/pywin32-adodbapi-and-ms-access/#comments</comments>
		<pubDate>Tue, 01 Feb 2011 15:38:08 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[PyWin32]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[adodbapi]]></category>
		<category><![CDATA[microsoft access]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=1650</guid>
		<description><![CDATA[Last week, there was an interesting thread on the PyWin32 mailing list about how to read Microsoft Access databases with Python without having Access actually installed. Vernon Cole had the solution, but I noticed that Google doesn&#8217;t seem to index the PyWin32 list very well, so I decided to write about it here. I took [...]]]></description>
			<content:encoded><![CDATA[<div class="socialize-in-content" style="float:left;"><div class="socialize-in-button socialize-in-button-left"><a href="http://twitter.com/share" class="twitter-share-button" data-counturl="http://www.blog.pythonlibrary.org/2011/02/01/pywin32-adodbapi-and-ms-access/" data-url="http://bit.ly/uosxG3" data-text="PyWin32: adodbapi and MS Access" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-left"><iframe src="http://www.facebook.com/plugins/like.php?href=http://www.blog.pythonlibrary.org/2011/02/01/pywin32-adodbapi-and-ms-access/&amp;layout=button_count&amp;show_faces=true&amp;width=100&amp;action=like&amp;font=arial&amp;colorscheme=light&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px !important; height:65px;" allowTransparency="true"></iframe></div></div><p>Last week, there was an interesting thread on the <a href="http://mail.python.org/pipermail/python-win32/2011-January/011086.html">PyWin32 mailing list</a> about how to read Microsoft Access databases with Python without having Access actually installed. Vernon Cole had the solution, but I noticed that Google doesn&#8217;t seem to index the PyWin32 list very well, so I decided to write about it here.<span id="more-1650"></span></p>
<p>I took his code and modified it slightly to make it even more explicit and I put together a lame database file with Microsoft Access XP (downloadable below). The <a href="http://adodbapi.sourceforge.net/">adodbapi</a> module&#8217;s (not to be confused with the adodb module) source distribution also includes a test database in its &#8220;test&#8221; folder that you can use as well. Anyway, here&#8217;s the code:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> adodbapi
&nbsp;
database = <span style="color: #483d8b;">&quot;db1.mdb&quot;</span>
constr = <span style="color: #483d8b;">'Provider=Microsoft.Jet.OLEDB.4.0; Data Source=%s'</span>  <span style="color: #66cc66;">%</span> database
tablename = <span style="color: #483d8b;">&quot;address&quot;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># connect to the database</span>
conn = adodbapi.<span style="color: black;">connect</span><span style="color: black;">&#40;</span>constr<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># create a cursor</span>
cur = conn.<span style="color: black;">cursor</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># extract all the data</span>
sql = <span style="color: #483d8b;">&quot;select * from %s&quot;</span> <span style="color: #66cc66;">%</span> tablename
cur.<span style="color: black;">execute</span><span style="color: black;">&#40;</span>sql<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># show the result</span>
result = cur.<span style="color: black;">fetchall</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> item <span style="color: #ff7700;font-weight:bold;">in</span> result:
    <span style="color: #ff7700;font-weight:bold;">print</span> item
&nbsp;
<span style="color: #808080; font-style: italic;"># close the cursor and connection</span>
cur.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
conn.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>This code was tested on the following:</p>
<ul>
<li>Windows XP Professional with Python 2.5.4 and adodbapi 2.4.0 with Microsoft Access installed</li>
<li>Windows 7 Home Premium (32-bit) with Python 2.6.4, adodbapi 2.2.6, without Microsoft Access</li>
</ul>
<h2>Downloads</h2>
<ul>
<li><a href='http://www.blog.pythonlibrary.org/wp-content/uploads/2011/02/adodbapi_access.zip'>adodbapi_access.zip</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2011/02/01/pywin32-adodbapi-and-ms-access/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Python: Changing Microsoft Office User Initials</title>
		<link>http://www.blog.pythonlibrary.org/2010/10/27/python-changing-microsoft-office-user-initials/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/10/27/python-changing-microsoft-office-user-initials/#comments</comments>
		<pubDate>Wed, 27 Oct 2010 23:37:36 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[System Administration]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Microsoft Office]]></category>
		<category><![CDATA[Registry]]></category>
		<category><![CDATA[System Admin]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=1350</guid>
		<description><![CDATA[A couple of months ago at work, we received a report that a file was locked. The dialog that appeared showed the initials of a user who wasn&#8217;t even working for us any more. Thus we discovered an annoying bug that can crop up with Office. Basically, a user is asked by Word or Excel [...]]]></description>
			<content:encoded><![CDATA[<div class="socialize-in-content" style="float:left;"><div class="socialize-in-button socialize-in-button-left"><a href="http://twitter.com/share" class="twitter-share-button" data-counturl="http://www.blog.pythonlibrary.org/2010/10/27/python-changing-microsoft-office-user-initials/" data-url="http://bit.ly/sLXXCS" data-text="Python: Changing Microsoft Office User Initials" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-left"><iframe src="http://www.facebook.com/plugins/like.php?href=http://www.blog.pythonlibrary.org/2010/10/27/python-changing-microsoft-office-user-initials/&amp;layout=button_count&amp;show_faces=true&amp;width=100&amp;action=like&amp;font=arial&amp;colorscheme=light&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px !important; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-left"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.blog.pythonlibrary.org/2010/10/27/python-changing-microsoft-office-user-initials/";
			reddit_title = "Python: Changing Microsoft Office User Initials";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-left"><g:plusone size="small" href="http://www.blog.pythonlibrary.org/2010/10/27/python-changing-microsoft-office-user-initials/"></g:plusone></div></div><p>A couple of months ago at work, we received a report that a file was locked. The dialog that appeared showed the initials of a user who wasn&#8217;t even working for us any more. Thus we discovered an annoying bug that can crop up with Office. Basically, a user is asked by Word or Excel to input their name and initials during the first run of that respective application and it will keep that data no matter who logs into the machine later on. This can lead to some serious confusion when we get error messages of this sort. Anyway, let&#8217;s take a quick look at how to get this done.<span id="more-1350"></span></p>
<p>We will be using Python&#8217;s <strong>_winreg</strong> module for this hack. You can see said hack below:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">_winreg</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
&nbsp;
key = CreateKey<span style="color: black;">&#40;</span>HKEY_CURRENT_USER,
                r<span style="color: #483d8b;">'Software<span style="color: #000099; font-weight: bold;">\M</span>icrosoft<span style="color: #000099; font-weight: bold;">\O</span>ffice<span style="color: #000099; font-weight: bold;">\1</span>1.0<span style="color: #000099; font-weight: bold;">\C</span>ommon<span style="color: #000099; font-weight: bold;">\U</span>serInfo'</span><span style="color: black;">&#41;</span>
res = QueryValueEx<span style="color: black;">&#40;</span>key, <span style="color: #483d8b;">&quot;UserInitials&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">repr</span> <span style="color: black;">&#40;</span>res<span style="color: black;">&#41;</span>
&nbsp;
username = u<span style="color: #483d8b;">&quot;mldr<span style="color: #000099; font-weight: bold;">\0</span>&quot;</span>
SetValueEx<span style="color: black;">&#40;</span>key, <span style="color: #483d8b;">&quot;UserInitials&quot;</span>, <span style="color: #ff4500;">0</span>, REG_BINARY, username<span style="color: black;">&#41;</span>
CloseKey<span style="color: black;">&#40;</span>key<span style="color: black;">&#41;</span></pre>
<p>Here we use the <strong>CreateKey</strong> method just in case the key doesn&#8217;t already exist. If the key does exist, then CreateKey will just open it. The first half of the script was used for checking to see if the key had the correct value in it. The last three lines overwrite the value with my initials. I can&#8217;t remember why I had to make a unicode string, but the guys on PyWin32 told me that was the way to do it. I can tell you that I wasn&#8217;t ever able to get a plain string to work. Once the value is set, we clean up after ourselves by closing the key.</p>
<p>That&#8217;s it! Easy, eh? Have fun with Python!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/10/27/python-changing-microsoft-office-user-initials/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SqlAlchemy and Microsoft Access</title>
		<link>http://www.blog.pythonlibrary.org/2010/10/10/sqlalchemy-and-microsoft-access/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/10/10/sqlalchemy-and-microsoft-access/#comments</comments>
		<pubDate>Sun, 10 Oct 2010 13:04:23 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[SqlAlchemy]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[databases]]></category>
		<category><![CDATA[microsoft access]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=1291</guid>
		<description><![CDATA[Update (10/12/2010) &#8211; One of my alert readers told me that SqlAlchemy 0.6.x currently does NOT support the Access dialect. Read here for more info. A year or two ago, I was asked to transfer some data from some old Microsoft Access files to our Microsoft SQL Server. Since I enjoy using SqlAlchemy, I decided [...]]]></description>
			<content:encoded><![CDATA[<div class="socialize-in-content" style="float:left;"><div class="socialize-in-button socialize-in-button-left"><a href="http://twitter.com/share" class="twitter-share-button" data-counturl="http://www.blog.pythonlibrary.org/2010/10/10/sqlalchemy-and-microsoft-access/" data-url="http://bit.ly/sjoTVA" data-text="SqlAlchemy and Microsoft Access" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-left"><iframe src="http://www.facebook.com/plugins/like.php?href=http://www.blog.pythonlibrary.org/2010/10/10/sqlalchemy-and-microsoft-access/&amp;layout=button_count&amp;show_faces=true&amp;width=100&amp;action=like&amp;font=arial&amp;colorscheme=light&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px !important; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-left"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.blog.pythonlibrary.org/2010/10/10/sqlalchemy-and-microsoft-access/";
			reddit_title = "SqlAlchemy and Microsoft Access";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-left"><g:plusone size="small" href="http://www.blog.pythonlibrary.org/2010/10/10/sqlalchemy-and-microsoft-access/"></g:plusone></div></div><p><strong>Update (10/12/2010) &#8211; One of my alert readers told me that SqlAlchemy 0.6.x currently does NOT support the Access dialect. Read <a href="http://www.sqlalchemy.org/docs/reference/dialects/index.html">here </a>for more info.</strong></p>
<p>A year or two ago, I was asked to transfer some data from some old Microsoft Access files to our Microsoft SQL Server. Since I enjoy using SqlAlchemy, I decided to see if it supported Access. The documentation at the time was pretty unhelpful in this regard, but it did seem to be possible and I found one thread about it on SqlAlchemy&#8217;s Google group.<span id="more-1291"></span></p>
<p>The code to connect to Microsoft Access is pretty simple. It goes something like this:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">from</span> sqlalchemy <span style="color: #ff7700;font-weight:bold;">import</span> create_engine
engine = create_engine<span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'access:///C:/some/path/database.MDB'</span><span style="color: black;">&#41;</span></pre>
<p>See how easy that was? You just tell SqlAlchemy what kind of database to connect to, add three forward slashes and then the path to the file. Once that&#8217;s done, you can do pretty much anything with the Access file that you can do with a normal database:</p>
<pre class="python"><span style="color: #808080; font-style: italic;">########################################################################</span>
<span style="color: #ff7700;font-weight:bold;">class</span> TableName<span style="color: black;">&#40;</span>Base<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    MS Access database
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    __tablename__ = <span style="color: #483d8b;">&quot;ROW&quot;</span>
    __table_args__ = <span style="color: black;">&#40;</span><span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;autoload&quot;</span>:<span style="color: #008000;">True</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>  <span style="color: #808080; font-style: italic;"># load the database</span>
    FILENUM = Column<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;FILE #&quot;</span>, Integer, key=<span style="color: #483d8b;">&quot;FILENUM&quot;</span><span style="color: black;">&#41;</span></pre>
<p>In the code above, I use SqlAlchemy&#8217;s declarative syntax to autoload the database&#8217;s structure. I can&#8217;t recall is this database had its primary key set, but I&#8217;m guessing it didn&#8217;t since I had to add that last line.</p>
<p>Anyway, once you have your connection, you can just run queries as you normally would. In my case, I ended up creating a model file to hold all the table definitions for the Access file and the SQL Server database, then I did a SELECT * on the Access file, looped over the result and inserted each row into the SQL Server one. The only thing you have to watch out for is that Access is a lot more forgiving of NULLS than SQL Server is, so I had to write some special handling around that atrocity.</p>
<p>Well, that&#8217;s really all there is to it. You can check out my other SqlAlchemy tutorials for more general information about using SqlAlchemy to interact with your database.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/10/10/sqlalchemy-and-microsoft-access/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>How to Find and List All Running Processes with Python</title>
		<link>http://www.blog.pythonlibrary.org/2010/10/03/how-to-find-and-list-all-running-processes-with-python/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/10/03/how-to-find-and-list-all-running-processes-with-python/#comments</comments>
		<pubDate>Sun, 03 Oct 2010 18:34:46 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[System Administration]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[System Admin]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=1271</guid>
		<description><![CDATA[The other day, I was tasked with finding a way to get a list of all running processes on a Windows XP virtual machine. I was also supposed to include information about how much CPU and memory each process used. Fortunately, this didn&#8217;t have to be a remote script, but one that could be run [...]]]></description>
			<content:encoded><![CDATA[<div class="socialize-in-content" style="float:left;"><div class="socialize-in-button socialize-in-button-left"><a href="http://twitter.com/share" class="twitter-share-button" data-counturl="http://www.blog.pythonlibrary.org/2010/10/03/how-to-find-and-list-all-running-processes-with-python/" data-url="http://bit.ly/sJkCrz" data-text="How to Find and List All Running Processes with Python" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-left"><iframe src="http://www.facebook.com/plugins/like.php?href=http://www.blog.pythonlibrary.org/2010/10/03/how-to-find-and-list-all-running-processes-with-python/&amp;layout=button_count&amp;show_faces=true&amp;width=100&amp;action=like&amp;font=arial&amp;colorscheme=light&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px !important; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-left"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.blog.pythonlibrary.org/2010/10/03/how-to-find-and-list-all-running-processes-with-python/";
			reddit_title = "How to Find and List All Running Processes with Python";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-left"><g:plusone size="small" href="http://www.blog.pythonlibrary.org/2010/10/03/how-to-find-and-list-all-running-processes-with-python/"></g:plusone></div></div><p>The other day, I was tasked with finding a way to get a list of all running processes on a Windows XP virtual machine. I was also supposed to include information about how much CPU and memory each process used. Fortunately, this didn&#8217;t have to be a remote script, but one that could be run on the client. After a fair bit of Googling here and there, I finally found a solution. In this article, we&#8217;ll look at some of the rejects as well as the eventual solution, which happens to work cross-platform.<span id="more-1271"></span></p>
<p>One of the first scripts I found was <a href="http://mail.python.org/pipermail/python-win32/2006-March/004340.html">this one</a> back from March of 2006:</p>
<pre class="python"><span style="color: #808080; font-style: italic;"># http://mail.python.org/pipermail/python-win32/2006-March/004340.html</span>
<span style="color: #ff7700;font-weight:bold;">import</span> win32com.<span style="color: black;">client</span>
wmi=win32com.<span style="color: black;">client</span>.<span style="color: black;">GetObject</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'winmgmts:'</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> p <span style="color: #ff7700;font-weight:bold;">in</span> wmi.<span style="color: black;">InstancesOf</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'win32_process'</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span> p.<span style="color: black;">Name</span>, p.<span style="color: black;">Properties_</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'ProcessId'</span><span style="color: black;">&#41;</span>, \
        <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>p.<span style="color: black;">Properties_</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'UserModeTime'</span><span style="color: black;">&#41;</span>.<span style="color: black;">Value</span><span style="color: black;">&#41;</span>+<span style="color: #008000;">int</span><span style="color: black;">&#40;</span>p.<span style="color: black;">Properties_</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'KernelModeTime'</span><span style="color: black;">&#41;</span>.<span style="color: black;">Value</span><span style="color: black;">&#41;</span>
    children=wmi.<span style="color: black;">ExecQuery</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Select * from win32_process where ParentProcessId=%s'</span> <span style="color: #66cc66;">%</span>p.<span style="color: black;">Properties_</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'ProcessId'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> child <span style="color: #ff7700;font-weight:bold;">in</span> children:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\t</span>'</span>,child.<span style="color: black;">Name</span>,child.<span style="color: black;">Properties_</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'ProcessId'</span><span style="color: black;">&#41;</span>, \
            <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>child.<span style="color: black;">Properties_</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'UserModeTime'</span><span style="color: black;">&#41;</span>.<span style="color: black;">Value</span><span style="color: black;">&#41;</span>+<span style="color: #008000;">int</span><span style="color: black;">&#40;</span>child.<span style="color: black;">Properties_</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'KernelModeTime'</span><span style="color: black;">&#41;</span>.<span style="color: black;">Value</span><span style="color: black;">&#41;</span></pre>
<p>This script requires the <a href="http://sourceforge.net/projects/pywin32/">PyWin32 package</a> to work. However, while it&#8217;s a handy little script, it doesn&#8217;t show anything that I want except the ProcessId. I don&#8217;t really care about the user or kernel mode times (i.e. the total CPU time by user or kernel). Also I don&#8217;t really like working with the black magic of COM, so I ended up rejecting this one out of hand.</p>
<p>Next up was an <a href="http://code.activestate.com/recipes/303339-getting-process-information-on-windows/">ActiveState recipe</a>. It looked promising:</p>
<pre class="python"><span style="color: #808080; font-style: italic;"># http://code.activestate.com/recipes/303339-getting-process-information-on-windows/</span>
<span style="color: #ff7700;font-weight:bold;">import</span> win32pdh, <span style="color: #dc143c;">string</span>, win32api
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> procids<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;">#each instance is a process, you can have multiple processes w/same name</span>
    junk, instances = win32pdh.<span style="color: black;">EnumObjectItems</span><span style="color: black;">&#40;</span><span style="color: #008000;">None</span>,<span style="color: #008000;">None</span>,<span style="color: #483d8b;">'process'</span>, win32pdh.<span style="color: black;">PERF_DETAIL_WIZARD</span><span style="color: black;">&#41;</span>
    proc_ids=<span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
    proc_dict=<span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> instance <span style="color: #ff7700;font-weight:bold;">in</span> instances:
        <span style="color: #ff7700;font-weight:bold;">if</span> instance <span style="color: #ff7700;font-weight:bold;">in</span> proc_dict:
            proc_dict<span style="color: black;">&#91;</span>instance<span style="color: black;">&#93;</span> = proc_dict<span style="color: black;">&#91;</span>instance<span style="color: black;">&#93;</span> + <span style="color: #ff4500;">1</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            proc_dict<span style="color: black;">&#91;</span>instance<span style="color: black;">&#93;</span>=<span style="color: #ff4500;">0</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> instance, max_instances <span style="color: #ff7700;font-weight:bold;">in</span> proc_dict.<span style="color: black;">items</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">for</span> inum <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">xrange</span><span style="color: black;">&#40;</span>max_instances<span style="color: #ff4500;">+1</span><span style="color: black;">&#41;</span>:
            hq = win32pdh.<span style="color: black;">OpenQuery</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># initializes the query handle </span>
            path = win32pdh.<span style="color: black;">MakeCounterPath</span><span style="color: black;">&#40;</span> <span style="color: black;">&#40;</span><span style="color: #008000;">None</span>,<span style="color: #483d8b;">'process'</span>,instance, <span style="color: #008000;">None</span>, inum,<span style="color: #483d8b;">'ID Process'</span><span style="color: black;">&#41;</span> <span style="color: black;">&#41;</span>
            counter_handle=win32pdh.<span style="color: black;">AddCounter</span><span style="color: black;">&#40;</span>hq, path<span style="color: black;">&#41;</span>
            win32pdh.<span style="color: black;">CollectQueryData</span><span style="color: black;">&#40;</span>hq<span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;">#collects data for the counter </span>
            <span style="color: #008000;">type</span>, val = win32pdh.<span style="color: black;">GetFormattedCounterValue</span><span style="color: black;">&#40;</span>counter_handle, win32pdh.<span style="color: black;">PDH_FMT_LONG</span><span style="color: black;">&#41;</span>
            proc_ids.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>instance,<span style="color: #008000;">str</span><span style="color: black;">&#40;</span>val<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            win32pdh.<span style="color: black;">CloseQuery</span><span style="color: black;">&#40;</span>hq<span style="color: black;">&#41;</span>
&nbsp;
    proc_ids.<span style="color: black;">sort</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> proc_ids
&nbsp;
<span style="color: #ff7700;font-weight:bold;">print</span> procids<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>Alas, while this also got me a list of processes from my Windows box (along with the PID), it didn&#8217;t give me any information on the CPU and memory utilization. I think this one could work if I used different counter names. I&#8217;m guessing if you wanted, you could figure out that information using MSDN. I didn&#8217;t want to mess with that, so I continued digging.</p>
<p>That recipe led me to the following one based on ctypes:</p>
<pre class="python"><span style="color: #808080; font-style: italic;"># http://code.activestate.com/recipes/305279/</span>
&nbsp;
<span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
Enumerates active processes as seen under windows Task Manager on Win NT/2k/XP using PSAPI.dll
(new api for processes) and using ctypes.Use it as you please.
&nbsp;
Based on information from http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q175030&amp;ID=KB;EN-US;Q175030
&nbsp;
By Eric Koome
email ekoome@yahoo.com
license GPL
&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
<span style="color: #ff7700;font-weight:bold;">from</span> ctypes <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#PSAPI.DLL</span>
psapi = windll.<span style="color: black;">psapi</span>
<span style="color: #808080; font-style: italic;">#Kernel32.DLL</span>
kernel = windll.<span style="color: black;">kernel32</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> EnumProcesses<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    arr = c_ulong <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">256</span>
    lpidProcess= arr<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    cb = sizeof<span style="color: black;">&#40;</span>lpidProcess<span style="color: black;">&#41;</span>
    cbNeeded = c_ulong<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    hModule = c_ulong<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    count = c_ulong<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    modname = c_buffer<span style="color: black;">&#40;</span><span style="color: #ff4500;">30</span><span style="color: black;">&#41;</span>
    PROCESS_QUERY_INFORMATION = 0x0400
    PROCESS_VM_READ = 0x0010
&nbsp;
    <span style="color: #808080; font-style: italic;">#Call Enumprocesses to get hold of process id's</span>
    psapi.<span style="color: black;">EnumProcesses</span><span style="color: black;">&#40;</span>byref<span style="color: black;">&#40;</span>lpidProcess<span style="color: black;">&#41;</span>,
                        cb,
                        byref<span style="color: black;">&#40;</span>cbNeeded<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#Number of processes returned</span>
    nReturned = cbNeeded.<span style="color: black;">value</span>/sizeof<span style="color: black;">&#40;</span>c_ulong<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    pidProcess = <span style="color: black;">&#91;</span>i <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> lpidProcess<span style="color: black;">&#93;</span><span style="color: black;">&#91;</span>:nReturned<span style="color: black;">&#93;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">for</span> pid <span style="color: #ff7700;font-weight:bold;">in</span> pidProcess:
&nbsp;
        <span style="color: #808080; font-style: italic;">#Get handle to the process based on PID</span>
        hProcess = kernel.<span style="color: black;">OpenProcess</span><span style="color: black;">&#40;</span>PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
                                      <span style="color: #008000;">False</span>, pid<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> hProcess:
            psapi.<span style="color: black;">EnumProcessModules</span><span style="color: black;">&#40;</span>hProcess, byref<span style="color: black;">&#40;</span>hModule<span style="color: black;">&#41;</span>, sizeof<span style="color: black;">&#40;</span>hModule<span style="color: black;">&#41;</span>, byref<span style="color: black;">&#40;</span>count<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            psapi.<span style="color: black;">GetModuleBaseNameA</span><span style="color: black;">&#40;</span>hProcess, hModule.<span style="color: black;">value</span>, modname, sizeof<span style="color: black;">&#40;</span>modname<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;&quot;</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span> i <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> modname <span style="color: #ff7700;font-weight:bold;">if</span> i <span style="color: #66cc66;">!</span>= <span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\x</span>00'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
            <span style="color: #808080; font-style: italic;">#-- Clean up</span>
            <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span>modname._length_<span style="color: black;">&#41;</span>:
                modname<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span>=<span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\x</span>00'</span>
&nbsp;
            kernel.<span style="color: black;">CloseHandle</span><span style="color: black;">&#40;</span>hProcess<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    EnumProcesses<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>This is pretty clever looking, but I&#8217;m pretty bad at parsing ctypes. It&#8217;s something I want to learn, but I had a deadline, doggone it! Plus this one only showed a list of running processes but no information about them. Fortunately, the author included a reference, but I decided to keep looking.</p>
<p>Next I found a thread about using Tim Golden&#8217;s handy <a href="http://tgolden.sc.sabren.com/python/wmi/index.html">WMI module</a> to do this sort of thing (below is copied right from the thread):</p>
<pre class="python"><span style="color: #808080; font-style: italic;"># http://mail.python.org/pipermail/python-win32/2003-December/001482.html</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> processes = WMI.<span style="color: black;">InstancesOf</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Win32_Process'</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>processes<span style="color: black;">&#41;</span>
<span style="color: #ff4500;">41</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: black;">&#91;</span>process.<span style="color: black;">Properties_</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Name'</span><span style="color: black;">&#41;</span>.<span style="color: black;">Value</span> <span style="color: #ff7700;font-weight:bold;">for</span> process <span style="color: #ff7700;font-weight:bold;">in</span> processes<span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># get</span>
the process names
<span style="color: black;">&#91;</span>u<span style="color: #483d8b;">'System Idle Process'</span>, u<span style="color: #483d8b;">'System'</span>, u<span style="color: #483d8b;">'SMSS.EXE'</span>, u<span style="color: #483d8b;">'CSRSS.EXE'</span>,
u<span style="color: #483d8b;">'WINLOGON.EXE'</span>, u<span style="color: #483d8b;">'SERVICES.EXE'</span>, u<span style="color: #483d8b;">'LSASS.EXE'</span>, u<span style="color: #483d8b;">'SVCHOST.EXE'</span>,
u<span style="color: #483d8b;">'SVCHOST.EXE'</span>, u<span style="color: #483d8b;">'SVCHOST.EXE'</span>, u<span style="color: #483d8b;">'SVCHOST.EXE'</span>, u<span style="color: #483d8b;">'SPOOLSV.EXE'</span>,
u<span style="color: #483d8b;">'ati2evxx.exe'</span>, u<span style="color: #483d8b;">'BAsfIpM.exe'</span>, u<span style="color: #483d8b;">'defwatch.exe'</span>, u<span style="color: #483d8b;">'inetinfo.exe'</span>,
u<span style="color: #483d8b;">'mdm.exe'</span>, u<span style="color: #483d8b;">'rtvscan.exe'</span>, u<span style="color: #483d8b;">'SCARDSVR.EXE'</span>, u<span style="color: #483d8b;">'WLTRYSVC.EXE'</span>,
u<span style="color: #483d8b;">'BCMWLTRY.EXE'</span>, u<span style="color: #483d8b;">'EXPLORER.EXE'</span>, u<span style="color: #483d8b;">'Apoint.exe'</span>, u<span style="color: #483d8b;">'carpserv.exe'</span>,
u<span style="color: #483d8b;">'atiptaxx.exe'</span>, u<span style="color: #483d8b;">'quickset.exe'</span>, u<span style="color: #483d8b;">'DSentry.exe'</span>, u<span style="color: #483d8b;">'Directcd.exe'</span>,
u<span style="color: #483d8b;">'vptray.exe'</span>, u<span style="color: #483d8b;">'ApntEx.exe'</span>, u<span style="color: #483d8b;">'FaxCtrl.exe'</span>, u<span style="color: #483d8b;">'digstream.exe'</span>,
u<span style="color: #483d8b;">'CTFMON.EXE'</span>, u<span style="color: #483d8b;">'wuauclt.exe'</span>, u<span style="color: #483d8b;">'IEXPLORE.EXE'</span>, u<span style="color: #483d8b;">'Pythonwin.exe'</span>,
u<span style="color: #483d8b;">'MMC.EXE'</span>, u<span style="color: #483d8b;">'OUTLOOK.EXE'</span>, u<span style="color: #483d8b;">'LineMgr.exe'</span>, u<span style="color: #483d8b;">'SAPISVR.EXE'</span>,
u<span style="color: #483d8b;">'WMIPRVSE.EXE'</span><span style="color: black;">&#93;</span>
&nbsp;
Here <span style="color: #ff7700;font-weight:bold;">is</span> how to get a single process <span style="color: #ff7700;font-weight:bold;">and</span> get its PID.
&nbsp;
<span style="color: #66cc66;">&gt;&gt;&gt;</span> p = WMI.<span style="color: black;">ExecQuery</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'select * from Win32_Process where
Name=&quot;Pythonwin.exe&quot;'</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: black;">&#91;</span>prop.<span style="color: black;">Name</span> <span style="color: #ff7700;font-weight:bold;">for</span> prop <span style="color: #ff7700;font-weight:bold;">in</span> p<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>.<span style="color: black;">Properties_</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># let's look at all the</span>
process <span style="color: #008000;">property</span> names
<span style="color: black;">&#91;</span>u<span style="color: #483d8b;">'Caption'</span>, u<span style="color: #483d8b;">'CommandLine'</span>, u<span style="color: #483d8b;">'CreationClassName'</span>, u<span style="color: #483d8b;">'CreationDate'</span>,
u<span style="color: #483d8b;">'CSCreationClassName'</span>, u<span style="color: #483d8b;">'CSName'</span>, u<span style="color: #483d8b;">'Description'</span>, u<span style="color: #483d8b;">'ExecutablePath'</span>,
u<span style="color: #483d8b;">'ExecutionState'</span>, u<span style="color: #483d8b;">'Handle'</span>, u<span style="color: #483d8b;">'HandleCount'</span>, u<span style="color: #483d8b;">'InstallDate'</span>,
u<span style="color: #483d8b;">'KernelModeTime'</span>, u<span style="color: #483d8b;">'MaximumWorkingSetSize'</span>, u<span style="color: #483d8b;">'MinimumWorkingSetSize'</span>,
u<span style="color: #483d8b;">'Name'</span>, u<span style="color: #483d8b;">'OSCreationClassName'</span>, u<span style="color: #483d8b;">'OSName'</span>, u<span style="color: #483d8b;">'OtherOperationCount'</span>,
u<span style="color: #483d8b;">'OtherTransferCount'</span>, u<span style="color: #483d8b;">'PageFaults'</span>, u<span style="color: #483d8b;">'PageFileUsage'</span>,
u<span style="color: #483d8b;">'ParentProcessId'</span>, u<span style="color: #483d8b;">'PeakPageFileUsage'</span>, u<span style="color: #483d8b;">'PeakVirtualSize'</span>,
u<span style="color: #483d8b;">'PeakWorkingSetSize'</span>, u<span style="color: #483d8b;">'Priority'</span>, u<span style="color: #483d8b;">'PrivatePageCount'</span>, u<span style="color: #483d8b;">'ProcessId'</span>,
u<span style="color: #483d8b;">'QuotaNonPagedPoolUsage'</span>, u<span style="color: #483d8b;">'QuotaPagedPoolUsage'</span>,
u<span style="color: #483d8b;">'QuotaPeakNonPagedPoolUsage'</span>, u<span style="color: #483d8b;">'QuotaPeakPagedPoolUsage'</span>,
u<span style="color: #483d8b;">'ReadOperationCount'</span>, u<span style="color: #483d8b;">'ReadTransferCount'</span>, u<span style="color: #483d8b;">'SessionId'</span>, u<span style="color: #483d8b;">'Status'</span>,
u<span style="color: #483d8b;">'TerminationDate'</span>, u<span style="color: #483d8b;">'ThreadCount'</span>, u<span style="color: #483d8b;">'UserModeTime'</span>, u<span style="color: #483d8b;">'VirtualSize'</span>,
u<span style="color: #483d8b;">'WindowsVersion'</span>, u<span style="color: #483d8b;">'WorkingSetSize'</span>, u<span style="color: #483d8b;">'WriteOperationCount'</span>,
u<span style="color: #483d8b;">'WriteTransferCount'</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> p<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>.<span style="color: black;">Properties_</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'ProcessId'</span><span style="color: black;">&#41;</span>.<span style="color: black;">Value</span> <span style="color: #808080; font-style: italic;"># get our ProcessId</span>
<span style="color: #ff4500;">928</span></pre>
<p>This is some cool stuff and I use Golden&#8217;s modules in some of my other code. However, I was still uncertain as to which counters to use to get to my information. I thought most of this stuff would just be coded for me or something! Well, it turned out that there is a package out there that does exactly what I needed AND it works on all the three of the major platforms! Amazing!</p>
<h2>The Cross-Platform Solution!</h2>
<p>The package&#8217;s name is <a href="http://code.google.com/p/psutil/">psutil</a> and it was what I decided to use. Here&#8217;s what I ended up with:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
<span style="color: #ff7700;font-weight:bold;">import</span> psutil
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
&nbsp;
logPath = r<span style="color: #483d8b;">'some<span style="color: #000099; font-weight: bold;">\p</span>ath<span style="color: #000099; font-weight: bold;">\p</span>roclogs'</span>
<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">exists</span><span style="color: black;">&#40;</span>logPath<span style="color: black;">&#41;</span>:
    <span style="color: #dc143c;">os</span>.<span style="color: black;">mkdir</span><span style="color: black;">&#40;</span>logPath<span style="color: black;">&#41;</span>
&nbsp;
separator = <span style="color: #483d8b;">&quot;-&quot;</span> <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">80</span>
format = <span style="color: #483d8b;">&quot;%7s %7s %12s %12s %30s, %s&quot;</span>
format2 = <span style="color: #483d8b;">&quot;%7.4f %7.2f %12s %12s %30s, %s&quot;</span>
<span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #ff4500;">1</span>:
    procs = psutil.<span style="color: black;">get_process_list</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    procs = <span style="color: #008000;">sorted</span><span style="color: black;">&#40;</span>procs, key=<span style="color: #ff7700;font-weight:bold;">lambda</span> proc: proc.<span style="color: black;">name</span><span style="color: black;">&#41;</span>
&nbsp;
    logPath = r<span style="color: #483d8b;">'some<span style="color: #000099; font-weight: bold;">\p</span>ath<span style="color: #000099; font-weight: bold;">\p</span>roclogs<span style="color: #000099; font-weight: bold;">\p</span>rocLog%i.log'</span> <span style="color: #66cc66;">%</span> <span style="color: #008000;">int</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    f = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span>logPath, <span style="color: #483d8b;">'w'</span><span style="color: black;">&#41;</span>
    f.<span style="color: black;">write</span><span style="color: black;">&#40;</span>separator + <span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: black;">&#41;</span>
    f.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">time</span>.<span style="color: black;">ctime</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> + <span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: black;">&#41;</span>
    f.<span style="color: black;">write</span><span style="color: black;">&#40;</span>format <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;%CPU&quot;</span>, <span style="color: #483d8b;">&quot;%MEM&quot;</span>, <span style="color: #483d8b;">&quot;VMS&quot;</span>, <span style="color: #483d8b;">&quot;RSS&quot;</span>, <span style="color: #483d8b;">&quot;NAME&quot;</span>, <span style="color: #483d8b;">&quot;PATH&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    f.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">for</span> proc <span style="color: #ff7700;font-weight:bold;">in</span> procs:
        cpu_percent = proc.<span style="color: black;">get_cpu_percent</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        mem_percent = proc.<span style="color: black;">get_memory_percent</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        rss, vms = proc.<span style="color: black;">get_memory_info</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        rss = <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>rss<span style="color: black;">&#41;</span>
        vms = <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>vms<span style="color: black;">&#41;</span>
        name = proc.<span style="color: black;">name</span>
        path = proc.<span style="color: black;">path</span>
        f.<span style="color: black;">write</span><span style="color: black;">&#40;</span>format2 <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>cpu_percent, mem_percent, vms, rss, name, path<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        f.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: black;">&#41;</span>
    f.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Finished log update!&quot;</span>
    <span style="color: #dc143c;">time</span>.<span style="color: black;">sleep</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">300</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;writing new log data!&quot;</span></pre>
<p>Yes, it&#8217;s an infinite loop and yes, that&#8217;s usually a very bad thing to do (except in GUI programming). However, for my purpose, I needed a way to check the user&#8217;s processes every 5 minutes or so to see what was causing the machine to act so weird. Thus, the script needs to run forever and log the results to uniquely named files. That&#8217;s all this script does, along with a little formatting magic. Feel free to use it or not as you see fit.</p>
<p>I hope you found this collection of material helpful. Hopefully it will save you all the digging I went through!</p>
<p><em>Note: While this last script appears to work just fine on Windows XP, on Windows 7 32 and 64-bit, you will get an &#8220;Access Denied&#8221; traceback, I suspect this is caused by Window 7&#8242;s increased security, but I will try to find a workaround.</p>
<p>UPDATE (10/09/2010) &#8211; The psutil folks don&#8217;t know why it doesn&#8217;t work, but one of their developers has confirmed the issue. You can follow along on their <a href="http://groups.google.com/group/psutil/browse_frm/thread/ec8bf72fa18f79a2">Google Groups list</a>.<br />
</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/10/03/how-to-find-and-list-all-running-processes-with-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting Remote Drive Space on Windows</title>
		<link>http://www.blog.pythonlibrary.org/2010/09/09/getting-remote-drive-space-on-windows/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/09/09/getting-remote-drive-space-on-windows/#comments</comments>
		<pubDate>Thu, 09 Sep 2010 22:50:00 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[System Administration]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[System Admin]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=1196</guid>
		<description><![CDATA[After about a year or so at my current job, as we were still working on upgrading the last few Windows 98 machines to Windows XP, we had a need to check which machines on our network were getting low on disk space. The issue was cropping up because we had Windows XP loaded on [...]]]></description>
			<content:encoded><![CDATA[<div class="socialize-in-content" style="float:left;"><div class="socialize-in-button socialize-in-button-left"><a href="http://twitter.com/share" class="twitter-share-button" data-counturl="http://www.blog.pythonlibrary.org/2010/09/09/getting-remote-drive-space-on-windows/" data-url="http://bit.ly/vX4W5I" data-text="Getting Remote Drive Space on Windows" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-left"><iframe src="http://www.facebook.com/plugins/like.php?href=http://www.blog.pythonlibrary.org/2010/09/09/getting-remote-drive-space-on-windows/&amp;layout=button_count&amp;show_faces=true&amp;width=100&amp;action=like&amp;font=arial&amp;colorscheme=light&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px !important; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-left"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.blog.pythonlibrary.org/2010/09/09/getting-remote-drive-space-on-windows/";
			reddit_title = "Getting Remote Drive Space on Windows";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-left"><g:plusone size="small" href="http://www.blog.pythonlibrary.org/2010/09/09/getting-remote-drive-space-on-windows/"></g:plusone></div></div><p>After about a year or so at my current job, as we were still working on upgrading the last few Windows 98 machines to Windows XP, we had a need to check which machines on our network were getting low on disk space. The issue was cropping up because we had Windows XP loaded on several machines that had 10 GB hard drives and a few with 20 GB and one or two with just 4 GB. Anyway, after some digging online, I discovered that the PyWin32 package could accomplish what I needed.<span id="more-1196"></span></p>
<p>Here is the code that I used:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> win32com.<span style="color: black;">client</span> as com
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> TotalSize<span style="color: black;">&#40;</span>drive<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot; Return the TotalSize of a shared drive [GB]&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        fso = com.<span style="color: black;">Dispatch</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Scripting.FileSystemObject&quot;</span><span style="color: black;">&#41;</span>
        drv = fso.<span style="color: black;">GetDrive</span><span style="color: black;">&#40;</span>drive<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> drv.<span style="color: black;">TotalSize</span>/<span style="color: #ff4500;">2</span><span style="color: #66cc66;">**</span><span style="color: #ff4500;">30</span>
    <span style="color: #ff7700;font-weight:bold;">except</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #ff4500;">0</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> FreeSpace<span style="color: black;">&#40;</span>drive<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot; Return the FreeSpace of a shared drive [GB]&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        fso = com.<span style="color: black;">Dispatch</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Scripting.FileSystemObject&quot;</span><span style="color: black;">&#41;</span>
        drv = fso.<span style="color: black;">GetDrive</span><span style="color: black;">&#40;</span>drive<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> drv.<span style="color: black;">FreeSpace</span>/<span style="color: #ff4500;">2</span><span style="color: #66cc66;">**</span><span style="color: #ff4500;">30</span>
    <span style="color: #ff7700;font-weight:bold;">except</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #ff4500;">0</span>
&nbsp;
workstations = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'computeNameOne'</span><span style="color: black;">&#93;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Hard drive sizes:'</span>
<span style="color: #ff7700;font-weight:bold;">for</span> compName <span style="color: #ff7700;font-weight:bold;">in</span> workstations:
    drive = <span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\\</span><span style="color: #000099; font-weight: bold;">\\</span>'</span> + compName + <span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\\</span>c$'</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'*************************************************<span style="color: #000099; font-weight: bold;">\n</span>'</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> compName
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'TotalSize of %s = %f GB'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>drive, TotalSize<span style="color: black;">&#40;</span>drive<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'FreeSpace on %s = %f GB'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>drive, FreeSpace<span style="color: black;">&#40;</span>drive<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'*************************************************<span style="color: #000099; font-weight: bold;">\n</span>'</span></pre>
<p>Note at the bottom that I used a list. Normally, I would list the computer names of every computer that I wanted to check. Then I would iterate over those names and put together the right path that I needed from a machine with full domain admin rights.</p>
<p>To get this to work, we needed to import win32com.client and call the following: <strong>com.Dispatch(&#8220;Scripting.FileSystemObject&#8221;)</strong>. This would get us a COM object that we could query to get a disk object. Once we had that, we can ask the disk how much total space it had and how much free space. Looking at this code today, I would combine the two functions into one and return a tuple. As you can see, I do a little bit of math on the result to get it to return the size in gigabytes. </p>
<p>That&#8217;s all there is to it. Simple stuff. I suspect that I didn&#8217;t write this code completely since the variable names suck. It is probably from an ActiveState recipe or a forum and I forgot to attribute it. If you recognize the code, let me know in the comments!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/09/09/getting-remote-drive-space-on-windows/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>A bbfreeze Tutorial &#8211; Build a Binary Series!</title>
		<link>http://www.blog.pythonlibrary.org/2010/08/19/a-bbfreeze-tutorial-build-a-binary-series/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/08/19/a-bbfreeze-tutorial-build-a-binary-series/#comments</comments>
		<pubDate>Thu, 19 Aug 2010 13:23:23 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Packaging]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[bbfreeze]]></category>
		<category><![CDATA[binaries]]></category>
		<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Distribution]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=1137</guid>
		<description><![CDATA[The bbfreeze package also allows us to create binaries, but only on Linux and Windows. It&#8217;s just an easy_install away, so if you plan on following along with the examples in the article, you should go get it. The bbfreeze package includes egg support, so it can include egg dependencies in your binary, unlike py2exe. [...]]]></description>
			<content:encoded><![CDATA[<div class="socialize-in-content" style="float:left;"><div class="socialize-in-button socialize-in-button-left"><a href="http://twitter.com/share" class="twitter-share-button" data-counturl="http://www.blog.pythonlibrary.org/2010/08/19/a-bbfreeze-tutorial-build-a-binary-series/" data-url="http://bit.ly/t6R0h2" data-text="A bbfreeze Tutorial &#8211; Build a Binary Series!" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-left"><iframe src="http://www.facebook.com/plugins/like.php?href=http://www.blog.pythonlibrary.org/2010/08/19/a-bbfreeze-tutorial-build-a-binary-series/&amp;layout=button_count&amp;show_faces=true&amp;width=100&amp;action=like&amp;font=arial&amp;colorscheme=light&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px !important; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-left"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.blog.pythonlibrary.org/2010/08/19/a-bbfreeze-tutorial-build-a-binary-series/";
			reddit_title = "A bbfreeze Tutorial &#8211; Build a Binary Series!";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-left"><g:plusone size="small" href="http://www.blog.pythonlibrary.org/2010/08/19/a-bbfreeze-tutorial-build-a-binary-series/"></g:plusone></div></div><p>The bbfreeze package also allows us to create binaries, but only on Linux and Windows. It&#8217;s just an easy_install away, so if you plan on following along with the examples in the article, you should go get it. The bbfreeze package includes egg support, so it can include egg dependencies in your binary, unlike py2exe. You can also freeze multiple scripts at once, include the Python interpreter and more. According to bbfreeze&#8217;s PyPI entry, it&#8217;s only been tested with Python 2.4-2.5, so keep that in mind. However, I was able to use it with Python 2.6 with no obvious problems.<span id="more-1137"></span></p>
<h2>Getting Started with bbfreeze</h2>
<p>You can use easy_install to download and install bbfreeze or you can just download its source or the egg file directly from the <a href="http://pypi.python.org/pypi/bbfreeze/">Python Package Index</a> (PyPI). In this article, we&#8217;ll try using it on a simple configuration file generator script and we&#8217;ll also try it against a lame wxPython program. My test machine was a Windows 7 Home Edition 32-bit laptop with bbfreeze 0.96.5, and Python 2.6.4. Let&#8217;s start with the configuration script:</p>
<pre class="python"><span style="color: #808080; font-style: italic;"># config_1.py</span>
<span style="color: #ff7700;font-weight:bold;">import</span> configobj
&nbsp;
<span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">def</span> createConfig<span style="color: black;">&#40;</span>configFile<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Create the configuration file
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    config = configobj.<span style="color: black;">ConfigObj</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    inifile = configFile
    config.<span style="color: black;">filename</span> = inifile
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'server'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;http://www.google.com&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'username'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;mike&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'password'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;dingbat&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'update interval'</span><span style="color: black;">&#93;</span> = <span style="color: #ff4500;">2</span>
    config.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">def</span> getConfig<span style="color: black;">&#40;</span>configFile<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Open the config file and return a configobj
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> configobj.<span style="color: black;">ConfigObj</span><span style="color: black;">&#40;</span>configFile<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> createConfig2<span style="color: black;">&#40;</span>path<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Create a config file
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    config = configobj.<span style="color: black;">ConfigObj</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    config.<span style="color: black;">filename</span> = path
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span> = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;product&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;Sony PS3&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;accessories&quot;</span><span style="color: black;">&#93;</span> = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'controller'</span>, <span style="color: #483d8b;">'eye'</span>, <span style="color: #483d8b;">'memory stick'</span><span style="color: black;">&#93;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;retail price&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;$400&quot;</span>
    config.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    createConfig2<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;sampleConfig2.ini&quot;</span><span style="color: black;">&#41;</span></pre>
<p>This script has a couple of functions that are pointless, but we&#8217;ll leave them in for illustrative purposes. According to the bbfreeze documentation, we should be able to create a binary with the following string typed into the command line:</p>
<p><code><br />
bb-freeze config_1.py<br />
</code></p>
<p>This assumes that you have &#8220;C:\Python26\Scripts&#8221; on your path. If you don&#8217;t, you&#8217;ll need to type the complete path out (i.e. &#8220;C:\Python26\Scripts\bb-freeze config_1.py&#8221;). When I ran this, I got an error. Here it is:</p>
<pre class="python">Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;C:<span style="color: #000099; font-weight: bold;">\P</span>ython26<span style="color: #000099; font-weight: bold;">\S</span>cripts<span style="color: #000099; font-weight: bold;">\b</span>b-freeze-script.py&quot;</span>, line <span style="color: #ff4500;">8</span>, <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #66cc66;">&lt;</span>module<span style="color: #66cc66;">&gt;</span>
    load_entry_point<span style="color: black;">&#40;</span><span style="color: #483d8b;">'bbfreeze==0.96.5'</span>, <span style="color: #483d8b;">'console_scripts'</span>, <span style="color: #483d8b;">'bb-freeze'</span><span style="color: black;">&#41;</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
  File <span style="color: #483d8b;">&quot;C:<span style="color: #000099; font-weight: bold;">\P</span>ython26<span style="color: #000099; font-weight: bold;">\l</span>ib<span style="color: #000099; font-weight: bold;">\s</span>ite-packages<span style="color: #000099; font-weight: bold;">\b</span>bfreeze-0.96.5-py2.6-win32.egg<span style="color: #000099; font-weight: bold;">\b</span>bfreeze<span style="color: #000099; font-weight: bold;">\_</span>_init__.py&quot;</span>, line <span style="color: #ff4500;">18</span>, <span style="color: #ff7700;font-weight:bold;">in</span> main
    f<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
  File <span style="color: #483d8b;">&quot;C:<span style="color: #000099; font-weight: bold;">\P</span>ython26<span style="color: #000099; font-weight: bold;">\l</span>ib<span style="color: #000099; font-weight: bold;">\s</span>ite-packages<span style="color: #000099; font-weight: bold;">\b</span>bfreeze-0.96.5-py2.6-win32.egg<span style="color: #000099; font-weight: bold;">\b</span>bfreeze<span style="color: #000099; font-weight: bold;">\f</span>reezer.py&quot;</span>, line <span style="color: #ff4500;">474</span>, <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #0000cd;">__call__</span>
    <span style="color: #008000;">self</span>.<span style="color: black;">addModule</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;encodings.*&quot;</span><span style="color: black;">&#41;</span>
  File <span style="color: #483d8b;">&quot;C:<span style="color: #000099; font-weight: bold;">\P</span>ython26<span style="color: #000099; font-weight: bold;">\l</span>ib<span style="color: #000099; font-weight: bold;">\s</span>ite-packages<span style="color: #000099; font-weight: bold;">\b</span>bfreeze-0.96.5-py2.6-win32.egg<span style="color: #000099; font-weight: bold;">\b</span>bfreeze<span style="color: #000099; font-weight: bold;">\f</span>reezer.py&quot;</span>, line <span style="color: #ff4500;">411</span>, <span style="color: #ff7700;font-weight:bold;">in</span> addModule
    <span style="color: #008000;">self</span>.<span style="color: black;">mf</span>.<span style="color: black;">import_hook</span><span style="color: black;">&#40;</span>name<span style="color: black;">&#91;</span>:<span style="color: #ff4500;">-2</span><span style="color: black;">&#93;</span>, fromlist=<span style="color: #483d8b;">&quot;*&quot;</span><span style="color: black;">&#41;</span>
  File <span style="color: #483d8b;">&quot;C:<span style="color: #000099; font-weight: bold;">\P</span>ython26<span style="color: #000099; font-weight: bold;">\l</span>ib<span style="color: #000099; font-weight: bold;">\s</span>ite-packages<span style="color: #000099; font-weight: bold;">\b</span>bfreeze-0.96.5-py2.6-win32.egg<span style="color: #000099; font-weight: bold;">\b</span>bfreeze<span style="color: #000099; font-weight: bold;">\m</span>odulegraph<span style="color: #000099; font-weight: bold;">\m</span>odulegraph.py&quot;</span>, line <span style="color: #ff4500;">256</span>, <span style="color: #ff7700;font-weight:bold;">in</span> import_hook
    modules.<span style="color: black;">update</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">ensure_fromlist</span><span style="color: black;">&#40;</span>m, fromlist<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
  File <span style="color: #483d8b;">&quot;C:<span style="color: #000099; font-weight: bold;">\P</span>ython26<span style="color: #000099; font-weight: bold;">\l</span>ib<span style="color: #000099; font-weight: bold;">\s</span>ite-packages<span style="color: #000099; font-weight: bold;">\b</span>bfreeze-0.96.5-py2.6-win32.egg<span style="color: #000099; font-weight: bold;">\b</span>bfreeze<span style="color: #000099; font-weight: bold;">\m</span>odulegraph<span style="color: #000099; font-weight: bold;">\m</span>odulegraph.py&quot;</span>, line <span style="color: #ff4500;">345</span>, <span style="color: #ff7700;font-weight:bold;">in</span> ensure_fromlist
    fromlist.<span style="color: black;">update</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">find_all_submodules</span><span style="color: black;">&#40;</span>m<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
  File <span style="color: #483d8b;">&quot;C:<span style="color: #000099; font-weight: bold;">\P</span>ython26<span style="color: #000099; font-weight: bold;">\l</span>ib<span style="color: #000099; font-weight: bold;">\s</span>ite-packages<span style="color: #000099; font-weight: bold;">\b</span>bfreeze-0.96.5-py2.6-win32.egg<span style="color: #000099; font-weight: bold;">\b</span>bfreeze<span style="color: #000099; font-weight: bold;">\m</span>odulegraph<span style="color: #000099; font-weight: bold;">\m</span>odulegraph.py&quot;</span>, line <span style="color: #ff4500;">369</span>, <span style="color: #ff7700;font-weight:bold;">in</span> find_all_submodules
    <span style="color: #ff7700;font-weight:bold;">for</span> <span style="color: black;">&#40;</span>path, mode, typ<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">in</span> ifilter<span style="color: black;">&#40;</span><span style="color: #008000;">None</span>, imap<span style="color: black;">&#40;</span>moduleInfoForPath, names<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
<span style="color: #008000;">NameError</span>: <span style="color: #ff7700;font-weight:bold;">global</span> name <span style="color: #483d8b;">'ifilter'</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> defined</pre>
<p>It would seem that the &#8220;modulegraph.py&#8221; file is missing an import from the <a href="http://docs.python.org/library/itertools.html">itertools</a> library, which is included with Python. I edited my copy of &#8220;modulegraph.py&#8221; to include the following line at the top of the file: &#8220;from itertools import ifilter&#8221;. This got rid of that traceback, but it raised another because &#8220;imap&#8221; wasn&#8217;t defined either. To fix the second error, I changed my import to &#8220;from itertools import ifilter,imap&#8221; and then it ran with no problems and produced a binary in a &#8220;dist&#8221; folder along with nine other files (see screenshot below).</p>
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/08/bbfreeze_dir.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/08/bbfreeze_dir.png" alt="bbfreeze_dir.png" title="bbfreeze_dir.png" width="599" height="324" class="aligncenter size-full wp-image-1148" /></a></p>
<h2>Using bbfreeze&#8217;s Advanced Configuration</h2>
<p>The PyPI page for bbfreeze (which is also its home page) has very little documentation. However, the page does say that the preferred way to use bbfreeze is with little scripts. We&#8217;re going to try using creating a binary with the lame wxPython, mentioned earlier. Here&#8217;s the wx code:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> wx
&nbsp;
<span style="color: #808080; font-style: italic;">########################################################################</span>
<span style="color: #ff7700;font-weight:bold;">class</span> DemoPanel<span style="color: black;">&#40;</span>wx.<span style="color: black;">Panel</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, parent<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;Constructor&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        wx.<span style="color: black;">Panel</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, parent<span style="color: black;">&#41;</span>
&nbsp;
        labels = <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Name&quot;</span>, <span style="color: #483d8b;">&quot;Address&quot;</span>, <span style="color: #483d8b;">&quot;City&quot;</span>, <span style="color: #483d8b;">&quot;State&quot;</span>, <span style="color: #483d8b;">&quot;Zip&quot;</span>,
                  <span style="color: #483d8b;">&quot;Phone&quot;</span>, <span style="color: #483d8b;">&quot;Email&quot;</span>, <span style="color: #483d8b;">&quot;Notes&quot;</span><span style="color: black;">&#93;</span>
&nbsp;
        mainSizer = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">VERTICAL</span><span style="color: black;">&#41;</span>
        lbl = wx.<span style="color: black;">StaticText</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label=<span style="color: #483d8b;">&quot;Please enter your information here:&quot;</span><span style="color: black;">&#41;</span>
        lbl.<span style="color: black;">SetFont</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">Font</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">12</span>, wx.<span style="color: black;">SWISS</span>, wx.<span style="color: black;">NORMAL</span>, wx.<span style="color: black;">BOLD</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        mainSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>lbl, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">for</span> lbl <span style="color: #ff7700;font-weight:bold;">in</span> labels:
            sizer = <span style="color: #008000;">self</span>.<span style="color: black;">buildControls</span><span style="color: black;">&#40;</span>lbl<span style="color: black;">&#41;</span>
            mainSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>sizer, <span style="color: #ff4500;">1</span>, wx.<span style="color: black;">EXPAND</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">SetSizer</span><span style="color: black;">&#40;</span>mainSizer<span style="color: black;">&#41;</span>
        mainSizer.<span style="color: black;">Layout</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> buildControls<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        sizer = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">HORIZONTAL</span><span style="color: black;">&#41;</span>
        size = <span style="color: black;">&#40;</span><span style="color: #ff4500;">80</span>,<span style="color: #ff4500;">40</span><span style="color: black;">&#41;</span>
        font = wx.<span style="color: black;">Font</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">12</span>, wx.<span style="color: black;">SWISS</span>, wx.<span style="color: black;">NORMAL</span>, wx.<span style="color: black;">BOLD</span><span style="color: black;">&#41;</span>
&nbsp;
        lbl = wx.<span style="color: black;">StaticText</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label=label, size=size<span style="color: black;">&#41;</span>
        lbl.<span style="color: black;">SetFont</span><span style="color: black;">&#40;</span>font<span style="color: black;">&#41;</span>
        sizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>lbl, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>|wx.<span style="color: black;">CENTER</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> label <span style="color: #66cc66;">!</span>= <span style="color: #483d8b;">&quot;Notes&quot;</span>:
            txt = wx.<span style="color: black;">TextCtrl</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, name=label<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            txt = wx.<span style="color: black;">TextCtrl</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, style=wx.<span style="color: black;">TE_MULTILINE</span>, name=label<span style="color: black;">&#41;</span>
        sizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>txt, <span style="color: #ff4500;">1</span>, wx.<span style="color: black;">ALL</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> sizer
&nbsp;
&nbsp;
&nbsp;
<span style="color: #808080; font-style: italic;">########################################################################</span>
<span style="color: #ff7700;font-weight:bold;">class</span> DemoFrame<span style="color: black;">&#40;</span>wx.<span style="color: black;">Frame</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Frame that holds all other widgets
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;Constructor&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        wx.<span style="color: black;">Frame</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #008000;">None</span>, wx.<span style="color: black;">ID_ANY</span>,
                          <span style="color: #483d8b;">&quot;cxFreeze Tutorial&quot;</span>,
                          size=<span style="color: black;">&#40;</span><span style="color: #ff4500;">600</span>,<span style="color: #ff4500;">400</span><span style="color: black;">&#41;</span>
                          <span style="color: black;">&#41;</span>
        panel = DemoPanel<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">Show</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    app = wx.<span style="color: black;">App</span><span style="color: black;">&#40;</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
    frame = DemoFrame<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    app.<span style="color: black;">MainLoop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>Now let&#8217;s create a simple freezing script!</p>
<pre class="python"><span style="color: #808080; font-style: italic;"># bb_setup.py</span>
<span style="color: #ff7700;font-weight:bold;">from</span> bbfreeze <span style="color: #ff7700;font-weight:bold;">import</span> Freezer
&nbsp;
f = Freezer<span style="color: black;">&#40;</span>distdir=<span style="color: #483d8b;">&quot;bb-binary&quot;</span><span style="color: black;">&#41;</span>
f.<span style="color: black;">addScript</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;sampleApp.py&quot;</span><span style="color: black;">&#41;</span>
f<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>First off, we import the <em>Freezer</em> class from the bbfreeze package. Freezer accepts three arguments: a destination folder, an includes iterable and an excludes iterable (i.e. a tuple or list). Just to see how well bbfreeze works with only its defaults, we leave out the includes and excludes tuples/lists. Once you have a Freezer object, you can add your script(s) by calling the Freezer object name&#8217;s <em>addScript</em> method. Then you just need to call the object (i.e.  f() ). If you do all that, you should end up with a 14.5 MB folder holding 18 files. When I ran the sampleApp.exe file, it ran just fine and was properly themed, however it also had a console screen. To figure out the correct syntax, I used <a href="http://code.google.com/p/gui2exe/">GUI2Exe</a>. Here&#8217;s the new code:</p>
<pre class="python"><span style="color: #808080; font-style: italic;"># bb_setup2.py</span>
<span style="color: #ff7700;font-weight:bold;">from</span> bbfreeze <span style="color: #ff7700;font-weight:bold;">import</span> Freezer
&nbsp;
includes = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
excludes = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'_gtkagg'</span>, <span style="color: #483d8b;">'_tkagg'</span>, <span style="color: #483d8b;">'bsddb'</span>, <span style="color: #483d8b;">'curses'</span>, <span style="color: #483d8b;">'email'</span>, <span style="color: #483d8b;">'pywin.debugger'</span>,
            <span style="color: #483d8b;">'pywin.debugger.dbgcon'</span>, <span style="color: #483d8b;">'pywin.dialogs'</span>, <span style="color: #483d8b;">'tcl'</span>,
            <span style="color: #483d8b;">'Tkconstants'</span>, <span style="color: #483d8b;">'Tkinter'</span><span style="color: black;">&#93;</span>
&nbsp;
bbFreeze_Class = Freezer<span style="color: black;">&#40;</span><span style="color: #483d8b;">'dist'</span>, includes=includes, excludes=excludes<span style="color: black;">&#41;</span>
&nbsp;
bbFreeze_Class.<span style="color: black;">addScript</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;sampleApp.py&quot;</span>, gui_only=<span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
&nbsp;
bbFreeze_Class.<span style="color: black;">use_compression</span> = <span style="color: #ff4500;">0</span>
bbFreeze_Class.<span style="color: black;">include_py</span> = <span style="color: #008000;">True</span>
bbFreeze_Class<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>If you run this, you should end up with a &#8220;dist&#8221; folder that contains 18 files and is 16.6 MB in size. Notice that we added a second argument to the <em>addScript</em> method: gui_only=True. This makes that annoying console go away. We also set compression to zero (no compression, I think) and include the Python interpreter. Turning on compression only reduced the result down to 14.3 MB though. </p>
<p>The bbfreeze package also handles &#8220;recipes&#8221; and includes several examples, however they are not documented well either and I couldn&#8217;t figure out how to include them with my current examples. Feel free to figure them out on your own!</p>
<h2>Wrapping Up</h2>
<p>Well, now you should know the basics of using bbfreeze to create binaries from your programs. I hope you found this helpful. The last article in this series will be on GUI2Exe. Look for it soon!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/08/19/a-bbfreeze-tutorial-build-a-binary-series/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A PyInstaller Tutorial &#8211; Build a Binary Series!</title>
		<link>http://www.blog.pythonlibrary.org/2010/08/10/a-pyinstaller-tutorial-build-a-binary-series/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/08/10/a-pyinstaller-tutorial-build-a-binary-series/#comments</comments>
		<pubDate>Wed, 11 Aug 2010 01:36:13 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Packaging]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[binaries]]></category>
		<category><![CDATA[Distribution]]></category>
		<category><![CDATA[PyInstaller]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=1102</guid>
		<description><![CDATA[In our previous article on building binaries, we learned a little about py2exe. This time around, we will be focusing our collective attention on the ins and outs of PyInstaller. We&#8217;ll use the same lame wxPython script from the last article for one of our examples, but we&#8217;ll also try a normal console script to [...]]]></description>
			<content:encoded><![CDATA[<div class="socialize-in-content" style="float:left;"><div class="socialize-in-button socialize-in-button-left"><a href="http://twitter.com/share" class="twitter-share-button" data-counturl="http://www.blog.pythonlibrary.org/2010/08/10/a-pyinstaller-tutorial-build-a-binary-series/" data-url="http://bit.ly/sniyEP" data-text="A PyInstaller Tutorial &#8211; Build a Binary Series!" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-left"><iframe src="http://www.facebook.com/plugins/like.php?href=http://www.blog.pythonlibrary.org/2010/08/10/a-pyinstaller-tutorial-build-a-binary-series/&amp;layout=button_count&amp;show_faces=true&amp;width=100&amp;action=like&amp;font=arial&amp;colorscheme=light&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px !important; height:65px;" allowTransparency="true"></iframe></div></div><p>In our previous article on building binaries, we learned a little about py2exe. This time around, we will be focusing our collective attention on the ins and outs of PyInstaller. We&#8217;ll use the same lame wxPython script from the last <a href="http://www.blog.pythonlibrary.org/2010/07/31/a-py2exe-tutorial-build-a-binary-series/">article </a>for one of our examples, but we&#8217;ll also try a normal console script to see what the differences are, if any. In case you didn&#8217;t know, PyInstaller works on Linux, Windows and Mac (experimental) and works with Python 1.5-2.6 (except on Windows, where there&#8217;s a caveat for 2.6 &#8211; see below). PyInstaller supports code-signing (Windows), eggs, hidden imports, single executable, single directory, and lots more!<span id="more-1102"></span></p>
<h2>Getting Started with PyInstaller</h2>
<p><strong>Note on Python 2.6 on Windows: </strong>If you read the PyInstaller <a href="http://www.pyinstaller.org/wiki/Python26Win">website </a>closely, you will see a warning about Python 2.6+ not being fully supported. The note says that you will currently need to have the Microsoft CRT installed for your executable to work. What this is probably referring to is the side-by-side assemblies / manifest issues that were introduced with Python 2.6 vis-a-vis Microsoft Visual Studio 2008. We already mentioned this problem in the first article. If you don&#8217;t know anything about it, please check out the py2exe website, the wxPython wiki or Google for the issue.</p>
<p>Anyway, let&#8217;s get on with the show. After you download PyInstaller, you just unzip the archive somewhere convenient. The follow these three simple steps:</p>
<ol>
<li>Run <strong>Configure.py</strong> to save some basic configuration data to a &#8220;.dat&#8221; file. This saves some time since PyInstaller won&#8217;t have to recalculate the configuration on the fly.</li>
<li>Run the following command on the command line:  <em>python Makespec.py [opts] <scriptname></em> where scriptname is the name of the main Python file you use to run your program.</li>
<li>Finally, run the following command via the command line:  <em>python Build.py specfile</em> to build your executable.</li>
</ol>
<p>Let&#8217;s run through this with a real script now. We&#8217;ll start with a simple console script that creates a faux configuration file. Here&#8217;s the code:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> configobj
&nbsp;
<span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">def</span> createConfig<span style="color: black;">&#40;</span>configFile<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Create the configuration file
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    config = configobj.<span style="color: black;">ConfigObj</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    inifile = configFile
    config.<span style="color: black;">filename</span> = inifile
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'server'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;http://www.google.com&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'username'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;mike&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'password'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;dingbat&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'update interval'</span><span style="color: black;">&#93;</span> = <span style="color: #ff4500;">2</span>
    config.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">def</span> getConfig<span style="color: black;">&#40;</span>configFile<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Open the config file and return a configobj
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> configobj.<span style="color: black;">ConfigObj</span><span style="color: black;">&#40;</span>configFile<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> createConfig2<span style="color: black;">&#40;</span>path<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Create a config file
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    config = configobj.<span style="color: black;">ConfigObj</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    config.<span style="color: black;">filename</span> = path
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span> = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;product&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;Sony PS3&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;accessories&quot;</span><span style="color: black;">&#93;</span> = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'controller'</span>, <span style="color: #483d8b;">'eye'</span>, <span style="color: #483d8b;">'memory stick'</span><span style="color: black;">&#93;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;retail price&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;$400&quot;</span>
    config.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    createConfig2<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;sampleConfig.ini&quot;</span><span style="color: black;">&#41;</span></pre>
<p>Now let&#8217;s make a spec file:</p>
<p><code><br />
c:\Python25\python c:\Users\Mike\Desktop\pyinstaller-1.4\Makespec.py config_1.py<br />
</code></p>
<p>On my test machine, I have 3 different Python versions installed, so I had to specify the Python 2.5 path explicitly (or set Python 2.5 as the default). Anyway, this should create a file similar to the following (which was named &#8220;config_1.spec&#8221;):</p>
<pre class="python"><span style="color: #808080; font-style: italic;"># -*- mode: python -*-</span>
a = Analysis<span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>HOMEPATH,<span style="color: #483d8b;">'support<span style="color: #000099; font-weight: bold;">\\</span>_mountzlib.py'</span><span style="color: black;">&#41;</span>, <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>HOMEPATH,<span style="color: #483d8b;">'support<span style="color: #000099; font-weight: bold;">\\</span>useUnicode.py'</span><span style="color: black;">&#41;</span>, <span style="color: #483d8b;">'config_1.py'</span><span style="color: black;">&#93;</span>,
             pathex=<span style="color: black;">&#91;</span><span style="color: #483d8b;">'C:<span style="color: #000099; font-weight: bold;">\\</span>Users<span style="color: #000099; font-weight: bold;">\\</span>Mike<span style="color: #000099; font-weight: bold;">\\</span>Desktop<span style="color: #000099; font-weight: bold;">\\</span>py2exe_ex'</span>, r<span style="color: #483d8b;">'C:<span style="color: #000099; font-weight: bold;">\P</span>ython26<span style="color: #000099; font-weight: bold;">\L</span>ib<span style="color: #000099; font-weight: bold;">\s</span>ite-packages'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
pyz = PYZ<span style="color: black;">&#40;</span>a.<span style="color: black;">pure</span><span style="color: black;">&#41;</span>
exe = EXE<span style="color: black;">&#40;</span>pyz,
          a.<span style="color: black;">scripts</span>,
          exclude_binaries=<span style="color: #ff4500;">1</span>,
          name=<span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'build<span style="color: #000099; font-weight: bold;">\\</span>pyi.win32<span style="color: #000099; font-weight: bold;">\\</span>config_1'</span>, <span style="color: #483d8b;">'config_1.exe'</span><span style="color: black;">&#41;</span>,
          debug=<span style="color: #008000;">False</span>,
          strip=<span style="color: #008000;">False</span>,
          upx=<span style="color: #008000;">True</span>,
          console=<span style="color: #008000;">True</span> <span style="color: black;">&#41;</span>
coll = COLLECT<span style="color: black;">&#40;</span> exe,
               a.<span style="color: black;">binaries</span>,
               a.<span style="color: black;">zipfiles</span>,
               a.<span style="color: black;">datas</span>,
               strip=<span style="color: #008000;">False</span>,
               upx=<span style="color: #008000;">True</span>,
               name=<span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'pyInstDist2'</span>, <span style="color: #483d8b;">'config_1'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre>
<p>For the Python script we&#8217;re using, we need to add an explicit path to the location of <em>configobj.py</em> in the <em>Analysis </em>section of the spec file in the <em>pathex</em> parameter. If you do not do this, when you run the resulting executable, it will open and close a console window really fast and you won&#8217;t be able to tell what it says unless you run the exe from the command line. I did the latter to find out what was wrong and discovered it could not find the configobj module. You can also specify the output path for your exe in the COLLECT function&#8217;s name parameter. In this case, we put PyInstaller&#8217;s output in the &#8220;config_1&#8243; subfolder of &#8220;pyInstDist2&#8243;, which should be a folder alongside your original script. There are a ton of options when configuring your spec file, which you can read about <a href="http://www.pyinstaller.org/export/latest/tags/1.4/doc/Manual.html?format=raw#configuring-your-pyinstaller-setup">here</a>.</p>
<p>To build the executable based on the spec file, do the following on the command line:</p>
<p><code><br />
c:\Python25\python c:\Users\Mike\Desktop\pyinstaller-1.4\Build.py config_1.spec<br />
</code></p>
<p>On my machine, I ended up with a folder that had 25 files in it that totaled 6.7 MB. You should be able to reduce the size using the Analysis section&#8217;s <em>excludes</em> parameter and/or compression.</p>
<h2>PyInstaller and wxPython</h2>
<p>Now let&#8217;s try creating a binary from a simple wxPython script. Here&#8217;s the Python script:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> wx
&nbsp;
<span style="color: #808080; font-style: italic;">########################################################################</span>
<span style="color: #ff7700;font-weight:bold;">class</span> DemoPanel<span style="color: black;">&#40;</span>wx.<span style="color: black;">Panel</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, parent<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;Constructor&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        wx.<span style="color: black;">Panel</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, parent<span style="color: black;">&#41;</span>
&nbsp;
        labels = <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Name&quot;</span>, <span style="color: #483d8b;">&quot;Address&quot;</span>, <span style="color: #483d8b;">&quot;City&quot;</span>, <span style="color: #483d8b;">&quot;State&quot;</span>, <span style="color: #483d8b;">&quot;Zip&quot;</span>,
                  <span style="color: #483d8b;">&quot;Phone&quot;</span>, <span style="color: #483d8b;">&quot;Email&quot;</span>, <span style="color: #483d8b;">&quot;Notes&quot;</span><span style="color: black;">&#93;</span>
&nbsp;
        mainSizer = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">VERTICAL</span><span style="color: black;">&#41;</span>
        lbl = wx.<span style="color: black;">StaticText</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label=<span style="color: #483d8b;">&quot;Please enter your information here:&quot;</span><span style="color: black;">&#41;</span>
        lbl.<span style="color: black;">SetFont</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">Font</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">12</span>, wx.<span style="color: black;">SWISS</span>, wx.<span style="color: black;">NORMAL</span>, wx.<span style="color: black;">BOLD</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        mainSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>lbl, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">for</span> lbl <span style="color: #ff7700;font-weight:bold;">in</span> labels:
            sizer = <span style="color: #008000;">self</span>.<span style="color: black;">buildControls</span><span style="color: black;">&#40;</span>lbl<span style="color: black;">&#41;</span>
            mainSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>sizer, <span style="color: #ff4500;">1</span>, wx.<span style="color: black;">EXPAND</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">SetSizer</span><span style="color: black;">&#40;</span>mainSizer<span style="color: black;">&#41;</span>
        mainSizer.<span style="color: black;">Layout</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> buildControls<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        sizer = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">HORIZONTAL</span><span style="color: black;">&#41;</span>
        size = <span style="color: black;">&#40;</span><span style="color: #ff4500;">80</span>,<span style="color: #ff4500;">40</span><span style="color: black;">&#41;</span>
        font = wx.<span style="color: black;">Font</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">12</span>, wx.<span style="color: black;">SWISS</span>, wx.<span style="color: black;">NORMAL</span>, wx.<span style="color: black;">BOLD</span><span style="color: black;">&#41;</span>
&nbsp;
        lbl = wx.<span style="color: black;">StaticText</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label=label, size=size<span style="color: black;">&#41;</span>
        lbl.<span style="color: black;">SetFont</span><span style="color: black;">&#40;</span>font<span style="color: black;">&#41;</span>
        sizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>lbl, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>|wx.<span style="color: black;">CENTER</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> label <span style="color: #66cc66;">!</span>= <span style="color: #483d8b;">&quot;Notes&quot;</span>:
            txt = wx.<span style="color: black;">TextCtrl</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, name=label<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            txt = wx.<span style="color: black;">TextCtrl</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, style=wx.<span style="color: black;">TE_MULTILINE</span>, name=label<span style="color: black;">&#41;</span>
        sizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>txt, <span style="color: #ff4500;">1</span>, wx.<span style="color: black;">ALL</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> sizer
&nbsp;
&nbsp;
&nbsp;
<span style="color: #808080; font-style: italic;">########################################################################</span>
<span style="color: #ff7700;font-weight:bold;">class</span> DemoFrame<span style="color: black;">&#40;</span>wx.<span style="color: black;">Frame</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Frame that holds all other widgets
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;Constructor&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        wx.<span style="color: black;">Frame</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #008000;">None</span>, wx.<span style="color: black;">ID_ANY</span>,
                          <span style="color: #483d8b;">&quot;PyInstaller Tutorial&quot;</span>,
                          size=<span style="color: black;">&#40;</span><span style="color: #ff4500;">600</span>,<span style="color: #ff4500;">400</span><span style="color: black;">&#41;</span>
                          <span style="color: black;">&#41;</span>
        panel = DemoPanel<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">Show</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    app = wx.<span style="color: black;">App</span><span style="color: black;">&#40;</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
    frame = DemoFrame<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    app.<span style="color: black;">MainLoop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>Since this is a GUI, we&#8217;ll create our spec file slightly differently:</p>
<p><code><br />
c:\Python25\python c:\Users\Mike\Desktop\pyinstaller-1.4\Makespec.py -F -w sampleApp.py<br />
</code></p>
<p>Note the -F and -w parameters. The -F command tells PyInstaller to create just one executable whereas the -w tells PyInstaller to hide the console window. Here&#8217;s the resulting spec file:</p>
<pre class="python"><span style="color: #808080; font-style: italic;"># -*- mode: python -*-</span>
a = Analysis<span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>HOMEPATH,<span style="color: #483d8b;">'support<span style="color: #000099; font-weight: bold;">\\</span>_mountzlib.py'</span><span style="color: black;">&#41;</span>, <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>HOMEPATH,<span style="color: #483d8b;">'support<span style="color: #000099; font-weight: bold;">\\</span>useUnicode.py'</span><span style="color: black;">&#41;</span>, <span style="color: #483d8b;">'sampleApp.py'</span><span style="color: black;">&#93;</span>,
             pathex=<span style="color: black;">&#91;</span><span style="color: #483d8b;">'C:<span style="color: #000099; font-weight: bold;">\\</span>Users<span style="color: #000099; font-weight: bold;">\\</span>Mike<span style="color: #000099; font-weight: bold;">\\</span>Desktop<span style="color: #000099; font-weight: bold;">\\</span>py2exe_ex'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
pyz = PYZ<span style="color: black;">&#40;</span>a.<span style="color: black;">pure</span><span style="color: black;">&#41;</span>
exe = EXE<span style="color: black;">&#40;</span> pyz,
          a.<span style="color: black;">scripts</span>,
          a.<span style="color: black;">binaries</span>,
          a.<span style="color: black;">zipfiles</span>,
          a.<span style="color: black;">datas</span>,
          name=<span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'pyInstDist'</span>, <span style="color: #483d8b;">'sampleApp.exe'</span><span style="color: black;">&#41;</span>,
          debug=<span style="color: #008000;">False</span>,
          strip=<span style="color: #008000;">False</span>,
          upx=<span style="color: #008000;">True</span>,
          console=<span style="color: #008000;">False</span> <span style="color: black;">&#41;</span></pre>
<p>Note that the last line has the &#8220;console&#8221; parameter set to &#8220;False&#8221;. If you build this like you did with the console script you should end up with one file in the &#8220;pyInstDist&#8221; folder that is approximately 7.1 MB in size. </p>
<h2>Wrapping Up</h2>
<p>This ends our quick tour of PyInstaller. I hope you found this helpful in your Python binary-making endeavors. There is much more information on the PyInstaller website and it&#8217;s pretty well documented, although the website is pretty plain. Be sure to give it a try and see just how much easy PyInstaller is to use!</p>
<p><em>Note: I tested all this using PyInstaller 1.4 and Python 2.5 on Windows 7 Home Premium (32-bit).</em></p>
<h2>Further Reading</h2>
<ul>
<li>PyInstaller Official <a href="http://www.pyinstaller.org">Website</a>, <a href="http://www.pyinstaller.org/export/latest/tags/1.4/doc/Manual.html?format=raw">Manual</a>, <a href="http://groups-beta.google.com/group/PyInstaller?pli=1">Mailing List</a></li>
<li>First <a href="http://www.blog.pythonlibrary.org/2010/07/31/a-py2exe-tutorial-build-a-binary-series/">article </a>in the &#8220;Build a Binary Series&#8221;</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/08/10/a-pyinstaller-tutorial-build-a-binary-series/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A py2exe tutorial &#8211; Build a Binary Series!</title>
		<link>http://www.blog.pythonlibrary.org/2010/07/31/a-py2exe-tutorial-build-a-binary-series/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/07/31/a-py2exe-tutorial-build-a-binary-series/#comments</comments>
		<pubDate>Sat, 31 Jul 2010 19:52:09 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Packaging]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[binaries]]></category>
		<category><![CDATA[py2exe]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[wxPython]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=1080</guid>
		<description><![CDATA[I received a request to create an article on how to use py2exe and wxPython to create an executable. I d, ecided to do a series on packaging instead. It is my intention to go over the major Windows binary building utilities and show you, dear reader, how to use them to create a binary [...]]]></description>
			<content:encoded><![CDATA[<div class="socialize-in-content" style="float:left;"><div class="socialize-in-button socialize-in-button-left"><a href="http://twitter.com/share" class="twitter-share-button" data-counturl="http://www.blog.pythonlibrary.org/2010/07/31/a-py2exe-tutorial-build-a-binary-series/" data-url="http://bit.ly/sAsXNj" data-text="A py2exe tutorial &#8211; Build a Binary Series!" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-left"><iframe src="http://www.facebook.com/plugins/like.php?href=http://www.blog.pythonlibrary.org/2010/07/31/a-py2exe-tutorial-build-a-binary-series/&amp;layout=button_count&amp;show_faces=true&amp;width=100&amp;action=like&amp;font=arial&amp;colorscheme=light&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px !important; height:65px;" allowTransparency="true"></iframe></div></div><p>I received a request to create an article on how to use py2exe and wxPython to create an executable. I d, ecided to do a series on packaging instead. It is my intention to go over the major Windows binary building utilities and show you, dear reader, how to use them to create a binary that you can distribute. Once those articles are done, I&#8217;ll show how to use Inno and NSIS. To kick things off, we&#8217;ll go over how to use py2exe, probably the most popular of the Windows executable packages.<span id="more-1080"></span></p>
<h2>Let&#8217;s Get Started</h2>
<p>For this tutorial, we&#8217;re going to use a wxPython script that doesn&#8217;t do anything. This is a contrived example, but we&#8217;re using wx to make it more visually interesting than just doing a console &#8220;Hello World&#8221; program. Note also that I am using py2exe 0.6.9, wxPython 2.8.11.0 and Python 2.6. Here&#8217;s what the end product should look like when run:</p>
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/07/py2exe_wx.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/07/py2exe_wx.png" alt="" title="py2exe_wx.png" width="496" height="400" class="aligncenter size-full wp-image-1084" /></a></p>
<p>Now that we know what it looks like, here&#8217;s a look at the code:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> wx
&nbsp;
<span style="color: #808080; font-style: italic;">########################################################################</span>
<span style="color: #ff7700;font-weight:bold;">class</span> DemoPanel<span style="color: black;">&#40;</span>wx.<span style="color: black;">Panel</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, parent<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;Constructor&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        wx.<span style="color: black;">Panel</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, parent<span style="color: black;">&#41;</span>
&nbsp;
        labels = <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Name&quot;</span>, <span style="color: #483d8b;">&quot;Address&quot;</span>, <span style="color: #483d8b;">&quot;City&quot;</span>, <span style="color: #483d8b;">&quot;State&quot;</span>, <span style="color: #483d8b;">&quot;Zip&quot;</span>,
                  <span style="color: #483d8b;">&quot;Phone&quot;</span>, <span style="color: #483d8b;">&quot;Email&quot;</span>, <span style="color: #483d8b;">&quot;Notes&quot;</span><span style="color: black;">&#93;</span>
&nbsp;
        mainSizer = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">VERTICAL</span><span style="color: black;">&#41;</span>
        lbl = wx.<span style="color: black;">StaticText</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label=<span style="color: #483d8b;">&quot;Please enter your information here:&quot;</span><span style="color: black;">&#41;</span>
        lbl.<span style="color: black;">SetFont</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">Font</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">12</span>, wx.<span style="color: black;">SWISS</span>, wx.<span style="color: black;">NORMAL</span>, wx.<span style="color: black;">BOLD</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        mainSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>lbl, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">for</span> lbl <span style="color: #ff7700;font-weight:bold;">in</span> labels:
            sizer = <span style="color: #008000;">self</span>.<span style="color: black;">buildControls</span><span style="color: black;">&#40;</span>lbl<span style="color: black;">&#41;</span>
            mainSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>sizer, <span style="color: #ff4500;">1</span>, wx.<span style="color: black;">EXPAND</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">SetSizer</span><span style="color: black;">&#40;</span>mainSizer<span style="color: black;">&#41;</span>
        mainSizer.<span style="color: black;">Layout</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> buildControls<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        sizer = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">HORIZONTAL</span><span style="color: black;">&#41;</span>
        size = <span style="color: black;">&#40;</span><span style="color: #ff4500;">80</span>,<span style="color: #ff4500;">40</span><span style="color: black;">&#41;</span>
        font = wx.<span style="color: black;">Font</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">12</span>, wx.<span style="color: black;">SWISS</span>, wx.<span style="color: black;">NORMAL</span>, wx.<span style="color: black;">BOLD</span><span style="color: black;">&#41;</span>
&nbsp;
        lbl = wx.<span style="color: black;">StaticText</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label=label, size=size<span style="color: black;">&#41;</span>
        lbl.<span style="color: black;">SetFont</span><span style="color: black;">&#40;</span>font<span style="color: black;">&#41;</span>
        sizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>lbl, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>|wx.<span style="color: black;">CENTER</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> label <span style="color: #66cc66;">!</span>= <span style="color: #483d8b;">&quot;Notes&quot;</span>:
            txt = wx.<span style="color: black;">TextCtrl</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, name=label<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            txt = wx.<span style="color: black;">TextCtrl</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, style=wx.<span style="color: black;">TE_MULTILINE</span>, name=label<span style="color: black;">&#41;</span>
        sizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>txt, <span style="color: #ff4500;">1</span>, wx.<span style="color: black;">ALL</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> sizer
&nbsp;
&nbsp;
&nbsp;
<span style="color: #808080; font-style: italic;">########################################################################</span>
<span style="color: #ff7700;font-weight:bold;">class</span> DemoFrame<span style="color: black;">&#40;</span>wx.<span style="color: black;">Frame</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Frame that holds all other widgets
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;Constructor&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        wx.<span style="color: black;">Frame</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #008000;">None</span>, wx.<span style="color: black;">ID_ANY</span>,
                          <span style="color: #483d8b;">&quot;Py2Exe Tutorial&quot;</span>,
                          size=<span style="color: black;">&#40;</span><span style="color: #ff4500;">600</span>,<span style="color: #ff4500;">400</span><span style="color: black;">&#41;</span>
                          <span style="color: black;">&#41;</span>
        panel = DemoPanel<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">Show</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    app = wx.<span style="color: black;">App</span><span style="color: black;">&#40;</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
    frame = DemoFrame<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    app.<span style="color: black;">MainLoop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>This is fairly straightforward, so I&#8217;ll leave it the reader to figure out. This article is about py2exe after all.</p>
<h2>The py2exe setup.py file</h2>
<p>The key to any py2exe script is the <em>setup.py</em> file. This file controls what gets included or excluded, how much we compress and bundle, and much more! Here is the simplest setup that we can use with the wx script above:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">distutils</span>.<span style="color: black;">core</span> <span style="color: #ff7700;font-weight:bold;">import</span> setup
<span style="color: #ff7700;font-weight:bold;">import</span> py2exe
&nbsp;
setup<span style="color: black;">&#40;</span>windows=<span style="color: black;">&#91;</span><span style="color: #483d8b;">'sampleApp.py'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></pre>
<p>As you can see, we import the <em>setup</em> method from <em>distutils.core</em> and then we import <em>py2exe</em>. Next we call setup with a <em>windows</em> keyword parameter and pass it the name of the main file inside a python list object. If you were creating a non-GUI project, than you would use the <em>console </em> key instead of <em>windows</em>. To run this, open up a command prompt and navigate to the appropriate location. Then type &#8220;python setup.py py2exe&#8221; to run it. This is what I got when I first ran it:</p>
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/07/py2exe_firstrun.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/07/py2exe_firstrun.png" alt="" title="py2exe_firstrun.png" width="450" height="325" class="aligncenter size-full wp-image-1085" /></a></p>
<p>It looks like wxPython requires the &#8220;MSVCP90.dll&#8221; and Windows can&#8217;t find it. A quick Google search yielded the consensus that I needed the &#8220;Microsoft Visual C++ 2008 Redistributable Package&#8221;, found <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=9b2da534-3e03-4391-8a4d-074b9f2bc1bf&#038;displaylang=en">here</a>. I downloaded it, installed it and tried py2exe again. Same error. This would have probably worked had I been using Visual Studio to create an exe of a C# program. Anyway, the trick was to search the hard drive for the file and then copy it to Python&#8217;s DLL folder, which on my machine was found at the following location: C:\Python26\DLLs (adjust as necessary on your machine). Once the DLL was in the proper place, the setup.py file ran just fine. The result was put into a &#8220;dist&#8221; folder which contains 17 files and weighs in at 15.3 MB. I double-clicked the &#8220;sampleApp.exe&#8221; file to see if my shiny new binary would work and it did! In older versions of wxPython, you would have needed to include a manifest file to get the right look and feel (i.e the themes), but that was taken care of in 2.8.10 (I think) as was the side-by-side (SxS) assembly manifest file that used to be required.</p>
<p>Note that for non-wxPython scripts, you will probably still need to mess with the SxS manifests and all the hoops that includes. You can read more about that in the <a href="http://py2exe.org/index.cgi/Tutorial">py2exe tutorial</a>.</p>
<h2>Creating an Advanced setup.py File</h2>
<p>Let&#8217;s see what other options py2exe gives us for creating binaries by creating a more complex setup.py file. </p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">distutils</span>.<span style="color: black;">core</span> <span style="color: #ff7700;font-weight:bold;">import</span> setup
<span style="color: #ff7700;font-weight:bold;">import</span> py2exe
&nbsp;
includes = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
excludes = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'_gtkagg'</span>, <span style="color: #483d8b;">'_tkagg'</span>, <span style="color: #483d8b;">'bsddb'</span>, <span style="color: #483d8b;">'curses'</span>, <span style="color: #483d8b;">'email'</span>, <span style="color: #483d8b;">'pywin.debugger'</span>,
            <span style="color: #483d8b;">'pywin.debugger.dbgcon'</span>, <span style="color: #483d8b;">'pywin.dialogs'</span>, <span style="color: #483d8b;">'tcl'</span>,
            <span style="color: #483d8b;">'Tkconstants'</span>, <span style="color: #483d8b;">'Tkinter'</span><span style="color: black;">&#93;</span>
packages = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
dll_excludes = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'libgdk-win32-2.0-0.dll'</span>, <span style="color: #483d8b;">'libgobject-2.0-0.dll'</span>, <span style="color: #483d8b;">'tcl84.dll'</span>,
                <span style="color: #483d8b;">'tk84.dll'</span><span style="color: black;">&#93;</span>
&nbsp;
setup<span style="color: black;">&#40;</span>
    options = <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;py2exe&quot;</span>: <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;compressed&quot;</span>: <span style="color: #ff4500;">2</span>,
                          <span style="color: #483d8b;">&quot;optimize&quot;</span>: <span style="color: #ff4500;">2</span>,
                          <span style="color: #483d8b;">&quot;includes&quot;</span>: includes,
                          <span style="color: #483d8b;">&quot;excludes&quot;</span>: excludes,
                          <span style="color: #483d8b;">&quot;packages&quot;</span>: packages,
                          <span style="color: #483d8b;">&quot;dll_excludes&quot;</span>: dll_excludes,
                          <span style="color: #483d8b;">&quot;bundle_files&quot;</span>: <span style="color: #ff4500;">3</span>,
                          <span style="color: #483d8b;">&quot;dist_dir&quot;</span>: <span style="color: #483d8b;">&quot;dist&quot;</span>,
                          <span style="color: #483d8b;">&quot;xref&quot;</span>: <span style="color: #008000;">False</span>,
                          <span style="color: #483d8b;">&quot;skip_archive&quot;</span>: <span style="color: #008000;">False</span>,
                          <span style="color: #483d8b;">&quot;ascii&quot;</span>: <span style="color: #008000;">False</span>,
                          <span style="color: #483d8b;">&quot;custom_boot_script&quot;</span>: <span style="color: #483d8b;">''</span>,
                         <span style="color: black;">&#125;</span>
              <span style="color: black;">&#125;</span>,
    windows=<span style="color: black;">&#91;</span><span style="color: #483d8b;">'sampleApp.py'</span><span style="color: black;">&#93;</span>
<span style="color: black;">&#41;</span></pre>
<p>This is pretty self-explanatory, but let&#8217;s unpack it anyway. First we set up a few lists that we pass to the options parameter of the setup function. </p>
<ul>
<li>The <em>includes</em> list is for special modules that you need to specifically include. Sometimes py2exe can&#8217;t find certain modules, so you get to manually specify them here. </li>
<li>The <em>excludes</em> list is a list of which modules to exclude from your program. In this case, we don&#8217;t need Tkinter since we&#8217;re using wxPython. This list of excludes is what GUI2Exe will exclude by default.</li>
<li>The <em>packages</em> list is a list of specific packages to include. Again, sometimes py2exe just can&#8217;t find something. I&#8217;ve had to include email, PyCrypto, or lxml here before. Note that if the excludes list contains something you&#8217;re trying to include in the packages or includes lists, py2exe may continue to exclude them.</li>
<li><em>dll_excludes</em> &#8211; excludes dlls that we don&#8217;t need in our project.</li>
</ul>
<p>In the <em>options</em> dictionary, we have a few other options to look at. The <em>compressed</em> key tells py2exe whether or not to compress the zipfile, if it&#8217;s set. The <em>optimize</em> key sets the optimization level. Zero is no optimization and 2 is the highest. The <em>bundle_files</em> key bundles dlls in the zipfile or the exe. Valid values for <em>bundle_files</em> are: 3 = don&#8217;t bundle (default) 2 = bundle everything but the Python interpreter 1 = bundle everything, including the Python interpreter. A couple of years ago, when I was first learning py2exe, I asked on their mailing list what the best option was because I was having issues with bundle option 1. I was told that 3 was probably the most stable. I went with that and stopped having random problems, so that&#8217;s what I currently recommend. If you don&#8217;t like distributing more than one file, zip them up or create an installer. The only other option I use in this list is the <em>dist_dir</em> one. I use it to experiment with different built options or to create custom builds when I don&#8217;t want to overwrite my main good build. You can read about all the other options (including ones not even listed here) on the <a href="http://py2exe.org/index.cgi/ListOfOptions">py2exe website</a>. By setting optimize to 2, we can reduce the size of folder by about one megabyte. </p>
<h2>Reducing a wxPython Script&#8217;s Binary Size</h2>
<p>There&#8217;s a <a href="http://bit.ly/bwIDNd">thread </a>on the wxPython mailing list about reducing the size of the binary. I contacted Steven Sproat, one of the people in the thread, about what he did and here&#8217;s the trick: Set the &#8220;bundle_files&#8221; option to 1 and the the zipfile to None. The result will be three files in your dist folder: MSVCR71.dll, sampleApp.exe and w9xpopen.exe. The size of the folder is 5.94 MB on my machine (Tested on a Windows XP machine). As I mentioned earlier, setting bundle_files to 1 can cause some users to experience issues when running your application, but this may have been fixed with the newer versions of py2exe. Here&#8217;s what the setup.py file looks like with the new options set:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">distutils</span>.<span style="color: black;">core</span> <span style="color: #ff7700;font-weight:bold;">import</span> setup
<span style="color: #ff7700;font-weight:bold;">import</span> py2exe
&nbsp;
includes = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
excludes = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'_gtkagg'</span>, <span style="color: #483d8b;">'_tkagg'</span>, <span style="color: #483d8b;">'bsddb'</span>, <span style="color: #483d8b;">'curses'</span>, <span style="color: #483d8b;">'email'</span>, <span style="color: #483d8b;">'pywin.debugger'</span>,
            <span style="color: #483d8b;">'pywin.debugger.dbgcon'</span>, <span style="color: #483d8b;">'pywin.dialogs'</span>, <span style="color: #483d8b;">'tcl'</span>,
            <span style="color: #483d8b;">'Tkconstants'</span>, <span style="color: #483d8b;">'Tkinter'</span><span style="color: black;">&#93;</span>
packages = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
dll_excludes = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'libgdk-win32-2.0-0.dll'</span>, <span style="color: #483d8b;">'libgobject-2.0-0.dll'</span>, <span style="color: #483d8b;">'tcl84.dll'</span>,
                <span style="color: #483d8b;">'tk84.dll'</span><span style="color: black;">&#93;</span>
&nbsp;
setup<span style="color: black;">&#40;</span>
    options = <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;py2exe&quot;</span>: <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;compressed&quot;</span>: <span style="color: #ff4500;">2</span>,
                          <span style="color: #483d8b;">&quot;optimize&quot;</span>: <span style="color: #ff4500;">2</span>,
                          <span style="color: #483d8b;">&quot;includes&quot;</span>: includes,
                          <span style="color: #483d8b;">&quot;excludes&quot;</span>: excludes,
                          <span style="color: #483d8b;">&quot;packages&quot;</span>: packages,
                          <span style="color: #483d8b;">&quot;dll_excludes&quot;</span>: dll_excludes,
                          <span style="color: #483d8b;">&quot;bundle_files&quot;</span>: <span style="color: #ff4500;">1</span>,
                          <span style="color: #483d8b;">&quot;dist_dir&quot;</span>: <span style="color: #483d8b;">&quot;dist&quot;</span>,
                          <span style="color: #483d8b;">&quot;xref&quot;</span>: <span style="color: #008000;">False</span>,
                          <span style="color: #483d8b;">&quot;skip_archive&quot;</span>: <span style="color: #008000;">False</span>,
                          <span style="color: #483d8b;">&quot;ascii&quot;</span>: <span style="color: #008000;">False</span>,
                          <span style="color: #483d8b;">&quot;custom_boot_script&quot;</span>: <span style="color: #483d8b;">''</span>,
                         <span style="color: black;">&#125;</span>
              <span style="color: black;">&#125;</span>,
    <span style="color: #dc143c;">zipfile</span> = <span style="color: #008000;">None</span>,
    windows=<span style="color: black;">&#91;</span><span style="color: #483d8b;">'sampleApp.py'</span><span style="color: black;">&#93;</span>
<span style="color: black;">&#41;</span></pre>
<p>Another way to reduce the size of the folder is to use compression programs as one of my readers, ProgMan, pointed out. Here are his results:</p>
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/07/sampleapps.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/07/sampleapps.png" alt="" title="sampleapps" width="496" height="315" class="aligncenter size-full wp-image-1096" /></a></p>
<h2>Wrapping Up</h2>
<p>You now know the basics for creating binaries with py2exe. I hope you have found this helpful for your current or future projects. If so, let me know in the comments!</p>
<h2>Further Reading</h2>
<ul>
<li>The py2exe <a href="http://py2exe.org/index.cgi/Tutorial">Tutorial</a></li>
<li><a href="http://www.blog.pythonlibrary.org/2008/08/27/packaging-wxpymail-for-distribution/">Packaging wxPyMail for Distribution</a></li>
<li><a href="http://code.google.com/p/gui2exe/">GUI2Exe</a></li>
<li>wxPython <a href="http://wiki.wxpython.org/py2exe">wiki page</a> on py2exe
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/07/31/a-py2exe-tutorial-build-a-binary-series/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 6.507 seconds -->

