Settings.toml Setup
Open the settings.toml 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_tokento your app's Twitter bearer token
Your settings.toml 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 CIRCUITPY_WIFI_SSID="your-wifi-ssid" CIRCUITPY_WIFI_PASSWORD="your-wifi-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
from os import getenv
import time
from adafruit_magtag.magtag import MagTag
# Get WiFi details, ensure these are setup in settings.toml
ssid = getenv("CIRCUITPY_WIFI_SSID")
password = getenv("CIRCUITPY_WIFI_PASSWORD")
if None in [ssid, password]:
raise RuntimeError(
"WiFi settings are kept in settings.toml, "
"please add them there. The settings file must contain "
"'CIRCUITPY_WIFI_SSID', 'CIRCUITPY_WIFI_PASSWORD', "
"at a minimum."
)
# 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 = getenv("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 = getenv("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 March 31, 2025
Text editor powered by tinymce.