How to Use Azure Functions with Python

How to Use Azure Functions With Python

Published September 27, 2019 by Mark Smith
Categories:

Here at Nexmo, we try to make our APIs as simple to use as possible. One awkward thing we can’t get away from, though, is that many of our APIs, like Nexmo Voice API need to ask your app what to do during a call. This means you need to run your own server. Or do you?

Going Serverless with Azure Functions

Microsoft just released Azure Functions support for Python, and it’s great! Lots of support has been provided to help you get up and running quickly, and it works with standard Python project idioms, like requirements.txt. It allows you to write small, standalone functions in Python, and then deploy them easily to the Azure cloud.

There’s a free tier that provides a million function executions free, per month. That should be enough for a small demo app, or even a small production app!

Let’s Get Functional

I’m going to show you how to build a simple Nexmo app with two webhooks hosted on Azure Functions. The idea is that the user calls a Nexmo number, (which will trigger the first webhook) and is greeted by a robotic voice. They’ll be asked to enter their mood. They’ll enter 1 for ‘happy’, 2 for ‘unhappy’, and whatever other options you like. At this point the second endpoint will be called with the input, and this will both generate an appropriate response.

I’ll describe all the steps to create all the code and configuration you’ll need, but if you’d like to see the end result, the code is hosted on GitHub

Requirements

As you can see below, there are a few things you’ll need to set up or install, but trust me, it’s worth it.

  • A free Nexmo Account so you can create your Nexmo Application and rent Nexmo Virtual Numbers.
  • A free Azure account so you can publish your Azure Functions.
  • Install the Nexmo CLI Tool

    This gives you the nexmo command in your console, which allows you to create Nexmo Voice Applications, buy Nexmo Phone Numbers, and link the two together.

  • Install Ngrok

    This gives you the ngrok command in your console, which will tunnel requests to your development machine, allowing Nexmo to send webhooks to your development server.

  • Install the Azure Functions Core Tools

    This gives you the func command in your console, which allows you to bootstrap your Azure Functions project and run them locally for development and testing.

  • Install the Azure CLI.

    This gives you the az command in your console. This will allow you to create various objects inside Azure, and to publish your Azure functions!

Creating Your First Function

Once you have all the requirements above installed, open up your console. You’ll create some boiler-plate code to kickstart building your Azure functions.

First let’s create a new Azure Functions project using the Azure Functions Core Tools command, func. Run func init to create an empty Azure Functions project:

Now cd into the new project directory and use func new to create a new Azure function to answer an inbound call. When it asks what type of function you’d like to create, select ‘5’, HTTP trigger. This is the type of Azure function that responds to HTTP requests. When it asks what to call the function, type answer_inbound because the endpoint will be used to answer inbound phone calls.

You can see from the output above that func has created a Python file, __init__.py and a config file, function.json.

Edit function.json and set “authlevel” to “anonymous”. This will allow Nexmo to call it without any extra authentication.

Run the boiler-plate Python function, using the func host command:

If you load up your browser at the URL http://localhost:7071/api/answer_inbound?name=bob you should see “Hello bob!” Well done! You’ve “written” your first Azure Function!

From Azure Function to Phone Call

You’ll want your function to output some NCCO actions, so that Nexmo knows what to do when someone dials your number. For that to happen, you’ll need to replace the function code with the following:

The code above returns a JSON response, containing two NCCO Actions. An NCCO Action is an instruction to Nexmo, telling it how to handle the phone call. In this case we have two actions:

  • The talk action instructs Nexmo to read a message to the caller.
  • The input action tells Nexmo to expect the user to enter a digit, which will then be sent to the URL specified in eventURL

Because we’ve set bargeIn to true in the talk action, if the caller enters a digit before the input action has started, Nexmo will assume that they’ve just been impatient, and will execute the following input instruction.

If you run func host start again, when you load your browser at http://localhost:7071/api/answer_inbound?name=bob you should see a bunch of JSON containing the actions described above.

Tunnel to Your Development Server

While you’re still developing, you’ll want Nexmo to be able to access your functions, so you can test them. I recommend following the instructions my colleague Aaron Bassett has written to connect your local development server to the Nexmo API using an Ngrok tunnel.

Assuming you now know how Ngrok works, in a separate console, run:

Check that you’re still running func host start in the other console window, and load the Ngrok URL that was printed out, followed by /api/answer_inbound. It should look something like https://r4nd0m.ngrok.io/api/answer_inbound (but with your own random prefix instead of r4nd0m!).

If that works, it’s time to tell Nexmo how to contact your development server!

Connect Nexmo to your development server

If you haven’t already, you’ll need to configure Nexmo CLI with your api key and secret. If you’ve already run nexmo setup, you don’t need to do this again.

Create a new Nexmo Voice Application

This creates an app called “Enter Your Mood” in the Nexmo Dashboard. When an inbound call is detected to any phone number linked to this app, it will call the webhook at https://r4nd0m.ngrok.io/api/answer_inbound, posting the details of the inbound call. The Azure Function at this endpoint is expected to respond with NCCO Actions … sound familiar? It’s also saved a private key, which we won’t be using just now, to a file called “private.key”

You now need to buy a Nexmo number and link it to the Nexmo app. So take a note of the Application ID that was just created (here it’s ‘4f33ff5e-dbbc-11e9-8656-6bdabe7b8258’).

Buy a Nexmo number, if you don’t have one already. I recommend buying it using the Nexmo Dashboard, but you can also search for numbers and purchase them using the Nexmo CLI tool. Once you have a number, link it to the app with the following command, replacing the phone number with the one you’ve just bought, and the app ID with the one you noted above:

Now, with your phone, call the Nexmo number you’ve just linked.

What should happen: A voice should answer, with the message above. If you enter a number on your phone’s number pad, the call will probably beep and then go dead. That’s because the second URL, at /api/mood_feedback doesn’t exist yet!

Handling Input

For this, follow similar steps to those above:

  • Run func new, select HTTP trigger and enter “mood_feedback” as your function name.
  • Modify the function.json file and set authLevel to anonymous.

Now, open up __init__.py and replace the function code with the following:

There’s a little extra code here, which will be used for extracting the data sent from the phone call, but for now, you should just be able to call the number again, and this time when you enter a number during the call, you should hear the message “thank you for telling us how you feel.”

Make the Response Dynamic

If that works, lets make sure that the response to the call is a little more sympathetic. Above the function, add the following global variables:

Now, in the NCCO you’re returning, replace the string with RESPONSES.get(req_body['dtmf'], UNEXPECTED_RESPONSE). This expression extracts the DTMF code from the request (req_body['dtmf']), attempts to find the associated response in RESPONSES, and if that key doesn’t exist, it falls back to UNEXPECTED_RESPONSE. Call your number and try it out!

Creating a Function App on Azure

What you’ve done so far is great – as long as your development machine is on and you have console windows open running func host & ngrok. But that’s impractical, so now I’ll show you how to deploy the code you’ve written to Azure Functions, so Microsoft can host it for you!

To interact with Azure’s servers, we’ll use the Azure CLI command, az.

First you need to log into your Azure account by running az login. It’ll load up the browser and ask you to log in to your Azure account. If you haven’t yet signed up for an Azure account, you can do that now.

Now, you’ll run the three az commands below – I’ve added a comment to each of them, so you can see what they do. The only thing you’ll need to change is to replace MYNEXMOFUNCTIONSTORE with something globally unique. The actual name you pick isn’t important – it’s just a place to store the data for your running functions, and won’t be seen by users. You’ll also need to change moodfeedbackapp to something globally unique.

Publish Your Function to Azure

You can check that your functions are deployed okay by going to https://moodfeedback.azurewebsites.net/api/answer_inbound (you’ll need to replace “moodfeedback” with your own function app name that you chose above.) in the browser and confirming that the NCCO JSON output is being produced.

Update Your Nexmo App

Nexmo still thinks it should call your development server when someone calls your Nexmo number! To fix this, update your Nexmo app to point to the new URL. Run the following command, replacing the application ID with your own, and replacing “moodfeedbackapp” with your own function app name.

Next Steps

The aim of this tutorial was to show you how to build webhook handlers for Nexmo Voice calls with Azure Functions.
Although this example doesn’t do that much, you will be able to build much more interesting, practical examples with the
aid of Azure storage and other APIs.

If you’d like to build interesting capabilities into your app, you could:

  • Send feedback results to a researcher, via the Nexmo SMS API.
  • Integrate a speech-to-text API to handle voice input, instead of numeric codes.
  • Store the feedback of each caller in a database, to analyse trends over time.

Other Resources

Leave a Reply

Your email address will not be published.