Python script timing

Basic usage

The main tracking functionality uses the Tracker object, which is used to create named blocks throughout your code. Blocks need start and stop calls, and multiple iterations are combined to summarize how long it takes to complete each leg. The report function prints the results from all blocks. If stop is not supplied a block name, the tracker will close and calculate elapsed time from the last open block (i.e. last in, first out).

As an example of the basic usage:

import jort
from time import sleep

tr = jort.Tracker()

tr.start('my_script')
sleep(1)
for _ in range(10):
    tr.start('sleep_1s')
    sleep(1)
    tr.stop('sleep_1s')
tr.stop('my_script')

tr.report()

The printed report appears as:

my_script | 11.0 s ± 0.0 s per iteration, n = 1
sleep_1s | 1.0 s ± 0.0 s per iteration, n = 10

Alternatively, you can use single line checkpoints with tr.checkpoint(), which create timing blocks that close at the start of the next checkpoint. Note that you must use another tr.stop() call to end the final checkpoint block.

Notifications

Notifications are handled by callbacks to timing functions. As of now, there are three main callbacks:

jort.PrintReport()
jort.EmailNotification()
jort.TextNotification()

Notifications are executed at the end of blocks using the function Tracker.stop with argument callbacks, which accepts a list of callbacks. Note: notification callbacks are not intended to be called frequently.

If used in the callback of a jort function decorator or command line tracker, the tracker will flag errors and print the appropriate message.

tr = jort.Tracker()
tr.start()
# your code here
tr.stop(callbacks=[jort.PrintReport(), jort.EmailNotification(), jort.TextNotification()])

PrintReport

PrintReport prints a formatted completion message with the runtime.

tr.stop(callbacks=[jort.PrintReport()])

EmailNotification

EmailNotification e-mails a formatted message with the runtime and other job details. If used to time a command line program, this callback can be used to send program output as an e-mail attachment.

Of course, to send e-mails from your account, you will need to enter login credentials with the command line tool jort config. For e-mail, jort needs the SMTP server (for Gmail this is smtp.gmail.com), your e-mail, and either a password or app password. At the moment, you can only send notification e-mails to yourself, from your own account.

tr.stop(callbacks=[jort.EmailNotification()])

TextNotification

TextNotification texts a formatted message with the runtime. jort uses Twilio to handle SMS messaging. Twilio offers a free trial tier.

You will need to enter login credentials with the command line tool jort config. For SMS, jort needs your phone number (to receive notifications), your Twilio number, account SID, and auth token. If you are using the free trial, you may only send SMS messages to verified phone numbers on your Twilio account.

tr.stop(callbacks=[jort.TextNotification()])

Function decorators

jort supports timing functions with decorators, via Tracker.track. Demonstrating on the first example:

tr = jort.Tracker()

@tr.track
def sleep_1s():
    sleep(1)

@tr.track
def my_script():
    sleep(1)
    for _ in range(10):
        sleep_1s()

my_script()
tr.report()

The printed report appears as:

my_script | 11.0 s ± 0.0 s per iteration, n = 1
sleep_1s | 1.0 s ± 0.0 s per iteration, n = 10

You can use notification callbacks (once again, it may not be useful to notify on functions that execute many times):

@tr.track(callbacks=[jort.EmailNotification()])
def my_script():
    sleep(1)
    for _ in range(10):
        sleep_1s()

If you want to time one-off functions, you can also use jort.track without instantiating a Tracker:

@jort.track
def my_script():
    sleep(1)
    for _ in range(10):
        sleep_1s()

Saving to database

jort allows you to save details of finished jobs to a local database. To save all blocks to database, use the to_db keyword. You can also optionally group jobs under a common “session” by specifying the session_name keyword:

tr = jort.Tracker(to_db=True, session_name="my_session")

If you do not want every block to be saved, you can specify manually:

tr.stop('my_script', to_db=True)

@tr.track(to_db=True)
def my_script():
    [...]

Logging

jort automatically logs results by default. You can change the destination filename, as well as the level of verbosity (0: no logging; 1: only elapsed times; 2: start and stop times). Defaults are logname='tracker.log' and verbose=2.

import jort
from time import sleep

tr = jort.Tracker(logname='my_log.log', verbose=1)