tweet-helper

twython wrapper to simplify tweeting from the commandline


License
MIT
Install
pip install tweet-helper==0.0.3

Documentation

About

This package is designed to quickly tweet things.

It was specifically designed to enable Mike Bayer to automate release announcements via Tweets as part of his build/release process for SqlAlchemy. Mike needed that functionality, and I needed to read his (very important) tweets.

The package is a single file and wraps the Twython library. It expects twitter credentials stuffed into the os environment in a certain way.

The package can be imported into a Python process for tweeting, but was designed to enable tweeting off a terminal prompt so any release process can invoke it.

python tweet_helper.py -a TWEET -m 'i tweeted this off the commandline using tweet_helper!'

There are full-fledged commandline twitter clients. This is not one of them. This project's goal is to simplify tweeting from the commandline.

This package is available on PyPi as tweet_helper.

Oh and yes there are tests.

RELEASE INFO / STRATEGY

v0.0.1 is the first release.

No breaking changes should be introduced until the next minor release v0.1.0.

It would probably be best to pin dependencies to tweet_helper<0.1.0

INSTALLATION

Install via pip, or another package manager if you want...

Python 2.7

pip install tweet_helper

Python 3

pip3 install tweet_helper

OR just download the file and invoke it as you wish. That might be easier in some situations. HOWEVER

Installing the package via pip/etc will install a console script entrypoint into your (virtualenv's) /bin named tweet_helper

So instead of doing...

python tweet_helper.py -a VERIFY

you can invoke it as

tweet_helper -a VERIFY

Isn't that handy?

SETUP

Twitter requires two sets of credentials:

  • APPLICATION
  • USER

We're going to store these in the following environment variables:

  • TWEET_HELPER__API_KEY
  • TWEET_HELPER__API_SECRET
  • TWEET_HELPER__USER_TOKEN
  • TWEET_HELPER__USER_SECRET

We're also going to store them in a bash file, so we can just 'source' them into the environment:

To start:

cp credentials.bash_template credentials.bash

This strategy lets our applications use the credentials, and we don't have to leave them on a filesystem or pass them along as command args which can be read.

!! IMPORTANT !!

The credentials.bash file contains very sensitive information.

It should NEVER be checked into source control or left lying around in plaintext.

This information can be used to compromise your Twitter Account and your Twitter Application.

If you store this data, it should be strongly encrypted - not plaintext.

I like using GPG and the blackbox wrapper (https://github.com/StackExchange/blackbox), which can automate decryption.

If you're using ansible, use a Vault (https://docs.ansible.com/ansible/2.4/vault.html)

There are many widely available tools for encryption of passcodes and tokens.

DON'T BE STUPID, ENCRYPT.

Also be sure to ignore the plaintext version of this file and only allow the encrypted version into your source control.

SETUP APPLICATION CREDENTIALS

To create application credentials, visit https://apps.twitter.com and create a new app.

Copy/Paste the following into your credentials.bash file

  • "API KEY" or "APP KEY" goes into TWEET_HELPER__API_KEY
  • "API SECRET" or "APP SECRET" goes into TWEET_HELPER__API_SECRET

SETUP USER CREDENTIALS

You can create a user token when you create an application IF the owner will be tweeting.

In the sqlalchemy example, it probably makes sense for Mike Bayer to own the application and SqlAlchemy user to tweet, so we will generate user credentials:

python tweet_helper.py -a AUTH

This will prompt you to visit a url, with text like this:

In a web-browser, visit the following url to authorize this application:

    https://api.twitter.com/oauth/authenticate?oauth_token=***************

What is the PIN code? 

While logged in to twitter as the correct user, visit the URL and authorize the application.

You will be presented with a PIN code. Copy/Paste that into the terminal window.

You will now have this data:

============================
AUTH SUCCESS
============================
- Human Formatted Report -
    screen_name: 2xlp
    user_id: 14275299
    Access Token: ****************
    Access Token Secret: ************
- Machine Readable Formats Below -
 - - - - - - - - - - - - - -
auth = {u'oauth_token': u'************',
        u'oauth_token_secret': u'************',
        u'screen_name': u'2xlp',
        u'user_id': u'14275299',
        u'x_auth_expires': u'0'}
 - - - - - - - - - - - - - -
export TWEET_HELPER__USER_TOKEN='*****'
export TWEET_HELPER__USER_SECRET='*****'
============================

Copy/Paste the two export lines into our "credentials" file to overwrite the default null values

You are done!

SETUP TESTING

Two steps

  1. populate the environment
  2. Validate your credentials

Which look like:

source credentials.bash
python tweet_helper.py -a VERIFY

If the credentials don't work, you'll see the following:

{'status': 'error', 'error': 'Twitter API returned a 400 (Bad Request), Bad Authentication data.'}

Notice how that's JSON? Yep, you can parse it.

If the credentials work, the payload will be:

{'status': 'success', 'api_result': {}, }

The value of api_result will be the api result of twitter's validation, which is twitter profile data for the authenticating user.

TWEET SOMETHING ON THE COMMANDLINE

You can now tweet something off the commandline

source credentials.bash
python tweet_helper.py -a TWEET -m "test yes it is a test http://example.com 'punctuation' \"other punctuation\""

On failure, an error is raised by Twython:

{'status': 'error', 'error': 'Twitter API returned a 400 (Bad Request), Bad Authentication data.'}

Notice how that's JSON? Yep, you can parse it.

On success, we'll see:

{'status': 'success', 'api_result': {}, }

The value of api_result will be the twitter api response for UPDATE STATUS which is a dict representing the newly formed tweet.

TWEET SOMETHING FROM AN APP

If you'd like to tweet from an app...

from tweet_helper import api_tweet

api_tweet(message="Tweet me!")

If you want more control...

from tweet_helper import new_TwitterUserClient

twitterUser = new_TwitterUserClient()
twitterUser.update_status(status="Tweet me!")

TODO

[] Tests for the authentication flow.