Auto Update for your Frozen Python Applications using Esky

Let’s assume you have a desktop application built with Python. It could be a traditional GUI app built with PyQT/wxPython/Kivy or any other GUI framework. Or it could be a web server that serves a browser based HTML GUI for the user. Either way, you have “frozen” the app using cx_freeze, py2app/py2exe or pyinstaller and now you want to add “auto update” to the app, so when there’s a new version of the application is available, the app can download and install the update, automatically. For this particular task, I found esky to be a good viable option. In this article, I am going to demonstrate how we can use esky to deliver updates to our apps.

Quick Introduction to Esky

If we want to use Esky to deliver updates, we need to freeze the app first. But this time, we will ask Esky to freeze the app for us, using our freezer of choice. For example, if we used py2app before, we will still use py2app but instead of directly using it, we will pass it to Esky and Esky will use the py2app to freeze the app for us. This step is necessary so that Esky can inject the necessary parts to handle updates/patches and install them gracefully.

For the apps to locate and download the updates, we need to serve the updates from a location on the internet/local network. Esky produces a zip archive. We can directly put it on our webserver. The apps we freeze needs to know the URL of the webserver and must have access to it.

On the other hand, inside our app, we need to write some codes which will scan the URL of the above mentioned webserver, find any newer updates and install them. Esky provides nice APIs to do these.

So now that we know the steps to follow, let’s start.

Creating a setup file

If you have frozen an app before, you probably know what a setup file is and how to write one. Here’s a sample that uses py2app to freeze an app:

Now we can generate the frozen app using:

This should generate a zip archive in the dist directory.

Hosting the app

Collect the zip file from the dist directory and put it somewhere accessible on the internet. For local testing, you can probably use Python’s built in HTTP server to distribute it.

Finding, Downloading and Installing Updates

Now we will see the client side code that we need to write to locate and install the updates.

Here’s some codes taken from a PyQT app. The find_esky_update method is part of a QMainWindow class. It is called inside the onQApplicationStarted method. So it checks the update as soon as the application starts.

We first check if the app is frozen. If it’s not, then there’s no way we can install updates. sys.frozen will contain information about the app if it’s frozen. Otherwise it will not be available. So we first ensure that it is indeed a frozen app.

Then we create an Esky app instance by providing it the URL of our webserver (where the updates are available). We only pass the root URL (without the zip file name). The find_update() method on the Esky app will find newer update and return some information if a new update is available. Otherwise it will be falsy.

If an update is available, we ask our user if s/he wants to update. Here we used QMessageBox for that. If they agree, we call the auto_update method with a callback. We will see the callback soon. The auto_update downloads the update and installs it. The callback we pass – it gets called every time something happens during the process. It can be a good way to display download progress using this callback.

Let’s see our example code here:

As you can see from the code, the callback gets a dictionary which has a key status and if it is “downloading”, we also have the amount of data we have received so far and the total size. We can use this to calculate the progress and print it. We can also display a nice progress bar if we wish.

So basically, this is all we need to find and install updates.

Rolling a new update

We have learned to use Esky, we have seen how to add auto update to our app. Now it’s time to build a new update. That is easy, we go back to the setup.py file we defined earlier. We had version="0.1", inside the setup() function. We need to bump it. So let’s make it 0.2 and build it. We will get a new zip file (the file contains the version if you notice carefully). Drop it on the webserver (the URL where we put our app). Run an older copy of the app (which includes the update checking codes described above). It should ask you for an update 🙂

Please note, you need to call the find_esky_update() method for the prompt to trigger. As I mentioned above, I run it in onQApplicationStarted method for PyQt. You need to find the appropriate place to call it from in your application.

Further Reading

You can find a nice tutorial with step by step instructions and code samples here: https://github.com/cloudmatrix/esky/tree/master/tutorial

Why I love Django & Django REST Framework

If you’re reading this article, it is very likely you are a serious Python developer or at least dabble with the language. If you happen to be a web developer, you probably have already used or at least heard about Django. Django is a pretty awesome web framework. And in this post, I am going to highlight a few key features that I absolutely love about Django. Along with Django, I will also discuss why I love DRF, the very popular REST API development framework for Django. Lately, these two have become indispensable parts of my life as a web developer and I feel it’s very important that I credit them for their awesomeness and spread the words!

Why I love Django?

  • I can quickly generate a project skeleton using the django-admin command. There is management commands to generate apps too.
  • I absolutely love Django’s project structure. It is very well organized and meaningful. A project is composed of reusable apps and the apps can self contain the codes and resources they need/use. The idea of reusable apps is very handy. There are plenty of open source apps that you can plug into your project and extend them as necessary. This allows us to reuse codes and get things done faster.
  • Django’s way of handling database access makes perfect sense to me. I define models, then automatically generate migrations from those. The migrations are written in Python, so I can adjust or tweak if necessary, programmatically. The Model definitions can be introspected by other parts of the framework to generate Admin UIs or API end points automagically – this is a huge win as we will see.
  • Django has a very powerful DB routing mechanism that allows us to use multiple databases and programmatically control the access to them. We can totally control which database is read from, which database is written to, for each app and each model.
  • The URL routing portion also makes great sense. There’s a main route configuration per project. We can add app specific routes to this configuration by include-ing them. You can add namespaces to these included ones. The namespacing gets rids of naming conflict when importing routes from 3rd party apps.
  • For simple views, the function based views are pretty efficient. But there’s also class based views for more control and dealing with complex needs.
  • The Generic Class Views are awesome! You can define ListView, CreateView, UpdateView, DetailView or a DeleteView. You pass them the Model to use and some configuration options, they will handle your CRUD operations for you while you can focus your time and concentration on preparing the templates. These have allowed me to build custom CRUD views very very fast. The generic views are very customizable, so you can alter the database queries, pagination, form fields, values passed to the template. If you’re still writing your own business logic for CRUD views, it’s time you took generic class views for a ride. What I like most is that generic views are generated dynamically. It’s not like scaffolding or code generation. In the case of scaffolding, when you need to add an extra field, you need to modify your model, controller, template, form etc. In class based generic views, you just update your model and everything is updated dynamically.
  • Talking about CRUD views, often you won’t even need to build them. The Django Admin interface takes in your models and generates a beautiful (and powerful) admin interface from them. The admin interface is very customizable. You can add custom actions, filtering, templates and whats not! Once you master Django’s admin interface, you will probably never need to build CRUD views from scratch. Many of my projects use Django Admin with high client satisfaction. And remember what we said about reusable apps and open source packages? There are several packages which provide alterations or replacement for the built in admin interface. You can plug in one of those for a different taste!
  • Management commands are easy to write and comes in very handy for simple tasks. When you install apps, they can provide useful management commands too. One of my favourite management command is “dbshell” which allows me to drop into the database’s command line without remembering the login details.
  • Django Templates are pretty awesome too. The syntax is quite similar to Jinja2 (which inspired many templating languages across different platforms). You can extend the templates by writing your own tags and filters. And there’s of course a backend for direct Jinja2 support.
  • Django is quite mature and the eco system is thriving. There’s a django package for almost everything you would need. There are many 3rd party packages for extending the different parts of Django. There are blogs, forums, cms etc apps which you can plug into your current project to add those functionality. Python also has a vast libraries for numerous purposes. It’s easy to plug them in when we need.
  • Oh, and did I forget to mention the documentation? Django documentation is superb. Very well written and covers almost everything in the framework. I would say Django Docs is one of the best out there.

The above mentioned features are just a few that I can remember right now. Django has been very pleasant to develop in. I have always felt a productivity boost as well as mental satisfaction when working with Django. Every time I faced a challenge, I have found a very simple solutions to it.

Why I love Django REST Framework?

  • Browsable APIs on the web – this is one of the best things about DRF. DRF provides very nice web browsable views for your API end points. These views allow HTML forms to submit data to the APIs. At the same time, they also show sample JSON payload for those requests. You can submit a request through the forms/json input and get back a response. So this is pretty much self documentation of the APIs. I have worked with front end and mobile developers (who consumed my APIs) and they absolutely loved the web browsable interface. In most cases, I didn’t even need to provide any API docs to them, they managed to figure things out for themselves. And if you would still want Swagger, there are 3rd party extensions for that too.
  • The ModelViewSet is like those admin views for Django. You can quickly generate CRUD based REST APIs out of your models using this class.
  • There is APIView which provides get, post, put, delete etc methods representing the HTTP verbs. You can extend APIView and provide business logic for these methods to quickly craft your APIs. There are mixins and some preset class based views to generate these methods based on querysets.
  • But don’t be satisfied just yet, ViewSets take things one step further. When you use APIView, you need to create two routes (for example one for /users and one for /users/1) but with ViewSets allow us to focus more on the business logic while forgetting about the route management. ViewSet is a class based view that has methods like list, retrieve, create, update, destroy – instead of the http verbs. The ViewSet methods allows us to cover all the REST operations in just one class. We add the view set to a router and the router generates all the necessary underlying django routes, ready to be included in a urlconf. And as mentioned earlier, the ModelViewSet is a ViewSet that generates these methods from a Model (queryset)
  • Authentication is baked in the framework. It’s very easy to setup different authentications for your APIs. The permission management is also very simple. The framework integrates nicely with some third party packages to support authentication methods which are not supported by the framework by default.
  • The framework is very customizable. We can easily extend the functionality to suit our needs. It’s all very simple, quite like the simplicity of Django!
  • The documentation is excellent. Adequate examples and very clearly described.

The only thing I am not completely happy with DRF is creating nested routes (/user/1/comment/2) is still pretty difficult/cumbersome. But the way DRF adds features quickly, I hope this will be resolved soon, in some upcoming releases!

Helping These Projects Grow

Django and DRF both are open source projects and are the results of many hours of dedication from kind hearted OSS enthusiasts. Today, we can build and maintain awesome projects because Django and DRF exists. We should all consider giving something back to these projects, in return to the benefits they have brought us!

We can help these projects by contributing codes, helping with translations, answering questions, promoting the projects or making donations.

Here you can learn how to contribute to Django — https://docs.djangoproject.com/en/dev/internals/contributing/

Django Software Foundation accepts donations here — https://www.djangoproject.com/fundraising/

DRF Contribution guide here — http://www.django-rest-framework.org/topics/contributing/

Django: Limiting User Access to Views

In this post, we would like to see how we can limit user accesses to our Django views.

Login Required & Permission Required Decorators

If you have worked with Django, you probably have used the login_required decorator already. Adding the decorator to a view limits access only to the logged in users. If the user is not logged in, s/he is redirected to the default login page. Or we can pass a custom login url to the decorator for that purpose.

Let’s see an example:

There’s another nice decorator – permission_required which works in a similar fashion:

Awesome but let’s learn how do they work internally.

How do they work?

We saw the magic of the login_required and permission_required decorators. But we’re the men of science and we don’t like to believe in magic. So let’s unravel the mystery of these useful decorators.

Here’s the code for the login_required decorator:

By reading the code, we can see that the login_required decorator uses another decorator – user_passes_test which takes/uses a callable to determine whether the user should have access to this view. The callable must accept an user instance and return a boolean value. user_passes_test returns a decorator which is applied to our view.

If we see the source of permission_required, we would see something quite similar. It also uses the same user_passes_test decorator.

Building Our Own Decorators

Now that we know how to limit access to a view based on whether the logged in user passes a test, it’s quite simple for us to build our own decorators for various purposes. Let’s say we want to allow access only to those users who have verified their emails.

Now we can use the decorator to a view like:

Users who have verified their email addresses will be able to access this view. And if they didn’t, they will be redirected to the login view. Using the reason query string, we can display a nice message explaining what’s happening.

Please note, we have used two decorators on the same view. We can use multiple decorators like this to make sure the user passes all the tests we require them to.

Embedding IPython in your application

If you work with Python regularly, you probably know about IPython already. IPython has web based notebooks, QT based GUI consoles and plain old simple Terminal based REPL which is simply fantastic. But that’s not all, we can also embed IPython in our applications too. And this can lead to a number of potential use cases.

Use Cases

A common use case could be to drop into a IPython shell for quick interactive debugging. This can come very handy during prototyping.

Let’s see an example:

When we run this code, we will get a nice IPython REPL where we can try out things. In our case, we haven’t done much except defining a variable named name. We can print it out.

I use Iron.io workers/queues/caches at my day to day job. So I often need to check status of the workers or get the size of a queue or even queue a few workers. I also need to check a few records on Mongodb. An interactive prompt can be really helpful for these.

Now I can just do launch_workers("send_emails", 3) to launch 3 worker instances for the “send_emails” worker. Or get the number of buyers with more than 100 purhcases with the top_buyers() function.

Customizing The Prompt

When we embed IPython, it displays it’s common banner when starting.

We can easily disable that. To do so, we need to pass empty string to the banner1 parameter to the embed method.

Or we can further customize the 2nd banner or the exit message like this:

Homebrew & Pyenv: Installing PyQT5 with Python3 on OSX

There was a time back in 2014 and earlier when PyQT5 installation was not straightforward and needed manual compilation. When searching on Google, still those posts come up on top results. But nothing to worry about, things have changed – it’s now quite simple.

Installation

If you are not already using Homebrew, you should start using it. Once Homebrew is installed, let’s install PyQT5 with this single command:

Verifying Installation

Let’s take a sample PyQT5 code as example and run it. For examples, I usually pick one up from the excellent PyQT tutorials on zetcode.com. Here’s one:

Run it using:

If you get a nice looking small window – it worked!

Integrating with Pyenv

I am a big fan of pyenv and use it for running different versions and flavours of Python. If you use pyenv too, chances are you have your own version of Python installed through it. However, the brew formula that installs PyQT5 depends on another formula python3 – homebrew’s own Python 3 installation. When we install PyQT5, this formula is used to install the bindings, so the bindings are only available to this particular Python 3 installation and unavailable to our pyenv versions.

We will discuss two potential solutions to this issue.

Switching to system

One simple work around is to use the Python 3 version installed by Homebrew. We can ask pyenv to switch to the system version whenever we’re doing PyQT5 development.

We can create an alias to quickly switch between Python versions. I have this in my .zshrc:

This way is very quick and simple but we miss the benefits of using pyenv.

Adding Site Packages

Alternatively, we can add the site-packages for this homebrew installed python 3 to our pyenv installation of python 3. Since both installations were built on the same machine and OS, the bindings should work correctly. We would be using .pth files to do this.

Let’s first find out the site-packages for the homebrew installation:

We would notice a message like:

That is the site-packages for this version.

Now let’s find our pyenv python3’s local site directory:

Now create a homebrew.pth file in that directory and put the previously found site packages path there.

Let’s create the file:

And put these contents:

Save and exit. Now you should be able to just use:

Dockerizing a Django Application

I assume you are already familiar with Docker and it’s use cases. If you haven’t yet started using Docker, I strongly recommend you do soon.

I have a Django application that I want to dockerize it for local development. I am also new to Docker, so everything I do in this post might not be suitable for your production environment. So please do check Docker best practices for production apps. This tutorial is meant to be a basic introduction to Docker. In this post, I am going to use Docker Machine and Docker Compose. You can get them by installing the awesome Docker Toolbox.

Components Breakdown

Before we start, we need to break down our requirements so we can individually build the required components. For my particular application, we need these:

  1. Django App Server
  2. MySQL Database Server
  3. Redis Server

We will build images for these separately so we can create individual containers and link them together to compose our ultimate application. We shall build our Django App server and use pre-built images for MySQL and Redis.

Building the Django App Server

Before we begin, let’s talk Dockerfiles. Dockerfiles are scripts to customize our docker builds. It allows us control and flexibility over how we build the images for our applications. We will use our custom Dockerfile to build the Django app server.

To build an image for a Django application we need to go through these following steps:

  • Select a Linux image, we choose Ubuntu
  • Install required packages for the distro.
  • Install Python packages which are required for the app
  • Provide a default command to run and ports to expose

Here’s the Dockerfile we shall use:

So what are we doing here:

  • We’re choosing phusion/baseimage as our base image. It’s a barebone image based on Ubuntu. Ubuntu by default comes with many packages which we don’t need to run inside docker. This base image gets rid of those and provides a very lean and clean image to start with.
  • We just provide a Maintainer name
  • We set DEBIAN_FRONTEND to be non interactive. This will not display any interactive prompts during the build process. Since the docker build process is automated, we really don’t have any way to interact during it. So we disable interaction. And as you might have guessed already ENV sets an environment variable.
  • We install some packages we shall need.
  • We copy our requirements.txt file to /app/src/requirements.txt, change the work directory and install the packages using pip. ADD is used to copy any files or directories to the container while it builds. You might wonder why we didn’t copy over our entire project – that’s because we want to use docker for our development. We will use a nice featire of Docker which would allow us to mount our local directories directly inside the container. Doing this, we would not need to copy files every time they change. More on this will come later.
  • We change directory to /app/src/lisp and run the runall management command. This command runs the Django default server along with some other services my application needs. But usually we would want to just do runserver
  • We EXPOSE port 8000

If you go through the Dockerfile References you will notice – we can do a lot more with Dockerfiles.

Docker Compose and Linking Services

As we mentioned earlier, we shall use pre-built images for MySQL and Redis. We could build them ourselves too but why not take advantage of the well maintained images from the generous folks in the docker community?

We can link multiple docker containers to compose a final application. We can do that using the docker command manually. But Docker Compose is a very nice tool which allows us to define the services we need in a very easy to read syntax. With docker compose, we don’t need to run them manually, we can just use simple commands to do complex docker magic! Here’s our docker-compose.yml file:

In our docker-compose file, we define 3 components:

  • For the web, we pass the path to Dockerfile to build key. We ask to restart always and define volumes to mount. .:/app/src means – mount the current directory on my OS X as /app/src/ on the container. We also define which ports to expose and which containers should be linked with it
  • We also define the mysql and redis components with respective configurations. Note that we define the pre-built image name in the image key. Please make sure the volume paths exist and are accessible.

You can consult the Compose File Reference for more details.

Running The Services

To run the application, we can do:

Please note, the Django server might throw errors if the MySQL / Redis server takes time to initialize. So I usually run them separately:

Database Configuration for Django

Our MySQL server is running on the IP of the Docker Machine. You need to use this IP address in your Django settings file. To get the IP of a docker machine, type in:

Creating Initial Databases

We can pass a MYSQL_DATABASE environment value to the mysql image so the database is created when creating the service. Or we can also connect to the docker machine manually and create our databases.

Extracting links and their page title from your Twitter Archive

Twitter allows us to download our Tweets from the account settings page. Once we request our archive, Twitter will take some time to prepare it and send us an email once this is ready. We will get a download link in the email. After unpacking the archive, we shall find a csv file that contains our tweets – tweets.csv. The archive also contains a html page (index.html) that displays our tweets on a nice UI. While this is nice to look at, our primary objective is to extract the links from our tweets.

If we look at the CSV file closely, we shall find a field named expanded_urls which generally contains the urls we use in our tweets. We will work with the values in this field. With the url, we also want to fetch their title. For this we will use Python 3 (I am using 3.5) and we need the requests and beautifulsoup4 packages to download and parse the pages. Let’s install them:

We will follow these steps to extract links and their page titles from the tweets:

  • Open the csv file and read row by row
  • Each row contains a tweet, we take the expanded_urls field
  • This field can contain multiple urls, separated by a comma. We need to iterate over them all
  • We will skip some domains, for example, we don’t want to visit links to twitter status updates
  • We fetch the html content using the requests library. If the page doesn’t return a HTTP 200, we ignore the response
  • We extract the title using beautiful soup and display it

Now let’s convert these steps to codes. Here’s the final script I came up with:

I am actually using this for a personal project I am doing here – https://github.com/masnun/bookmarks – it’s basically a bare bone django admin app where I intend to store the links I visit/share. I come across a lot of interesting projects, articles, videos and then later lose track of them. Hope this app will remedy that. This piece of code is part of a twitter import functionality of the mentioned app.

Python 3: Using blocking functions or codes with asyncio

We know we can do a lot of async stuff with asyncio but have you ever wondered how to execute blocking codes with it? It’s pretty simple actually, asyncio allows us to run blocking code using BaseEventLoop.run_in_executor method. It will run our functions in parallel and provide us with Future objects which we can await or yield from.

Let’s see an example with the popular requests library:

If you run the code snippet, you can see how the two responses are fetched asynchronously 🙂

Creating a Twitter Retweet Bot in Python

We want to create a bot that will track specific topics and retweet them. We shall use the Twitter Streaming API to track topics. We will use the popular tweepy package to interact with Twitter.

Let’s first install Tweepy

We need to create a Twitter app and get the tokens. We can do that from : https://apps.twitter.com/.

Now let’s see the codes:

The code is pretty much self explanatory:

  • We create a Twitter API client using the oAuth details we got earlier
  • We subclass StreamListener to implement our own on_data method
  • We create an instance of this class, then create a new Stream by passing the auth handler and the listener
  • We use the track method to track a number of topics we are interested in
  • When we start to track the topics, it will pass the data to on_data method where we parse the tweet, check some common words to avoid, check language and then retweet it.