def build_workflow()

in source/workflowapi/app.py [0:0]


def build_workflow(workflow):

    logger.info("Sanity Check for End of workflow")
    endcount = 0
    for Name, stage in workflow["Stages"].items():

        # Stage must have an End or a Next key
        if "End" in stage and stage["End"] == True:
            endcount += 1
        elif "Next" in stage:
            pass
        else:
            raise BadRequestError("Stage %s must have either an 'End' or and 'Next' key" % (
                Name))

    if endcount != 1:
        raise BadRequestError("Workflow %s must have exactly 1 'End' key within its stages" % (
            workflow["Name"]))

    logger.info("Get stage definitions")

    for Name, stage in workflow["Stages"].items():
        s = get_stage_by_name(Name)

        logger.info(json.dumps(s))

        s["stateMachineAsl"] = json.loads(s["Definition"])
        stage.update(s)

        # save the operators for this stage to the list of operators in the
        # workflow.  This list is maintained to make finding workflows that
        # use an operator easier later
        workflow["Operations"].extend(stage["Operations"])

        logger.info(json.dumps(s))

    # Build the workflow state machine.
    startStageAsl = workflow["Stages"][workflow["StartAt"]]["stateMachineAsl"]
    startAt = startStageAsl["StartAt"]
    logger.info(startAt)

    workflowAsl = {
        "StartAt": startAt,
        "States": {
        }
    }

    logger.info("Merge stages into workflow state machine")
    for workflowStageName, workflowStage in workflow["Stages"].items():
        logger.info("LOOP OVER WORKFLOW STAGES")
        logger.info(json.dumps(workflowStage))


        # if this stage is not the end stage
        # - link the end of this stages ASL to the start of the next stages ASL
        if "Next" in workflowStage:
            nextWorkflowStageName = workflowStage["Next"]
            nextWorkflowStage = workflow["Stages"][workflowStage["Next"]]

            logger.info("NEXT STAGE")
            logger.info(json.dumps(nextWorkflowStage))

            # Find the End state for this stages ASL and link it to the start of
            # the next stage ASL
            print(json.dumps(workflowStage["stateMachineAsl"]["States"]))
            for k, v in workflowStage["stateMachineAsl"]["States"].items():
                print(k)
                if ("End" in v):
                    endState = k

            # endState = find("End", workflowStage["stateMachineAsl"]["States"])

            logger.info("END STATE {}".format(endState))

            workflowStage["stateMachineAsl"]["States"][endState]["Next"] = nextWorkflowStage["stateMachineAsl"][
                "StartAt"]

            # Remove the end key from the end state
            workflowStage["stateMachineAsl"]["States"][endState].pop("End")

        workflowAsl["States"].update(workflowStage["stateMachineAsl"]["States"])

        # Remove ASL from the stage since we rolled it into the workflow and ASL in saved in the stage defintition
        workflowStage.pop("stateMachineAsl")

        logger.info("IN LOOP WORKFLOW")
        logger.info(json.dumps(workflowAsl))

    logger.info(json.dumps(workflowAsl))
    workflow["WorkflowAsl"] = workflowAsl

    return workflow