Might want to add some code comments so that it's easy to tell the intention of each method. Personal experience: when you write a little bit of a pydoc for your code it can highlight code smells. e.g.: If the docstring is too long then maybe you are doing too much in one method.
Looking at the run function, you might benefit to use a switch-case in place of that plethora of if-elif's. It would look a bit neater IMHO.