I recently had some hair-raising adventures in the land of website deployment. I’ve been completely rebuilding my website with a Django backend because I love Python. (This blog will eventually be hosted there, although WordPress does excel at the blog thing, so I might just get crazy and integrate Django AND WordPress. But I digress.) I had everything working all fine and dandy on my local computer and was ready to deploy my almost-identical-but-now-Django-backed placeholder site. I’ve long had Apache serving a few VirtualHosts and handling the SSL certificates on my personal DigitalOcean droplet, so my choice of web server was made for me. At least all that domain config stuff was done, so it would be a cinch to get Django up and running in place of my static site, I thought.
I thought wrong.
It started off so well. I installed python and PostgreSQL on my server and configured my production settings file to match (and to pull in the passwords from a separate ini file on the server and out of the git tracking). I set up a bare repo and some git hooks to make pushing to production easy. (I know I should also set up a separate staging subdomain for testing, but I’ve been in a hurry to get something real up there since I’m starting the ol’ job hunt.) Everything seemed to be ready to push so I turned to the Apache config.
This is where my troubles began. I had been running Django’s testing server locally, but the docs were very clear that this testing server should not be used in production. They did not go into details as to why other than “security and scaling,” but I took their word for it. That’s okay, I thought; I have Apache set up already anyway. The docs also kept talking about this “WSGI” thing, but when I had tried to figure out how to configure that, it had mostly just confused me, and well, it was working on my machine.
Tkinter (a shortening of “Tk interface”) is the standard GUI package that comes with python. I’m using it to built my first non-web GUI. I may move to wxPython down the line, but Python 3.5 is not currently supported, Tkinter does what I need it to do, and since the inclusion of ttk (themed Tk), the styling of the widgets look just fine to my eye.
Tkinter documentation and help as far as best practices and design patterns is not particularly thorough or abundant (Tkdocs and effbot have been very helpful references, if not quite sufficient), so I thought I’d put down and share the basic template I wrangled together over a couple of days of learning. Especially because it can be hard to find simple, well-commented skeleton templates for good overall application organization, this is something that would have helped me a lot. I’ve kept all my application logic in other scripts, so this is just the GUI. I’ll probably update this as I learn more; visit the GitHub repository for updates.
I’ve been teaching myself Python lately and I’m working through a few different books to do so. One of them is Gray Hat Python by Justin Seitz. I feared it might be a little dated, but it looked like a fun way to learn.
From the very first, “Hello World!” I was already unable to get my code to run. Here’s the example:
It didn’t work in Eclipse, and it didn’t work with the command line (I’m on my Windows 10 machine). There were no errors thrown, and the correct function was clearly being accessed, but something was causing the function to stop after the first character. Some quality time with Google led me to several other people with this problem, people who were obviously following the same book I was and equally stumped. Unfortunately all the answers given either didn’t work for me or they were just too far over my head for me to practically sort out.
Well after banging my head against this for hours, I finally found a solution! As always seems to be the case, the problem was simple: printf in this instance works with Python 2.x and it expects strings to be encoded as bytes. By contrast, in Python 3, the version I have installed, literal strings are in unicode. I needed to find a way to get the string and the function to to speak the same encoding language. But the code solution given in the post in which I learned this discrepancy still didn’t work, nor did a few others I tried. Frustrated, and at this point having wasted 2 or 3 hours, I decided to do once last round of searches before calling it a night. That’s when I stumbled upon this post in a Python mailing list archive. Simply changing printf() to wprintf() fixed my problem! I now have a couple of different ways to get around this issue in the future!
So, for anyone else working through Gray Hat Python with Python 3, the final working solution is: