importcsvimportloggingimporttimefromcollectionsimportdefaultdictfromioimportStringIOimportcachetools.funcimportrequestslogger=logging.getLogger(__name__)@cachetools.func.ttl_cache(ttl=86400)# 1 daydef_get(url:str)->list[dict[str,str]]:whileTrue:response=requests.get(url)ifresponse.status_code==429:logger.warning("HTTP 429 %s%s",url,response.headers)time.sleep(1)# time.sleep() blocks the IO loop. An asynchronous version like asyncio.sleep() wouldn't.else:breakresponse.raise_for_status()returnlist(csv.DictReader(StringIO(response.text)))def_codes(url:str,key:str)->tuple[str,...]:returntuple(row[key]forrowin_get(url))