I recently started working in Python (v. 3) and had to develop some scripts to perform various tasks that weren’t part of the main, long-running application.
tl;dr: Create a Class, instantiate and run it with an
Coming from the Ruby world, and having worked a lot with similar sorts
of tasks, I decided to follow my usual pattern of creating a
class, which gets instantiated with the specific environment and
runtime parameters, and then run using some performative verb method,
One of the tasks was to implement a “smoke test” of the application, to ensure all the endpoints were answering correctly. (This was at a time when some of the endpoints weren’t entirely finished and were returning 500 server errors; we wanted to make sure we weren’t regressing from that point when we deployed a new version to staging.)
Declaring a “Runner” Class
Declaring a class in Python is simple enough, especially if it’s not inheriting anything:
This gave me the basis for injecting all the various bits and pieces of the runtime environment for the task, using the “if name” idiom.
Python has the idiom of checking whether the currently running script
was called directly by comparing the content of the
variable to the string
"__main__". Putting this after the class, the
body of the
if part can then gather up the environment runtime
information it needs, instantiate the task class, and receive the
outcomes from the class.
This script took the outcomes and created a nice-looking report of the results. If the task class was called by some other object, that consumer could do other operations if it wanted.
Re-thinking this now, I think it might be nicer to have the reporting part as a method on the object, enabling the use of decorators for doing other things with the results, they could easily do that and still have the formatted report. So let’s do that in this example.
The output of running the script would be:
I think this applies to other patterns as well, such at gateway / proxy objects that might be long-lived in an application, specific service clients, background jobs to free up resources in the main application, ETL tasks that chain off each other, and many other one-off types of mini applications. I’ve not yet written command line utilities, but I think these would also benefit from this.