Skip to content

Commit 1362a74

Browse files
committed
💡 Add monitors to SDK
1 parent 589c0c9 commit 1362a74

File tree

5 files changed

+71
-4
lines changed

5 files changed

+71
-4
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ ENV=dev uvicorn whitebox.main:app --reload
8787

8888
### Tests:
8989

90-
- Run: `ENV=test pytest -s`
90+
- Run: `ENV=test pytest` or `ENV=test pytest -s` to preserve logs.
9191
- Watch: `ENV=test ptw`
9292
- Run test coverage `ENV=test coverage run -m pytest`
9393
- Look at coverage report: `coverage report` or `coverage html` to generate an html. To view it in your browser open the `htmlcov/index.html` file.

whitebox/cron_tasks/shared.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import List, Union
1+
from typing import List, Tuple, Union
22

33
import pandas as pd
44
from sqlalchemy.orm import Session
@@ -24,7 +24,7 @@ async def get_model_dataset_rows_df(db: Session, model_id: str) -> pd.DataFrame:
2424

2525
async def get_model_inference_rows_df(
2626
db: Session, model_id: str
27-
) -> tuple[pd.DataFrame, pd.DataFrame, pd.Series]:
27+
) -> Tuple[pd.DataFrame, pd.DataFrame, pd.Series]:
2828
inference_rows_in_db = crud.inference_rows.get_inference_rows_by_model(
2929
db=db, model_id=model_id
3030
)

whitebox/sdk/whitebox.py

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,18 @@
22
import numpy as np
33
import pandas as pd
44
from whitebox.schemas.model import FeatureTypes, ModelCreateDto, ModelType
5-
from typing import Dict
5+
from typing import Dict, Optional
66
import requests
77
import logging
88
from fastapi import status
99

10+
from whitebox.schemas.modelMonitor import (
11+
AlertSeverity,
12+
ModelMonitorCreateDto,
13+
MonitorMetrics,
14+
MonitorStatus,
15+
)
16+
1017

1118
class APiVersion(str, Enum):
1219
v1 = "v1"
@@ -177,3 +184,38 @@ def _check_processed_and_non_processed_length(
177184
"Processed and non processed dataframes must have the same length."
178185
)
179186
return True
187+
188+
def create_model_monitor(
189+
self,
190+
model_id: str,
191+
name: str,
192+
status: MonitorStatus,
193+
metric: MonitorMetrics,
194+
feature: Optional[str],
195+
lower_threshold: Optional[float],
196+
severity: AlertSeverity,
197+
email: str,
198+
):
199+
"""
200+
Creates a monitor for a model.
201+
"""
202+
203+
model_monitor = ModelMonitorCreateDto(
204+
model_id=model_id,
205+
name=name,
206+
status=status,
207+
metric=metric,
208+
feature=feature,
209+
lower_threshold=lower_threshold,
210+
severity=severity,
211+
email=email,
212+
)
213+
214+
result = requests.post(
215+
url=f"{self.host}/{self.api_version}/model-monitors",
216+
json=model_monitor.dict(),
217+
headers={"api-key": self.api_key},
218+
)
219+
220+
logger.info(result.json())
221+
return result.json()

whitebox/tests/utils/maps.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,5 @@
3333
"sdk_delete_model",
3434
"sdk_log_training_dataset",
3535
"sdk_log_inferences",
36+
"sdk_create_model_monitor",
3637
]

whitebox/tests/v1/test_sdk.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import pandas as pd
22
import pytest
3+
from whitebox.schemas.modelMonitor import AlertSeverity, MonitorMetrics, MonitorStatus
34
from whitebox.sdk import Whitebox
45
from whitebox.tests.v1.conftest import get_order_number, state, state_sdk
56
from whitebox.tests.v1.mock_data import (
@@ -171,3 +172,26 @@ def test_sdk_log_inferences(client):
171172
timestamps=timestamps,
172173
actuals=mixed_actuals,
173174
)
175+
176+
177+
@pytest.mark.order(get_order_number("sdk_create_model_monitor"))
178+
def test_sdk_create_model_monitor(client):
179+
with requests_mock.Mocker() as m:
180+
m.post(
181+
url=f"{state_sdk.wb.host}/v1/model-monitors",
182+
json=model_multi_create_payload,
183+
headers={"api-key": state_sdk.wb.api_key},
184+
)
185+
186+
model_monitor = state_sdk.wb.create_model_monitor(
187+
model_id="mock_model_id",
188+
name="test",
189+
status=MonitorStatus.active,
190+
metric=MonitorMetrics.accuracy,
191+
feature="feature1",
192+
lower_threshold=0.7,
193+
severity=AlertSeverity.high,
194+
email="jaclie.chan@chinamail.io",
195+
)
196+
197+
assert model_monitor == model_monitor

0 commit comments

Comments
 (0)