|
| 1 | +import pytest |
| 2 | + |
| 3 | +vetiver = pytest.importorskip("vetiver", reason="vetiver library not installed") |
| 4 | + |
| 5 | +import json # noqa |
| 6 | +import pins # noqa |
| 7 | +import pandas as pd # noqa |
| 8 | +import numpy as np # noqa |
| 9 | + |
| 10 | +from pins.boards import BoardRsConnect # noqa |
| 11 | +from pins.rsconnect.api import RsConnectApi # noqa |
| 12 | +from pins.rsconnect.fs import RsConnectFs # noqa |
| 13 | +from rsconnect.api import RSConnectServer, RSConnectClient # noqa |
| 14 | + |
| 15 | +RSC_SERVER_URL = "http://localhost:3939" |
| 16 | +RSC_KEYS_FNAME = "vetiver-testing/rsconnect_api_keys.json" |
| 17 | + |
| 18 | +pytestmark = pytest.mark.vetiver # noqa |
| 19 | + |
| 20 | + |
| 21 | +def get_key(name): |
| 22 | + with open(RSC_KEYS_FNAME) as f: |
| 23 | + api_key = json.load(f)[name] |
| 24 | + return api_key |
| 25 | + |
| 26 | + |
| 27 | +def rsc_from_key(name): |
| 28 | + with open(RSC_KEYS_FNAME) as f: |
| 29 | + api_key = json.load(f)[name] |
| 30 | + return RsConnectApi(RSC_SERVER_URL, api_key) |
| 31 | + |
| 32 | + |
| 33 | +def rsc_fs_from_key(name): |
| 34 | + |
| 35 | + rsc = rsc_from_key(name) |
| 36 | + |
| 37 | + return RsConnectFs(rsc) |
| 38 | + |
| 39 | + |
| 40 | +def rsc_delete_user_content(rsc): |
| 41 | + guid = rsc.get_user()["guid"] |
| 42 | + content = rsc.get_content(owner_guid=guid) |
| 43 | + for entry in content: |
| 44 | + rsc.delete_content_item(entry["guid"]) |
| 45 | + |
| 46 | + |
| 47 | +@pytest.fixture(scope="function") |
| 48 | +def rsc_short(): |
| 49 | + # tears down content after each test |
| 50 | + fs_susan = rsc_fs_from_key("susan") |
| 51 | + |
| 52 | + # delete any content that might already exist |
| 53 | + rsc_delete_user_content(fs_susan.api) |
| 54 | + |
| 55 | + yield BoardRsConnect("", fs_susan, allow_pickle_read=True) # fs_susan.ls to list content |
| 56 | + |
| 57 | + rsc_delete_user_content(fs_susan.api) |
| 58 | + |
| 59 | + |
| 60 | +def test_deploy(rsc_short): |
| 61 | + np.random.seed(500) |
| 62 | + |
| 63 | + # Load data, model |
| 64 | + X_df, y = vetiver.mock.get_mock_data() |
| 65 | + model = vetiver.mock.get_mock_model().fit(X_df, y) |
| 66 | + |
| 67 | + v = vetiver.VetiverModel(model=model, ptype_data=X_df, model_name="susan/model") |
| 68 | + |
| 69 | + board = pins.board_rsconnect(server_url=RSC_SERVER_URL, api_key=get_key("susan"), allow_pickle_read=True) |
| 70 | + |
| 71 | + vetiver.vetiver_pin_write(board=board, model=v) |
| 72 | + connect_server = RSConnectServer(url=RSC_SERVER_URL, api_key=get_key("susan")) |
| 73 | + |
| 74 | + vetiver.deploy_rsconnect( |
| 75 | + connect_server=connect_server, |
| 76 | + board=board, |
| 77 | + pin_name="susan/model", |
| 78 | + title="testapivetiver", |
| 79 | + extra_files=["requirements.txt"], |
| 80 | + ) |
| 81 | + |
| 82 | + # get url of where content lives |
| 83 | + client = RSConnectClient(connect_server) |
| 84 | + dicts = client.content_search() |
| 85 | + rsc_api = list(filter(lambda x: x["title"] == "testapivetiver", dicts)) |
| 86 | + content_url = rsc_api[0].get("content_url") |
| 87 | + |
| 88 | + h = {"Authorization": 'Key {}'.format(get_key("susan"))} |
| 89 | + |
| 90 | + endpoint = vetiver.vetiver_endpoint(content_url + "/predict") |
| 91 | + response = vetiver.predict(endpoint, X_df, headers=h) |
| 92 | + |
| 93 | + assert isinstance(response, pd.DataFrame), response |
| 94 | + assert response.iloc[0, 0] == 44.47 |
| 95 | + assert len(response) == 100 |
0 commit comments