Build a GPS Routing API with Python Flask
Create a free Distance Matrix API using Flask with a Selenium Bot deployed on Heroku
Create a free Distance Matrix API using Flask with a Selenium Bot deployed on Heroku
Article originally published on Medium.
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.
💌 New articles straight in your inbox for free: Newsletter
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.
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 your API
Let us do it in three steps
- Build a Selenium Bot that will query the distance from City A to City B on the Google Maps Website
- Set up your Flask API that will receive the request and return a distance
- Deploy your code on Heroku
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
"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
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
Create ProcFile to launch your web app
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
Enter Two Links
- https://github.com/heroku/heroku-buildpack-google-chrome
- https://github.com/heroku/heroku-buildpack-chromedriver
Set up Environment Variables
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”}
What can we get in Google Maps?
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.
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
Step 2: Errors management and extracting all distances
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.
About Me
Let’s connect on Linkedin and Twitter, I am a Supply Chain Engineer that is using data analytics to improve logistics operations and reduce costs.
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