Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
80be181
feat: add CWL workflow submission endpoint and storage model
ryuwd Apr 2, 2026
5d8ed95
fix: enforce schema_version as Literal["1.0"] with default in JobHint
ryuwd Apr 2, 2026
001e8ff
fix: normalize CWL before hashing to prevent duplicate workflow rows
ryuwd Apr 2, 2026
13f8c14
feat: use JSON body for CWL submission and add job wrapper template
ryuwd Apr 2, 2026
93f3215
chore: regenerate diracx client
ryuwd Apr 2, 2026
13bba67
refactor: move job wrapper and commands from dirac-cwl into diracx
ryuwd Apr 2, 2026
0de1f46
fix: job wrapper uses jobs.search
ryuwd Apr 2, 2026
f649f63
feat: ReplicaMap integration and added dirac cwl executor
ryuwd Apr 2, 2026
69bb5ae
refactor: cleaned executor significantly
ryuwd Apr 2, 2026
ddadf76
feat(core): extend replica map key validation to accept SB: sandbox r…
ryuwd Apr 6, 2026
e4416cf
refactor(core): remove path field from IOSource — tar structure deter…
ryuwd Apr 6, 2026
ebf46f5
feat(api): extend DiracReplicaMapFsAccess to resolve SB: sandbox paths
ryuwd Apr 6, 2026
bdad870
feat(api): add SB: path parsing and sandbox replica map injection
ryuwd Apr 6, 2026
b0ea2d5
feat(api): add cwltool as explicit dependency of diracx-api
ryuwd Apr 6, 2026
dd118a6
test(api): add unit tests for DiracExecutor, DiracPathMapper, DiracCo…
ryuwd Apr 6, 2026
2c46728
test(api): extend FsAccess tests with LFN resolution coverage
ryuwd Apr 6, 2026
f1ce58d
test(api): add unit tests for JobWrapper commands, output parsing, re…
ryuwd Apr 6, 2026
c587a18
test(api): add integration test for dirac-cwl-run subprocess with rep…
ryuwd Apr 6, 2026
53e3c55
refactor(api): remove backward-compat paths from CWL-only JobWrapper
ryuwd Apr 6, 2026
c97208a
test(api): add JobWrapper integration test for full CWL execution chain
ryuwd Apr 6, 2026
836081f
refactor(api): remove unnecessary module mocking from test files
ryuwd Apr 7, 2026
8d9635c
refactor(cli): move CWL executor package from diracx-api to diracx-cli
ryuwd Apr 7, 2026
25c45be
fix: depend on cwl-utils
ryuwd Apr 7, 2026
d6c3341
chore: update lockfile
ryuwd Apr 7, 2026
1db8f7b
feat: add CWL input parsing module (YAML, JSON, CLI args, range)
ryuwd Apr 7, 2026
bd85cab
feat: add sandbox scanning, grouping, and path rewriting
ryuwd Apr 7, 2026
fc6b398
test: add missing SB passthrough test for rewrite_sandbox_refs
ryuwd Apr 7, 2026
6c7f8cd
feat: add submission confirmation prompt
ryuwd Apr 7, 2026
6c6964d
feat: add shared CWL submission pipeline
ryuwd Apr 7, 2026
2633bdd
feat: add dirac cwl submit command
ryuwd Apr 7, 2026
aea7e6b
feat: add dirac submit command (simple mode)
ryuwd Apr 7, 2026
63763ce
feat: add dirac job command group with search
ryuwd Apr 7, 2026
d16bf1f
feat: add server-side range expansion for parametric CWL jobs
ryuwd Apr 7, 2026
67e07a7
test: add integration tests for CWL submission pipeline
ryuwd Apr 7, 2026
1f88445
refactor(cli): restructure to resource-based hierarchy
ryuwd Apr 8, 2026
a851b97
chore: regenerated client
ryuwd Apr 8, 2026
636bc7d
chore: updated lockfile
ryuwd Apr 8, 2026
32a33a2
test: no skipping if cwltool or dirac-cwl-run not available
ryuwd Apr 8, 2026
f1c3202
chore: update lockfile
ryuwd Apr 8, 2026
763ead5
fix(core): SoftwareDistModule should be empty to not break the pilot
ryuwd Apr 9, 2026
4234958
feat: wire up --range submission to server-side CWL model
ryuwd Apr 9, 2026
26e3f35
fix: use explicit import for diracxTokenFromPEM in job wrapper
ryuwd Apr 9, 2026
5f32354
fix: clean up temp CWL file and extract sandbox PFNs in job wrapper
ryuwd Apr 9, 2026
20238d7
refactor: remove unnecessary sandbox PFN extraction from job wrapper
ryuwd Apr 9, 2026
8c19b4d
feat: append input parameters to job name for parametric jobs
ryuwd Apr 9, 2026
483ceb7
fix: accept jobID as last argument in job wrapper
ryuwd Apr 9, 2026
3fd7812
feat: set ApplicationStatus from CWL task label
ryuwd Apr 9, 2026
3ebc763
feat: stream stderr lines as ApplicationStatus via Popen
ryuwd Apr 9, 2026
49a4bae
fix: drain stdout/stderr concurrently and restore failure Application…
ryuwd Apr 9, 2026
d09c0e3
refactor: use asyncio subprocess for non-blocking stderr streaming
ryuwd Apr 9, 2026
76acbf8
feat(cli): capture stdout/stderr to log files in generated CWL
ryuwd Apr 9, 2026
6f13421
fix: use stdout.log instead of std.out in integration test
ryuwd Apr 9, 2026
28ea1ff
fix: rate-limit status commits and handle commit failures gracefully
ryuwd Apr 9, 2026
424f524
feat: filter ApplicationStatus to cwltool lifecycle transitions only
ryuwd Apr 9, 2026
42428ef
fix: anchor status regex to log-level prefix and use capture group
ryuwd Apr 9, 2026
36fbae1
fix(cli): sandbox submit
ryuwd Apr 10, 2026
582ac77
fix: strip #fragment from InputSandbox JDL field
ryuwd Apr 10, 2026
85eea01
fix: no temp files
ryuwd Apr 10, 2026
0beb974
fix: some things need uploading regardless
ryuwd Apr 10, 2026
1f35e11
refactor: code around job wrapper sandbox handling
ryuwd Apr 10, 2026
b3cc06a
fix: resolve relative path before as_uri() in sandbox replica map
ryuwd Apr 10, 2026
de7349e
feat(cli): add dirac job sandbox commands for output sandbox exploration
ryuwd Apr 10, 2026
82fdbfb
fix(cli): use SandboxType enum instead of string for get_job_sandbox
ryuwd Apr 10, 2026
caf9f89
fix(cli): strip SB:SE| prefix before get_sandbox_file client call
ryuwd Apr 10, 2026
e1ecb19
fix: output sandbox assignment — don't wrap SB: ref in Path()
ryuwd Apr 10, 2026
933c6dc
fix: remove unnecessary doc
ryuwd Apr 10, 2026
eeb15b1
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ pip-log.txt
.tox
.ruff_cache
.mypy_cache
workernode


# Eclipse
.project
Expand Down
1 change: 1 addition & 0 deletions diracx-api/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ classifiers = [
"Topic :: System :: Distributed Computing",
]
dependencies = [
"cwl-utils",
"diracx-client",
"diracx-core",
"httpx",
Expand Down
66 changes: 66 additions & 0 deletions diracx-api/src/diracx/api/job_report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
"""All classes related to job reports."""

from __future__ import annotations

from datetime import datetime, timezone

from diracx.client.aio import AsyncDiracClient # type: ignore[attr-defined]
from diracx.core.models.job import JobMinorStatus, JobStatus, JobStatusUpdate


class JobReport:
"""JobReport."""

def __init__(self, job_id: int, source: str, client: AsyncDiracClient) -> None:
"""Initialize Job Report.

:param job_id: the job ID
:param source: source for the reports
:param client: DiracX client instance
"""
self.job_status_info: dict[
str, dict[str, str]
] = {} # where job status updates are cumulated
self.job_id = job_id
self.source = source
self._client = client

def set_job_status(
self,
status: JobStatus | None = None,
minor_status: JobMinorStatus | None = None,
application_status: str | None = None,
) -> None:
"""Add a new job status to the job report.

:param status: job status
:param minor_status: job minor status
:param application_status: application status
"""
timestamp = str(datetime.now(timezone.utc))
# add job status record
self.job_status_info.update(
{
timestamp: JobStatusUpdate(
Status=status,
MinorStatus=minor_status,
ApplicationStatus=application_status,
Source=self.source,
).model_dump()
}
)

async def send_stored_status_info(self):
"""Send all the accumulated job status information."""
if not self.job_status_info:
return
body = {self.job_id: self.job_status_info}
ret = await self._client.jobs.set_job_statuses(body)
if ret.success:
self.job_status_info = {}
else:
raise RuntimeError(f"Could not set job statuses: {ret}")

async def commit(self):
"""Send all the accumulated information."""
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be debounced or use some rate limiter in the JobReport class itself

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would replace the rate limiting logic in the JobWrapper which would be better here

await self.send_stored_status_info()
Loading
Loading