Source code for oarepo_config.workflows.low_level

#!/usr/bin/env python3
#
# Copyright (c) 2026 CESNET z.s.p.o.
#
# This file is a part of oarepo-config (see https://github.com/oarepo/oarepo-config).
#
# oarepo-config is free software; you can redistribute it and/or modify it
# under the terms of the MIT License; see LICENSE file for more details.
#
"""Configuration for workflows."""

from __future__ import annotations

import inspect
import warnings
from typing import TYPE_CHECKING, Any

from flask_babel import LazyString
from invenio_base.utils import obj_or_import_string
from invenio_i18n import gettext as _

if TYPE_CHECKING:
    try:
        from oarepo_workflows import WorkflowRequestPolicy
        from oarepo_workflows.services.permissions import DefaultWorkflowPermissions
    except ImportError:
        WorkflowRequestPolicy = None  # type: ignore[assignment]
        DefaultWorkflowPermissions = None  # type: ignore[assignment]

    from flask_babel import LazyString
else:
    LazyString = Any  # type: ignore[assignment]

from ..base import get_constant_from_caller, set_constants_in_caller


[docs] def register_workflow( workflow_code: str, workflow_name: str | LazyString, permissions_policy: str | type, requests_policy: str | type, use_low_level_workflows: bool = False, ) -> None: """Register a submission/review workflow that records can go through. A workflow defines the path a record takes from being created to being published - for example, who may create it, whether it needs review/approval before publishing, and who may perform each of those steps. This adds one such workflow to the repository, so that it can be selected when configuring where records may be submitted (e.g. a community). This is a low-level, single-workflow building block. Repositories that use the community-based workflow shape provided by the ``oarepo_app`` package typically use its higher-level ``configure_workflows(IndividualWorkflow(...), CommunityWorkflow(...))`` helper instead - see this package's README for the difference. Args: workflow_code: A short, unique identifier for the workflow, e.g. ``"default"``. workflow_name: The human-readable name of the workflow, shown to users, e.g. ``_("Default workflow")``. permissions_policy: Who is allowed to do what with records that use this workflow (create, edit, delete, publish, ...). Pass either a permissions policy class or its import path as a string. requests_policy: What review/approval requests are available for records using this workflow (e.g. a publish request that needs a curator's approval). Pass either a request policy class or its import path as a string. use_low_level_workflows: Set to ``True`` to silence the warning recommending :func:`configure_workflows` instead, for the (uncommon) cases that genuinely need this low-level, single-workflow API. Requires the optional ``oarepo_workflows`` (and, for its defaults, ``oarepo_requests``) package to be installed. Invenio configuration variables set: * ``WORKFLOWS`` - the new workflow is appended; workflows already registered (by earlier calls) are kept. * ``REQUESTS_PERMISSION_POLICY`` - only if not already set by an earlier call; defaults to ``CreatorsFromWorkflowRequestsPermissionPolicy``. Example: .. code-block:: python from oarepo_workflows.services.permissions import ( DefaultWorkflowPermissions, ) from oarepo_requests.services.permissions.workflow_policies import ( CreatorsFromWorkflowRequestsPermissionPolicy, ) config.register_workflow( workflow_code="default", workflow_name=_("Default workflow"), permissions_policy=DefaultWorkflowPermissions, requests_policy=CreatorsFromWorkflowRequestsPermissionPolicy, ) """ if not use_low_level_workflows: warnings.warn( "register_workflow() is a low-level, single-workflow building block. " "configure_workflows(IndividualWorkflow(...), CommunityWorkflow(...)) is a " "simplified solution that should be used instead for the common case. Pass " "use_low_level_workflows=True if you intentionally need the low-level API.", stacklevel=2, ) try: from oarepo_requests.services.permissions.workflow_policies import ( CreatorsFromWorkflowRequestsPermissionPolicy, ) from oarepo_workflows import Workflow, WorkflowRequestPolicy from oarepo_workflows.services.permissions import DefaultWorkflowPermissions except ImportError as e: raise ImportError("oarepo_workflows package is required for workflow registration.") from e WORKFLOWS = get_constant_from_caller("WORKFLOWS", []) permission_policy_cls = obj_or_import_string(permissions_policy) if not (inspect.isclass(permission_policy_cls) and issubclass(permission_policy_cls, DefaultWorkflowPermissions)): raise TypeError("permissions_policy must be a subclass of DefaultWorkflowPermissions") requests_policy_cls = obj_or_import_string(requests_policy) if not (inspect.isclass(requests_policy_cls) and issubclass(requests_policy_cls, WorkflowRequestPolicy)): raise TypeError("requests_policy must be a subclass of WorkflowRequestPolicy") WORKFLOWS.append( Workflow( code=workflow_code, label=_(workflow_name), permission_policy_cls=permission_policy_cls, request_policy_cls=requests_policy_cls, ) ) REQUESTS_PERMISSION_POLICY = get_constant_from_caller( "REQUESTS_PERMISSION_POLICY", CreatorsFromWorkflowRequestsPermissionPolicy ) set_constants_in_caller(locals())