Package: py-api-saga
PY API SAGAPY API SAGAis a complete class-based fashion of building saga pattern for microservices. It offers both narrative
patternsOrchestration-Based SagaandChoreography-Based Saga. To execute saga operations use the following method.orchestrator_executechoreography_executeorchestrator_executeEvery transition is carried out one by one. If exception arises, all prior operations
will be compensated in the reversed order. All the operation responses are contained in the result list and the results
are arranged in the same sequence as the Saga operations.choreography_executeEvery transition is carried out concurrently, and no operation is dependent on any other
process. Hence, multithreading is used an if an error occurs in any of the operation process all the succeeded
operations will be compensated.While executing compensations possible Exceptions are recorded and raised wrapped in a SagaException once all
compensations have been executed.Key features:Easy: Designed to be easy to use and intuitive.Fast to code: Type hints and automatic docs lets you focus only on business logic.Framework friendly: Since it developed with standard Python, so it can simply implement with python based
frameworks like Django and Flask.Retry operation attempts: Retry an operation action again if it fails.RequirementsPython >= 3.6Installationpip install py-api-sagaAfter installation, importSagaAssemblerfrompy_api_saga.py_api_sagaDeclartionThe saga operation contains only two function operation action and compensation. The action and compensation are
by two ways.when operation has arguments then pass the function along with in a tuple.When function is without argument then simply pass the function name.Examplefrompy_api_saga.py_api_sagaimportSagaAssembler...# Operation with argument functionsSagaAssembler.saga().operation((function_name,arg_1,arg_2),(compensation_function_name,arg_1)).orchestrator_execute()...# Operation without argument functionsSagaAssembler.saga().operation(function_name,compensation_function_name).orchestrator_execute()UsageSimple exampleimportjsonimportrequestsdefupdate_product_state(state):#function to update the state in product service.url="https://host/productService/product/123/"# updat e product state from 'in_stock' to 'sold_out'response=requests.post(url=url,data=json.dumps({"state":state}))ifresponse!=200:raiseException(response.error)returnresponsedefupdate_shipping_state(shipping_state):#function to update the state in shipping service.url="https://host/shippingService/product/123/shipping/"# update shipping state to 'ready_to_dispatch'response=requests.post(url=url,data=json.dumps({"state":shipping_state}))ifresponse!=200:raiseException(response.error)returnresponseNow build saga as given below:...frompy_api_saga.py_api_sagaimportSagaAssembler...try:result=SagaAssembler.saga().operation((update_product_state,'sold_out'),(update_product_state,'in_stock')).operation((update_shipping_state,'ready_to_dispatch')).choreography_execute()exceptSagaAssembler.SagaExceptionasexception:returnstr(exception.operation_error)...Advanced saga usageThe prior operation result can be accessed inside the operation function when usingorchestrator_execute.Exampledeffunction_name(args):# access previous functions outcomes.prior_results=function_name.saga_results...Advanced saga Exception handlingWhen an error occurs in saga execution it can be handled usingSagaException. The SagaException provides error as well
as information to track error function and compensation results.Exmaple...exceptSagaAssembler.SagaExceptionasexception:# Errorexception.operation_error# Function name responsible for the error.exception.operation_name# Compensation success result list.exception.compensation_success_result# Error list that occurs when compensation is executed.exception.compensation_errors