Skip to content

Commit 6d33440

Browse files
committed
create workbench_path attribute
1 parent fdd1ef9 commit 6d33440

3 files changed

Lines changed: 49 additions & 27 deletions

File tree

vetiver/server.py

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
import json
44
import requests
55
import uvicorn
6-
import os
7-
import subprocess
86
import logging
97
import pandas as pd
108
from fastapi import FastAPI, Request, testclient
@@ -16,13 +14,11 @@
1614
from urllib.parse import urljoin
1715
from typing import Callable, List, Union
1816

19-
from .utils import _jupyter_nb, inform
17+
from .utils import _jupyter_nb, get_workbench_path
2018
from .vetiver_model import VetiverModel
2119
from .meta import VetiverMeta
2220
from .helpers import api_data_to_frame, response_to_frame
2321

24-
_log = logging.getLogger(__name__)
25-
2622

2723
class VetiverAPI:
2824
"""Create model aware API
@@ -74,6 +70,7 @@ def __init__(
7470
self.model = model
7571
self.app_factory = app_factory
7672
self.app = app_factory()
73+
self.workbench_path = None
7774

7875
if "check_ptype" in kwargs:
7976
check_prototype = kwargs.pop("check_ptype")
@@ -96,6 +93,14 @@ def _init_app(self):
9693
app = self.app
9794
app.openapi = self._custom_openapi
9895

96+
@app.on_event("startup")
97+
async def startup_event():
98+
logger = logging.getLogger("uvicorn.error")
99+
if self.workbench_path:
100+
logger.info(f"VetiverAPI starting at {self.workbench_path}")
101+
else:
102+
logger.info("VetiverAPI starting...")
103+
99104
@app.get("/", include_in_schema=False)
100105
def docs_redirect():
101106

@@ -264,25 +269,13 @@ def run(self, port: int = 8000, host: str = "127.0.0.1", **kw):
264269
>>> v_api.run() # doctest: +SKIP
265270
"""
266271
_jupyter_nb()
267-
# check to see if in Posit Workbench, pulled from FastAPI section of user guide
268-
# https://docs.posit.co/ide/server-pro/user/vs-code/guide/proxying-web-servers.html#running-fastapi-with-uvicorn # noqa
269-
path = ""
270-
if "RS_SERVER_URL" in os.environ and os.environ["RS_SERVER_URL"]:
271-
path = (
272-
subprocess.run(
273-
f"echo $(/usr/lib/rstudio-server/bin/rserver-url -l {port})",
274-
stdout=subprocess.PIPE,
275-
shell=True,
276-
)
277-
.stdout.decode()
278-
.strip()
272+
self.workbench_path = get_workbench_path(port)
273+
274+
if self.workbench_path:
275+
uvicorn.run(
276+
self.app, port=port, host=host, root_path=self.workbench_path, **kw
279277
)
280-
# subprocess is run, new URL given
281-
if len(path) > 0:
282-
inform(_log, f"INFO: vetiver running at: {path}")
283-
uvicorn.run(self.app, port=port, host=host, root_path=path, **kw)
284278
else:
285-
inform(_log, f"INFO: vetiver running at: {host+':'+port}")
286279
uvicorn.run(self.app, port=port, host=host, **kw)
287280

288281
def _custom_openapi(self):

vetiver/tests/test_xgboost.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,17 @@
55
from vetiver.data import mtcars # noqa
66
from vetiver.handlers.xgboost import XGBoostHandler # noqa
77
import numpy as np # noqa
8+
import sys # noqa
89
from fastapi.testclient import TestClient # noqa
910

1011
import vetiver # noqa
1112

13+
# hack since xgboost 2.0 dropped 3.7 support
14+
if sys.version_info[0] == 3 and sys.version_info[1] < 8:
15+
PREDICT_VALUE = 21.064373016357422
16+
else:
17+
PREDICT_VALUE = 19.963224411010742
18+
1219

1320
@pytest.fixture
1421
def xgb_model():
@@ -57,7 +64,7 @@ def test_vetiver_build(vetiver_client):
5764

5865
response = vetiver.predict(endpoint=vetiver_client, data=data)
5966

60-
assert response.iloc[0, 0] == 21.064373016357422
67+
assert response.iloc[0, 0] == 19.963224411010742
6168
assert len(response) == 1
6269

6370

@@ -66,7 +73,7 @@ def test_batch(vetiver_client):
6673

6774
response = vetiver.predict(endpoint=vetiver_client, data=data)
6875

69-
assert response.iloc[0, 0] == 21.064373016357422
76+
assert response.iloc[0, 0] == 19.963224411010742
7077
assert len(response) == 3
7178

7279

@@ -75,7 +82,7 @@ def test_no_ptype(vetiver_client_check_ptype_false):
7582

7683
response = vetiver.predict(endpoint=vetiver_client_check_ptype_false, data=data)
7784

78-
assert response.iloc[0, 0] == 21.064373016357422
85+
assert response.iloc[0, 0] == 19.963224411010742
7986
assert len(response) == 1
8087

8188

vetiver/utils.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import nest_asyncio
22
import warnings
33
import sys
4+
import os
5+
import subprocess
46
from types import SimpleNamespace
57

68
no_notebook = False
@@ -14,8 +16,8 @@ def _jupyter_nb():
1416

1517
if not no_notebook:
1618
warnings.warn(
17-
"WARNING: Jupyter Notebooks are not considered stable environments "
18-
"for production code"
19+
"You may be running from a notebook environment. Jupyter Notebooks are "
20+
"not considered stable environments for production code"
1921
)
2022
nest_asyncio.apply()
2123
else:
@@ -31,3 +33,23 @@ def inform(log, msg):
3133

3234
if not modelcard_options.quiet:
3335
print(msg, file=sys.stderr)
36+
37+
38+
def get_workbench_path(port):
39+
# check to see if in Posit Workbench, pulled from FastAPI section of user guide
40+
# https://docs.posit.co/ide/server-pro/user/vs-code/guide/proxying-web-servers.html#running-fastapi-with-uvicorn # noqa
41+
42+
if "RS_SERVER_URL" in os.environ and os.environ["RS_SERVER_URL"]:
43+
path = (
44+
subprocess.run(
45+
f"echo $(/usr/lib/rstudio-server/bin/rserver-url -l {port})",
46+
stdout=subprocess.PIPE,
47+
shell=True,
48+
)
49+
.stdout.decode()
50+
.strip()
51+
)
52+
# subprocess is run, new URL given
53+
return path
54+
else:
55+
return None

0 commit comments

Comments
 (0)