from datetime import date
from typing import Optional, Any, Dict, Literal, List, Union, Mapping
import json
import nest_asyncio
import pandas as pd
from mosqlient import types
from [Link] import Mosqlient, Client
from [Link] import schema
nest_asyncio.apply()
class Model([Link]):
client: Optional[Client] = None
_schema: [Link]
def __init__(
self,
id: int,
repository: str,
category: str,
time_resolution: str,
predictions_count: int,
active: bool,
created_at: date,
last_update: date,
description: Optional[str] = "",
imdc_year: Optional[int] = None,
**kwargs,
):
super().__init__(**kwargs)
self._schema = [Link](
id=id,
repository=repository,
description=description,
category=category,
time_resolution=time_resolution,
imdc_year=imdc_year,
predictions_count=predictions_count,
active=active,
created_at=created_at,
last_update=last_update,
)
def __repr__(self) -> str:
return [Link]
@classmethod
def get(cls, api_key: str, **kwargs):
client = Mosqlient(x_uid_key=api_key)
params = [Link](**kwargs)
return list(cls(**item) for item in [Link](params))
def predictions(self, api_key: str, **kwargs):
return [Link](api_key=api_key, model_id=[Link], **kwargs)
@property
def id(self) -> int:
return self._schema.id
@property
def repository(self) -> str:
return self._schema.repository
@property
def description(self) -> Optional[str]:
return self._schema.description
@property
def category(self) -> str:
return self._schema.category
@property
def time_resolution(self) -> str:
return self._schema.time_resolution
@property
def imdc_year(self) -> int | None:
return self._schema.imdc_year
@property
def predictions_count(self) -> int:
return self._schema.predictions_count
@property
def active(self) -> bool:
return self._schema.active
@property
def created_at(self) -> date:
return self._schema.created_at
@property
def last_update(self) -> date:
return self._schema.last_update
class Prediction([Link]):
client: Optional[Client] = None
model: Model
_schema: [Link]
def __init__(
self,
id: int,
model: Model | dict,
disease: [Link],
commit: [Link],
case_definition: Literal["probable", "reported"],
published: bool,
created_at: date,
adm_level: [Link],
description: [Link] = "",
start: Optional[date] = None,
end: Optional[date] = None,
scores: Optional[Dict[str, float]] = None,
adm_0: Optional[str] = None,
adm_1: Optional[int] = None,
adm_2: Optional[int] = None,
adm_3: Optional[int] = None,
data: Optional[[Link]] = None,
client: Optional[Client] = None,
**kwargs,
):
if isinstance(model, dict):
model = Model(**model)
kwargs["model"] = model
kwargs["client"] = client
super().__init__(**kwargs)
[Link] = client
_data = []
if data is not None:
if isinstance(data, str):
try:
loaded = [Link](data)
_data = [[Link](**d) for d in loaded]
except [Link]:
raise ValueError("str `data` must be JSON serializable")
elif isinstance(data, [Link]):
_data = [
[Link](**d)
for d in data.to_dict(orient="records")
]
elif isinstance(data, list):
_data = [[Link](**d) for d in data]
[Link] = model
self._schema = [Link](
id=id,
model=model._schema,
disease=disease,
commit=commit,
description=description,
case_definition=case_definition,
published=published,
created_at=created_at, # type: ignore
start_date=start, # type: ignore
end_date=end, # type: ignore
scores=scores or {},
adm_level=adm_level,
adm_0=adm_0,
adm_1=adm_1,
adm_2=adm_2,
adm_3=adm_3,
data=_data,
)
def __repr__(self) -> str:
return f"Prediction <{[Link]}>"
def update_published(self, status: bool):
if not [Link]:
raise ValueError("Cannot update a prediction that has no ID.")
if not [Link]:
raise ValueError("Prediction instance has no client.")
params = [Link](
id=[Link], published=status
)
res = [Link](params)
if res.status_code == 201:
self._schema.published = status
return res
@staticmethod
def validate_prediction(
api_key: str,
repository: str,
disease: str,
description: str,
commit: str,
prediction: Union[List[Dict], [Link]],
adm_level: int,
case_definition: str = "probable",
published: bool = True,
adm_0: str = "BRA",
adm_1: Optional[int] = None,
adm_2: Optional[int] = None,
adm_3: Optional[int] = None,
) -> None:
owner, repo_name = [Link]("/")
model = [Link](
api_key=api_key,
repository_onwer=owner,
repository_name=repo_name,
)
if not model:
model = [Link](
api_key=api_key,
repository_organization=owner,
repository_name=repo_name,
)
if not model:
raise ValueError(f"Model '{repository}' not found")
model = model[0]
prediction_data = []
if isinstance(prediction, [Link]):
df = [Link]()
if "date" in [Link]:
df["date"] = df["date"].astype(str)
prediction_data = df.to_dict(orient="records")
else:
prediction_data = prediction
float_fields = [
"lower_95",
"lower_90",
"lower_80",
"lower_50",
"pred",
"upper_50",
"upper_80",
"upper_90",
"upper_95",
]
rows = []
for item in prediction_data:
i: Dict[str, Any] = {"date": str(item["date"])}
for field in float_fields:
i[field] = float(item[field])
[Link]([Link](**i))
[Link](
id=None,
model=model._schema,
disease=disease,
commit=commit,
case_definition=case_definition,
published=published,
description=description,
adm_level=adm_level,
adm_0=adm_0,
adm_1=adm_1,
adm_2=adm_2,
adm_3=adm_3,
data=rows,
)
@classmethod
def get(cls, api_key: str, **kwargs):
client = Mosqlient(x_uid_key=api_key)
params = [Link](**kwargs)
return list(cls(**item, client=client) for item in [Link](params))
@classmethod
def post(cls, api_key: str, **kwargs):
client = Mosqlient(x_uid_key=api_key)
params = [Link](**kwargs)
res = [Link](params)
data = [Link]([Link])
if "id" in data:
predictions = [Link](api_key=api_key, id=data["id"])
if predictions:
return predictions[0]
return cls(**data, client=client)
def delete(self, api_key: str):
if not [Link]:
raise ValueError("Cannot delete a prediction that has no ID.")
return self.delete_by_id(api_key=api_key, id=[Link])
@classmethod
def delete_by_id(cls, api_key: str, id: int):
client = Mosqlient(x_uid_key=api_key)
params = [Link](id=id)
return [Link](params)
@property
def id(self) -> [Link] | None:
return self._schema.id
@property
def disease(self) -> [Link]:
return self._schema.disease
@property
def description(self) -> [Link]:
return self._schema.description
@property
def commit(self) -> [Link]:
return self._schema.commit
@property
def data(self) -> List[[Link]]:
if not self._schema.data and [Link] and [Link]:
params = [Link](id=[Link])
raw_data = [Link](params)
self._schema.data = [
[Link](**d) for d in raw_data
]
return self._schema.data or []
def to_dataframe(self) -> [Link]:
return [Link]([dict(d) for d in [Link]])
@property
def case_definition(self) -> str | None:
return self._schema.case_definition
@property
def published(self) -> bool:
return self._schema.published
@property
def start(self) -> date | None:
return self._schema.start_date # type: ignore
@property
def end(self) -> date | None:
return self._schema.end_date # type: ignore
@property
def scores(self) -> Optional[Mapping[str, float | None]]:
return self._schema.scores or {}
@property
def created_at(self) -> date:
return self._schema.created_at # type: ignore
@property
def adm_0(self) -> str | None:
return self._schema.adm_0
@property
def adm_1(self) -> int | None:
return self._schema.adm_1
@property
def adm_2(self) -> int | None:
return self._schema.adm_2