aaron-schroeder / distilling-flask

Strava app for display and analysis of personal running data, powered by Flask, Dash, and Pandas.
MIT License
3 stars 0 forks source link

Gracefully handle stravalib/Strava API rate limiting. #48

Open aaron-schroeder opened 1 year ago

aaron-schroeder commented 1 year ago

Currently, this can happen if a user is trying to add more activities at once than the rate limit allows, and generally if they are doing a lot of interacting with the app.

Update 4/7/23: A partial mitigation strategy is now in place on a branch - each api json response is saved in its entirety to the database on the first request.

In dev mode, I like the idea of just displaying dummy data (probably from the mock stravalib).

In production, I suppose I should handle things more gracefully: just messages when data is missing; potentially info about the rate limiting itself; a countdown on the page showing how many more requests are remaining.

Sub task: #55

Strava API request limits:

Stravalib seems to keep track of some rate limits (re stravalib.exc.RateLimitExceeded). I want verify for myself that they work accurately and reflect the rate limits on my account.

I want to see if there is specific, actionable information about rate limits in Stravalib's exceptions that I can use to make my retry scheme smarter. I just need to wait to tinker until I'm rate-limited.

I handle this in the very specific case of the batch-add-activity task. But it exists in lots of places where I haven't dealt with it.

Stravalib points of contact

Notes

Successful response example

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Tue, 10 Oct 2020 20:11:01 GMT
X-Ratelimit-Limit: 600,30000
X-Ratelimit-Usage: 314,27536

Rate-limited response example

HTTP/1.1 429 Too Many Requests
Content-Type: application/json; charset=utf-8
Date: Tue, 10 Oct 2020 20:11:05 GMT
X-Ratelimit-Limit: 600,30000
X-Ratelimit-Usage: 692,29300

Rate-limited json response b'{"message":"Rate Limit Exceeded","errors":[{"resource":"Application","field":"overall rate limit","code":"exceeded"}]}'

aaron-schroeder commented 1 year ago

Notes about strava batch-save

One interesting wrinkle is figuring out whether I'll regain access in ~15 minutes or the next day, and planning retries accordingly. Currently, my retry scheme will definitely fail if the daily rate limit is hit, with a possibility of giving up on even a 15-minute rate limit. I don't necessarily mind giving up, but if it happens, I want it to happen loudly so the user knows their activities weren't added.

aaron-schroeder commented 1 year ago

Create a flask endpoint that shows rate-limit status

I'm a visual person and want to debug that way.

Start off with an endpoint that answers "is this app rate-limited?"

Looking under the hood of stravalib, it seems that:

aaron-schroeder commented 1 year ago

I guess the question now that I can check the rate limit status of the response in multiple ways...what do I want to do w that info? Here are some scenarios that I may encounter during a large backfill of strava activities:

https://github.com/aaron-schroeder/distilling-flask/blob/e0f7df51c0851a0b4b034fb1fb911b76bc03d551/distilling_flask/io_storages/strava/models.py#L83-#L102