I have a simple Python Bottle API used to support an iOS app. It is hosted on Heroku.
I use TelemetryDeck for analytics, so I want to send signals with each API call. I'm not using Node so cannot use their JS SDK and thus I have to send signals over HTTP.
Here is my function for sending telemetry signals.
def send_telemetry(type, success):
url = TELEMETRY_DECK_URL
headers = {
"Content-Type": "application/json; charset=utf-8"
}
data = [
{
"isTestMode": "false",
"appID": TELEMETRY_DECK_APP_ID,
"clientUser": "apiProcess",
"sessionID": "",
"type": "API Called",
"payload": {
"api_type": type,
"api_success": success
}
}
]
response = requests.post(url, headers=headers, json=data)
# Print to Heroku logs
print(response.text)
Here is an example of where I call the telemetry method from an app route.
@app.get('/')
def example():
# Other code
if result:
send_telemetry("type", "true")
response.status = 200
return make_response(result)
else:
send_telemetry("type", "false")
response.status = 404
return make_error("Error (404)")
This all works fine, but I am concerned that the telemetry method is running synchronously before Bottle returns a response, and of course it cannot run after the response is returned due to WSGI limitations.
Is there a way to asynchronously trigger an analytics method and not delay execution at the callsite in the route, so performance is not impacted. I'm happy for a "fire and forget" solution and don't need to receive a callback.
I looked at solutions using multithreading
but they looked more complex than what I needed.
I actually got this working simply using the threading
module.
In my route handler I simply insert this code which generates a thread targeting my send_telemetry
function. It runs in a separate thread as expected, and does not hold up execution of Bottle returning a response.
import threading
thread = threading.Thread(target=send_telemetry, args=["type", "true"])
thread.start()