11import json
22import re
33from http import HTTPStatus
4- from typing import Annotated , Any
4+ from typing import Annotated , cast
55
66import xmltodict
77from fastapi import APIRouter , Depends , HTTPException
1515
1616router = APIRouter (prefix = "/tasks" , tags = ["tasks" ])
1717
18+ type JSON = dict [str , "JSON" ] | list ["JSON" ] | str | int | float | bool | None
1819
19- def convert_template_xml_to_json (xml_template : str ) -> Any : # noqa: ANN401
20+
21+ def convert_template_xml_to_json (xml_template : str ) -> dict [str , JSON ]:
2022 json_template = xmltodict .parse (xml_template .replace ("oml:" , "" ))
2123 json_str = json .dumps (json_template )
2224 # To account for the differences between PHP and Python conversions:
2325 for py , php in [("@name" , "name" ), ("#text" , "value" ), ("@type" , "type" )]:
2426 json_str = json_str .replace (py , php )
25- return json .loads (json_str )
27+ return cast ( "dict[str, JSON]" , json .loads (json_str ) )
2628
2729
2830def fill_template (
2931 template : str ,
3032 task : RowMapping ,
31- task_inputs : dict [str , str ],
33+ task_inputs : dict [str , str | int ],
3234 connection : Connection ,
33- ) -> Any : # noqa: ANN401
35+ ) -> dict [ str , JSON ]:
3436 """Fill in the XML template as used for task descriptions and return the result,
3537 converted to JSON.
3638
@@ -79,22 +81,25 @@ def fill_template(
7981 }
8082 """
8183 json_template = convert_template_xml_to_json (template )
82- return _fill_json_template (
83- json_template ,
84- task ,
85- task_inputs ,
86- fetched_data = {},
87- connection = connection ,
84+ return cast (
85+ "dict[str, JSON]" ,
86+ _fill_json_template (
87+ json_template ,
88+ task ,
89+ task_inputs ,
90+ fetched_data = {},
91+ connection = connection ,
92+ ),
8893 )
8994
9095
9196def _fill_json_template (
92- template : dict [ str , Any ] ,
97+ template : JSON ,
9398 task : RowMapping ,
94- task_inputs : dict [str , str ],
95- fetched_data : dict [str , Any ],
99+ task_inputs : dict [str , str | int ],
100+ fetched_data : dict [str , str ],
96101 connection : Connection ,
97- ) -> dict [ str , Any ] | list [ dict [ str , Any ]] | str :
102+ ) -> JSON :
98103 if isinstance (template , dict ):
99104 return {
100105 k : _fill_json_template (v , task , task_inputs , fetched_data , connection )
@@ -115,7 +120,7 @@ def _fill_json_template(
115120 if match .string == template :
116121 # How do we know the default value? probably ttype_io table?
117122 return task_inputs .get (field , [])
118- template = template .replace (match .group (), task_inputs [field ])
123+ template = template .replace (match .group (), str ( task_inputs [field ]) )
119124 if match := re .search (r"\[LOOKUP:(.*)]" , template ):
120125 (field ,) = match .groups ()
121126 if field not in fetched_data :
@@ -176,7 +181,7 @@ def get_task(
176181 tags = database .tasks .get_tags (task_id , expdb )
177182 name = f"Task { task_id } ({ task_type .name } )"
178183 dataset_id = task_inputs .get ("source_data" )
179- if dataset_id and (dataset := database .datasets .get (dataset_id , expdb )):
184+ if isinstance ( dataset_id , int ) and (dataset := database .datasets .get (dataset_id , expdb )):
180185 name = f"Task { task_id } : { dataset .name } ({ task_type .name } )"
181186
182187 return Task (
0 commit comments