Dry-run¶
The dry-run module provides the toolkit for safely executing production code without side-effects.
Usage¶
A context-manager is provided to safely wrap code in a dry-run context as well as a function to get the current dry-run state.
WARNING: It is the responsibility of everyone to implement differentiated behaviors between dry-run and non dry-run.
NOTE: The transaction module will automatically honor the dry-run context and not commit.
Context Manager¶
You can use the context-manager directly to ensure a dry-run context in a particular part of the code:
from shared.dry_run import dry_run
def increase_longevity():
with dry_run():
distribute_magic_pill_to_all_members()
It is still the responsibility of each function to implement the appropriate logic:
from shared.dry_run import is_dry_run
def distribute_magic_pill_to_all_members():
distributor: Distributor
if is_dry_run():
distributor = FakeDistributor()
else:
distributor = LaPosteDistributor()
distributor.distribute()
Commands¶
Commands that use command_with_dry_run from shared.cli.helpers are automatically using the context-manager under the hood.
from components.billing import cash_in
from shared.cli.helpers.dry_run import command_with_dry_run
from shared.dry_run import is_dry_run
@command_with_dry_run
def make_money(dry_run: bool) -> None:
# dry_run argument in commands is preserved for backward compatibility but can be replaced by `is_dry_run()`
assert dry_run == is_dry_run()
cash_in()
It guarantees that everything inside the context will commit together or fail together. Note that explicit call to commit inside the context manager is forbidden as it is handled by the context manager.
This code will commit automatically as soon as you exit the context manager, if a failure occurs, the session will be rollback appropriately.
However, if this code is itself contained in another transaction, the commit will occur only when exiting the outermost context:
def create_user():
with transaction() as session:
session.add(User(name="Marcel"))
def complex_operation():
with transaction() as session:
... # some code
create_user() # does not commit
... # some more code
# commits!