This demo shows how to connect a phone number to a Python script executing logic on a local Docker container via a Flask webserver and ngrok websocket. {/*placeholder for mermaid diagram or markdown diagram*/} ### 📋 Prerequisites
Before getting started, please make sure you have the following prerequisites. - Sign up for a free [SignalWire Space](https://id.signalwire.com/onboarding) - Install [Docker Desktop](https://www.docker.com/products/docker-desktop/) - Buy a [SignalWire Phone Number](/guides/buying-a-phone-number/) - Create a free [ngrok account](https://ngrok.com/)
:::tip Extra Credit Ask SignalWire staff for a promo code to elevate your account out of Trial status and add extra credit to your account. :::
## **1. 🔌 Set up WireStarter** {#wirestarter} WireStarter is a Docker container which sets up the SignalWire SDKs and builds a development and testing environment for new developers. :::info Fresh Install WireStarter has been updated recently. If youve used WireStarter before, be sure to delete the previous version and reinstall the latest version of the container. ::: 1. **Open Docker Desktop** Docker Desktop must be running at the start of the process. 2. **Install and Run WireStarter** Run the following command from your system terminal to download and install the WireStarter Docker Container. bash docker run -it -d --rm --name wirestarter briankwest/wirestarter:latest If you already have the latest version of WireStarter installed, you can also start it from the **Images** window in Docker Desktop. 3. **Start and Configure SWSH** Now that WireStarter is installed and running, we will start [SWSH (the SignalWire Interactive Shell)](/tools/swsh/) in the Container. SWSH will ask for your SignalWire Space ID, SignalWire Project ID, SignalWire Project Token, ngrok Token, and ngrok Args (most users should leave ngrok Args blank). Make sure you have that information handy by opening the SignalWire [tokens page](https://my.signalwire.com?page=credentials) and the ngrok [Your Authtoken page](https://dashboard.ngrok.com/get-started/your-authtoken). Switch over to Docker Desktop, and open the running WireStarter container. Click on the Exec tab to open the integrated terminal. ![The Exec tab in the WireStarter Docker container.](./docker-desktop-exec-tab.webp) In that tab, run the following command to start SWSH: bash exec bash {/*Placeholder for screenshot*/} After you enter your authentication information, SWSH will automatically open an NGROK Tunnel and display the NGROK Tunnel URL in the integrated terminal output. Save this URL - well need it in the next step! :::danger Keep WireStarter open If the WireStarter container is stopped and restarted, NGROK will generate a new tunnel URL. To avoid reentering this URL in the SWML script (as shown in the following step), keep the WireStarter container running throughout the demo. ::: ## **2. 📜 Create the SWML Script** The call flow will be handled by a [SWML (SignalWire Markup Language)](/sdks/reference/swml/introduction/) Script, which itself seeks logic from the websocket we will host locally using Flask. To create a SWML Script, navigate to the **Relay / SWML** page of your SignalWire Dashboard. On that page, select the **SWML Scripts** tab as shown in the below screenshot. Click **Create a SWML Script**. Name the Script vicky, and copy and paste the following SWML into the text box labeled SWML. json { version : 1.0.0, sections : { main : [ { ai : { prompt : { top_p : 0.3, text : Hello, Im Vickey a virtual assistant., temperature : 0.3 }, post_prompt : { text : Summarize the conversation }, SWAIG : { functions : [ { argument : { type : object, properties : { phone : { description : The users phone number in e164 format, type : string }, } }, function : whats_up, purpose : When users ask whats up brother }, { argument : { type : object, properties : { phone : { description : The users phone number in e164 format, type : string }, } }, function : whats_day, purpose : When users ask what day it is } ], defaults : { web_hook_url : [NGROK_TUNNEL_HOST]/swaig } }, languages : [ { voice : nova, name : English, code : en-US, engine : openai } ] } } ] } } Replace [NGROK_TUNNEL_HOST] with the actual NGROK Tunnel URL generated in the previous step. Append /swaig to the end of the URL. The complete web_hook_url should look like this: ... defaults : { web_hook_url : https://1234-56-78-901-23.ngrok-free.app/swaig } ... After saving the SWML Script, navigate to the **Phone Numbers** page of your SignalWire Dashboard. Select the number you wish to use for this demo. Click **Edit Settings**. Set Handle Calls Using to **a SWML Script**, and select the vicky SWML Script using the drop-down menu. ## **3. 🐍 Create project directories and copy in the Python app** In this step, we will download our server Python application and set it up to run within the WireStarter container. This app includes logic which our SWML Script will trigger via HTTP requests to its websocket connection. The Python app uses Flask to create a local server on the WireStarter container, which WireStarter in turn exposes to the NGROK Tunnel URL. Copy the below Python code and save it as app.py in your Downloads folder. Alternatively, download app.py directly using the button below. python from flask import Flask, jsonify, request import json app = Flask(__name__) @app.route(/swaig, methods=[POST]) def swaig(): request_data = request.get_json() print(Received request data:\n, json.dumps(request_data, indent=4)) response_message = {response: Tell the user: special teams, special plays, special players } print(Response data:\n, json.dumps(response_message, indent=4)) return jsonify(response_message) if __name__ == __main__: app.run(debug=True) Download app.py
Return to the integrated terminal in the running WireStarter Docker Container. Enter exit once to exit SWSH. Navigate to the root of the container using cd /. Then, run the following command to create a folder named livewire within workdir in the container: bash mkdir /workdir/livewire Return to your system terminal, and navigate to your Downloads folder. Copy the container ID from the Containers view in Docker Desktop. ![Container ID in Docker Desktop.](./docker-desktop-container-id.webp) Finally, run the following command to copy app.py into /workdir/livewire/ within the WireStarter container. Replace [container-id] with the WireStarter container ID from Docker Desktop. bash docker cp app.py [container-id]:/workdir/livewire/ ## **4. 🚀 Run and test the application** 1. **Run app.py** Return to the Docker integrated terminal. Run the Python application using the below command: bash python3 app.py 2. **Dial the phone number** We did it! The application should now be ready to test. Using your cell phone or softphone, dial the phone number you assigned to the SWML Script back in Step 2. Vicky will answer. 3. **Test the server logic** Our demo Python app is set up with very minimal logic - thats where your creativity comes in! To make sure the SWML Script is correctly contacting our server, ask Vicky what day is it? or whats up, brother? If Vicky responds, special teams, special plays, special players, you know the demo is working. Congratulations! ## 🧰 Troubleshooting - **Vicky says something isnt available and nothing shows up in the Docker integrated terminal logs** This occurs when the SWML Script is unable to reach the websocket. This often occurs when the NGROK url is incorrect, so first, check it for typos. If you have stopped and restarted the WireStarter container, youll need to update the web_hook_url in the SWML Script with the new NGROK Tunnel URL, as this regenerated on container restart. - **The Python app sends 404 responses (seen in the Docker logs) when Vicky contacts the Python app** This occurs when the NGROK tunnel URL is correctly set in the SWML script, but it is missing the /swaig path. ##### Made with ❤️ by SignalWires DevEx team {#devex} *Have feedback on this site? Drop us a line at devex@signalwire.com or say hi on the [Community Slack](https://signalwire-community.slack.com/).*