1- from json import loads
21from typing import Annotated
32from urllib .parse import urlparse , urlunparse
43
54import idna
65import requests
7- from celery .result import AsyncResult
86from ecoindex .backend .dependencies .validation import validate_api_key_batch
97from ecoindex .backend .models .dependencies_parameters .id import IdParameter
108from ecoindex .backend .utils import check_quota
1715 example_daily_limit_response ,
1816 example_host_unreachable ,
1917)
20- from ecoindex .models .tasks import QueueTaskApi , QueueTaskApiBatch , QueueTaskResult
18+ from ecoindex .models .tasks import QueueTaskApi , QueueTaskApiBatch
2119from ecoindex .scraper .scrap import EcoindexScraper
2220from ecoindex .worker .tasks import ecoindex_batch_import_task , ecoindex_task
23- from ecoindex .worker_component import app as task_app
21+ from ecoindex .worker_component import (
22+ NoSuchJobError ,
23+ cancel_job ,
24+ ecoindex_batch_queue ,
25+ ecoindex_queue ,
26+ fetch_job ,
27+ get_queue_for_job ,
28+ get_queue_position ,
29+ get_retry_policy ,
30+ get_tasks_in_progress ,
31+ map_job_status_to_task_status ,
32+ parse_job_result ,
33+ )
2434from fastapi import APIRouter , Depends , HTTPException , Response , status
2535from fastapi .params import Body
2636from sqlmodel .ext .asyncio .session import AsyncSession
@@ -70,6 +80,18 @@ def convert_url_to_punycode(url: str) -> str:
7080 return url
7181
7282
83+ def _enqueue_settings (* , with_retry : bool = True ) -> dict :
84+ settings = Settings ()
85+ enqueue_settings = {
86+ "result_ttl" : settings .RQ_RESULT_TTL ,
87+ "failure_ttl" : settings .RQ_FAILURE_TTL ,
88+ "job_timeout" : settings .RQ_JOB_TIMEOUT ,
89+ }
90+ if with_retry :
91+ enqueue_settings ["retry" ] = get_retry_policy ()
92+ return enqueue_settings
93+
94+
7395@router .post (
7496 name = "Add new ecoindex analysis task to the waiting queue" ,
7597 path = "/" ,
@@ -142,14 +164,16 @@ async def add_ecoindex_analysis_task(
142164 detail = f"The URL { web_page .url } is unreachable. Are you really sure of this url? 🤔 ({ e .response .status_code if e .response else '' } )" ,
143165 )
144166
145- task_result = ecoindex_task .delay ( # type: ignore
167+ job = ecoindex_queue .enqueue (
168+ ecoindex_task ,
146169 url = str (web_page .url ),
147170 width = web_page .width ,
148171 height = web_page .height ,
149172 custom_headers = headers ,
173+ ** _enqueue_settings (),
150174 )
151175
152- return task_result .id
176+ return job .id
153177
154178
155179@router .get (
@@ -166,23 +190,35 @@ async def get_ecoindex_analysis_task_by_id(
166190 response : Response ,
167191 id : IdParameter ,
168192) -> QueueTaskApi :
169- t = AsyncResult (id = str (id ), app = task_app )
193+ try :
194+ job = fetch_job (str (id ))
195+ except NoSuchJobError as exc :
196+ raise HTTPException (
197+ status_code = status .HTTP_404_NOT_FOUND ,
198+ detail = "Task not found" ,
199+ ) from exc
200+
201+ queue = get_queue_for_job (job )
202+ task_status = map_job_status_to_task_status (job )
203+ result = parse_job_result (job )
170204
171205 task_response = QueueTaskApi (
172- id = str (t .id ),
173- status = t .state ,
206+ id = job .id ,
207+ status = task_status ,
208+ queue_position = get_queue_position (job , queue ),
209+ tasks_in_progress = get_tasks_in_progress (queue ),
174210 )
175211
176- if t . state == TaskStatus .PENDING :
212+ if task_status == TaskStatus .PENDING :
177213 response .status_code = status .HTTP_425_TOO_EARLY
178214
179215 return task_response
180216
181- if t . state == TaskStatus .SUCCESS :
182- task_response .ecoindex_result = QueueTaskResult ( ** loads ( t . result ))
217+ if task_status == TaskStatus .SUCCESS :
218+ task_response .ecoindex_result = result
183219
184- if t . state == TaskStatus .FAILURE :
185- task_response .task_error = t . info
220+ if task_status == TaskStatus .FAILURE :
221+ task_response .task_error = result
186222
187223 response .status_code = status .HTTP_200_OK
188224
@@ -198,9 +234,13 @@ async def get_ecoindex_analysis_task_by_id(
198234async def delete_ecoindex_analysis_task_by_id (
199235 id : IdParameter ,
200236) -> None :
201- res = task_app .control .revoke (id , terminate = True , signal = "SIGKILL" )
202-
203- return res
237+ try :
238+ cancel_job (str (id ))
239+ except NoSuchJobError as exc :
240+ raise HTTPException (
241+ status_code = status .HTTP_404_NOT_FOUND ,
242+ detail = "Task not found" ,
243+ ) from exc
204244
205245
206246@router .post (
@@ -227,12 +267,14 @@ async def add_ecoindex_analysis_task_batch(
227267 ],
228268 batch_key : str = Depends (validate_api_key_batch ),
229269):
230- task_result = ecoindex_batch_import_task .delay ( # type: ignore
270+ job = ecoindex_batch_queue .enqueue (
271+ ecoindex_batch_import_task ,
231272 results = [result .model_dump () for result in results ],
232273 source = batch_key ["source" ], # type: ignore
274+ ** _enqueue_settings (with_retry = False ),
233275 )
234276
235- return task_result .id
277+ return job .id
236278
237279
238280@router .get (
@@ -250,14 +292,22 @@ async def get_ecoindex_analysis_batch_task_by_id(
250292 id : IdParameter ,
251293 _ : str = Depends (validate_api_key_batch ),
252294) -> QueueTaskApiBatch :
253- t = AsyncResult (id = str (id ), app = task_app )
295+ try :
296+ job = fetch_job (str (id ))
297+ except NoSuchJobError as exc :
298+ raise HTTPException (
299+ status_code = status .HTTP_404_NOT_FOUND ,
300+ detail = "Task not found" ,
301+ ) from exc
302+
303+ task_status = map_job_status_to_task_status (job )
254304
255305 task_response = QueueTaskApiBatch (
256- id = str ( t .id ) ,
257- status = t . state ,
306+ id = job .id ,
307+ status = task_status ,
258308 )
259309
260- if t . state == TaskStatus .PENDING :
310+ if task_status == TaskStatus .PENDING :
261311 response .status_code = status .HTTP_425_TOO_EARLY
262312
263313 return task_response
0 commit comments