11from json import loads
2+ from typing import Annotated
23
34import requests
45from celery .result import AsyncResult
6+ from ecoindex .backend .dependencies .validation import validate_api_key_batch
57from ecoindex .backend .models .dependencies_parameters .id import IdParameter
68from ecoindex .backend .utils import check_quota
79from ecoindex .config .settings import Settings
810from ecoindex .database .engine import get_session
11+ from ecoindex .database .models import ApiEcoindexes
912from ecoindex .models import WebPage
1013from ecoindex .models .enums import TaskStatus
1114from ecoindex .models .response_examples import (
1215 example_daily_limit_response ,
1316 example_host_unreachable ,
1417)
15- from ecoindex .models .tasks import QueueTaskApi , QueueTaskResult
16- from ecoindex .worker .tasks import ecoindex_task
18+ from ecoindex .models .tasks import QueueTaskApi , QueueTaskApiBatch , QueueTaskResult
19+ from ecoindex .worker .tasks import ecoindex_batch_import_task , ecoindex_task
1720from ecoindex .worker_component import app as task_app
1821from fastapi import APIRouter , Depends , HTTPException , Response , status
1922from fastapi .params import Body
3740)
3841async def add_ecoindex_analysis_task (
3942 response : Response ,
40- web_page : WebPage = Body (
41- default = ...,
42- title = "Web page to analyze defined by its url and its screen resolution" ,
43- example = WebPage (url = "https://www.ecoindex.fr" , width = 1920 , height = 1080 ),
44- ),
43+ web_page : Annotated [
44+ WebPage ,
45+ Body (
46+ default = ...,
47+ title = "Web page to analyze defined by its url and its screen resolution" ,
48+ example = WebPage (url = "https://www.ecoindex.fr" , width = 1920 , height = 1080 ),
49+ ),
50+ ],
4551 session : AsyncSession = Depends (get_session ),
4652) -> str :
4753 if Settings ().DAILY_LIMIT_PER_HOST :
4854 remaining_quota = await check_quota (
4955 session = session , host = web_page .get_url_host ()
5056 )
51- response .headers ["X-Remaining-Daily-Requests" ] = str (remaining_quota - 1 )
57+
58+ if remaining_quota :
59+ response .headers ["X-Remaining-Daily-Requests" ] = str (remaining_quota - 1 )
5260
5361 if (
5462 Settings ().EXCLUDED_HOSTS
@@ -63,13 +71,12 @@ async def add_ecoindex_analysis_task(
6371 r = requests .head (url = web_page .url , timeout = 5 )
6472 r .raise_for_status ()
6573 except Exception :
66- print (f"The URL { web_page .url } is not reachable" )
6774 raise HTTPException (
6875 status_code = 521 ,
6976 detail = f"The URL { web_page .url } is unreachable. Are you really sure of this url? 🤔" ,
7077 )
7178
72- task_result = ecoindex_task .delay (
79+ task_result = ecoindex_task .delay ( # type: ignore
7380 url = str (web_page .url ), width = web_page .width , height = web_page .height
7481 )
7582
@@ -93,7 +100,7 @@ async def get_ecoindex_analysis_task_by_id(
93100 t = AsyncResult (id = str (id ), app = task_app )
94101
95102 task_response = QueueTaskApi (
96- id = t .id ,
103+ id = str ( t .id ) ,
97104 status = t .state ,
98105 )
99106
@@ -125,3 +132,63 @@ async def delete_ecoindex_analysis_task_by_id(
125132 res = task_app .control .revoke (id , terminate = True , signal = "SIGKILL" )
126133
127134 return res
135+
136+
137+ @router .post (
138+ name = "Save ecoindex analysis from external source in batch mode" ,
139+ path = "/batch" ,
140+ response_description = "Identifier of the task that has been created in queue" ,
141+ responses = {
142+ status .HTTP_201_CREATED : {"model" : str },
143+ status .HTTP_403_FORBIDDEN : {"model" : str },
144+ },
145+ description = "This save ecoindex analysis from external source in batch mode. Limited to 100 entries at a time" ,
146+ status_code = status .HTTP_201_CREATED ,
147+ )
148+ async def add_ecoindex_analysis_task_batch (
149+ results : Annotated [
150+ ApiEcoindexes ,
151+ Body (
152+ default = ...,
153+ title = "List of ecoindex analysis results to save" ,
154+ example = [],
155+ min_length = 1 ,
156+ max_length = 100 ,
157+ ),
158+ ],
159+ batch_key : str = Depends (validate_api_key_batch ),
160+ ):
161+ task_result = ecoindex_batch_import_task .delay ( # type: ignore
162+ results = [result .model_dump () for result in results ],
163+ source = batch_key ["source" ], # type: ignore
164+ )
165+
166+ return task_result .id
167+
168+
169+ @router .get (
170+ name = "Get ecoindex analysis batch task by id" ,
171+ path = "/batch/{id}" ,
172+ responses = {
173+ status .HTTP_200_OK : {"model" : QueueTaskApiBatch },
174+ status .HTTP_425_TOO_EARLY : {"model" : QueueTaskApiBatch },
175+ },
176+ response_description = "Get one ecoindex batch task result by its id" ,
177+ description = "This returns an ecoindex batch task result given by its unique identifier" ,
178+ )
179+ async def get_ecoindex_analysis_batch_task_by_id (
180+ response : Response ,
181+ id : IdParameter ,
182+ _ : str = Depends (validate_api_key_batch ),
183+ ) -> QueueTaskApiBatch :
184+ t = AsyncResult (id = str (id ), app = task_app )
185+
186+ task_response = QueueTaskApiBatch (
187+ id = str (t .id ),
188+ status = t .state ,
189+ )
190+
191+ if t .state == TaskStatus .PENDING :
192+ response .status_code = status .HTTP_425_TOO_EARLY
193+
194+ return task_response
0 commit comments