MITB Banner

How To Run A Development Server For Flask Web Applications Using Google Colab

Share
Development Server

A lot of people know how to build ML models, but surprisingly few are comfortable with the deployment process. Deploying models is a necessary skill in the industry, and the first step of deployment is running our ML models on the web during development for demos and testing. This can be done using a simple development server before deployment. A development server can be built with just a few lines of code using a framework like Flask. In this article, we will explore a very simple development server which will enable us to render the output predictions of our image classifier model (written using PyTorch) on a public webpage. This entire code can be run on Google Colab, without installing anything on our local machine. 

Google Colab provides a virtual machine environment, so unlike when running Flask on our local machine, we cannot access localhost. Hence, we need to expose it to a public URL using the library flask-ngrok, which generates a temporary URL where the web app runs.

First, let’s create two folders called images and references in the current project directory, where we will store images (to be classified by our classifier) and a dictionary mapping class indices to human-understandable class names.

 import os
 PROJECT_ROOT_DIR = "."
 IMAGES_PATH = os.path.join(PROJECT_ROOT_DIR, 'images')
 os.makedirs(IMAGES_PATH, exist_ok=True)
 REFERENCE_FILES_PATH = os.path.join(PROJECT_ROOT_DIR, 'references')
 os.makedirs(REFERENCE_FILES_PATH, exist_ok=True) 

Next, let’s install ngrok, which will help us with the temporary url generation.

!pip install flask-ngrok

After installing Flask, let’s create a web app, called app. When we call run_with_ngrok(), ngrok will start when app is run, creating the temporary URL. 

app = Flask(__name__)
run_with_ngrok(app)

Now, let’s upload the {class index: [class ID, class name]} dictionary into the references folder we created. The link for the document is available here:

imagenet_class_index = json.load(open(os.path.join(REFERENCE_FILES_PATH,
'imagenet_class_index.json')))

Next, let’s use PyTorch’s torchvision package to create a classifier from one of its pre-trained models (densenet121). Then, we define a pipeline that takes in an image in bytes and resizes it, centre crops it, converts it to a tensor, and then normalizes the result, to be fed into the model. Note that we should load the model only once, before serving requests,  so that it is not unnecessarily loaded multiple times which would be a waste of computational power. This is very important in production systems.

 model = models.densenet121(pretrained=True)
 model.eval()
 def transform_image(image_bytes):
    my_transforms = transforms.Compose([transforms.Resize(255),
                                        transforms.CenterCrop(224),
                                        transforms.ToTensor(),
                                        transforms.Normalize(
                                            [0.485, 0.456, 0.406],
                                            [0.229, 0.224, 0.225])])
    image = Image.open(io.BytesIO(image_bytes))
    return my_transforms(image).unsqueeze(0) 

We can test transform_image by running it on a test image; the output should be a tensor. A tensor is like a matrix of N dimensions: all neural networks expect inputs to be tensors.

 with open(os.path.join(IMAGES_PATH, 'test_pic.jpg'), 'rb') as f:
    image_in_bytes = f.read()
    tensor = transform_image(image_bytes=image_in_bytes)
    print(tensor) 

Next, let’s define the get_prediction method which takes in the image in bytes, transforms it to a tensor using the pipeline defined in the previous function, and then performs forward propagation using the model and returns the predicted class name. The model outputs the integer class index (0,1,2…) which has to be converted to the string key to get the corresponding string class index and name from imagenet_class_index.

 def get_prediction(image_bytes):
    tensor = transform_image(image_bytes=image_bytes)
    outputs = model.forward(tensor)
    _, y_hat = outputs.max(1)
    predicted_idx = str(y_hat.item())
    return imagenet_class_index[predicted_idx] 

We can test the above function by calling it with our test image. The image should return a class index and name as shown below.

 with open(os.path.join(IMAGES_PATH, 'test_pic.jpg'), 'rb') as f:
  image_in_bytes = f.read()
  print(get_prediction(image_bytes=image_in_bytes)) 

The test_pic used was a girl in a skirt, so the model is quite right! Next, let’s define web app functions. We’ll define the home/root web page at index (‘/’) and another page (‘/predict’) where the JSON output should be rendered.

 @app.route("/")
 def root():
    return 'Root of Flask WebApp!'
 @app.route('/predict')
 def predict():
    file_doc = open(os.path.join(IMAGES_PATH, 'wolf.jpg'),'rb')
    img_bytes = file_doc.read()
    class_id, class_name = get_prediction(image_bytes=img_bytes)
    return jsonify({'class_id': class_id, 'class_name': class_name}) 

Hence, the home page should say ‘Root of Flask WebApp!’ and the /predict page should give us our model’s output for the input image, in this case, a wolf. Let’s run the web app with the following command:

app.run()

This means ngrok is exposing our web app onto the temporary URL http://be8dd2d747fc.ngrok.io (it is different every time it is run). If we go to this URL we get our home page:

And if we go to the ‘/predict’ domain, we get our model’s prediction.

The model is right, and its JSON output is successfully being rendered on a public webpage! That’s it, we have now successfully built a development server and deployed our model on the web. This is a great way to give a demo of our web app before deploying it into production. Nowadays more and more people are using Google Colab because of its low overhead and easy access to GPUs, and now you too know how to create and test ML web apps on Google Colab from scratch!

For the complete running code, please refer to this link.

PS: The story was written using a keyboard.
Picture of Divya Sundaresan

Divya Sundaresan

BTech CSE graduate and aspiring Master’s student in ML, here to demonstrate and decode the latest advancements in Deep Learning.
Related Posts

Download our Mobile App

CORPORATE TRAINING PROGRAMS ON GENERATIVE AI

Generative AI Skilling for Enterprises

Our customized corporate training program on Generative AI provides a unique opportunity to empower, retain, and advance your talent.

3 Ways to Join our Community

Telegram group

Discover special offers, top stories, upcoming events, and more.

Discord Server

Stay Connected with a larger ecosystem of data science and ML Professionals

Subscribe to our Daily newsletter

Get our daily awesome stories & videos in your inbox
Recent Stories

Featured

Subscribe to The Belamy: Our Weekly Newsletter

Biggest AI stories, delivered to your inbox every week.

AI Courses & Careers

Become a Certified Generative AI Engineer

AI Forum for India

Our Discord Community for AI Ecosystem, In collaboration with NVIDIA. 

AIM Conference Calendar

Immerse yourself in AI and business conferences tailored to your role, designed to elevate your performance and empower you to accomplish your organization’s vital objectives. Revel in intimate events that encapsulate the heart and soul of the AI Industry.

Flagship Events

Rising 2024 | DE&I in Tech Summit

April 4 and 5, 2024 | 📍 Hilton Convention Center, Manyata Tech Park, Bangalore

MachineCon GCC Summit 2024

June 28 2024 | 📍Bangalore, India

MachineCon USA 2024

26 July 2024 | 583 Park Avenue, New York

Cypher India 2024

September 25-27, 2024 | 📍Bangalore, India

Cypher USA 2024

Nov 21-22 2024 | 📍Santa Clara Convention Center, California, USA

Data Engineering Summit 2024

May 30 and 31, 2024 | 📍 Bangalore, India

Download the easiest way to
stay informed