- product:voice - sdk:compatibility - language:python You can learn more about voice status callbacks, all of the possible parameters you can use, and how to set them up in our [status callback mega guide](/compatibility-api/guides/signalwire-status-callbacks#voice-status-callbacks)! Full code example: Voice Status Callbacks
python from flask import Flask, request import logging import pandas as pd from signalwire.rest import Client as signalwire_client logging.basicConfig(level=logging.INFO) app = Flask(__name__) failedCallArray = [] allCallArray = [] client = signalwire_client(ProjectID, AuthToken, signalwire_space_url=example-space.signalwire.com) @app.route(/CallStatus, methods=[POST]) def incoming_calls(): call_sid = request.values.get(CallSid, None) call_status = request.values.get(CallStatus, None) event_timestamp = request.values.get(Timestamp, None) recording_url = request.values.get(RecordingUrl, None) call_direction = request.values.get(Direction, None) to_number = request.values.get(To, None) from_number = request.values.get(From, None) logging.info(SID: {}, Status: {}, Timestamp: {}, Direction: {}.format(call_sid, call_status, event_timestamp, call_direction)) if (call_status != ringing and call_status != initiated and call_status != answered and call_status != in-progress and call_status != queued and call_status != failed): allCallArray.append([call_sid, call_status, event_timestamp, call_direction, to_number, from_number, recording_url]) adf = pd.DataFrame(allCallArray, columns=(Call SID, Call Status, Event Timestamp, Call Direction, To Number, From Number, Recording URL (if present))) print(All Calls) print(adf.to_string()) if (call_status == failed): failedCallArray.append([call_sid, call_status, event_timestamp, call_direction, to_number, from_number, recording_url]) df = pd.DataFrame(failedCallArray, columns=(Call SID, Call Status, Event Timestamp, Call Direction, To Number, From Number, Recording URL (if present))) print(Failed Calls) print(df.to_string()) if len(failedCallArray) > 100: df.to_csv(failedCallReport.csv, index=False, encoding=utf-8) m = client.messages.create( body=Call Failure Alert! You have received 100 call failures. A CSV of the failures has been downloaded and the failure database will now reset., from_=+12022358941, to=+12147903161) print(CSV of Failed Calls Downloaded & Message Alert Sent) while len(failedCallArray) > 0: failedCallArray.pop() return (, 200) if __name__ == __main__: app.run() ### Configuring the Code Below is an example of a simple call status tracker that will log every status change event (initiated to ringing, ringing to answered, etc) to the console along with the CallSID, CallStatus, Timestamp, and Direction. If a call has reached an end-stage state, i.e. completed, canceled, no-answer, or busy, it will be added to our table of call records. This table will exclude failed calls and in-progress calls so as to not have duplicate records. If a call fails, it will be added to a separate table containing failed calls along with relevant data to investigate later. If at any point the number of failed calls in the table reaches 100, the table will be downloaded to CSV and an SMS alert will be sent out to notify whoever would be in charge of dealing with the failures. After the CSV has been downloaded and the alert has been sent, we will clear the failed calls array so it can begin appending new failed calls again. After every call is appended to either of the tables, the tables will reprint so that its easy to see the updated list of completed and failed calls. python from flask import Flask, request import logging import pandas as pd from signalwire.rest import Client as signalwire_client logging.basicConfig(level=logging.INFO) app = Flask(__name__) # create empty arrays to store our call records - one for failed only and one to handle all other end stage statuses (not queued, not ringing, not answered, etc) failedCallArray = [] allCallArray = [] # authenticate the SignalWire client client = signalwire_client(ProjectID, AuthToken, signalwire_space_url=example-space.signalwire.com) @app.route(/CallStatus, methods=[POST]) def incoming_calls(): # grab incoming parameters posted to webhook and assign them variables call_sid = request.values.get(CallSid, None) call_status = request.values.get(CallStatus, None) event_timestamp = request.values.get(Timestamp, None) recording_url = request.values.get(RecordingUrl, None) call_direction = request.values.get(Direction, None) to_number = request.values.get(To, None) from_number = request.values.get(From, None) # log some basic information to print to console for EVERY status change logging.info(SID: {}, Status: {}, Timestamp: {}, Direction: {}.format(call_sid, call_status, event_timestamp, call_direction)) # create a separate array for all end stage statuse updates and add them to our call log table, display updated table if (call_status != ringing and call_status != initiated and call_status != answered and call_status != in-progress and call_status != queued and call_status != failed): allCallArray.append([call_sid, call_status, event_timestamp, call_direction, to_number, from_number, recording_url]) adf = pd.DataFrame(allCallArray, columns=(Call SID, Call Status, Event Timestamp, Call Direction, To Number, From Number, Recording URL (if present))) print(All Calls) print(adf.to_string()) # if call status is failed, log call record to call failure table and display table if (call_status == failed): failedCallArray.append([call_sid, call_status, event_timestamp, call_direction, to_number, from_number, recording_url]) df = pd.DataFrame(failedCallArray, columns=(Call SID, Call Status, Event Timestamp, Call Direction, To Number, From Number, Recording URL (if present))) print(Failed Calls) print(df.to_string()) # if the number of failed calls is over 100 if len(failedCallArray) > 100: # download call logs with necessary data to CSV and send an sms alert of the failures df.to_csv(failedCallReport.csv, index=False, encoding=utf-8) m = client.messages.create( body=Call Failure Alert! You have received 100 call failures. A CSV of the failures has been downloaded and the failure database will now reset., from_=+1xxxxxxxxxx, to=+1xxxxxxxxxx) print(CSV of Failed Calls Downloaded & Message Alert Sent) # clear array to start adding fresh logs again while len(failedCallArray) > 0: failedCallArray.pop() # Return 200 OK return (, 200) if __name__ == __main__: app.run() ### Running the application You will need the Flask framework and the SignalWire [Python SDK](/compatibility-api/sdks) downloaded. To run the application, execute export FLASK_APP=your_file_name.py then run flask run.