Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/workflows/precommit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Code Checks

on:
workflow_dispatch:
push:
branches: ['main']
pull_request:
release:
types: [published]

jobs:
pre-commit:
name: "Run pre-commit"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: pre-commit/action@v2.0.3
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@


exclude: "(.*\\.csv)|(^pins/tests/_snapshots)"
exclude: "(.*\\.csv)|(^examples/)|(^vetiver/tests/snapshots/)"
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.4.0
Expand Down
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ help:
@echo "clean-test - remove test and coverage artifacts"
@echo "lint - check style with flake8"
@echo "test - run tests quickly with the default Python"
@echo "test-rsc - run tests for rsconnect"
@echo "coverage - check code coverage quickly with the default Python"
@echo "docs - generate Sphinx HTML documentation, including API docs"
@echo "cdocs - cleanout previous build & generate Sphinx HTML documentation, including API docs"
Expand Down Expand Up @@ -54,6 +55,9 @@ lint:
flake8 vetiver

test: clean-test
pytest -m 'not rsc_test'

test-rsc: clean-test
pytest

coverage:
Expand Down
30 changes: 22 additions & 8 deletions examples/coffeeratings.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,32 @@
from pathlib import Path

# Load training data
raw = pd.read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2020/2020-07-07/coffee_ratings.csv')
raw = pd.read_csv(
"https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2020/2020-07-07/coffee_ratings.csv"
)
df = pd.DataFrame(raw)
coffee = df[["total_cup_points", "aroma", "flavor", "sweetness", "acidity", \
"body", "uniformity", "balance"]].dropna()

X_train, X_test, y_train, y_test = model_selection.train_test_split(coffee.iloc[:,1:],coffee['total_cup_points'],test_size=0.2)
coffee = df[
[
"total_cup_points",
"aroma",
"flavor",
"sweetness",
"acidity",
"body",
"uniformity",
"balance",
]
].dropna()

X_train, X_test, y_train, y_test = model_selection.train_test_split(
coffee.iloc[:, 1:], coffee["total_cup_points"], test_size=0.2
)

# fit model
lr_fit = LinearRegression().fit(X_train, y_train)

# create vetiver model
v = vetiver.VetiverModel(lr_fit, ptype_data=X_train, model_name = "v")
v = vetiver.VetiverModel(lr_fit, ptype_data=X_train, model_name="v")

# version model via pin
from pins import board_folder
Expand All @@ -27,12 +41,12 @@
model_board = board_folder(path=path, versioned=True, allow_pickle_read=True)
vetiver_pin_write(board=model_board, model=v)

myapp = vetiver.VetiverAPI(v, check_ptype = True)
myapp = vetiver.VetiverAPI(v, check_ptype=True)
api = myapp.app

# next, run myapp.run() to start API and see visual documentation
# create app.py file that includes pinned VetiverAPI to be deployed
vetiver.vetiver_write_app(model_board, "v", file = path+"app.py")
vetiver.vetiver_write_app(model_board, "v", file=path + "app.py")

# automatically create requirements.txt
vetiver.load_pkgs(model=v, path=path)
Expand Down
4 changes: 2 additions & 2 deletions examples/coffeeratings/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
import pins

# edited to reflect Docker container path, and allow_pickle_read=True
b = pins.board_folder('/code/app', allow_pickle_read=True)
v = vetiver.vetiver_pin_read(b, 'v', version = '20220415T174503Z-06d9b')
b = pins.board_folder("/code/app", allow_pickle_read=True)
v = vetiver.vetiver_pin_read(b, "v", version="20220415T174503Z-06d9b")

vetiver_api = vetiver.VetiverAPI(v)
api = vetiver_api.app
2 changes: 1 addition & 1 deletion examples/coffeeratings/vetiver_requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,4 @@ uvicorn==0.17.6
# via vetiver

# manually edited to reflect appropriate versions of packages currently being developed
git+https://github.com/isabelizimm/vetiver-python.git@37dff15a63238b1e6c44788af70473f19c29d83e
git+https://github.com/isabelizimm/vetiver-python.git@37dff15a63238b1e6c44788af70473f19c29d83e
4 changes: 2 additions & 2 deletions vetiver/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
from .handlers.base import BaseHandler, create_handler, InvalidModelError # noqa
from .handlers.sklearn import SKLearnHandler # noqa
from .handlers.torch import TorchHandler # noqa
from .rsconnect import deploy_rsconnect # noqa
from .monitor import compute_metrics, pin_metrics, plot_metrics, _rolling_df # noqa
from .rsconnect import deploy_rsconnect # noqa
from .monitor import compute_metrics, pin_metrics, plot_metrics, _rolling_df # noqa

__author__ = "Isabel Zimmerman <isabel.zimmerman@rstudio.com>"
__all__ = []
Expand Down
1 change: 1 addition & 0 deletions vetiver/data/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ def __dir__():

def __getattr__(k):
import pandas as pd

f_path = sources.get("mtcars")
if k == "chicago":
f_path = sources.get("chicago")
Expand Down
6 changes: 4 additions & 2 deletions vetiver/pin_read_write.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,14 @@ def vetiver_pin_read(board, name: str, version: str = None) -> VetiverModel:

Notes
-----
If reading a board from RSConnect, the `board` argument must be in "username/modelname" format.
If reading a board from RSConnect, the `board` argument must be in
"username/modelname" format.

"""

warnings.warn(
"vetiver_pin_read will be removed in v1.0.0. Use classmethod VetiverModel.from_pin() instead",
"vetiver_pin_read will be removed in v1.0.0. Use classmethod "
"VetiverModel.from_pin() instead",
DeprecationWarning,
)

Expand Down
2 changes: 1 addition & 1 deletion vetiver/ptype.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class NoAvailablePTypeError(Exception):

def __init__(
self,
message="There is no method available to create a 0-row input data prototype for `model`",
message="There is no method to create a 0-row input data prototype for `model`",
):
self.message = message
super().__init__(self.message)
Expand Down
11 changes: 5 additions & 6 deletions vetiver/rsconnect.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,16 @@ def deploy_rsconnect(

Parameters
----------
connect_server:
connect_server:
RSConnect Server
board:
board:
Pins board
pin_name: str
Name of pin
version: str
Version of pin
extra_files: typing.List[str]
Any extra files to include in
Any extra files to include in
new:
Force as a new deploy
app_id:
Expand All @@ -46,7 +46,7 @@ def deploy_rsconnect(
Optional name of a Python executable
conda_mode: bool
Use conda to build an environment.yml
force_generate: bool
force_generate: bool
Force generating "requirements.txt" or "environment.yml"
log_callback: typing.Callable
Callback to use to write the log to
Expand All @@ -64,11 +64,10 @@ def deploy_rsconnect(
shutil.copyfile(file, os.path.join(temp, filename))
new_files = new_files + [os.path.join(temp, filename)]
extra_files = new_files

if board.fs.protocol == "file":
shutil.copytree(board.path_to_pin(pin_name), os.path.join(temp, pin_name))


tmp_app = temp + "/app.py"

write_app(
Expand Down
3 changes: 1 addition & 2 deletions vetiver/tests/test_build_vetiver_model.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import pytest
import sklearn

import vetiver as vt
Expand Down Expand Up @@ -74,7 +73,7 @@ def test_vetiver_model_no_ptype():
)

assert vt4.model == model
assert vt4.ptype == None
assert vt4.ptype is None


def test_vetiver_model_from_pin():
Expand Down
11 changes: 4 additions & 7 deletions vetiver/tests/test_rsconnect.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
from pins.boards import BoardRsConnect
from pins.rsconnect.api import RsConnectApi
from pins.rsconnect.fs import RsConnectFs
from vetiver import VetiverModel, vetiver_pin_write, mock
import sklearn
from rsconnect.api import RSConnectServer

import vetiver
Expand All @@ -25,6 +23,7 @@ def server_from_key(name):
api_key = json.load(f)[name]
return RSConnectServer(RSC_SERVER_URL, api_key)


def rsc_from_key(name):
with open(RSC_KEYS_FNAME) as f:
api_key = json.load(f)[name]
Expand Down Expand Up @@ -60,14 +59,14 @@ def rsc_short():
rsc_delete_user_content(fs_susan.api)



def test_board_pin_write(rsc_short):
v = vetiver.VetiverModel(
model=model, ptype_data=X_df, model_name="susan/model", versioned=None
)
vetiver.vetiver_pin_write(board=rsc_short, model=v)
assert isinstance(rsc_short.pin_read("susan/model"), sklearn.dummy.DummyRegressor)


@pytest.mark.xfail
def test_deploy(rsc_short):
# TODO: test in Dockerfile
Expand All @@ -76,11 +75,9 @@ def test_deploy(rsc_short):
)

vetiver.vetiver_pin_write(board=rsc_short, model=v)

vetiver.deploy_rsconnect(
connect_server=server_from_key("susan"),
board=rsc_short,
pin_name="susan/model"
connect_server=server_from_key("susan"), board=rsc_short, pin_name="susan/model"
)
response = vetiver.predict(RSC_SERVER_URL + "/predict/", json=X_df)
assert response.status_code == 200, response.text
Expand Down
1 change: 0 additions & 1 deletion vetiver/tests/test_write_docker.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import pytest
import os
import sys
import vetiver
Expand Down
5 changes: 3 additions & 2 deletions vetiver/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

no_notebook = False
try:
from IPython import get_ipython
from IPython import get_ipython # noqa
except ImportError:
no_notebook = True

Expand All @@ -12,7 +12,8 @@ def _jupyter_nb():

if not no_notebook:
warnings.warn(
"WARNING: Jupyter Notebooks are not considered stable environments for production code"
"WARNING: Jupyter Notebooks are not considered stable environments "
"for production code"
)
nest_asyncio.apply()
else:
Expand Down
2 changes: 1 addition & 1 deletion vetiver/write_docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def write_docker(
py_version = str(sys.version_info.major) + "." + str(sys.version_info.minor)

if rspm_env:
rspm = "\nRUN pip config set global.index-url https://colorado.rstudio.com/rspm/pypi/latest/simple"
rspm = "\nRUN pip config set global.index-url https://colorado.rstudio.com/rspm/pypi/latest/simple" # noqa
else:
rspm = ""

Expand Down