from flask import Flask, request, make_response, url_for
import plivo
from urllib.parse import urlparse, parse_qs
from plivo import utils
from plivo import plivoxml

app = Flask(__name__)

@app.route('/speak/', methods=['GET', 'POST'])
def validate_signature():
    signature = request.headers.get('X-Plivo-Signature-V3', 'signature')
    nonce = request.headers.get('X-Plivo-Signature-V3-Nonce', '12345')
    url = url_for('validate_signature', _external=True)
    auth_token = "<auth_token>"
    method = request.method
    if method == 'GET':
        valid = plivo.utils.validate_v3_signature(
            method, url, nonce, auth_token, signature)
    else:
        params = request.get_json()
        valid = plivo.utils.validate_v3_signature(
            method, url, nonce, auth_token, signature, params)
    print(valid)
    r = plivoxml.ResponseElement()
    speak_params = {
        'loop': '3'
    }
    r.add(plivoxml.SpeakElement("Hello, from Plivo", **speak_params))
    response = make_response(r.to_string())
    response.headers["Content-type"] = "text/xml"
    print(r.to_string())
    return response


if __name__ == "__main__":
    app.run(host='0.0.0.0', debug=True)
true

You can control outgoing calls using XML too. The initial outbound call is made through an API request; when the call gets answered, the Plivo API calls the web application specified by the answer URL, which provides instructions on how to process the call.