async def infection_global_detail(token: APIKey = Depends(get_api_key), db: Session = Depends(get_db) ) -> InfectionGlobalDataInResponse: """ 查询全球疫情数据信息 <br/> """ logger.info(f"received parameters, token:{token}") try: global_detail = GlobalDataModel() global_data = Covid19.get_infection_global_data(db=db) last_update_date = Covid19.get_last_update_date(db=db) for _d in global_data: global_detail.region.update({ _d.country_en: { "confirmed_add": _d.confirmed_add, "deaths_add": _d.deaths_add, "recovered_add": _d.recovered_add } }) global_detail.last_update_date = str(last_update_date) global_detail.confirmed_add += _d.confirmed_add global_detail.deaths_add += _d.deaths_add global_detail.recovered_add += _d.recovered_add except Exception as e: logger.error(f"{SYSTEM_ERROR}: {e}") raise CustomException(SYSTEM_ERROR) return InfectionGlobalDataInResponse(data={"global": global_detail})
async def area_list( token: APIKey = Depends(get_api_key), db: Session = Depends(get_db), region_filters: RegionFilters = Depends(get_region_filters), hmt_filters: Hmtfilters = Depends(get_hmt_filters) ) -> AreaListInResponse: """ 查询指定国家的疫情城市列表数据 <br/> region: 国家 <br/> include_hmt: 默认为 true,当 region 为 China 时返回包含港澳台疫情数据信息,false 为不返回 """ logger.info( f"received parameters, token:{token}, region_filters:{region_filters}, hmt_filters: {hmt_filters}" ) try: area_data = Covid19.get_area_list(db=db, region=region_filters.name, hmt=hmt_filters.include_hmt) data = [_d[0] for _d in area_data if _d[0] and _d[0] != "Recovered"] except Exception as e: logger.error(f"{SYSTEM_ERROR}: {e}") raise CustomException(SYSTEM_ERROR) return AreaListInResponse(data=data)
async def population( token: APIKey = Depends(get_api_key), db: Session = Depends(get_db), country_filters: RegionFilters = Depends(get_allow_empty_region_filters), ) -> PopulationInResponse: """ 查询人口数据信息 <br/> region: 国家 (非必传,默认值查全部国家) <br/> """ logger.info( f"received parameters, token:{token}, country_filters: {country_filters}" ) try: _population = list() population_data = Population.get_population( db=db, country=country_filters.name) for _d in population_data: _population.append( PopulationModel(name=_d.country_en, population_num=_d.population_num)) except Exception as e: logger.error(f"{SYSTEM_ERROR}: {e}") raise CustomException(SYSTEM_ERROR) return PopulationInResponse(data=_population)
async def authentication_register( register_filters: RegisterFilters, db: Session = Depends(get_db), ) -> AuthenticationRegisterInResponse: """ 获取接口调用凭证 <br/> email: 获取凭证的邮箱地址 凭证会以邮件方式发往改邮箱 """ logger.info(f"received parameters, register_filters:{register_filters}") bloom_filter = BloomFilterUtils() email = EmailUtils() if not register_filters or not email.check_email(register_filters.email): raise CustomException(EMAIL_ERROR, msg_dict={"error": "format is incorrect"}) # 邮箱已认证 if bloom_filter.contains(register_filters.email) or CovidUser.get_user( db=db, condition={CovidUser.email.key: register_filters.email}): raise CustomException(EMAIL_ERROR, msg_dict={"error": "email has been certified"}) # 发送 token 信息 token = FishMD5.hmac_md5(register_filters.email, str(get_time_uuid())) send_status = email.send_mail(EMAIL_CONTENT.format(_Token=token), register_filters.email) if not send_status: raise CustomException(EMAIL_ERROR, msg_dict={"error": "failed to send"}) # 保存,记录邮箱信息 CovidUser.add_user(db=db, email=register_filters.email, token=token) bloom_filter.add(register_filters.email) return AuthenticationRegisterInResponse(data={"status": True})
def check_date_filter(date_filters: DateFilters): # 判断日期 if not date_filters.start_date and not date_filters.end_date: # 默认为最新数据 date_filters.start_date = None date_filters.end_date = None elif date_filters.start_date and date_filters.end_date: # 自定义日期 # 判断是否超过 10 天 try: start_date = datetime.datetime.strptime(date_filters.start_date, "%Y-%m-%d") end_date = datetime.datetime.strptime(date_filters.end_date, "%Y-%m-%d") except Exception as _: raise CustomException( PARAM_ERROR, msg_dict={"error": "start_date or end_date is incorrect"}) if (end_date - start_date).days > 10 or (end_date - start_date).days < 0: raise CustomException( PARAM_ERROR, msg_dict={ "error": "The difference between start_date and end_date cannot be greater than 10 or less than 0" }) elif date_filters.start_date and not date_filters.end_date: # 具体的一天(start_date 和 end_date 相同) date_filters.start_date = date_filters.start_date date_filters.end_date = None else: raise CustomException( PARAM_ERROR, msg_dict={"error": "You can’t just enter the end_date"}) return date_filters
async def region_list(token: APIKey = Depends(get_api_key), db: Session = Depends(get_db)) -> RegionListInResponse: """ 查询有疫情信息的国家列表 <br/> """ logger.info(f"received parameters, token:{token}") try: region_data = Covid19.get_region_list(db=db) data = [_d[0] for _d in region_data if _d[0]] except Exception as e: logger.error(f"{SYSTEM_ERROR}: {e}") raise CustomException(SYSTEM_ERROR) return RegionListInResponse(data=data)
async def infection_region_detail( token: APIKey = Depends(get_api_key), db: Session = Depends(get_db), region_filters: RegionFilters = Depends(get_region_filters), date_filters: DateFilters = Depends(get_date_filters), hmt_filters: Hmtfilters = Depends(get_hmt_filters), ) -> InfectionRegionDetailInResponse: """ 查询指定国家在某段时间内的疫情明细数据信息 <br/> region: 国家 (必传,默认值为 China) <br/> start_date: 开始日期(非必传,不传代表获取最新数据。可单独指定,单独指定表示查询这一天一直到最新一天的的数据信息)) <br/> end_date: 结束日期 (非必传,不传代表获取最新数据。不可单独指定)<br/> include_hmt: 默认为 true,当 region 为 China 时返回包含港澳台疫情数据信息,false 为不返回<br/> 日期最长可以查询10天 """ logger.info( f"received parameters, token:{token}, region_filters:{region_filters}, " f"date_filters: {date_filters}, hmt_filters:{hmt_filters}") # 判断日期 date_filters = check_date_filter(date_filters) # 判断 htm hmt_filters = check_htm_filter(hmt_filters, region_filters) try: data = dict({"area": {}}) area_data = Covid19.get_infection_country_area_data( db=db, country=region_filters.name, start_date=date_filters.start_date, end_date=date_filters.end_date, hmt=hmt_filters.include_hmt) for _d in area_data: if ("Recovered" == str(_d.province_en)): continue if not data.get("area").get(str(_d.province_en)): # 城市不存在 data.get("area").update({ str(_d.province_en): { str(_d.update_date): { "confirmed_add": _d.confirmed_add, "deaths_add": _d.deaths_add, "recovered_add": _d.recovered_add, "confirmed": _d.confirmed, "deaths": _d.deaths, "recovered": _d.recovered } } }) else: # 城市已经存在 if data.get("area").get(_d.province_en).get(str( _d.update_date)): # 日期已经存在 data["area"][str(_d.province_en)][str( _d.update_date)]["confirmed_add"] += _d.confirmed_add data["area"][str(_d.province_en)][str( _d.update_date)]["deaths_add"] += _d.deaths_add data["area"][str(_d.province_en)][str( _d.update_date)]["recovered_add"] += _d.recovered_add data["area"][str(_d.province_en)][str( _d.update_date)]["confirmed"] += _d.confirmed data["area"][str(_d.province_en)][str( _d.update_date)]["deaths"] += _d.deaths data["area"][str(_d.province_en)][str( _d.update_date)]["recovered"] += _d.recovered else: # 日期不存在 data.get("area").get(_d.province_en).update({ str(_d.update_date): { "confirmed_add": _d.confirmed_add, "deaths_add": _d.deaths_add, "recovered_add": _d.recovered_add, "confirmed": _d.confirmed, "deaths": _d.deaths, "recovered": _d.recovered } }) except Exception as e: if isinstance(e, CustomException): logger.error(f"custom exception: {e}") raise e logger.error(f"{SYSTEM_ERROR}: {e}") raise CustomException(SYSTEM_ERROR) return InfectionRegionDetailInResponse(data=data)
async def exception_handler(request: Request, exc: CustomException): return JSONResponse( status_code=exc.status_code, content=exc.to_dict(custom_response_id=request.state.request_tag))
async def get_api_key(token: str = Security(api_key_header), ): if token: return token else: raise CustomException(HTTP_FORBIDDEN, status_code=403)