Using Python and Twilio Messaging to find out if the Suez Canal is still blocked

March 25, 2021
Written by
Sam Agnew
Twilion

Copy of Generic Blog Header 1(4).png

Recently a 200,000 ton container ship named the Ever Given has become stuck in the Suez Canal, halting one of the world's busiest waterways and disrupting global supply chains. And it looks like it might take weeks to move it. Luckily for those on the edge of their seats, with the Marine Traffic API we can access the location of marine vessels programmatically.

My coworker Kelley Robinson used this to create a Twilio phone number that you can text to see if the Ever Given is still stuck. Try it out by texting +1 (586) 800-BOAT, which is +1 (586) 800-2628, to get the status of the situation.

Boat still stuck? Text message

Let's walk through how you could build your own version of this, using Twilio Programmable Messaging, Flask, and the Marine Traffic API.

Setting up your environment

Make sure to have your Python environment set up before we get started. Getting everything working correctly, especially with respect to virtual environments is important for isolating your dependencies if you have multiple projects running on the same machine.

You can also run through this guide to make sure you’re good to go before moving on.

Installing dependencies

Now that your environment is set up, you’re going to need to install some third party libraries. We’re going to use:

Navigate to the directory where you want this code to live and run the following command in your terminal with your virtual environment activated to install these dependencies:

pip install Marine-Traffic-API==0.20.1 Flask==1.1.2 twilio==6.55.0

Retrieving data from the Marine Traffic API

First you need to sign up for an API key here. Sign up for an account and fill out the form with your information.

Signing up for the Marine Traffic API

Now that you have an account, head to where you can sign up for API services for vessel information and click to get an API key.

 

Get an API Key

Now set your API key set to an environment variable named MARINE_TRAFFIC_API_KEY, and run the following code in a Python shell to get the location and speed of the Ever Given:

import os
from marinetrafficapi import MarineTrafficApi

api_key = os.environ['MARINE_TRAFFIC_API_KEY']
api = MarineTrafficApi(api_key=api_key)

vessel = api.single_vessel_positions(time_span=240, mmsi=353136000)

vessel = vessel.models[0]

latitude = vessel.latitude.value
longitude = vessel.longitude.value
speed = vessel.speed.value

print(latitude, longitude, speed)

Now we can move on to putting this behind a phone number for users to text for updates.

Setting up your Twilio account

Before being able to respond to messages, you’ll need a Twilio phone number. You can buy a phone number here.

Your Flask app will need to be visible from the Internet in order for Twilio to send requests to it. We will use ngrok for this, which you’ll need to install if you don’t have it. In your terminal run the following command:

ngrok http 5000

ngrok terminal screen

This provides us with a publicly accessible URL to the Flask app. Configure your phone number as seen in this image so that when a text message is received, Twilio will send a POST request to the /sms route on the app we are going to build, which will sit behind your Ngrok URL:

Configuring your Twilio number

It's time to actually build the app.

Building the Flask app

Now that you have a Twilio number and are able to grab the data you need from the Marine Traffic API, you want to allow users to text a phone number to view this data.

Let’s create our Flask app. Create a file called app.py and add the following code to it:

import os

from flask import Flask
from marinetrafficapi import MarineTrafficApi
from twilio.twiml.messaging_response import MessagingResponse

api_key = os.environ['MARINE_TRAFFIC_API_KEY']
api = MarineTrafficApi(api_key=api_key)

app = Flask(__name__)

@app.route('/sms', methods=["GET","POST"])
def boat():
    resp = MessagingResponse()

    vessel = api.single_vessel_positions(time_span=240, mmsi=353136000)
    vessel = vessel.models[0]

    latitude = vessel.latitude.value
    longitude = vessel.longitude.value
    speed = vessel.speed.value

    stuck_latitude = 30.01765
    stuck_longitude = 32.5802
    stuck_speed = 0

    if speed != stuck_speed and latitude != stuck_latitude and longitude != stuck_longitude:
        resp.message("It's moving!")
    else:
        resp.message("Still stuck 😔")

    return str(resp)

We only need one route on this app: /sms to handle incoming text messages.

Run your code with the following terminal command:

flask run

Text your Twilio number to see the results. The time_span threshold used here is 240 minutes, and as things change you might need to increase that depending on how long it's been since the Marine Traffic API has had an update on this particular vessel.

Staying up to date

Unfortunately, this dog is not nearby to mitigate the situation, so it looks like the Ever Given will be stuck for a bit longer.

If you're looking for something fun to do in the meantime, try playing TwilioQuest, our documentation video game. It has a really awesome Python mission! You can also work on other fun Python projects like generating Nintendo music through phone calls.

Feel free to reach out if you have any questions or comments or just want to show off the cool stuff you’ve built.