def _get_workflow_as_clientside_update(self) -> WorkflowUpdateData: """Return (clientside.Update, delta_id). Raise Workflow.DoesNotExist if a race deletes the Workflow. """ with self._lookup_requested_workflow_with_auth_and_cooperative_lock( ) as workflow: if self.scope["user"].is_anonymous: user = None else: user_id = self.scope["user"].id lock_user_by_id(user_id, for_write=False) user = query_clientside_user(user_id) update = clientside.Update( user=user, workflow=workflow.to_clientside(), tabs={ tab.slug: tab.to_clientside() for tab in workflow.live_tabs }, steps={ step.id: step.to_clientside() for step in Step.live_in_workflow(workflow) }, ) return WorkflowUpdateData(update, workflow.last_delta_id)
def locked_and_loaded_step( workflow_id: int, step_slug: str ) -> ContextManager[Tuple[DbObjectCooperativeLock, Step, str]]: """Yield `WorkflowLock`, `step` and `file_param_id_name`. SECURITY: the caller may want to test the Step's `file_upload_api_token`. Raise UploadError(404, "workflow-not-found") on missing/deleted Workflow. Raise UploadError(404, "step-not-found") on missing/deleted Step. Raise UploadError(400, "step-module-deleted") on code-less Step. Raise UploadError(400, "step-has-no-file-param") on a Step with no File param. """ try: with Workflow.lookup_and_cooperative_lock( id=workflow_id) as workflow_lock: workflow = workflow_lock.workflow try: step = Step.live_in_workflow(workflow).get(slug=step_slug) except Step.DoesNotExist: raise UploadError(404, "step-not-found") try: module_zipfile = MODULE_REGISTRY.latest(step.module_id_name) except KeyError: raise UploadError(400, "step-module-deleted") try: file_param_id_name = next( iter(pf.id_name for pf in module_zipfile.get_spec().param_fields if pf.type == "file")) except StopIteration: raise UploadError(400, "step-has-no-file-param") yield workflow_lock, step, file_param_id_name except Workflow.DoesNotExist: raise UploadError(404, "workflow-not-found")
def _load_step_by_slug_sync(workflow: Workflow, step_slug: str) -> Step: """Return a Step or raise HandlerError.""" try: return Step.live_in_workflow(workflow).get(slug=step_slug) except Step.DoesNotExist: raise HandlerError("DoesNotExist: Step not found")
def _load_step_by_id(workflow: Workflow, step_id: int) -> Step: """Return a Step or raises HandlerError.""" try: return Step.live_in_workflow(workflow).get(id=step_id) except Step.DoesNotExist: raise HandlerError("DoesNotExist: Step not found")
def _workflow_has_notifications(workflow_id: int) -> bool: """Detect whether a workflow sends email on changes.""" return Step.live_in_workflow(workflow_id).filter( notifications=True).exists()