Build a GPS Routing API with Python Flask

Create a free Distance Matrix API using Flask with a Selenium Bot deployed on Heroku

Build a GPS Routing API with Python Flask
Photo by Samantha Gollnick / Unsplash

Create a free Distance Matrix API using Flask with a Selenium Bot deployed on Heroku

My first project using GPS routing was 4 years ago. I wanted to optimize a transport plan for 1,200 trucks deliveries/month covering 50 stores from a Cross-Docking platform.

I have built a Transportation Route Optimization tool using Excel-VBA — mainly for transport plan design using distance collected from Google Maps API.

This was my first experience using an API; Google Maps API was free with a limit of 10,000 requests per day.

What about now?

A few years later, Google changed its billing policy so you have to pay from the first request.

If you have never subscribed to the Google Cloud Platform (GCP) service you can have 200$ free credits after setting up a credit card.

But, what if

  • you need to get several thousand distances?
  • you don’t care if it takes a long time?
  • you don’t feel confident about using your personal card (or cannot get a company credit card) for non-personal projects?

This article will show you a solution built with a Flask API using a selenium bot connected to Google Map WebPage.

🔗
You can find the full code uploaded in this repository: Github

How does it work?

Before starting to read this part, please forget everything you know about how to put in production a fast, efficient and stable code ensuring quick response with limited resources.

This will be simple, quick and dirty, with no intention to be a scalable solution. The performance will be way lower than if you directly query the official Google API — but here it’s free :)

Build a GPS Routing API with Python Flask
Full Process to get the distance between two cities in your Google Sheet — (Image by Author)

Build your API

Let us do it in three steps

  1. Build a Selenium Bot that will query the distance from City A to City B on the Google Maps Website
  2. Set up your Flask API that will receive the request and return a distance
  3. Deploy your code on Heroku
🔗
You can find the full code in this Github repository: Link

Set up your Selenium Bot

  • Set ChromeDriver options to ensure the highest speed of execution
  • Input Environment Variables that will be created in your Heroku instance

Write your distance scrapper

Google Maps link to get the distance from "Paris, France" to "Marseille, France

"https://www.google.fr/maps/dir/Paris,France/Marseille, France/data=!4m2!4m1!3e0"/data=!4m2!4m1!3e0" is added to ensure that you take the road transportation distance

Set up your Flask API

Your API link to get the distance from "Paris, France" to "Marseille, France"
http://xxx-xxx.herokuapp.com/distance/Paris,France/Marseille,France
(replace xxx-xxx by your Heroku app name)

<fr> = Paris,France
<to> = Marseille, France

Deploy your API

I will skip details on how to create and deploy an app on Heroku. You can find links to Medium articles explaining detailed steps to create your Heroku instance at the end of the article.

Prepare files for deployment on Heroku

Prepare requirements.txt file with a listing of libraries needed with pip freeze

(env) C:\Users\yourprojectfolder> pip freeze > requirements.txt

Create ProcFile to launch your web app

(env) C:\Users\yourprojectfolder> echo web: gunicorn -t 120 -b :$PORT app:app > Procfile

P.S: Please make sure that your app name is "app" and your python script is named "app.py"

Download Buildpacks on Heroku to use Selenium + ChromeDriver

Go to settings > Add Buildpack

Buildpacks menu in your Heroku App Settings — (Image by Author)

Enter Two Links

Set up Environment Variables

Config Vars menu in your Heroku App Settings — (Image by Author)
CHROMEDRIVER_PATH: /app/.chromedriver/bin/chromedriver
GOOGLE_CHROME_BIN: /app/.apt/usr/bin/google-chrome

Test your API


Test your API to calculate the distance

From: Paris, France
To: Marseille, France

Request link
http://xxx-xxx.herokuapp.com/distance/Paris,France/Marseille,France
(replace xxx-xxx with your Heroku app name)

Response
{“distance”:”775 km”}

Your API response for the query of distance from Paris to Marseille — (Image by Author)

What can we get in Google Maps?

Distance from Paris (France) to Marseille (France): 775 km — (Image by Author)

It’s matching :)

Conclusion and next steps

I deployed this solution on a free Heroku instance and tested it using a Google Sheet querying my API to get 40 road distances.

Google Sheet using my newly created geolocation API to get the distance between cities — (Image by Author)

Next Step 1: Find a way to ensure that your sheets send queries once at a time

If you not, you can quickly exceed your memory quota

Heroku logs — (Image by Author)

Step 2: Errors management and extracting all distances

Distance and route time from Paris (France) to Bordeaux (France) — (Image by Author)

You can see in the example above, that the first result showed is the shortest travel time and may not be the shortest distance.

Route time can change if you query at a different time of the day, so you’d better take the three distances.

References

Many details were skipped in this article to make it concise and easy to read. You can find detailed instructions in the excellent articles listed below.

[1] Michael Browne, Running ChromeDriver with Python Selenium on Heroku (2019), Link

[2] Moses Gitau, Deploying a Flask application on Heroku (2018), Link