{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# R Serving with FastAPI" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "This notebook's CI test result for us-west-2 is as follows. CI test results in other regions can be found at the end of the notebook. \n", "\n", "![This us-west-2 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/us-west-2/r_examples|r_serving_with_fastapi|FastAPI_Example.ipynb)\n", "\n", "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Dockerfile" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* The dockerfile defines the environment in which our server will be executed. \n", "* Below, you can see that the entrypoint for our container will be [deploy.R](deploy.R)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%pycat Dockerfile" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Code: deploy.R\n", "\n", "**deploy.R** handles the following steps\n", "* Loads the R libraries used by the server.\n", "* Loads a pretrained `xgboost` model that has been trained on the classical [Iris](https://archive.ics.uci.edu/ml/datasets/iris) dataset.\n", " * Dua, D. and Graff, C. (2019). UCI Machine Learning Repository [http://archive.ics.uci.edu/ml]. Irvine, CA: University of California, School of Information and Computer Science.\n", "* Defines an inference function that takes a matrix of iris features and returns predictions for those iris examples.\n", "* Wraps the inference function to make it thread-safe for passing to python through reticulate.\n", "* Finally, it generates the [endpoints.py](endpoints.py) from python and launches the FastAPI server app using those endpoint definitions." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%pycat deploy.R" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Code: endpoints.py" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**endpoints.py** defines two routes:\n", "* `/ping` returns a status of 'Alive' to indicate that the application is healthy\n", "* `/invocations` applies the previously defined inference function to the input features from the request body\n", "\n", "Note, that FastAPI is typed. The `Example` class define the type of the input that we expect to receive from the request.\n", "\n", "For more information about the requirements for building your own inference container, see:\n", "[Use Your Own Inference Code with Hosting Services](https://docs.aws.amazon.com/sagemaker/latest/dg/your-algorithms-inference-code.html)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%pycat endpoints.py" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Build the Serving Image" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "!docker build -t r-fastapi ." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Launch the Serving Container" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "!echo \"Launching FastAPI\"\n", "!docker run -d --rm -p 5000:8080 r-fastapi\n", "!echo \"Waiting for the server to start..\" && sleep 10" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "!docker container list" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Define Simple Python Client" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import requests\n", "from tqdm import tqdm\n", "import pandas as pd\n", "\n", "pd.set_option(\"display.max_rows\", 500)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def get_predictions(examples, instance=requests, port=5000):\n", " payload = {\"features\": examples}\n", " return instance.post(f\"http://127.0.0.1:{port}/invocations\", json=payload)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def get_health(instance=requests, port=5000):\n", " instance.get(f\"http://127.0.0.1:{port}/ping\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Define Example Inputs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We define example inputs from the Iris dataset." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "column_names = [\"Sepal.Length\", \"Sepal.Width\", \"Petal.Length\", \"Petal.Width\", \"Label\"]\n", "iris = pd.read_csv(\n", " \"s3://sagemaker-sample-files/datasets/tabular/iris/iris.data\", names=column_names\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "iris_features = iris[[\"Sepal.Length\", \"Sepal.Width\", \"Petal.Length\", \"Petal.Width\"]]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "example_inputs = iris_features.values.tolist()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Plumber" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "predicted = get_predictions(example_inputs).json()[\"output\"]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "iris[\"predicted\"] = predicted" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "iris" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Stop All Serving Containers" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, we will shut down the serving container we launched for the test." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "!docker kill $(docker ps -q)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Notebook CI Test Results\n", "\n", "This notebook was tested in multiple regions. The test results are as follows, except for us-west-2 which is shown at the top of the notebook.\n", "\n", "![This us-east-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/us-east-1/r_examples|r_serving_with_fastapi|FastAPI_Example.ipynb)\n", "\n", "![This us-east-2 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/us-east-2/r_examples|r_serving_with_fastapi|FastAPI_Example.ipynb)\n", "\n", "![This us-west-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/us-west-1/r_examples|r_serving_with_fastapi|FastAPI_Example.ipynb)\n", "\n", "![This ca-central-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/ca-central-1/r_examples|r_serving_with_fastapi|FastAPI_Example.ipynb)\n", "\n", "![This sa-east-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/sa-east-1/r_examples|r_serving_with_fastapi|FastAPI_Example.ipynb)\n", "\n", "![This eu-west-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/eu-west-1/r_examples|r_serving_with_fastapi|FastAPI_Example.ipynb)\n", "\n", "![This eu-west-2 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/eu-west-2/r_examples|r_serving_with_fastapi|FastAPI_Example.ipynb)\n", "\n", "![This eu-west-3 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/eu-west-3/r_examples|r_serving_with_fastapi|FastAPI_Example.ipynb)\n", "\n", "![This eu-central-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/eu-central-1/r_examples|r_serving_with_fastapi|FastAPI_Example.ipynb)\n", "\n", "![This eu-north-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/eu-north-1/r_examples|r_serving_with_fastapi|FastAPI_Example.ipynb)\n", "\n", "![This ap-southeast-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/ap-southeast-1/r_examples|r_serving_with_fastapi|FastAPI_Example.ipynb)\n", "\n", "![This ap-southeast-2 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/ap-southeast-2/r_examples|r_serving_with_fastapi|FastAPI_Example.ipynb)\n", "\n", "![This ap-northeast-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/ap-northeast-1/r_examples|r_serving_with_fastapi|FastAPI_Example.ipynb)\n", "\n", "![This ap-northeast-2 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/ap-northeast-2/r_examples|r_serving_with_fastapi|FastAPI_Example.ipynb)\n", "\n", "![This ap-south-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/ap-south-1/r_examples|r_serving_with_fastapi|FastAPI_Example.ipynb)\n" ] } ], "metadata": { "kernelspec": { "display_name": "conda_python3", "language": "python", "name": "conda_python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.13" } }, "nbformat": 4, "nbformat_minor": 4 }