Add unified job status endpoint GET /api/v3_0/jobs/<uuid>#2141
Conversation
Documentation build overview
8 files changed ·
|
Agent-Logs-Url: https://github.com/FlexMeasures/flexmeasures/sessions/908cf53c-f5b1-484a-a2f2-a6c796a3319a Co-authored-by: BelhsanHmida <149331360+BelhsanHmida@users.noreply.github.com>
Agent-Logs-Url: https://github.com/FlexMeasures/flexmeasures/sessions/908cf53c-f5b1-484a-a2f2-a6c796a3319a Co-authored-by: BelhsanHmida <149331360+BelhsanHmida@users.noreply.github.com>
Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
|
@copilot please update the JSON response returned by the jobs endpoint. Add the missing Also include these documented RQ job attributes as top-level response fields:
So the response should look roughly like: {
"status": "FINISHED",
"message": "Job has finished.",
"result": ...,
"func_name": "...",
"origin": "...",
"enqueued_at": "...",
"started_at": "...",
"ended_at": "..."
}Add/update tests to check these fields are present for queued/started/finished jobs where applicable. Make sure datetime fields are returned in a JSON-safe way, e.g. serialized as strings or |
…imestamps Agent-Logs-Url: https://github.com/FlexMeasures/flexmeasures/sessions/a3f1bd92-bddc-4dbb-b4ee-bd58611ab6a2 Co-authored-by: BelhsanHmida <149331360+BelhsanHmida@users.noreply.github.com>
Done in commit 454b0fc. The response now includes all the requested fields: {
"status": "FINISHED",
"message": "Scheduling job has finished.",
"result": null,
"func_name": "flexmeasures.data.services.scheduling.create_schedule",
"origin": "scheduling",
"enqueued_at": "2026-04-28T10:00:00+00:00",
"started_at": "2026-04-28T10:00:01+00:00",
"ended_at": "2026-04-28T10:00:05+00:00"
}Datetime fields are serialised as ISO-8601 strings or |
|
@copilot The tests still feel a bit incomplete for the response contract we discussed. Can you add coverage for a |
|
@nhoening right now |
Agent-Logs-Url: https://github.com/FlexMeasures/flexmeasures/sessions/9b7a4fb6-3243-4a89-979e-3cdcaf0b8e99 Co-authored-by: BelhsanHmida <149331360+BelhsanHmida@users.noreply.github.com>
Done in commit ab0d6f3.
All 5 tests pass. |
Good point. I'm not sure all jobs have access to this in a similar way, though. Can you check for scheduling and forecasting jobs? |
Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
I checked most of the jobs we create locally. For forecasting jobs, yes: we already have enough context. The jobs carry For scheduling jobs, mostly yes as well: One edge case I found is the wrap-up job from sequential scheduling: that one is cached against the asset, but it does not seem to store the related asset/sensor ref in |
Yes, let's do that as a principle from now on. Jobs need to provide a means to show what they are about. |
|
Scope update: I am currently onboarding a partner and a big value-add would be if the returned information had exception information if something went wrong. If It would be great to test this:
Maybe the latter can be turned into an automated test, ask copilot about that. |
Context: - Job metadata should consistently show what a scheduling job is about - The sequential wrap-up job was cached against an asset but did not carry matching job metadata Change: - Store asset_or_sensor metadata on the sequential scheduling wrap-up job - Keeps this job aligned with the other scheduling job variants Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
Context: - Sequential scheduling should expose what each job is about - The wrap-up job now carries asset_or_sensor metadata and needs regression coverage Change: - Assert that the deferred wrap-up job exposes the site asset context in its metadata Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
Implemented this now. Failed jobs on I also checked the two cases you suggested:
In both cases the endpoint now returns the failed status, the human-readable message, and the traceback context.
{
"ended_at": "2026-04-30T14:09:48.281063+00:00",
"enqueued_at": "2026-04-30T14:09:46.032891+00:00",
"exc_info": null,
"func_name": "flexmeasures.data.services.scheduling.make_schedule",
"message": "Scheduling job has finished.",
"origin": "scheduling",
"result": true,
"started_at": "2026-04-30T14:09:46.047736+00:00",
"status": "FINISHED"
}
{
"ended_at": "2026-04-30T14:09:48.354535+00:00",
"enqueued_at": "2026-04-30T14:09:48.327122+00:00",
"exc_info": "Traceback (most recent call last): ... AssertionError: assert 1 == 2\n",
"func_name": "flexmeasures.data.services.scheduling.make_schedule",
"message": "Scheduling job failed with AssertionError: assert 1 == 2.",
"origin": "scheduling",
"result": null,
"started_at": "2026-04-30T14:09:48.336711+00:00",
"status": "FAILED"
}
{
"ended_at": "2026-04-30T14:09:48.638125+00:00",
"enqueued_at": "2026-04-30T14:09:48.408118+00:00",
"exc_info": "Traceback (most recent call last): ... ValueError: The input data yields an infeasible problem. Constraint validation has found the following issues: ...\n",
"func_name": "flexmeasures.data.services.scheduling.make_schedule",
"message": "Scheduling job failed with ValueError: The input data yields an infeasible problem. Constraint validation has found the following issues: ...",
"origin": "scheduling",
"result": null,
"started_at": "2026-04-30T14:09:48.419319+00:00",
"status": "FAILED"
}I also turned the failure scenarios into automated coverage in the jobs endpoint tests, including the infeasible schedule case. |
|
Great - on the infeasible example, is the actual message about contraint validation truncated? And what happens if a mis-configuration happens, e.g. |
The actual response I got was: {
"message": {
"json": {
"soc-min": [
"Cannot convert value 'abc' to a valid quantity. 'abc' is not defined in the unit registry"
]
}
},
"result": "Rejected",
"status": "UNPROCESSABLE_ENTITY"
} |
nhoening
left a comment
There was a problem hiding this comment.
It works.
Two requests about error states, and although the job's meta information now contains asset/sensor ID, no use of check_access(asset, "read") or check_access(sensor, "read") is in this PR. For that, I'd also request an extra test (to check that a user who is allowed to read information gets it, but a user who doesn't have the permission cannot.
Co-authored-by: Nicolas Höning <nicolas@seita.nl> Signed-off-by: Mohamed Belhsan Hmida <149331360+BelhsanHmida@users.noreply.github.com>
Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
…vailable Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
Implemented this now. The jobs endpoint now resolves the related asset/sensor from the job metadata and applies I also added coverage for that, so a user who can read the related resource gets the job status, while a user without read access gets a In addition, I handled the Redis / queue-unavailable case as well: the endpoint now returns a |
nhoening
left a comment
There was a problem hiding this comment.
Thanks.
Just one question: I ran a forecasting job and got this:
{
"ended_at": "2026-05-04T15:01:03.146562+00:00",
"enqueued_at": "2026-05-04T14:59:24.156219+00:00",
"exc_info": null,
"func_name": "run_cycle",
"message": "Forecasting job has finished.",
"origin": "forecasting",
"result": 14.210693120956421,
"started_at": "2026-05-04T15:00:48.893739+00:00",
"status": "FINISHED"
}
Why is result 14.21 ?
|
I assumed you wanted me to review. If I was correct, I ask you to be more explicit with that going forward. Re-request the review. |
Signed-off-by: Nicolas Höning <nicolas@seita.nl>
yes i meant for a re review. |
That For forecasting cycle jobs, I agree this is not very explicit in the unified jobs endpoint, especially since the actual forecast values are available through the forecasting endpoint. I think the better follow-up would be to make that more explicit there, for example by returning structured result data like I’ll open an issue for this. |
|
If this pr is approved @nhoening please merge, i can't. |
Single endpoint to poll the status of any background job (scheduling, forecasting, etc.) by UUID — without needing to know which queue or resource the job belongs to.
Changes
flexmeasures/api/v3_0/jobs.py— newJobAPIview withGET /<uuid>:@auth_required()); no resource-level permission check needed since the UUID is only known to the submitterenqueued_at,started_at,ended_at) are serialised as ISO-8601 strings ornullflexmeasures/api/v3_0/__init__.py— registersJobAPIat/api/v3_0flexmeasures/api/v3_0/tests/test_jobs_api.py— covers: unknown UUID → 400, queued →QUEUED(with metadata assertions), finished →FINISHED(with timing assertions), unauthenticated → 401documentation/api/change_log.rst/documentation/changelog.rst— changelog entriesExample response