Dryable - enabling --dry-run
functionality
Sometimes we are want to check the basic logic of our programs without running certain operations that are lengthy and cause side effects.
E.g. we would like some script to tell us what it would have done, but without actually doing it: a good example is when you have a script that is supposed to delete some old files or database entries, and you want to use a “dry run” to see what it would do, before actually letting it loose.
$ ./my-deleting-script --dry-run # don't really delete anything, just show me
The problem with that sort of thing is that your code gets filled with
annoying if
statements like:
if not dryRun:
doTheThing()
else:
logTheThing()
This is precisely what Dryable
is for. You set the “dry run” mode like this:
dryable.set( True ) # or False to turn it off
Here’s an example if how to use it:
import dryable
import requests
import sys
def findOldFilesForDeletion():
return [ 'some', 'results' ]
@dryable.Dryable()
def deleteFiles( results ):
print( 'will now open an real world connection'
'that requires a server and will make side effects' )
requests.post( 'http://url.to.some.server/results', data = str( results ) )
# the next line ensures that deleteFiles
# will not run if --dry-run is specified on the command line
dryable.set( '--dry-run' in sys.argv )
# now code as usual
results = findOldFilesForDeletion()
print( 'got: {}'.format( results ) )
deleteFiles( results )
Installation
Install dryable like so
$ pip install dryable
Returning Custom Values
By default a Dryable
decorated function will return None
in dry-run mode. If you need some other value, specify it like so:
@dryable.Dryable( [ 'fake person 1', 'fake person 2' ] )
def getPeopleFromDatabase():
return actualQueryFromDB()
What If I Have Different Things I Want To Dry-Run?
If you’re using dryable
, you may run into situations in which you want to dry-run some code, but not some other code.
E.g. you want to have --dont-delete-files
and separately --dont-save-to-db
or something.
The way to handle this situation is with labels
import dryable
@dryable.Dryable( label = 'labelA' )
def functionA():
print( "Hi, I am A" )
@dryable.Dryable( label = 'labelB' )
def functionB():
print( "Hi, I am B" )
dryable.set( True, 'labelA' )
functionA() # this will be dried up
functionB() # this will run for real
Logging
Dryable logs to a logger called dryable
which is available via Dryable.logger
What If I want to log a dryable function with a custom message ?
You can define a custom message using logging_msg
parameter:
import dryable
@dryable.Dryable( logging_msg = 'Function A were not executed (--dry-run)' )
def functionA():
print( "Hi, I am A" )
Optionally, you may also inject the following patterns, which will be interpreted by Dryable:
Placeholder | Description |
---|---|
{label} |
Label defined in @Dryable() |
{function} |
Function name |
{args} , {kwargs} |
Args and kwargs passed to the function |
import dryable
@dryable.Dryable( logging_msg = 'Would have called {function} with args {args} (--dry-run)' )
def functionA(paramA):
print( "Hi, I am A" )