From 5b7a3685319cb5cdc0bd8ff9d5acf51552d43807 Mon Sep 17 00:00:00 2001 From: Leonardo Schwarz Date: Wed, 20 May 2026 09:11:24 +0200 Subject: [PATCH 1/2] Created Using field --- bfabric_rest_proxy/docs/changelog.md | 2 ++ .../feeder_operations/create_workunit.py | 34 +++++++++++-------- .../src/bfabric_rest_proxy/server.py | 6 ++-- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/bfabric_rest_proxy/docs/changelog.md b/bfabric_rest_proxy/docs/changelog.md index cb127f2b..d94fac79 100644 --- a/bfabric_rest_proxy/docs/changelog.md +++ b/bfabric_rest_proxy/docs/changelog.md @@ -7,6 +7,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). ### Changed - `feeder_operations.create_workunit` is now a thin authorization + audit-stamping wrapper around `bfabric.operations.workunit.create_workunit`. The workunit creation now flips the workunit to status `failed` on any error after initial creation (was: orphaned in `processing` status). +- `POST /create/workunit/v1` request body now accepts an optional `created_using` field (e.g. calling-app identifier). It is recorded as the `Created Using` custom attribute alongside the server-stamped `Created For` attribute. The wrapper signature changed accordingly: it now takes a single `CreateWorkunitRequest` (subclass of `CreateWorkunitParams`) instead of separate `params` + `created_using` arguments. +- Renamed the workunit custom attribute that records the initiating web-app user from `WebApp User` to `Created For`. ### Fixed diff --git a/bfabric_rest_proxy/src/bfabric_rest_proxy/feeder_operations/create_workunit.py b/bfabric_rest_proxy/src/bfabric_rest_proxy/feeder_operations/create_workunit.py index 6b0b78a5..e05ef933 100644 --- a/bfabric_rest_proxy/src/bfabric_rest_proxy/feeder_operations/create_workunit.py +++ b/bfabric_rest_proxy/src/bfabric_rest_proxy/feeder_operations/create_workunit.py @@ -2,32 +2,36 @@ from bfabric import Bfabric from bfabric.entities import Workunit -from bfabric.operations.workunit import CreateWorkunitParams, create_workunit as _create_workunit +from bfabric.operations.workunit import CreateWorkunitParams +from bfabric.operations.workunit import create_workunit as _create_workunit -__all__ = ["CreateWorkunitParams", "create_workunit"] +__all__ = ["CreateWorkunitParams", "CreateWorkunitRequest", "create_workunit"] + + +class CreateWorkunitRequest(CreateWorkunitParams): + """Proxy-level request: core workunit params plus client-supplied audit metadata.""" + + created_using: str | None = None def create_workunit( user_client: Bfabric, feeder_client: Bfabric, - params: CreateWorkunitParams, + request: CreateWorkunitRequest, ) -> Workunit: - """Create a workunit with the given parameters, using the feeder client on behalf of the user client. - - Before proceeding, it will be checked if the user has permission to read the target container. + """Create a workunit using the feeder client on behalf of the user client. - :param user_client: the web application user, which initiates the operation - :param feeder_client: the feeder user, which will actually perform the operation - :param params: the workunit parameters - :return: the created workunit - :raise: BfabricException if any API operation fails - :raise: RuntimeError if authorization fails + `Created For` is set server-side from the authenticated user. + `Created Using` is set from the (optional) client-supplied field. """ - _check_container_access(user_client=user_client, container_id=params.container_id) + _check_container_access(user_client=user_client, container_id=request.container_id) + audit_attributes = {"Created For": user_client.auth.login} + if request.created_using is not None: + audit_attributes["Created Using"] = request.created_using return _create_workunit( client=feeder_client, - params=params, - audit_attributes={"WebApp User": user_client.auth.login}, + params=request, + audit_attributes=audit_attributes, ) diff --git a/bfabric_rest_proxy/src/bfabric_rest_proxy/server.py b/bfabric_rest_proxy/src/bfabric_rest_proxy/server.py index d248b012..69fb6cea 100644 --- a/bfabric_rest_proxy/src/bfabric_rest_proxy/server.py +++ b/bfabric_rest_proxy/src/bfabric_rest_proxy/server.py @@ -14,7 +14,7 @@ from pydantic import BaseModel, Field, SecretStr, model_validator from bfabric import Bfabric, BfabricAuth, BfabricClientConfig -from bfabric_rest_proxy.feeder_operations.create_workunit import CreateWorkunitParams, create_workunit +from bfabric_rest_proxy.feeder_operations.create_workunit import CreateWorkunitRequest, create_workunit from bfabric_rest_proxy.settings import ServerSettings from bfabric_rest_proxy.feeder_operations.is_employee import is_employee @@ -108,9 +108,9 @@ def read(user_client: BfabricUserClientDep, params: ReadParams): def post_create_workunit( user_client: BfabricUserClientDep, feeder_client: BfabricFeederClientDep, - params: CreateWorkunitParams, + request: CreateWorkunitRequest, ): - workunit = create_workunit(user_client=user_client, feeder_client=feeder_client, params=params) + workunit = create_workunit(user_client=user_client, feeder_client=feeder_client, request=request) return [{**workunit.data_dict, "uri": workunit.uri}] From 11a46ee3c789099cfe30996ab822c6bbaf6f9edb Mon Sep 17 00:00:00 2001 From: Leonardo Schwarz Date: Wed, 20 May 2026 09:23:17 +0200 Subject: [PATCH 2/2] Keep /create/workunit/v1 body key as 'params' --- bfabric_rest_proxy/src/bfabric_rest_proxy/server.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bfabric_rest_proxy/src/bfabric_rest_proxy/server.py b/bfabric_rest_proxy/src/bfabric_rest_proxy/server.py index 69fb6cea..91477714 100644 --- a/bfabric_rest_proxy/src/bfabric_rest_proxy/server.py +++ b/bfabric_rest_proxy/src/bfabric_rest_proxy/server.py @@ -108,9 +108,9 @@ def read(user_client: BfabricUserClientDep, params: ReadParams): def post_create_workunit( user_client: BfabricUserClientDep, feeder_client: BfabricFeederClientDep, - request: CreateWorkunitRequest, + params: CreateWorkunitRequest, ): - workunit = create_workunit(user_client=user_client, feeder_client=feeder_client, request=request) + workunit = create_workunit(user_client=user_client, feeder_client=feeder_client, request=params) return [{**workunit.data_dict, "uri": workunit.uri}]