Coverage for seedboxsync/front/apis/taskstatus.py: 100%
28 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-07-26 17:46 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-07-26 17:46 +0000
1#
2# Copyright (C) 2015-2026 Guillaume Kulakowski <guillaume@kulakowski.fr>
3#
4# For the full copyright and license information, please view the LICENSE
5# file that was distributed with this source code.
6#
7"""SeedboxSync api TaskStatus view."""
9from typing import Any
10from flask_restx import Namespace, fields
11from seedboxsync.core.dao import TaskStatus
12from seedboxsync.front.apis import DateTimeOrZero, Resource
14api = Namespace("taskstatuses", description="Operations related to taskstatus")
17# ==========================
18# Models
19# ==========================
20taskstatus_model = api.model(
21 "TaskStatuses",
22 {
23 "key": fields.String(
24 required=True,
25 description="Unique task identifier",
26 example="sync_blackhole",
27 ),
28 "running": fields.Boolean(
29 dt_format="iso8601",
30 required=True,
31 description="Whether the task is currently running",
32 example=False,
33 ),
34 "started": DateTimeOrZero(
35 dt_format="iso8601",
36 required=False,
37 description="Timestamp when the task execution started",
38 ),
39 "finished": DateTimeOrZero(
40 dt_format="iso8601",
41 required=True,
42 description="Timestamp when the task execution finished",
43 ),
44 },
45)
46taskstatus_list_envelope = Resource.build_envelope_model(api, "TaskStatusList", nested_model=taskstatus_model)
47taskstatus_envelope = Resource.build_envelope_model(api, "TaskStatus", nested_model=taskstatus_model, as_list=False)
50# ==========================
51# Endpoints
52# ==========================
53@api.route("")
54class TaskStatusList(Resource):
55 """
56 Endpoint for managing taskstatus list.
58 Provides a list of taskstatus.
59 """
61 @api.doc("list_taskstatus") # type: ignore[untyped-decorator]
62 @api.marshal_with(taskstatus_list_envelope, code=200, description="List of taskstatuses") # type: ignore[untyped-decorator]
63 def get(self) -> dict[str, Any]:
64 """Retrieve a list of taskstatus."""
65 select = TaskStatus.select(
66 TaskStatus.key,
67 TaskStatus.running,
68 TaskStatus.started,
69 TaskStatus.finished,
70 )
72 return self.build_envelope(list(select.dicts()), type="TaskStatus")
75@api.route("/<string:key>")
76@api.response(404, "TaskStatus not found")
77@api.param("key", "The taskstatus key")
78class TaskStatuses(Resource):
79 """
80 Endpoint for managing taskstatuses.
82 Provides taskstatuses operations.
83 """
85 @api.doc("get_taskstatus") # type: ignore[untyped-decorator]
86 @api.marshal_with(taskstatus_envelope, code=200, description="TaskStatus element") # type: ignore[untyped-decorator]
87 def get(self, key: str) -> dict[str, Any]:
88 """
89 Retrieve a taskstatus.
91 Args:
92 key (str): TaskStatus identifier.
94 Returns:
95 dict[str, Any]: API response envelope containing the taskstatus.
96 """
97 select: TaskStatus | None = None
98 try:
99 select = (
100 TaskStatus.select(
101 TaskStatus.key,
102 TaskStatus.running,
103 TaskStatus.started,
104 TaskStatus.finished,
105 )
106 .where(TaskStatus.key == key)
107 .dicts()
108 .get()
109 )
110 except TaskStatus.DoesNotExist: # type: ignore[attr-defined]
111 api.abort(404, f"TaskStatus {key} doesn't exist")
113 return self.build_envelope(select, type="TaskStatus")