travis codecov pyup codacy pypi docs gitter

The business transaction DSL

stories is a business transaction DSL. It provides a simple way to define a complex business transaction that includes processing over many steps and by many different objects. It makes error handling a primary concern by taking a “Railway Oriented Programming” approach to capturing and returning errors from any step in the transaction.

stories is based on the following ideas:

  • A business transaction is a series of operations where any can fail and stop the processing.
  • A business transaction can describe its steps on an abstract level without being coupled to any details about how individual operations work.
  • A business transaction doesn’t have any state.
  • Each operation shouldn’t accumulate state, instead it should receive an input and return an output without causing any side-effects.
  • The only interface of an operation is ctx.
  • Each operation provides a meaningful piece of functionality and can be reused.
  • Errors in any operation should be easily caught and handled as part of the normal application flow.


stories provide a simple way to define a complex business scenario that include many processing steps.

from stories import story, argument, Success

class PurchaseProduct:

    def purchase(I):


    def create_order(self, ctx):

        order = Order.objects.create(
        return Success(order=order)

    def calculate_price(self, ctx):

        return Success(...

This code style allow you clearly separate actual business scenario from implementation details.


stories library was heavily inspired by dry-transaction ruby gem.