I have a Django project and one of the functions currently runs onclick of my html –
def follow(request):
api = get_api(request)
followers = tweepy.Cursor(api.followers_ids, wait_on_rate_limit=True).items()
for x in followers:
try:
api.create_friendship(x)
except Exception:
pass
return render(request, "followed.html")
The function runs and follows the followers of the authorised user. My issue is that when deployed on my pythonanywhere web app the function will load in the browser and then timeout after around 10 minutes. I have tested on users up to 100 followers and it all works.
This would be fine but the Twitter API has a rate limit and so for some users who have large followings this function will take a long time to complete.
Is there a way of diverting to the followed.html and keeping the function running in the background until it is completed?
I have added the oauth functions just in case they are needed too –
def auth(request):
# start the OAuth process, set up a handler with our details
oauth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
# direct the user to the authentication url
# if user is logged-in and authorized then transparently goto the callback URL
auth_url = oauth.get_authorization_url(True)
response = HttpResponseRedirect(auth_url)
# store the request token
request.session['request_token'] = oauth.request_token
return response
def callback(request):
verifier = request.GET.get('oauth_verifier')
oauth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
token = request.session.get('request_token')
# remove the request token now we don't need it
request.session.delete('request_token')
oauth.request_token = token
# get the access token and store
try:
oauth.get_access_token(verifier)
except tweepy.TweepError:
print('Error, failed to get access token')
request.session['access_key_tw'] = oauth.access_token
request.session['access_secret_tw'] = oauth.access_token_secret
print(request.session['access_key_tw'])
print(request.session['access_secret_tw'])
response = HttpResponseRedirect(reverse('index'))
return response
2
Answers
You should look at using a task queue to do work in the background. In general, doing any work that is "blocking" while handling a HTTP request (eg something makes your server wait, such as connecting to another server and getting data) should be done as a background task.
Common (and good!) Python task queues are Celery and rq – rq is particularly lightweight and also has a Django wrapper django-rq
I’d spend a bit of time reading the rq or Celery docs to get an idea of how to make your Twitter API calls happen as background tasks, which will avoid your web server timing out.
You can use an asynchronous task queue (e.g. celery) for this. take a look at this:
https://realpython.com/asynchronous-tasks-with-django-and-celery/