What's your new year's resolution? One of mine is to be more active in helping and mentoring new Pythonistas, which is why I wrote the twitter bot behind @PythonQuestions. Inspired by the @MongoQuestion twitter bot, @PythonQuestions tweets new Stack Overflow questions tagged "Python".

How it Works

@PythonQuestions is actually a (relatively) generic "tweet questions from Stack Overflow" bot, composed of three components:

  1. The Stack Overflow polling script, which is designed to be run from a cron job (or another means of periodic scheduling)
  2. The database of questions (MongoDB of course), which for now is used only to remember which questions have already been tweeted.
  3. The Twitter update script, also designed to be run from a cron job.
  4. (There's also a bare-bones Flask web application which serves redirects for the pyq.io link-shortening domain. The web app currently redirects requests to http://pyq.io/ to the Stack Overflow "Questions tagged Python" page.)

Polling Stack Overflow

Stack Overflow doesn't (to my knowledge) have a Push API, so @PythonQuestions polls the /questions API periodically (right now, every 5 minutes). It queries using fromdate sorted by creation to find recent questions. For @PythonQuestions, it filters questions to only those containing the "python" tag, though this is configurable.

A few details of these questions are then upserted into MongoDB using the Stack Overflow question ID as _id, which ensures that the database only holds one copy of any given question, even if it appears several times while polling.

Tweeting About It

The twitter script consults the questions database periodically to find questions which have not yet been tweeted about, then uses the Flask-Tweepy extension (which adapts the Tweepy module for use with Flask) to update the status of the @PythonQuestions Twitter user.

Tweepy makes sending Tweets fairly painless, but Twitter itself sure doesn't. In a future blog post, I'll cover the steps needed to set up an application account, configure it properly, configure your Tweepy appropriately, and get up and running. I've done this once or twice before, so I'm reasonably familiar with the steps, but they're not well or obviously documented on Twitter's Developer site.

Putting it Together

Using a web application framework for what is essentially a series of scripts may seem an odd choice. Aside from the fact that I hope to expand the scope of the web application, using Flask and its extensions made development painless--the whole application was a matter of a few hours to write, test, and launch. I'm using Flask-PyMongo, Flask-Tweepy (as previously mentioned), and Flask-Script.

Flask-Script loads the Flask application object (and thus the configuration), and offers a few decorators to declare settings for argparse. Writing a command-line script then becomes:

from pythonquestions import app
from flask.ext.script import Manager
manager = Manager(app)

@manager.command
@manager.option('-s', '--since')
def stackoverflow(since='1d'):
    # implement the script here

Critically, this setup lets me share one set of configuration (API keys, usernames, database configuration, etc) for both the cron scripts and the web application.

Lend a Hand

In his 2011 in Review: The Python Portion, Jesse Noller called on us to be welcoming to new or inexperienced users, and to mentor them to a point where they can become contributors to, rather than passive members of, the Python community. In some small way, I hope @PythonQuestions can be a part of that.

Here's how I think that can happen:

  • Follow @PythonQuestions on Twitter, and start answering questions. Stack Overflow's game mechanics will give you a jolt of dopamine that's the perfect remedy for caffeine wearing off in the afternoon.
  • Fork the python-questions project on GitHub and help make it better. I'm especially interested in ideas about what could make the web app portion of it more useful than simply a list of questions (which already exists in better and more useful form at Stack Overflow), or in integrations with other Q&A services or sites frequented by Pythonistas.

And more broadly, echoing Jesse's thoughts:

  • Be active, constructive, and engaged with less-experienced Pythonistas in your community and online. The goal is to teach, not just to answer specific questions, and certainly not to ridicule or insult (even unintentionally) a novice programmer. Take the time to link to documentation, or explain detail that may not be obvious at first blush.