Skip to content

Commit 6fdbd00

Browse files
authored
Merge pull request #137 from rstudio/docker-prepare
New `prepare_docker` function
2 parents 3577d77 + 54f8fb3 commit 6fdbd00

7 files changed

Lines changed: 76 additions & 8 deletions

File tree

.github/workflows/tests.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535
python -m pip install -e .[dev,torch,statsmodels,xgboost]
3636
- name: Run Tests
3737
run: |
38-
pytest -m 'not rsc_test' --cov --cov-report xml
38+
pytest -m 'not rsc_test and not docker' --cov --cov-report xml
3939
- name: Upload coverage
4040
uses: codecov/codecov-action@v2
4141

@@ -80,13 +80,16 @@ jobs:
8080
run: |
8181
python -m pip install --upgrade pip
8282
python -m pip install -e ".[dev]"
83-
- name: run Docker
83+
- name: Run Docker
8484
run: |
8585
python script/setup-docker/docker.py
8686
docker build -t mock .
8787
docker run -d -v $PWD/pinsboard:/vetiver/pinsboard -p 8080:8080 mock
8888
sleep 5
8989
curl -s --retry 10 --retry-connrefused http://0.0.0.0:8080
90+
- name: Run tests
91+
run: |
92+
pytest vetiver -m 'docker'
9093
9194
test-no-extras:
9295
name: "Test no exra ml frameworks"

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ lint:
5555
flake8 vetiver
5656

5757
test: clean-test
58-
pytest -m 'not rsc_test'
58+
pytest -m 'not rsc_test and not docker'
5959

6060
test-rsc: clean-test
6161
pytest

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ addopts = "--doctest-modules"
1212
doctest_optionflags = "NORMALIZE_WHITESPACE"
1313
markers = [
1414
"rsc_test: tests for rstudio connect",
15+
"docker: tests for docker deployments"
1516
]
1617

1718
[tool.setuptools_scm]

script/setup-docker/docker.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import vetiver
22
import pins
3+
import numpy as np
4+
5+
np.random.seed(500)
36

47
X, y = vetiver.get_mock_data()
58
model = vetiver.get_mock_model().fit(X, y)
@@ -9,6 +12,5 @@
912
v = vetiver.VetiverModel(model, "mymodel", ptype_data=X)
1013

1114
vetiver.vetiver_pin_write(board, v)
12-
vetiver.load_pkgs(v, path="vetiver_")
13-
vetiver.write_app(board, "mymodel")
14-
vetiver.write_docker()
15+
16+
vetiver.prepare_docker(board, "mymodel")

vetiver/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from .pin_read_write import vetiver_pin_write # noqa
1010
from .attach_pkgs import * # noqa
1111
from .meta import * # noqa
12-
from .write_docker import write_docker # noqa
12+
from .write_docker import write_docker, prepare_docker # noqa
1313
from .write_fastapi import write_app, vetiver_write_app # noqa
1414
from .handlers.base import BaseHandler, create_handler, InvalidModelError # noqa
1515
from .handlers.sklearn import SKLearnHandler # noqa
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import pytest
2+
import vetiver
3+
import pandas as pd
4+
import numpy as np
5+
6+
DOCKER_URL = "http://0.0.0.0:8080/predict"
7+
8+
pytestmark = pytest.mark.docker # noqa
9+
10+
11+
def test_predict_sklearn_df_check_ptype():
12+
np.random.seed(500)
13+
14+
X, y = vetiver.mock.get_mock_data()
15+
response = vetiver.predict(endpoint=DOCKER_URL, data=X)
16+
17+
assert isinstance(response, pd.DataFrame), response
18+
assert response.iloc[0, 0] == 44.47
19+
assert len(response) == 100

vetiver/write_docker.py

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import sys
22
import warnings
3+
from pathlib import Path
4+
5+
from .write_fastapi import write_app
6+
from .attach_pkgs import load_pkgs
7+
from .vetiver_model import VetiverModel
38

49

510
def vetiver_write_docker(
@@ -88,5 +93,43 @@ def write_docker(
8893
CMD ["uvicorn", "app.app:api", "--host", "{host}", "--port", "{port}"]
8994
"""
9095

91-
f = open(f"{path}Dockerfile", "x")
96+
f = open(Path(path, "Dockerfile"), "x")
9297
f.write(docker_script)
98+
99+
100+
def prepare_docker(
101+
board,
102+
pin_name: str,
103+
path: str = "./",
104+
version=None,
105+
rspm_env: bool = False,
106+
host: str = "0.0.0.0",
107+
port: str = "8080",
108+
):
109+
"""Create all files needed for Docker
110+
111+
Parameters
112+
----------
113+
board :
114+
Pin board for model
115+
pin_name : str
116+
Name of pin
117+
path :
118+
Path to output
119+
version :
120+
Pin version to be used
121+
rspm_env: bool
122+
Whether or not RStudio Package Manager should be used
123+
host: str
124+
Host address to run VetiverAPI from Dockerfile
125+
port: str
126+
Port to run VetiverAPI from Dockerfile
127+
128+
"""
129+
130+
v = VetiverModel.from_pin(board=board, name=pin_name, version=version)
131+
write_app(
132+
board=board, pin_name=pin_name, version=version, file=Path(path, "app.py")
133+
)
134+
load_pkgs(v, path=Path(path, "vetiver_"))
135+
write_docker(path=path, rspm_env=rspm_env, host=host, port=port)

0 commit comments

Comments
 (0)