Secrets.py Setup
Open the secrets.py file on your CircuitPython device using Mu or your favorite text editor. You're going to edit this file to enter the Twitter Bearer Token you saved earlier.
-
Change
twitter_bearer_token
to your app's Twitter bearer token
Your secrets.py file should look like this:
# This file is where you keep secret settings, passwords, and tokens! # If you put them in the code you risk committing that info or sharing it secrets = { 'ssid' : 'home ssid', 'password' : 'my password', 'timezone' : "America/New_York", # http://worldtimeapi.org/timezones 'github_token' : 'fawfj23rakjnfawiefa', 'hackaday_token' : 'h4xx0rs3kret', 'twitter_bearer_token' : 'YOUR_SECRET_TWITTER_BEARER_TOKEN' }
To use with CircuitPython, you need to first install a few libraries, into the lib folder on your CIRCUITPY drive. Then you need to update code.py with the example script.
Thankfully, we can do this in one go. In the example below, click the Download Project Bundle button below to download the necessary libraries and the code.py file in a zip file. Extract the contents of the zip file, open the directory MagTag_Twitter/ and then click on the directory that matches the version of CircuitPython you're using and copy the contents of that directory to your CIRCUITPY drive.
Your CIRCUITPY drive should now look similar to the following image:

# SPDX-FileCopyrightText: 2019 Dave Astels for Adafruit Industries. # SPDX-FileCopyrightText: 2020 Brent Rubell for Adafruit Industries. # # SPDX-License-Identifier: Unlicense import time from adafruit_magtag.magtag import MagTag try: from secrets import secrets except ImportError: print( """WiFi settings are kept in secrets.py, please add them there! the secrets dictionary must contain 'ssid' and 'password' at a minimum""" ) raise # Set to the twitter username you'd like to fetch tweets from TWITTER_USERNAME = "adafruit" # Set to the amount of time to deep sleep for, in minutes SLEEP_TIME = 15 # Set up where we'll be fetching data from DATA_SOURCE = ( "https://api.twitter.com/1.1/statuses/user_timeline.json?" "screen_name=%s&count=1&tweet_mode=extended" % TWITTER_USERNAME ) TWEET_TEXT = [0, "full_text"] TWEET_FULL_NAME = [0, "user", "name"] TWEET_HANDLE = [0, "user", "screen_name"] magtag = MagTag(url=DATA_SOURCE, json_path=(TWEET_FULL_NAME, TWEET_HANDLE, TWEET_TEXT)) # Set Twitter OAuth2.0 Bearer Token bearer_token = secrets["twitter_bearer_token"] magtag.set_headers({"Authorization": "Bearer " + bearer_token}) # Display setup magtag.set_background("/images/background.bmp") # Twitter name magtag.add_text( text_position=(70, 10), text_font="/fonts/Arial-Bold-12.pcf", ) # Twitter handle (@username) magtag.add_text( text_position=(70, 30), text_font="/fonts/Arial-12.bdf", text_transform=lambda x: "@%s" % x, ) # Tweet text magtag.add_text( text_font="/fonts/Arial-Bold-12.pcf", text_wrap=30, text_maxlen=160, text_position=( 5, (magtag.graphics.display.height // 2) + 20, ), line_spacing=0.75, ) # preload characters magtag.preload_font() try: value = magtag.fetch() print("Response is", value) except (ValueError, RuntimeError, ConnectionError, OSError) as e: print("Some error occured, retrying! -", e) time.sleep(2) print("Sleeping!") magtag.exit_and_deep_sleep(SLEEP_TIME * 60)
Every 15 minutes, the MagTag will attempt to fetch and display a new tweet from the Twitter handler specified in the code.
Then it goes into a deep sleep mode for 15 minutes to save energy.
Change the Twitter Handle
To display tweets from a specific Twitter account, change the following line in the code to the account you'd like to show tweets from:
TWITTER_USERNAME = 'adafruit'
Change the Sleep Time
After fetching and displaying a tweet, the MagTag goes into a deep-sleep mode for 15 minutes. Modify the following line in the code to reflect how long the MagTag will enter the deep sleep mode for, in minutes.
SLEEP_TIME = 15
Code Walkthrough
Data Sources
This project fetches data directly from Twitter's timeline API. A request is made to api.twitter.com to fetch the most recent status from a Twitter account, their full name, and their Twitter handle/username (such as @adafruit).
# Set up where we'll be fetching data from DATA_SOURCE = "https://api.twitter.com/1.1/statuses/user_timeline.json?count=1&screen_name=%s"%TWITTER_USERNAME TWEET_TEXT = [0, 'text'] TWEET_FULL_NAME = [0, 'user', 'name'] TWEET_HANDLE = [0, 'user', 'screen_name']
MagTag Library
The MagTag library makes it simple to create projects for the MagTag ePaper display. The code passes it the URL to fetch data from along with the JSON paths to retrieve the data.
- For more information about the MagTag library, check out Melissa's guide here...
magtag = MagTag( url=DATA_SOURCE, json_path=(TWEET_FULL_NAME, TWEET_HANDLE, TWEET_TEXT) ) # Set Twitter OAuth2.0 Bearer Token bearer_token = secrets['twitter_bearer_token'] magtag.set_headers({'Authorization': 'Bearer ' + bearer_token})
Display Objects
The code sets up a bitmap image background (a white background with a black Twitter logo) and text fields to hold the contents of the API response.
# Display setup magtag.set_background("/images/background.bmp") # Twitter username magtag.add_text( text_position=(70, 10), text_font="/fonts/Arial-Bold-12.pcf", ) # Twitter handle (@username) magtag.add_text( text_position=(70, 30), text_font="/fonts/Arial-12.bdf", text_transform=lambda x: "@%s"%x, ) # Tweet text magtag.add_text( text_font="/fonts/Arial-Bold-12.pcf", text_wrap=40, text_maxlen=140, text_position=( 10, (magtag.graphics.display.height // 2)+20, ), line_spacing=0.75, ) # preload characters magtag.preload_font()
Text Transform
Unfortunately, Twitter's API returns a twitter username without the "@" prefix. To add the @ prefix before a twitter username, the code uses an anonymous function (a "lambda") which is passed to the text_transform
parameter in the magtag.add_text()
function.
So, by calling text_transform
=lambda x: "@%s"%x
, we're creating a new anonymous function which looks like:
def x_function(x):
return "@%s"%x
Update the Display
The main chunk of code attempts to fetch the URL from Twitter's API using magtag.fetch()
. Then it parses out the data sources and displays the values on text labels.
try: value = magtag.fetch() print("Response is", value) except (ValueError, RuntimeError) as e: print("Some error occured, retrying! -", e) time.sleep(2) print("Sleeping!") magtag.exit_and_deep_sleep(SLEEP_TIME * 60)
The code exits and goes into deep sleep until the next SLEEP_TIME
minutes.
magtag.exit_and_deep_sleep(SLEEP_TIME * 60)
Page last edited January 18, 2025
Text editor powered by tinymce.