HomePython Page 4 - Python Email Libraries, part 1: POP3
Getting Messages from the Server - Python
Some very useful business software connects with and interacts with email in various ways. If you are building or working with such software, you might want to know how Python accomplishes these tasks. This article series discusses how to use the email libraries built into Python. In this first part, POP3 is covered.
After you have downloaded the list of messages from the server, you can now begin to download the messages themselves. An example of how you might do this follows:
Overall, this code loops through each element of message info that was downloaded in the previous block of code. For each of those bits of message info, it splits them into the message number and the message size. Note the way the string library’s split method simplifies this operation. For each message whose size is less than 20 kilobytes (sizes are returned in raw bytes, hence the 20000 rather than 20), it downloads the message and strips off the server response. The actual data of a downloaded message is given to you as a list of strings, where each string contains one line of the message.
We use the string library join method to easily put all of these strings together in one massive string with a newline character at the end of each line. We then put this string on a list containing all of the downloaded messages. This data structure could then be used with Python’s built in email parsing library to create an easily accessible data structure for accessing the header fields for each message. The actual process for doing this will be covered in a later article.
Advanced Topics: Network Latency and Threading
Generally, that’s about it. RFC 1725 contains further information on exactly how to specify specific subsets of messages for info retrieval, which is a useful capability, although sometimes it is easier to simply grab all the message info and process it locally. An important thing to note about all of these various networking calls described here is that they are all “blocking” calls. This means that execution of the main program thread is suspended while it waits for a response from the server.
If you are using these networking calls within the context of a command line script, or even a Web script, this will probably not matter. Generally, there will be a good reason for having the program’s main execution thread wait for the network calls to complete before moving on to its next step. However, if you are using these calls in a program served by a GUI front end, this blocking can be very frustrating for a user.
Because network communication time-outs are usually defined in the time frame of 30-60 seconds, using these calls in the main execution stream of a GUI program will lock the GUI until that call completes. If the call happens to fail or the server doesn’t respond, that means the GUI is locked for 30-60 seconds while it is waiting for the IP implementation on that computer to tell it whether or not the network communication succeeded. This behavior for a GUI is usually not considered acceptable.
The solution to this problem lies in separate execution threads for the network operations. Overall, a solution to this problem would take a form something like this. The event handler for a GUI component that needs to cause a network operation should spin a separate execution thread off that actually performs the network call. A status bar update can be used to notify the user that the network operation is in process. This separate thread will then perform the network call and effect any change that needs to be made to the GUI. This prevents the GUI from becoming unresponsive while the network call is proceeding.