rstudio / vetiver-python

Version, share, deploy, and monitor models.
https://rstudio.github.io/vetiver-python/stable/
MIT License
59 stars 17 forks source link

`vetiver.deploy_rsconnect` fails on rsconnect-python < 1.12.1 #131

Closed SamEdwardes closed 1 year ago

SamEdwardes commented 1 year ago

TL/DR

I think that vetiver needs to pin a requirement of rsconnect-python >= 1.12.1.

Reprex rsconnect-python==1.7.1

requirements.txt

vetiver==0.1.8
rsconnect-python==1.7.1

train_and_deploy_model.py

import os

import pins
import vetiver

from vetiver.data import mtcars
from sklearn.linear_model import LinearRegression

# Fit a model ------------------------------------------------------------------

lm = LinearRegression().fit(mtcars, mtcars["mpg"])
model_name = "sam.edwardes/mtcars-linear-model"

v = vetiver.VetiverModel(
    lm,
    model_name=model_name,
    save_ptype=True,
    ptype_data=mtcars
)

# Pin model --------------------------------------------------------------------

board = pins.board_rsconnect(
    server_url=os.getenv("CONNECT_URL"),
    api_key=os.getenv("CONNECT_API_KEY"),
    allow_pickle_read=True
)

vetiver.vetiver_pin_write(board, v)

# Deploy model -----------------------------------------------------------------

vetiver.deploy_rsconnect(
    connect_server=os.getenv("CONNECT_URL"),
    board=board,
    pin_name=model_name
)

Execute the code:

python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip wheel setuptools
python -m pip install -r requirements.txt
python python train_and_deploy_model.py
Traceback (most recent call last):
  File "/usr/home/sam.edwardes/tmp/vetiver-reprex/train_model.py", line 33, in <module>
    vetiver.deploy_rsconnect(
  File "/usr/home/sam.edwardes/tmp/vetiver-reprex/.venv/lib/python3.10/site-packages/vetiver/rsconnect.py", line 101, in deploy_rsconnect
    deploy_python_fastapi(
TypeError: deploy_python_fastapi() got an unexpected keyword argument 'image'

Reprex rsconnect-python>=1.8.0 and rsconnect-python<=1.12.0

requirements.txt

I tested under the following scenarios, they all go the same error:

vetiver==0.1.8
rsconnect-python==XXX

train_and_deploy_model.py

import os

import pins
import vetiver

from vetiver.data import mtcars
from sklearn.linear_model import LinearRegression

# Fit a model ------------------------------------------------------------------

lm = LinearRegression().fit(mtcars, mtcars["mpg"])
model_name = "sam.edwardes/mtcars-linear-model"

v = vetiver.VetiverModel(
    lm,
    model_name=model_name,
    save_ptype=True,
    ptype_data=mtcars
)

# Pin model --------------------------------------------------------------------

board = pins.board_rsconnect(
    server_url=os.getenv("CONNECT_URL"),
    api_key=os.getenv("CONNECT_API_KEY"),
    allow_pickle_read=True
)

vetiver.vetiver_pin_write(board, v)

# Deploy model -----------------------------------------------------------------

vetiver.deploy_rsconnect(
    connect_server=os.getenv("CONNECT_URL"),
    board=board,
    pin_name=model_name
)

Execute the code:

python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip wheel setuptools
python -m pip install -r requirements.txt
python python train_and_deploy_model.py
Traceback (most recent call last):
  File "/usr/home/sam.edwardes/tmp/vetiver-reprex/train_model.py", line 33, in <module>
    vetiver.deploy_rsconnect(
  File "/usr/home/sam.edwardes/tmp/vetiver-reprex/.venv/lib/python3.10/site-packages/vetiver/rsconnect.py", line 101, in deploy_rsconnect
    deploy_python_fastapi(
  File "/usr/home/sam.edwardes/tmp/vetiver-reprex/.venv/lib/python3.10/site-packages/rsconnect/actions.py", line 811, in deploy_python_fastapi
    return _deploy_by_python_framework(
  File "/usr/home/sam.edwardes/tmp/vetiver-reprex/.venv/lib/python3.10/site-packages/rsconnect/actions.py", line 1058, in _deploy_by_python_framework
    ) = gatherer(connect_server, app_store, directory, entry_point, new, app_id, title)
  File "/usr/home/sam.edwardes/tmp/vetiver-reprex/.venv/lib/python3.10/site-packages/rsconnect/actions.py", line 1381, in gatherer
    return _gather_basic_deployment_info_for_framework(
  File "/usr/home/sam.edwardes/tmp/vetiver-reprex/.venv/lib/python3.10/site-packages/rsconnect/actions.py", line 1440, in _gather_basic_deployment_info_for_framework
    app_id, existing_app_mode = app_store.resolve(connect_server.url, app_id, app_mode)
AttributeError: 'NoneType' object has no attribute 'url'
isabelizimm commented 1 year ago

Ah, thank you for this! I do notice that your connect_server argument is the url, not a Connect Server object (see https://rstudio.github.io/vetiver-python/stable/reference/vetiver.deploy_rsconnect.html#vetiver-deploy-rsconnect). That should solve your error for some versions.

I still think this is a good idea to pin the version due to the other errors you are hitting, but starting at rsconnect-python>=1.11 rather than 1.12.1.

SamEdwardes commented 1 year ago

Thank you for taking a look @isabelizimm.

I was putting the wrong value into the connect_server argument. I found this example to be the most helpful: https://docs.posit.co/connect/user/vetiver/#example.

So I think I was incorrect to say that these versions do not work:

After fixing my code:

import os
import sys

import pins
import vetiver

from vetiver.data import mtcars
from sklearn.linear_model import LinearRegression
from rsconnect.api import RSConnectServer

# Fit a model ------------------------------------------------------------------

lm = LinearRegression().fit(mtcars, mtcars["mpg"])
model_name = "sam.edwardes/mtcars-linear-model3"

v = vetiver.VetiverModel(
    lm,
    model_name=model_name,
    save_ptype=True,
    ptype_data=mtcars
)

# Pin model --------------------------------------------------------------------

board = pins.board_rsconnect(
    server_url=os.getenv("CONNECT_SERVER"),
    api_key=os.getenv("CONNECT_API_KEY"),
    allow_pickle_read=True
)

vetiver.vetiver_pin_write(board, v)

# Deploy model -----------------------------------------------------------------

connect_server = RSConnectServer(
    url=os.getenv("CONNECT_SERVER"), 
    api_key=os.getenv("CONNECT_API_KEY")
)

vetiver.deploy_rsconnect(
    connect_server=connect_server,
    board=board,
    pin_name=model_name,
    python=sys.executable,
)

After making the code changes, I was able to deploy successfully using:

vetiver==0.1.8
rsconnect-python==1.8.0

So maybe vetiver should just be pinned to require rsconnect-python>=1.8.0?