From be8bc6b4ecda3789797bfe093d88d21595ef2ebe Mon Sep 17 00:00:00 2001 From: isabelizimm Date: Fri, 13 Oct 2023 16:53:12 -0400 Subject: [PATCH 01/12] docs on deploying custom elements --- docs/custom_elements.qmd | 194 +++++++++++++++++++++++++++++++++++++++ docs/custom_handler.md | 46 ---------- 2 files changed, 194 insertions(+), 46 deletions(-) create mode 100644 docs/custom_elements.qmd delete mode 100644 docs/custom_handler.md diff --git a/docs/custom_elements.qmd b/docs/custom_elements.qmd new file mode 100644 index 00000000..3c43c082 --- /dev/null +++ b/docs/custom_elements.qmd @@ -0,0 +1,194 @@ +# Creating and deploying custom elements + +In some cases, you may need to create and deploy custom elements as part of your MLOps workflow using Vetiver. This could be necessary when there is no existing implementation for the type of model you want to deploy, or when you want to implement a current handler in a different way. You may also have a custom element in a known framework, such as a custom column transformer for a scikit-learn model. + +In these cases, extra steps will be required to successfully create and deploy a `VetiverModel` object. + +# Making a custom model + +Vetiver supports basic [scikit-learn](https://scikit-learn.org/), [torch](https://pytorch.org/), [statsmodels](https://www.statsmodels.org/stable/index.html), [xgboost](https://xgboost.readthedocs.io/en/stable/), and [spacy](https://spacy.io/) models. If you need to alter the usage of these models, or deploy a different type of model, you will likely need to create a custom model handler. + +To create a custom model handler, you should create a subclass of Vetiver's BaseHandler class. This custom handler should include the following: + +- `model_type`: A static method that declares the type of your model. +- `handler_predict()`: A method that defines how predictions should be made for your model. This method is used at the /predict endpoint in the VetiverAPI. + +Here's an example of a custom handler for a model of `newmodeltype` type. + +```python +from vetiver.handlers.base import BaseHandler + +class CustomHandler(BaseHandler): + def __init__(self, model, ptype_data): + super().__init__(model, ptype_data) + + model_type = staticmethod(lambda: newmodeltype) + pip_name = "scikit-learn" # package's installation name on pip + + def handler_predict(self, input_data, check_prototype: bool): + """ + Your code for making predictions using the custom model + + Parameters + ---------- + input_data: + Data POSTed to API endpoint + check_prototype: bool + Whether the prototype should be enforced + """ + prediction = model.fancy_new_predict(input_data) + + return prediction + +new_model = CustomHandler(model, ptype_data) + +VetiverModel(new_model, "custom_model") +``` + +Once you have defined your custom handler, you can initialize it with your model and pass it to the VetiverModel class. + +If your model is a common type, please consider [submitting a pull request](https://github.com/rstudio/vetiver-python/pulls). + +To deploy custom elements, you need to include the necessary source code in your deployment files. If your model or other elements can be imported from a Python package, you can include the relevant packages in a `requirements.txt` file for deployment. However, if you have custom source code in local files, you will need to include those files in the deployment process. + +# Deploying custom elements + +If your `VetiverModel` includes custom source code, you need to include that code in your deployment files to build an API in another location. To do so, + +```{.python filename="model.py"} +from sklearn.base import BaseEstimator, TransformerMixin +from sklearn.tree import DecisionTreeClassifier +from sklearn.pipeline import Pipeline + +# create custom data preprocessing +class FeatureSelector(BaseEstimator, TransformerMixin): + def __init__(self, columns): + self.columns = columns + + def fit(self, X, y=None): + return self + + def transform(self, X, y=None): + return X[self.columns] + +# create model +model = Pipeline(steps=[ + ('feature_selector', FeatureSelector(features)), + ('decision_tree', DecisionTreeClassifier()) +]) + +# create deployable model object +from vetiver import VetiverModel, vetiver_pin_write + +v = VetiverModel(model, "selected_decision_tree", protoype_data = X) + +# pin model to some location, eg, Posit Connect +import pins + +board = pins.board_connect(allow_pickle_read=True) +vetiver_pin_write(board, v) +``` + +::: {.panel-tabset} +## Docker + +To generate files needed to start a Docker container, you can use the command `vetiver.prepare_docker`. + +```{.python} +vetiver.prepare_docker(board, "selected_decision_tree") +``` + +When you run this line, 3 files are generated: a Dockerfile, an `app.py` file, and a `vetiver_requirements.txt`. In the `app.py` file, you'll need to add an import statement that is formatted `from {name of file, excluding .py, that has custom element} import {name of custom element}`. + +```{.python filename=="app.py"} +from vetiver import VetiverModel +import vetiver +import pins +from model import FeatureSelector # add this line to import your custom feature engineering + + +b = pins.board_connect(allow_pickle_read=True) +v = VetiverModel.from_pin(b, 'selected_decision_tree') + +vetiver_api = vetiver.VetiverAPI(v) +api = vetiver_api.app +``` + +Add a line to your Dockerfile to copy your source file(s) into your Docker container. The format will be `COPY path/to/your/filename.py /vetiver/app/filename.py`, where the destination is always in the `/vetiver/app/` directory. + +```{.bash filename="Dockerfile"} +# # Generated by the vetiver package; edit with care +# start with python base image +FROM python:3.10 + +# create directory in container for vetiver files +WORKDIR /vetiver + +# copy and install requirements +COPY vetiver_requirements.txt /vetiver/requirements.txt + +# +RUN pip install --no-cache-dir --upgrade -r /vetiver/requirements.txt + +# copy app file +COPY app.py /vetiver/app/app.py + +# ADD THIS LINE to copy model source code +COPY model.py /vetiver/app/model.py + +# expose port +EXPOSE 8080 + +# run vetiver API +CMD ["uvicorn", "app.app:api", "--host", "0.0.0.0", "--port", "8080"] +``` + +## Posit Connect + +To deploy custom elements to Posit Connect, you'll first start with the command `vetiver.write_app`. + +```{.python} +vetiver.write_app(board, 'selected_decision_tree') +``` + +This will generate an `app.py` file, where you'll need to add an import statement that is formatted `from {name of file, excluding .py, that has custom element} import {name of custom element}`. + +```{.python filename=="app.py"} +from vetiver import VetiverModel +import vetiver +import pins +from model import FeatureSelector # add this line to import your custom feature engineering + + +b = pins.board_connect(allow_pickle_read=True) +v = VetiverModel.from_pin(b, 'selected_decision_tree') + +vetiver_api = vetiver.VetiverAPI(v) +api = vetiver_api.app +``` + +After editing the app.py file, you can deploy it to Posit Connect using the `rsconnect` package. Use the `rsconnect.api.actions.deploy_python_fastapi()` function to deploy the API, specifying the Connect server URL, API key, directory containing the `app.py` and `model.py` files, and the entry point of the API. + +```{.python} +from rsconnect.api.actions import deploy_python_fastapi +import rsconnect + +url = "example.connect.com" # your Posit Connect server url +api_key = os.environ(CONNECT_API_KEY) # your Posit Connect API key + +connect_server = rsconnect.api.RSConnectServer( + url = url + api_key = api_key +) + +rsconnect.actions.deploy_python_fastapi( + connect_server = connect_server, + directory = "./", # path to the directory containing the app.py and model.py files + entry_point = "app:api" # the API is the app.py file, in a variable named api + ) + +``` + +::: + +Please note that the above steps are a general guide, and you may need to adapt them to your specific use case and deployment environment. If you have any questions, please consider [opening an issue](https://github.com/rstudio/vetiver-python/issues/new). diff --git a/docs/custom_handler.md b/docs/custom_handler.md deleted file mode 100644 index 9009f403..00000000 --- a/docs/custom_handler.md +++ /dev/null @@ -1,46 +0,0 @@ -# Custom Handlers - -There are two different ways that vetiver supports flexible handling for models that do not work automatically with the vetiver framework. The first way is with new model types where there is no current implementation for the type of model you would like to deploy. The second way is when you would like to implement a current handler, but in a different way. In either case, you should create a custom handler from vetiver's `BaseHandler()`. At a minimum, you must give the type of your model via `model_type` how predictions should be made, via the method `handler_predict()`. Then, initialize your handler with your model, and pass the object into `VetiverModel`. - -This example shows a custom handler of `newmodeltype` type. - -```python -from vetiver.handlers.base import BaseHandler - -class CustomHandler(BaseHandler): - def __init__(self, model, ptype_data): - super().__init__(model, ptype_data) - - model_type = staticmethod(lambda: newmodeltype) - pip_name = "scikit-learn" # pkg name on pip, used for tracking pkg versions - - def handler_predict(self, input_data, check_ptype: bool): - """ - Generates method for /predict endpoint in VetiverAPI - - The `handler_predict` function executes at each API call. Use this - function for calling `predict()` and any other tasks that must be executed at each API call. - - Parameters - ---------- - input_data: - Test data - check_ptype: bool - Whether the ptype should be enforced - - Returns - ------- - prediction - Prediction from model - """ - # your code here - prediction = model.fancy_new_predict(input_data) - - return prediction - -new_model = CustomHandler(model, ptype_data) - -VetiverModel(new_model, "custom_model") -``` - -If your model is a common type, please consider [submitting a pull request](https://github.com/rstudio/vetiver-python/pulls). From ed1a2d88c24cec559fa5c5509796ca1dfa475067 Mon Sep 17 00:00:00 2001 From: isabelizimm Date: Fri, 13 Oct 2023 16:58:23 -0400 Subject: [PATCH 02/12] updating typos --- docs/custom_elements.qmd | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/custom_elements.qmd b/docs/custom_elements.qmd index 3c43c082..995d1c13 100644 --- a/docs/custom_elements.qmd +++ b/docs/custom_elements.qmd @@ -4,9 +4,9 @@ In some cases, you may need to create and deploy custom elements as part of your In these cases, extra steps will be required to successfully create and deploy a `VetiverModel` object. -# Making a custom model +# Making a custom model -Vetiver supports basic [scikit-learn](https://scikit-learn.org/), [torch](https://pytorch.org/), [statsmodels](https://www.statsmodels.org/stable/index.html), [xgboost](https://xgboost.readthedocs.io/en/stable/), and [spacy](https://spacy.io/) models. If you need to alter the usage of these models, or deploy a different type of model, you will likely need to create a custom model handler. +Vetiver supports basic [scikit-learn](https://scikit-learn.org/), [torch](https://pytorch.org/), [statsmodels](https://www.statsmodels.org/stable/index.html), [xgboost](https://xgboost.readthedocs.io/en/stable/), and [spacy](https://spacy.io/) models. If you need to alter the usage of these models, or deploy a different type of model, you will likely need to create a custom model handler. To create a custom model handler, you should create a subclass of Vetiver's BaseHandler class. This custom handler should include the following: @@ -53,7 +53,7 @@ To deploy custom elements, you need to include the necessary source code in your # Deploying custom elements -If your `VetiverModel` includes custom source code, you need to include that code in your deployment files to build an API in another location. To do so, +If your `VetiverModel` includes custom source code, you need to include that code in your deployment files to build an API in another location. To do so, ```{.python filename="model.py"} from sklearn.base import BaseEstimator, TransformerMixin @@ -64,10 +64,10 @@ from sklearn.pipeline import Pipeline class FeatureSelector(BaseEstimator, TransformerMixin): def __init__(self, columns): self.columns = columns - + def fit(self, X, y=None): return self - + def transform(self, X, y=None): return X[self.columns] @@ -151,7 +151,7 @@ To deploy custom elements to Posit Connect, you'll first start with the command vetiver.write_app(board, 'selected_decision_tree') ``` -This will generate an `app.py` file, where you'll need to add an import statement that is formatted `from {name of file, excluding .py, that has custom element} import {name of custom element}`. +This will generate an `app.py` file, where you'll need to add an import statement that is formatted `from {name of file, excluding .py, that has custom element} import {name of custom element}`. ```{.python filename=="app.py"} from vetiver import VetiverModel @@ -177,8 +177,8 @@ url = "example.connect.com" # your Posit Connect server url api_key = os.environ(CONNECT_API_KEY) # your Posit Connect API key connect_server = rsconnect.api.RSConnectServer( - url = url - api_key = api_key + url = url, + api_key = api_key ) rsconnect.actions.deploy_python_fastapi( @@ -191,4 +191,4 @@ rsconnect.actions.deploy_python_fastapi( ::: -Please note that the above steps are a general guide, and you may need to adapt them to your specific use case and deployment environment. If you have any questions, please consider [opening an issue](https://github.com/rstudio/vetiver-python/issues/new). +Please note that the above steps are a general guide, and you may need to adapt them to your specific use case and deployment environment. If you have any questions, please consider [opening an issue](https://github.com/rstudio/vetiver-python/issues/new). From 3fd9d9b8ed613c76ff0068fe605b4fec12c30a42 Mon Sep 17 00:00:00 2001 From: isabelizimm Date: Fri, 13 Oct 2023 17:14:23 -0400 Subject: [PATCH 03/12] pin plum-dispatch version --- .github/workflows/docs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index a8aeba83..d740f6e7 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -23,6 +23,7 @@ jobs: run: | python -m pip install --upgrade pip python -m pip install -e .[docs] + python -m pip install plum-dispatch==2.2.2 - name: Set up Quarto uses: quarto-dev/quarto-actions/setup@v2 - name: build docs From 6b2a78e3fa1ba465ea9bf6be9768c1d47b7ac1b0 Mon Sep 17 00:00:00 2001 From: isabelizimm Date: Fri, 13 Oct 2023 17:19:00 -0400 Subject: [PATCH 04/12] try to bump python version --- .github/workflows/docs.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index d740f6e7..e0c7e5b4 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -18,12 +18,11 @@ jobs: fetch-depth: 0 - uses: actions/setup-python@v4 with: - python-version: 3.9 + python-version: 3.10 - name: Install dependencies run: | python -m pip install --upgrade pip python -m pip install -e .[docs] - python -m pip install plum-dispatch==2.2.2 - name: Set up Quarto uses: quarto-dev/quarto-actions/setup@v2 - name: build docs From edbf6e3bf24ff7fb0a949b8130b6db10c2d66554 Mon Sep 17 00:00:00 2001 From: isabelizimm Date: Fri, 13 Oct 2023 17:24:19 -0400 Subject: [PATCH 05/12] add quotes --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index e0c7e5b4..192afd31 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -18,7 +18,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-python@v4 with: - python-version: 3.10 + python-version: '3.10' - name: Install dependencies run: | python -m pip install --upgrade pip From 4afdaecbff2af88bf105ebd6685b60e95f3c50b8 Mon Sep 17 00:00:00 2001 From: isabelizimm Date: Fri, 13 Oct 2023 17:33:29 -0400 Subject: [PATCH 06/12] griffe is not being installed --- .github/workflows/docs.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 192afd31..90fda593 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -18,11 +18,12 @@ jobs: fetch-depth: 0 - uses: actions/setup-python@v4 with: - python-version: '3.10' + python-version: 3.9 - name: Install dependencies run: | python -m pip install --upgrade pip python -m pip install -e .[docs] + python -m pip install griffe==0.32.3 - name: Set up Quarto uses: quarto-dev/quarto-actions/setup@v2 - name: build docs From b638845d59065924c46ee84cd694b3cf98464cb0 Mon Sep 17 00:00:00 2001 From: isabelizimm Date: Fri, 13 Oct 2023 17:37:16 -0400 Subject: [PATCH 07/12] rearrange site --- docs/_quarto.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_quarto.yml b/docs/_quarto.yml index c383012c..8d678431 100644 --- a/docs/_quarto.yml +++ b/docs/_quarto.yml @@ -24,7 +24,7 @@ website: file: reference/index.qmd - text: "Advanced Usage" menu: - - custom_handler.md + - custom_elements.qmd - text: "Changelog" file: changelog.md - text: "Learn more" From 9062ea30e2fa17fa135d85f0d86e2fea40cfc8ee Mon Sep 17 00:00:00 2001 From: Isabel Zimmerman <54685329+isabelizimm@users.noreply.github.com> Date: Thu, 19 Oct 2023 10:16:44 -0400 Subject: [PATCH 08/12] Update docs/custom_elements.qmd Co-authored-by: Sam Edwardes --- docs/custom_elements.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/custom_elements.qmd b/docs/custom_elements.qmd index 995d1c13..ad691039 100644 --- a/docs/custom_elements.qmd +++ b/docs/custom_elements.qmd @@ -100,7 +100,7 @@ vetiver.prepare_docker(board, "selected_decision_tree") When you run this line, 3 files are generated: a Dockerfile, an `app.py` file, and a `vetiver_requirements.txt`. In the `app.py` file, you'll need to add an import statement that is formatted `from {name of file, excluding .py, that has custom element} import {name of custom element}`. -```{.python filename=="app.py"} +```{.python filename="app.py"} from vetiver import VetiverModel import vetiver import pins From 666094a9a0ff1d0905a9a7eee8e74ea7e1839a0b Mon Sep 17 00:00:00 2001 From: isabelizimm Date: Fri, 27 Oct 2023 12:29:04 -0400 Subject: [PATCH 09/12] describe all elements as custom code --- docs/{custom_elements.qmd => custom_code.qmd} | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) rename docs/{custom_elements.qmd => custom_code.qmd} (77%) diff --git a/docs/custom_elements.qmd b/docs/custom_code.qmd similarity index 77% rename from docs/custom_elements.qmd rename to docs/custom_code.qmd index ad691039..14a2cf28 100644 --- a/docs/custom_elements.qmd +++ b/docs/custom_code.qmd @@ -1,19 +1,26 @@ -# Creating and deploying custom elements +# Creating and deploying custom code -In some cases, you may need to create and deploy custom elements as part of your MLOps workflow using Vetiver. This could be necessary when there is no existing implementation for the type of model you want to deploy, or when you want to implement a current handler in a different way. You may also have a custom element in a known framework, such as a custom column transformer for a scikit-learn model. +In some cases, you may need to create and deploy custom code as part of your MLOps workflow using vetiver. This could be necessary when you need to: + +- deploy custom models in vetiver +- deploy unsupported models in vetiver +- include custom code in vetiver +- deploy a vetiver model with a custom pipeline + + You may also have custom code in a known framework, such as a column transformer for a scikit-learn model. In these cases, extra steps will be required to successfully create and deploy a `VetiverModel` object. # Making a custom model -Vetiver supports basic [scikit-learn](https://scikit-learn.org/), [torch](https://pytorch.org/), [statsmodels](https://www.statsmodels.org/stable/index.html), [xgboost](https://xgboost.readthedocs.io/en/stable/), and [spacy](https://spacy.io/) models. If you need to alter the usage of these models, or deploy a different type of model, you will likely need to create a custom model handler. +Vetiver supports basic [scikit-learn](https://scikit-learn.org/), [torch](https://pytorch.org/), [statsmodels](https://www.statsmodels.org/stable/index.html), [xgboost](https://xgboost.readthedocs.io/en/stable/), and [spacy](https://spacy.io/) models. If you need to alter the usage of these models, or deploy a different type of model, you will likely need to create a new model handler. -To create a custom model handler, you should create a subclass of Vetiver's BaseHandler class. This custom handler should include the following: +To create a model handler, you should create a subclass of vetiver's `BaseHandler` class. This handler should include the following: - `model_type`: A static method that declares the type of your model. - `handler_predict()`: A method that defines how predictions should be made for your model. This method is used at the /predict endpoint in the VetiverAPI. -Here's an example of a custom handler for a model of `newmodeltype` type. +Here's an example of a handler for a model of `newmodeltype` type. Once you have defined your handler, you can initialize it with your model and pass it to the `VetiverModel` class. ```python from vetiver.handlers.base import BaseHandler @@ -45,15 +52,13 @@ new_model = CustomHandler(model, ptype_data) VetiverModel(new_model, "custom_model") ``` -Once you have defined your custom handler, you can initialize it with your model and pass it to the VetiverModel class. - If your model is a common type, please consider [submitting a pull request](https://github.com/rstudio/vetiver-python/pulls). -To deploy custom elements, you need to include the necessary source code in your deployment files. If your model or other elements can be imported from a Python package, you can include the relevant packages in a `requirements.txt` file for deployment. However, if you have custom source code in local files, you will need to include those files in the deployment process. +To deploy custom code, you need to include the necessary source code in your deployment files. If your model or other elements can be imported from a Python package, you can include the relevant packages in a `requirements.txt` file for deployment. However, if you have custom source code in local files, you will need to include those files in the deployment process. # Deploying custom elements -If your `VetiverModel` includes custom source code, you need to include that code in your deployment files to build an API in another location. To do so, +If your `VetiverModel` includes custom source code, you need to include that code in your deployment files to build an API in another location. The example below shows a user-created `FeatureSelector`, which is part of a scikit-learn pipeline. ```{.python filename="model.py"} from sklearn.base import BaseEstimator, TransformerMixin @@ -145,7 +150,7 @@ CMD ["uvicorn", "app.app:api", "--host", "0.0.0.0", "--port", "8080"] ## Posit Connect -To deploy custom elements to Posit Connect, you'll first start with the command `vetiver.write_app`. +To deploy custom code to Posit Connect, you'll first start with the command `vetiver.write_app`. ```{.python} vetiver.write_app(board, 'selected_decision_tree') @@ -167,7 +172,7 @@ vetiver_api = vetiver.VetiverAPI(v) api = vetiver_api.app ``` -After editing the app.py file, you can deploy it to Posit Connect using the `rsconnect` package. Use the `rsconnect.api.actions.deploy_python_fastapi()` function to deploy the API, specifying the Connect server URL, API key, directory containing the `app.py` and `model.py` files, and the entry point of the API. +After editing the `app.py` file, you can deploy it to Posit Connect using the `rsconnect` package. Use the `rsconnect.api.actions.deploy_python_fastapi()` function to deploy the API, specifying the Connect server URL, API key, directory containing the `app.py` and `model.py` files, and the entry point of the API. ```{.python} from rsconnect.api.actions import deploy_python_fastapi From 225788b5dc8f83d7c1c7197648bf9642d6271b25 Mon Sep 17 00:00:00 2001 From: isabelizimm Date: Fri, 27 Oct 2023 12:39:39 -0400 Subject: [PATCH 10/12] ptype->prototype --- docs/custom_code.qmd | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/custom_code.qmd b/docs/custom_code.qmd index 14a2cf28..d6b9ebc0 100644 --- a/docs/custom_code.qmd +++ b/docs/custom_code.qmd @@ -1,6 +1,6 @@ # Creating and deploying custom code -In some cases, you may need to create and deploy custom code as part of your MLOps workflow using vetiver. This could be necessary when you need to: +In some cases, you may need to create and deploy custom code as part of your MLOps workflow using vetiver. This could be necessary when you need to: - deploy custom models in vetiver - deploy unsupported models in vetiver @@ -26,8 +26,8 @@ Here's an example of a handler for a model of `newmodeltype` type. Once you have from vetiver.handlers.base import BaseHandler class CustomHandler(BaseHandler): - def __init__(self, model, ptype_data): - super().__init__(model, ptype_data) + def __init__(self, model, prototype_data): + super().__init__(model, prototype_data) model_type = staticmethod(lambda: newmodeltype) pip_name = "scikit-learn" # package's installation name on pip @@ -47,7 +47,7 @@ class CustomHandler(BaseHandler): return prediction -new_model = CustomHandler(model, ptype_data) +new_model = CustomHandler(model, prototype_data) VetiverModel(new_model, "custom_model") ``` From 5c94351323fccd7df1a4f57c8461213fbf916662 Mon Sep 17 00:00:00 2001 From: isabelizimm Date: Fri, 27 Oct 2023 14:25:18 -0400 Subject: [PATCH 11/12] formatting docstring for VetiverAPI --- vetiver/server.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vetiver/server.py b/vetiver/server.py index cf7d24ba..ac0fe028 100644 --- a/vetiver/server.py +++ b/vetiver/server.py @@ -49,8 +49,11 @@ class VetiverAPI: This generates an API with either 2 or 3 GET endpoints and 1 POST endpoint. ├──/ping (GET) + ├──/metadata (GET) + ├──/pin-url (GET, if VetiverModel metadata `url` field is not None) + └──/predict (POST) Parameter `check_ptype` was changed to `check_prototype`. Handling of `check_ptype` From 0a1c1c329fe16e28e95659d3321efc7656249a84 Mon Sep 17 00:00:00 2001 From: isabelizimm Date: Fri, 27 Oct 2023 14:30:15 -0400 Subject: [PATCH 12/12] add triple backticks --- vetiver/server.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vetiver/server.py b/vetiver/server.py index ac0fe028..9260efc9 100644 --- a/vetiver/server.py +++ b/vetiver/server.py @@ -46,15 +46,15 @@ class VetiverAPI: Notes ----- - This generates an API with either 2 or 3 GET endpoints and 1 POST endpoint. + This generates an API with either 3 or 4 GET endpoints and 1 POST endpoint. + ``` ├──/ping (GET) - ├──/metadata (GET) - + ├──/prototype (GET) ├──/pin-url (GET, if VetiverModel metadata `url` field is not None) - └──/predict (POST) + ``` Parameter `check_ptype` was changed to `check_prototype`. Handling of `check_ptype` will be removed in a future version.