SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Google App Engineで開発するスケールするアプリケーション

Google App Engineで開発するスケールするアプリケーション(後編)

Google App EngineとTwitterの連携アプリケーション構築

  • X ポスト
  • このエントリーをはてなブックマークに追加

ユーザーデータ取得処理

 Twitterのユーザデータを保存するためのクラス(Kind)を定義したところで、次はTwitterからユーザデータを取得する処理を実装します。処理の概要は中編の図7などを参照してください。

初期データ作成処理

 本稿のアプリケーションでは、最初の1件のユーザを追加する処理は、開発者がブラウザからURLを入力し動作させる必要があります。以下に実装について説明します。

初期データ作成用リクエストハンドラ

 初期データを作成するための処理URLは「http://ホスト名/ciu」というURLでアクセスします。このURLのためのリクエストハンドラはmain.pyに以下のように記述します。

リスト2 main.py 初期データ作成用ハンドラ処理
class CreateInitUserHandler(webapp.RequestHandler):
    # 初期ユーザ1件を作成するためのメソッド
    def get(self):
        screen_name = 'haru860'    # 初期ユーザのscreen_name
        _put_tw_user(screen_name)  # TwitterUserの保存
        _put_wait_get_related_data(screen_name) # 擬似キューへの保存

 リクエストハンドラとは、HTTPのメソッド(GETや、POST)を受け付ける処理で、getやpostという名前のメソッドにリクエスト受付時の処理を実装します。

リクエストハンドラのアプリケーションへの追加

 リクエストハンドラをアプリケーションに追加するには、リスト3のようにwebapp.WSGIApplicationのコンストラクタにURLのマッピングとハンドラクラスを渡し、インスタンスを生成します。その後、wsgiref.handlers.CGIHandler().run(application)で、アプリケーションが起動されます。

リスト3 main.py 初期データ作成用ハンドラ処理
def main():
    application = webapp.WSGIApplication([
        ('/', MainHandler)
        ('/ciu', CreateInitUserHandler),
        ],
        debug=True)
    wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__':
    main()

Twitterユーザ生成処理

 _put_tw_userメソッドは、引数で渡されたscreen_nameに該当するTwitterのユーザデータをDatastoreに保存する処理です。ソースを以下に示します。

リスト4 main.py _put_tw_userメソッド
from models import TwitterUser
import twitterutil as twutil

def _put_tw_user(screen_name):
    # screen_nameに該当するデータを取得する
    tw_user = TwitterUser.get_by_key_name(screen_name)

    # 既に存在する場合は、そのデータを返す
    if tw_user != None:
        return tw_user

    # Twitter APIにアクセスしてユーザデータを取得する
    user = twutil.create_twitter_user(screen_name)

    # Counterクラスから連番を取得する
    user.seq = Counter.next_id('TwitterUser')
    user.put()
    return user

 次にTwitterのユーザ属性取得API(http://twitter.com/users/show/$screen_name.xml)にアクセスし、ユーザデータを取得するcreate_twitter_userメソッドを以下に示します。

リスト5 twitterutil.py create_twitter_userメソッド
def create_twitter_user(screen_name):
    url = 'http://twitter.com/users/show/' + screen_name + '.xml'
    return _create_twitter_user_by_xmlstr(_get_api_response(url))

 get_api_responseメソッドは引数で指定されたURLにアクセスし、レスポンス文字列を返すメソッドです。ここでは、取得したXML文字列を_create_twitter_user_by_xmlstrメソッドに渡して、TwitterUserエンティティを返しています。_get_api_responseメソッドと_create_twitter_user_by_elementメソッドのソースをそれぞれリスト6、7 に示します。

リスト6 _get_api_responseメソッド
def _get_api_response(url):
    # ベーシック認証でTwitterにアクセスする
    base64string = base64.encodestring("%s:%s" % ("haru860", "passwordxx"))[:-1]
    headers = {"Authorization": "Basic %s" % base64string}
    # URL Fetch APIを使用
    return urlfetch.fetch(url,payload=None,method=urlfetch.GET,headers=headers).content
リスト7 _create_twitter_user_by_elementメソッド
def _create_twitter_user_by_xmlstr(xml_string):
    user_elem = etree.fromstring(xml_string)
    return _create_twitter_user_by_element(user_elem)

 リスト7から呼んでいる_create_twitter_user_by_elementメソッドはXML要素をもとにTwitterUserエンティティを返すメソッドですが、ここではソースの説明を割愛します。

Counter用クラス

 リスト3ではCounterクラスのnext_idメソッドを呼び出して連番を取得していますが、Counterクラスはその名前の通り、連番を生成するためのクラスです。以下にCounterクラスのソースを示します。

リスト8 models.py Counterクラスの作成
class Counter(db.Model):
    count = db.IntegerProperty()
    @classmethod
    def next_id(cls, name):
        def txn():
            obj = cls.get_by_key_name(name)
            if obj is None:
                obj = cls(key_name=name,count=0)
            obj.count += 1
            obj.put()
            return obj.count
        return db.run_in_transaction(txn)

 next_idメソッドは、引数にカウンタの名前を取り、その名前ごとのカウンタ値を保持したエンティティをDatastoreに保存します。next_idメソッド内では、txn()という関数オブジェクトを作成し、db.run_in_transaction(txn)に引数で渡しています。これは引数で渡した関数オブジェクト内に記述された処理のトランザクションを保証するための仕組みです。

関連ユーザデータ収集用エンティティ格納処理

 リスト2の初期データ作成用ハンドラ(CreateInitUserHandler)のpostメソッドでは、新規TwitterUserエンティティを1件作成すると同時に、WaitGetRelatedDataエンティティを1件作成します。WaitGetRelatedDataエンティティは、中編のユーザデータ取得処理で説明しているように、擬似的なキューとして使用されるエンティティです。_put_wait_get_related_dataは引数で渡されたscreen_nameをWaitGetRelatedDataエンティティの属性に格納してDatastoreに保存するという単純な処理なのでソースは割愛します。

次のページ
ユーザデータ収集処理

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Google App Engineで開発するスケールするアプリケーション連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 佐藤 治夫 (株式会社ビープラウド)(サトウ ハルオ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/5023 2010/04/19 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング