Deploy a Machine Learning Model as a Web App with Anvil and Deepnote
Tags: machinelearning, python, datascience, webdev
Published: 2020-11-06 17:25:34

> _Prefer watching to reading? This tutorial is also on YouTube:_
> {% youtube 0ppptVxgEI8 %}


# Deploying Data Science with nothing but Python

[Deepnote](https://deepnote.com) is a seriously slick Python notebook, hosted in the cloud, with incredible real-time collaboration. It's great for working with other data scientists. But what happens when you want to share your project with non-programmers? They need an easy-to-use interface -- so you need to **deploy what you've built**.

[Anvil](https://anvil.works) lets you build full-featured web apps entirely in Python (no HTML or JS required) -- and you can connect it to external notebooks.

Follow along as we use Deepnote and Anvil to deploy a machine learning model as a web app -- a web app anyone can use!

![The app we're going to build](https://anvil.works/learn/tutorials/img/deepnote-to-web-app/deepnote-demo-app.gif)
_We're going to build this app -- and it's going to be easy!_


---

## Step 0 - Get the notebook

In this example, we're going to start with an image classifier that can tell the difference between cats and dogs. Believe it or not, getting this notebook running in the cloud is the easy part! Just open the notebook in Deepnote and click **Duplicate**:

### [**Open the notebook >>**](https://deepnote.com/project/b3979913-ea08-4cd2-92fb-0b9345492bf1)

![Deepnote screenshot](https://anvil.works/learn/tutorials/img/deepnote-to-web-app/deepnote-clone.png)
_Click “Duplicate” to make a copy of this notebook in your own (free) Deepnote account._


All right, we have a notebook. **Let's deploy it as a web app!**

---

## Step 1 - Create your Anvil app

Creating web apps with Anvil is simple. No need to wrestle with HTML, CSS, JavaScript or PHP -- we can do everything in Python.

[Log in](https://anvil.works/login) to Anvil and click 'New Blank App'. Choose the Material Design theme.

![Location of the Create App button](https://anvil.works/learn/tutorials/img/feedback-form/create-app.png)

First, name the app. Click on the name at the top of the screen and give it a name:

![Rename your app by clicking on the title](https://anvil.works/learn/tutorials/img/rename-app.png)
---

## Step 2 - Add your components

We construct the UI by dragging-and-dropping [components](https://anvil.works/docs/client/components) from the [Toolbox](https://anvil.works/docs/editor#toolbox). Drop a **Card** and a **FileLoader**. The FileLoader will let users upload the image they want classified. 

Next, add an **Image** component, which will display the input image, and a **Label** to display the returned classification.

![Anvil Drag and Drop demo](https://anvil.works/learn/tutorials/img/deepnote-to-web-app/drag-drop-images-classifier.gif)

Select the `Label` we just added and, in the components properties, change the name to 'results_lbl'. Then add a spacer component above the label to centre the label against the image.

Now we have a user interface, let's connect our app to the code in our Jupyter notebook.

---

## Step 3 - Enable the Uplink

From the IDE, let's enable the Uplink. Open the Gear menu in the top left of the IDE, then select `Uplink` and then `Enable the Anvil Server Uplink`.

![Enable the Uplink via the gear at the top of the left panel](https://anvil.works/learn/tutorials/img/deepnote-to-web-app/uplink-activation.gif)

This will then give us an Uplink key we can use in our Deepnote notebook. 

Now let's install the Uplink in our Deepnote environment, and connect our script using the key we just created.

---

## Step 4 - Install the Uplink Library in our Deepnote notebook

It's time to connect our notebook to Anvil!

The first thing we need to do is install the `anvil-uplink` library. Let's add `!pip install anvil-uplink` to our notebook:

```bash
!pip install anvil-uplink
```

The `!` operator tells our notebook that this line is a command line script and not Python code.

---

## Step 5 - Connecting our Script

Now that the Uplink library will be installed when we start our notebook, we can connect our notebook in the same way as any other Uplink script.

Start by importing the `anvil.server` module:
```python
import anvil.server
```

Then connect to the Uplink:
```python
anvil.server.connect("your-uplink-key")
```


Replace "your-uplink-key" with the Uplink key from your app. 

Run the cell. You should see output like this:

```
Connecting to wss://anvil.works/uplink
Anvil websocket open
Authenticated OK
```

That's it! When we run our notebook, it will now connect to our web app via the Uplink. Next, let's create a function we can call from our Anvil app.

---

## Step 6 - Creating a callable function

In a new cell, let's define a function we can call from our app to classify an image. We'll call it `classify_image`, and decorate it with `@anvil.server.callable` so we can call it from the web.

The image will be passed to our `classify_image` function as an Anvil [media object](https://anvil.works/docs/media). We'll write it to a temporary file and load it into it into [Pillow](https://pillow.readthedocs.io/en/stable/#). 

Our notebook already has a function, `get_prediction()`, for putting the Pillow image through the classifier. We'll call that function and return the results in two parts: the numerical score, and then the classification. We'll say anything scoring less than 0.5 is a 'dog', and anything else is a 'cat'.

Here is how our finished cell should look:
```python
import anvil.media

@anvil.server.callable
def classify_image(file):
  with anvil.media.TempFile(file) as f:
    img = load_img(f)
  
  score = get_prediction(img)

  return score, 'dog' if score < 0.5 else 'cat'
```

Our notebook is now ready to classify images! Let's go back into our Anvil app and call that `classify_image` function when someone uploads an image.

---

## Step 7 - Calling notebook functions from the web

In the design view of our Anvil app, double click the FileLoader component we added earlier. It will take us to the code view and add a function that runs whenever a file is uploaded. 

![Adding a FileLoader change event](https://anvil.works/learn/tutorials/img/deepnote-to-web-app/fileloader-event.gif)

In the function, type `anvil.server.callable()` and pass it the name of our notebook function `'classify_image'`. Then pass it the uploaded `file` as the argument to our notebook function. (Anvil will take care of transmitting the data.)

We can then create two variables, `score` and `cls`, and set them to the two values returned by `classify_image`:

![Calling the server](https://anvil.works/learn/tutorials/img/deepnote-to-web-app/fileloader_event__server_call.png)


---

## Step 8 - Displaying our classification

We've got the results -- it's time to show them on the screen!

Still in our `file_loader_1_change` function, let's display the classification as text on our Label, and display the uploaded image on the Image component.

We set the text of `results_lbl` to include both the classification and the score returned by our model:
```python
self.results_lbl.text = f"{cls} ({score:.1f})"
```

Then set the source of `image_1` to the uploaded file:
```python
self.image_1.source = file
```

The finished function will look like this:

```python
def file_loader_1_change(self, file, **event_args):
    """This method is called when a new file is loaded into this FileLoader"""
    score, classification = anvil.server.call('classify_image', file)
    
    self.result_lbl.text = f"{classification} ({score})"
    self.image_1.source = file
```

We now have an app that takes an image, sends it to our Deepnote notebook, classifies it and returns the results to our app. It's all in the cloud, and all in Python!

All we need to do now is deploy our app to the internet for everyone to use.

---

## Step 9 - Publishing our app

From the IDE, open the Gear menu in the top left of the IDE, then select `Publish app` and then `Share via public link`. Choose a URL and click "Apply":

![Publish your app](https://anvil.works/learn/tutorials/img/deepnote-to-web-app/publish-app.gif)

That's it -- we've deployed a machine learning model as a web app, with Deepnote hosting the notebook and Anvil hosting the web app. Best of all, we didn't need anything but Python!

---

## Clone the App

You can open the source code for the finished Anvil app here:

### [**Clone the finished Anvil app >>**](https://anvil.works/build#clone:WCPMOPRJTTTBW2AQ=X3D2ITSI5ZXBHSHDL3VYR6KY)

And you can duplicate our Deepnote notebook from the link below:

### [**Open the finished notebook >>**](https://deepnote.com/project/b3979913-ea08-4cd2-92fb-0b9345492bf1)

---

## New to Anvil?

If you haven't seen it before, [Anvil](https://anvil.works/) makes web development accessible: Build fully featured webs apps painlessly, without JavaScript, HTML or CSS - **just Python**.

The runtime platform is open source, and the online IDE is free, so you can try it out at https://anvil.works.