-
Notifications
You must be signed in to change notification settings - Fork 18
Description
Describe the bug
Dear, I am trying to deploy an sklearn random forest model to Posit connect from within an ipython notebook in jupyterlab on Posit workbench.
I have followed the python instructions from the Get started-guide as well as the Posit youtube video on MLOps and all works well until I am trying to deploy the model using vetiver.deploy_rsconnect where I get the following error: RSConnectException: -n/--name cannot be specified in conjunction with options -s/--server (full error trace below)
Full error trace
/opt/python/3.10.6/lib/python3.10/site-packages/vetiver/write_fastapi.py:21: UserWarning: Pinned vetiver model has no active version and no datetime on versions,
Do you need to check your pinned model?
Using version 4509
warnings.warn(
---------------------------------------------------------------------------
RSConnectException Traceback (most recent call last)
Input In [10], in <cell line: 1>()
----> 1 vetiver.deploy_rsconnect(
2 connect_server = connect_server,
3 board = model_board,
4 pin_name = "kytos_lab/cars_mpg",
5 )
File /opt/python/3.10.6/lib/python3.10/site-packages/vetiver/rsconnect.py:104, in deploy_rsconnect(connect_server, board, pin_name, version, extra_files, new, app_id, title, python, conda_mode, force_generate, log_callback, image)
94 tmp_app = temp + "/app.py"
96 write_app(
97 board=board,
98 pin_name=pin_name,
(...)
101 overwrite=False,
102 )
--> 104 deploy_python_fastapi(
105 connect_server=connect_server,
106 directory=temp,
107 extra_files=extra_files,
108 excludes=None,
109 entry_point="app:api",
110 new=new,
111 app_id=app_id,
112 title=title,
113 python=python,
114 conda_mode=conda_mode,
115 force_generate=force_generate,
116 log_callback=log_callback,
117 image=image,
118 )
File /opt/python/3.10.6/lib/python3.10/site-packages/rsconnect/actions.py:897, in deploy_python_fastapi(connect_server, directory, extra_files, excludes, entry_point, new, app_id, title, python, conda_mode, force_generate, log_callback, image)
856 def deploy_python_fastapi(
857 connect_server: api.RSConnectServer,
858 directory: str,
(...)
869 image: str = None,
870 ) -> typing.Tuple[str, typing.Union[list, None]]:
871 """
872 A function to deploy a Python ASGI API module to RStudio Connect. Depending on the files involved
873 and network latency, this may take a bit of time.
(...)
895 of log lines. The log lines value will be None if a log callback was provided.
896 """
--> 897 return _deploy_by_python_framework(
898 connect_server,
899 directory,
900 extra_files,
901 excludes,
902 entry_point,
903 gather_basic_deployment_info_for_fastapi,
904 image,
905 new,
906 app_id,
907 title,
908 python,
909 conda_mode,
910 force_generate,
911 log_callback,
912 )
File /opt/python/3.10.6/lib/python3.10/site-packages/rsconnect/actions.py:1210, in _deploy_by_python_framework(connect_server, directory, extra_files, excludes, entry_point, gatherer, image, new, app_id, title, python, conda_mode, force_generate, log_callback)
1201 _, environment = get_python_env_info(
1202 directory,
1203 python,
1204 conda_mode=conda_mode,
1205 force_generate=force_generate,
1206 )
1207 bundle = create_api_deployment_bundle(
1208 directory, extra_files, excludes, entry_point, app_mode, environment, True, image
1209 )
-> 1210 return _finalize_deploy(
1211 connect_server,
1212 app_store,
1213 directory,
1214 app_id,
1215 app_mode,
1216 deployment_name,
1217 deployment_title,
1218 default_title,
1219 bundle,
1220 log_callback,
1221 )
File /opt/python/3.10.6/lib/python3.10/site-packages/rsconnect/actions.py:769, in _finalize_deploy(connect_server, app_store, file_name, app_id, app_mode, name, title, title_is_default, bundle, log_callback)
737 def _finalize_deploy(
738 connect_server: api.RSConnectServer,
739 app_store: AppStore,
(...)
747 log_callback: typing.Callable,
748 ) -> typing.Tuple[str, typing.Union[list, None]]:
749 """
750 A common function to finish up the deploy process once all the data (bundle
751 included) has been resolved.
(...)
767 of log lines. The log lines value will be None if a log callback was provided.
768 """
--> 769 app = deploy_bundle(connect_server, app_id, name, title, title_is_default, bundle, None)
770 app_url, log_lines, _ = spool_deployment_log(connect_server, app, log_callback)
771 app_store.set(
772 connect_server.url,
773 abspath(file_name),
(...)
778 app_mode,
779 )
File /opt/python/3.10.6/lib/python3.10/site-packages/rsconnect/actions.py:1793, in deploy_bundle(remote_server, app_id, name, title, title_is_default, bundle, env_vars)
1771 def deploy_bundle(
1772 remote_server: api.TargetableServer,
1773 app_id: int,
(...)
1778 env_vars: typing.List[typing.Tuple[str, str]],
1779 ) -> typing.Dict[str, typing.Any]:
1780 """
1781 Deploys the specified bundle.
1782
(...)
1791 task that may be queried for deployment progress.
1792 """
-> 1793 ce = RSConnectExecutor(
1794 server=remote_server,
1795 app_id=app_id,
1796 name=name,
1797 title=title,
1798 title_is_default=title_is_default,
1799 bundle=bundle,
1800 env_vars=env_vars,
1801 )
1802 ce.deploy_bundle()
1803 return ce.state["deployed_info"]
File /opt/python/3.10.6/lib/python3.10/site-packages/rsconnect/api.py:341, in RSConnectExecutor.__init__(self, name, url, api_key, insecure, cacert, ca_data, cookies, account, token, secret, timeout, logger, **kwargs)
339 self.reset()
340 self._d = kwargs
--> 341 self.setup_remote_server(
342 name=name,
343 url=url or kwargs.get("server"),
344 api_key=api_key,
345 insecure=insecure,
346 cacert=cacert,
347 ca_data=ca_data,
348 account_name=account,
349 token=token,
350 secret=secret,
351 )
352 self.setup_client(cookies, timeout)
353 self.logger = logger
File /opt/python/3.10.6/lib/python3.10/site-packages/rsconnect/api.py:390, in RSConnectExecutor.setup_remote_server(self, name, url, api_key, insecure, cacert, ca_data, account_name, token, secret)
378 def setup_remote_server(
379 self,
380 name: str = None,
(...)
388 secret: str = None,
389 ):
--> 390 validation.validate_connection_options(
391 url=url,
392 api_key=api_key,
393 insecure=insecure,
394 cacert=cacert,
395 account_name=account_name,
396 token=token,
397 secret=secret,
398 name=name,
399 )
401 if cacert and not ca_data:
402 ca_data = text_type(cacert.read())
File /opt/python/3.10.6/lib/python3.10/site-packages/rsconnect/validation.py:21, in validate_connection_options(url, api_key, insecure, cacert, account_name, token, secret, name)
18 present_options_mutually_exclusive_with_name = _get_present_options(options_mutually_exclusive_with_name)
20 if name and present_options_mutually_exclusive_with_name:
---> 21 raise RSConnectException(
22 "-n/--name cannot be specified in conjunction with options {}".format(
23 ", ".join(present_options_mutually_exclusive_with_name)
24 )
25 )
26 if not name and not url and not shinyapps_options:
27 raise RSConnectException(
28 "You must specify one of -n/--name OR -s/--server OR -A/--account, -T/--token, -S/--secret."
29 )
RSConnectException: -n/--name cannot be specified in conjunction with options -s/--server
I find the documentation generally a bit limited to figure out what is going on. I have been looking at the Vetiver python function reference, the documentation of Posit connect on deploying Vetiver and the Rsconnect-python documentation but I get sometimes contradictory information (for example should I use deploy_rsconnect or deploy_python_fastapi?).
Because my notebook kernel kept dying unexpectedly (after very long waits of doing nothing), I tried to also execute the deploy_python_fastapi in interactive python REPL from the terminal - this just keeps hanging for hours without any errors.
I did not yet try to directly use the rsconnect-python CLI outside of an interactive python environment, but I hoped that I could just run the example without any problems.
To Reproduce
I tried to publish the default example to my posit connect server and I observe the same error. To reproduce this example, you will need to have a Posit connect server to publish to.
from vetiver.data import mtcars
from vetiver import VetiverModel, write_app, vetiver_pin_write, VetiverAPI
from sklearn import tree
from pins import board_folder, board_rsconnect
from rsconnect.actions import deploy_python_fastapi
from rsconnect.api import RSConnectServer
# below you should change the values or use environmental variables to load them
API_KEY = <get api key from env var>
SERVER = <get connect server address from env var>
connect_server = RSConnectServer(
url=SERVER, # load from an .env file
api_key=API_KEY # load from an .env file
)
model_board = board_rsconnect(server_url=SERVER,
api_key=API_KEY,
allow_pickle_read=True,
versioned=True
)
car_mod = tree.DecisionTreeRegressor().fit(mtcars.drop(columns="mpg"), mtcars["mpg"])
# don't forget to replace user_name with the user associated with the API_KEY
v = VetiverModel(car_mod, model_name = "user_name/cars_mpg",
prototype_data = mtcars.drop(columns="mpg"))
vetiver_pin_write(model_board, v)
app = VetiverAPI(v, check_prototype=True)
deploy_rsconnect(
connect_server = connect_server,
board = model_board,
pin_name = "user_name/cars_mpg",
)Expected behavior
I would expect that following the code above allows me to deploy my model to Posit connect
Desktop (please complete the following information):
- OS: Ubuntu 22.04 LTS
- Browser: Firefox 118.0.2 (64-bit)
- Version: Posit Connect v2023.09.0-0-g3448da6cf4 - Posit Workbench 2023.09.0+463.pro11, “Desert Sunflower” (6cc4ae5f)
- Python version: 3.10.6