山pの楽しいお勉強生活

勉強の成果を垂れ流していきます

Python3とAWS LambdaでTwitterの名前に天気を表示する

はじめに

数日前に話題になっていた「Twitterの名前を5分毎に東京の天気☼☂☃と連動させるサーバレスプログラムを書いたら色々知らないことが出てきた話」を読んで、Pythonのいい練習になりそう!って事で自分でやってみた話です。

数日経って元記事見てみたら、既に何人かやっている人いるみたいです。(同じくPython3の人もいる) が、まぁ、他より割りと詳しく書いているので、試してみたい人はどうぞ。

楽しいお題?をくれた山本一成さんに感謝します。

前提

  • Python3がインストールされている
  • Twitterのアカウントを持っている
  • AWSアカウントを持っている

OpenWeatherMapAPIのAPIキーを取得

  • OpenWeatherMapにアクセス → Sign Up
    • 既に登録済みの人はSign In
  • API keysでKeyを確認
  • 検索したい都市名を取得
    • ここのJSONから調べる
    • 面倒なら「tokyo」、「osaka」、「nagoya-shi」、「london」とか
  • ブラウザで試す
    • ↓のURLに都市名とAPI Keyを入れこんで確認
    • http://api.openweathermap.org/data/2.5/weather?q=${都市名}&appid=${API Key}

Python3からOpenWeatherMapAPIを叩く

  • requests というモジュールを使う例が多かったのでpipで入れる
    • 後でLambdaに乗せる時ために、「-t」オプションをつけてスクリプトと同じ場所にインストール
    • pip install requests -t .
  • コードを書いて実行
import requests
import json

SEARCH_CITY = "tokyo"
OPEN_WEATHER_MAP_API_KEY = "取得したAPI Key"
API_URL = "http://api.openweathermap.org/data/2.5/weather?q={city}&APPID={key}"

# URIスキーム
url = API_URL.format(city=SEARCH_CITY, key=OPEN_WEATHER_MAP_API_KEY)
r = requests.get(url)

# 結果はJSON形式なのでデコードする
data = json.loads(r.text)
print(data)

TwitterAPI Tokenを取得

Twitterで名前更新

  • twitter というモジュールを使う例が多かったのでpipで入れる
    • 後でLambdaに乗せる時ために、「-t」オプションをつけてスクリプトと同じ場所にインストール
    • pip install twitter -t .
  • コードを書いて実行
import twitter

# メモしたキーとアクセストークンを設定
auth = twitter.OAuth(consumer_key="Consumer Key (API Key)",
                     consumer_secret="Consumer Secret (API Secret)",
                     token="Access Token",
                     token_secret="Access Token Secret")

t = twitter.Twitter(auth=auth)
t.account.update_profile(name="山pです。")

ちなみに

  • Tweetする場合
    • t.statuses.update(status="ついーとするないよう")

天気を含めてTwitterの名前更新

import requests
import json
import twitter


SEARCH_CITY = "tokyo"
OPEN_WEATHER_MAP_API_KEY = "取得したAPI Key"
API_URL = "http://api.openweathermap.org/data/2.5/weather?q={city}&APPID={key}"

# https://openweathermap.org/weather-conditions
WEATHER_EMOJI_MAP = {
    "01d": "☀",  # clear sky
    "02d": "🌤",  # few clouds
    "03d": "☁",  # scattered clouds
    "04d": "⛅",  # broken clouds
    "09d": "🌧",  # shower rain
    "10d": "🌦",  # rain
    "11d": "🌩",  # thunderstorm
    "13d": "🌨",  # snow
    "50d": "🌁"  # mist
}


def get_weather_icon():

    # URIスキーム
    url = API_URL.format(city=SEARCH_CITY, key=OPEN_WEATHER_MAP_API_KEY)
    r = requests.get(url)
    # 結果はJSON形式なのでデコードする
    data = json.loads(r.text)
    return data["weather"][0]["icon"].replace("n", "d")


def get_weather_emoji():
    return WEATHER_EMOJI_MAP.get(get_weather_icon())


def update_twitter_screen_name(name):

    # メモしたキーとアクセストークンを設定
    auth = twitter.OAuth(consumer_key="Consumer Key (API Key)",
                        consumer_secret="Consumer Secret (API Secret)",
                        token="Access Token",
                        token_secret="Access Token Secret")

    t = twitter.Twitter(auth=auth)
    t.account.update_profile(name=name)


def main():
    emoji = get_weather_emoji()
    twitter_name = "山p" + emoji
    update_twitter_screen_name(twitter_name)


if __name__ == '__main__':
    main()
  • 天気を絵文字に変換するのがかなり面倒なので、ここでは種類が少ないiconを使って変換してます。
  • 正確に天気が欲しい場合には↓を見て変換すれば良いと思います。

Lambadaに乗せるために準備

コードを変更

  • mainではなく、eventとcontextを受け取るhandler関数を作成
    • 名前はなんでもいいけどとりあえず。
  • Lambdaで環境変数を設定できるので、コードからKeyなどを除去して環境変数から取得するようにする。
import requests
import json
import twitter
import os

SEARCH_CITY = os.environ["SEARCH_CITY"]
OPEN_WEATHER_MAP_API_KEY = os.environ["OPEN_WEATHER_MAP_API_KEY"]
TWITTER_CONSUMER_KEY = os.environ["TWITTER_CONSUMER_KEY"]
TWITTER_CONSUMER_SECRET = os.environ["TWITTER_CONSUMER_SECRET"]
TWITTER_TOKEN = os.environ["TWITTER_TOKEN"]
TWITTER_TOKEN_SECRET = os.environ["TWITTER_TOKEN_SECRET"]

API_URL = "http://api.openweathermap.org/data/2.5/weather?q={city}&APPID={key}"

# https://openweathermap.org/weather-conditions
WEATHER_EMOJI_MAP = {
    "01d": "☀",  # clear sky
    "02d": "🌤",  # few clouds
    "03d": "☁",  # scattered clouds
    "04d": "⛅",  # broken clouds
    "09d": "🌧",  # shower rain
    "10d": "🌦",  # rain
    "11d": "🌩",  # thunderstorm
    "13d": "🌨",  # snow
    "50d": "🌁"  # mist
}


def get_weather_icon():

    # URIスキーム
    url = API_URL.format(city=SEARCH_CITY, key=OPEN_WEATHER_MAP_API_KEY)
    r = requests.get(url)
    # 結果はJSON形式なのでデコードする
    data = json.loads(r.text)
    return data["weather"][0]["icon"].replace("n", "d")


def get_weather_emoji():
    return WEATHER_EMOJI_MAP.get(get_weather_icon())


def update_twitter_screen_name(name):
    # 取得したキーとアクセストークンを設定する
    auth = twitter.OAuth(consumer_key=TWITTER_CONSUMER_KEY,
                         consumer_secret=TWITTER_CONSUMER_SECRET,
                         token=TWITTER_TOKEN,
                         token_secret=TWITTER_TOKEN_SECRET)

    t = twitter.Twitter(auth=auth)
    t.account.update_profile(name=name)


def handler(event, context):
    emoji = get_weather_emoji()
    twitter_name = "山p" + emoji
    update_twitter_screen_name(twitter_name)

Zip圧縮

  • ここでわざわざライブラリをスクリプトと同じ場所に置いていることが生きてくる
  • フォルダ毎ではなくて、ファイルを直で圧縮
    • コマンド例 : zip -r upload.zip *

Lambadaに乗せる

参考