目次


Python、Django、MongoDB を使用して Bluemix 上で世界銀行のデータをグラフ化するアプリを作成、デプロイする

Comments

世界銀行では、開発指標に関する膨大なデータを公開して無料でアクセスできるようにしています。そのデータは、世界各国の経済、健康、環境、エネルギー、インフラストラクチャー、貧困、社会的発展、教育、科学、テクノロジーなど多岐の分野にわたります。世界銀行のこれらのデータをグラフや図表に視覚化することができれば、これらの分野における各国の成長について、データ・アナリストが現状を把握するのに役立つはずです。

この記事では、世界銀行の API を使用してデータを取り出し、そのデータを理解しやすいグラフにレンダリングする Web ベースのグラフ生成アプリケーションを開発する方法を紹介します。

世界銀行がデータを公開していることから、開発者はそのデータを利用したアプリケーションを作成することができます。このアプリケーションは、政府が国の迅速な発展のために資源を最適に管理できるよう、是正・予防措置を講じる上で役立つものにすることができます。この記事では、世界銀行の API によってデータを取り出し、そのデータを理解しやすいグラフにレンダリングする Web ベースのグラフ生成アプリケーションを開発する方法を紹介します。

コードと説明が複雑にならないよう、私が作成するグラフ生成アプリケーションでは、各国のエネルギー消費傾向を明らかにすることにフォーカスします。エネルギー消費に関するダッシュボードから、太陽光、バイオマス、水力、風力、地熱などの各種エネルギー源の各国での消費傾向を迅速に把握できるようにします。

アプリケーションについて

このアプリケーションは、IBM Bluemix 上で Python、Django、および (データ・キャッシュとして) MongoDB を使用して開発します。フロントエンドの設計には、Highcharts という JavaScript グラフ生成エンジンによって公開されているグラフ生成用の API を使用します。Highcharts を使用することで、ユーザーはグラフを印刷したり、画像または PDF としてグラフをダウンロードしたりすることもできます。Django は Web アプリケーションの迅速な開発を促す、Python ベースのオープンソース Web アプリケーション・フレームワークです。Django では、ユーザーが簡潔で保守しやすいコードを作成できるようになっています。Django を使用している有名なサイトには、Pinterest、Instagram、Mozilla、The Washington Times、Disqus、Public Broadcasting Service などがあります。

このアプリケーションに対して統計やメトリック (例えば、米国の太陽光エネルギー消費量など) を問い合わせると、アプリケーションは世界銀行の REST API を使用して該当するメトリックに関連付けられた JSON データを取得し、PyMongo セッションを使用してそのデータを MongoDB のコレクションに格納します。このデータは MongoDB に 1 日間キャッシュしておき、同じ統計を要求する問い合わせに対しては、世界銀行の API に対して問い合わせを行うのではなく、MongoDB のキャッシュからデータを取り出して提供します。データ・キャッシュは毎日リフレッシュして、アプリケーションに対する最初の呼び出しによって再びデータが取り込まれるようにします。

記事の最後のセクションでは、このアプリケーションを Bluemix にデプロイするのがいかに簡単であるかを示します。Bluemix は、アプリケーションとサービスを作成、管理、実行するための、オープン・スタンダードとクラウドをベースとした IBM のプラットフォームです。

それでは早速、グラフ生成アプリケーションの作成に取り掛かりましょう!

アプリケーションを作成するために必要となるもの

Iアプリケーションを直接 Bluemix にデプロイして、ローカルで開発しないという方法を選択する場合は、この記事のステップ 1 からステップ 3 をスキップして、「ステップ 4. アプリケーションを Bluemix にデプロイする」に進んでも構いません。ソース・コードは IBM DevOps Services リポジトリーから複製することができます。それには、以下のコマンドを使用します。

git clone https://hub.jazz.net/git/mamtasharma/trendsapp001

上記の「コードを入手する」ボタンをクリックすれば、IBM DevOps Services を使用してオンラインで完全なコードを参照することもできます。コードの詳しい説明については、この記事の「ステップ 3. グラフ生成アプリケーションを作成して構成する」を参照してください。

ステップ 1. Django プロジェクトをセットアップする

  1. Python と Django をインストールします。ローカルでセットアップする場合は、必ず Python をインストールしてから Django をインストールしてください。
  2. Django プロジェクトを作成します。Django でのプロジェクトとは、Django のインスタンスに対する設定の集まりであり、その中にはデータベース構成、Django 固有のオプション、アプリケーション固有の設定などが含まれます。Django プロジェクトを作成するには、以下のコマンドを実行します。
    django-admin.py startproject trends_app

    startproject コマンドにより、trends_app という名前のディレクトリーが作成され、そこに以下の 5 つのファイルが生成されます。これらのファイルによって、実際に動作する Django アプリケーションは構成されています。

    trends_app/
        manage.py
        trends_app/
            __init__.py
            settings.py
            urls.py
            wsgi.py
  3. Django について十分理解している場合は、以下に記載する各ファイルの詳細な説明を読み飛ばして構いません。そうでない場合は、これらの簡単な説明が、各ファイルの役割に関する基本知識を得るのに役立つはずです。
    • trends_app/: 上位にある trends_app/ ディレクトリーは、Django プロジェクトのコンテナーのような役割を果たします。
    • manage.py: Django プロジェクトを扱うためのコマンドライン・ユーティリティー。「python manage.py」と入力すると、使用可能なコマンドのリストが表示されます。
    • trends_app/trends_app/: 内側にある trends_app/trends_app ディレクトリーは、プロジェクトの実際の Python パッケージです。このディレクトリーの名前が Python パッケージ名となります。例えば、「import trends_app.settings」といったコマンドによって、このディレクトリー内に何かをインポートする場合には、この名前を使用する必要があります。
    • __init__.py: このファイルは、Python が trends_app/ ディレクトリーをパッケージ (Python モジュールから成るグループ) として扱うために必要です。
    • settings.py: この Django プロジェクトの設定/構成。
    • urls.py: この Django プロジェクトの各 URL。Django で駆動するサイトの「目次」とみなしてください。
    • wsgi.py: WSGI 対応 Web サーバーがプロジェクトに対応する際のエントリー・ポイント。

ステップ 2. 開発用サーバーを起動する

Django には、軽量の開発用 Web サーバーが組み込まれています。このサーバーは、ソース・コードに変更を加えるたびに自動的にリロードされるようになっています。

  1. サーバーを起動するには、カレント・ディレクトリーをプロジェクトのコンテナー・ディレクトリーに変更し (cd trends_app)、以下のコマンドを実行します。
    python manage.py runserver

    以下のメッセージが表示された場合、それはサーバーがローカルのポート 8000 で起動されることを意味します。

    Validating models...
    
    0 errors found
    August 25, 2014 - 21:51:25
    Django version 1.6.5, using settings 'trends_app.settings'
    Starting development server at http://127.0.0.1:8000/
    Quit the server with CTRL-BREAK.
  2. Web ブラウザーで http://127.0.0.1:8000/ にアクセスすると、Django で駆動された最初のページが表示されます。Django で駆動された最初のページ
    Django で駆動された最初のページ

ステップ 3. グラフ生成アプリケーションを作成して構成する

  1. サンプル Django アプリケーションを作成します。以下のコマンドを用いると、trends という名前の Django アプリケーションが作成されます。
    django-admin.py startapp trends
  2. 以下に記載するコードを使用するように settings.py ファイルを変更します。
    INSTALLED_APPS = (
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.sites',
        'django.contrib.messages',
        trends,
    )
  3. ここで、URL マッピングを構成します。URL マッピングは、アプリケーションへのアクセスがどのように行われるかを指定するものです。以下のコード・リストに trends_app/urls.py ファイルがどのような内容になっているかを示します。
    from django.conf.urls import include, url
    
    urlpatterns = [
        url(r'^trends/', include('trends.urls'))
    ]
  4. trends/urls.py ファイルの内容を変更し、URL fetch_and_draw_data/fetch_and_draw_data()ビュー関数にマッピングするコードを含めるようにします (以下のコード・リストを参照)。trends/urls.py ファイルで URL をビュー関数にマッピングすることにより、Django はビュー関数がどこにあるのかを把握できるようになります。
    urlpatterns = [
        url(r'^$', views.index, name='index'),
        url(r'^fetch_and_draw_data/', views.fetch_and_draw_data, name='fetch_and_draw_data'),
    ]
  5. 以下の fetch_and_draw_data() という名前のビュー関数を trends/views.py ファイルに含めるようにします。これにより、trends/views.py ファイルには、リクエストを引数として受け取ってレスポンスを返す Python 関数が含まれるようになります。この場合のリクエストは、通常は Web サーバーからのリクエストです。ビューはリクエストに伴って渡されたすべてのパラメーターを取得した後、適切なレスポンスを決定するために必要なロジックを実行します。
    def fetch_and_draw_data(request):
        connect.initialize()
        country = request.GET.get('country', 'USA')
        metric = request.GET.get('metric', 'Total')
    
        country_code = countries_mapping[country]
        indicator_code = indicators_mapping[metric]
        data_url = get_url(country_code, indicator_code)
        json_from_cache = connect.get_json_data(data_url)
        ...
        //create a data list
        data_list = {"graphTitle": graphTitle ,"xAxisLabels" : xAxisLabels,
        "xAxisTitle" : xAxisTitle, "yAxisTitle" : yAxisTitle, "yAxisValues" : yAxisValues}
        return HttpResponse(simplejson.dumps(data_list))
  6. trends/connect.py という名前の新規ファイルを作成して、そこに initialize() 関数を追加します。trends/connect.py ファイルの役割は、MongoDB への接続を確立することです。接続を確立するには、MongoDB に対する Python インターフェースである PyMongo が使用されます。PyMongo は、initialize() 関数の呼び出しによって MongoDB 内で初期化されます。

    以下のコード・スニペットには、Bluemix の VCAP_SERVICE 変数から取得した接続資格情報を使用して PyMongo セッションを確立する方法が示されています (ここでは、MongoDB サービスのインスタンスが Bluemix 上で実行中になっていることが前提となっています)。

    # Initialize MongoDB connection with credentials from vcap config
    def initialize():
      # If connection is not initialized, initialize it.
      if not config.initialized:
        #Get the connection credentials from VCAP variables
        vcap_config = os.environ.get('VCAP_SERVICES')
        decoded_config = json.loads(vcap_config)
        for key, value in decoded_config.iteritems():
             if key.startswith('mongodb'):
                 mongo_creds = decoded_config[key][0]['credentials']
        mongo_url = str(mongo_creds['url'])
    
        client = pymongo.MongoClient(mongo_url)
        config.db = config.client['db']
        config.collection = config.db['mycollection']
        config.collection.remove({})
        config.initialized=True
        refresh()
  7. trends/connect.py ファイルに refresh() 関数を追加します。refresh() 関数は、initialize() 関数が実行されると呼び出され、24 時間ごとに実行される周期タスクになっています。この周期タスクでは、MongoDB のコレクションに含まれる既存のデータをクリーンアップし、次にアプリケーションが呼び出されたときに、世界銀行の REST URL からデータが取得されるようにします。
    # Periodic task to purge data from MongoDB collection
    def refresh():
      config.collection.remove({})
      threading.Timer(86400, refresh).start()
  8. trends/views.py ファイルに get_url() 関数を追加します。リクエスト・パラメーターとして受け取った国名とメトリック名 (例えば、「Solar Energy Consumption (太陽光エネルギー消費量)」など) がコードにマッピングされて get_url() 関数に渡されると、この関数は渡された引数を基に API の URL を構成します (以下のコード・リストを参照)。
    def get_url(country_code, indicators):
      return ("http://api.worldbank.org/countries/%s/indicators/%s?per_page=10&date=2000:2010&format=json" % (country_code, indicators)) ;
  9. trends/connect.py ファイルに get_json_data() 関数を追加します。この関数は、該当する URL が MongoDB のコレクションに既に存在しているかどうかを確認します。この URL のエントリーが見つからなければ、API の URL を呼び出して JSON フォーマットのデータを取得し、そのデータを MongoDB のコレクションにキャッシュします。エントリーが見つかった場合は、キャッシュから既存の URL に対応するデータを返します。

    以下のコード・リストには、get_json_data() 関数を呼び出すことで、データの取得とキャッシングがどのように行われるかが示されています。

    # Hit the World Bank url to retrieve data
    def get_json_data(data_url):
      # If data is in cache, return it
      if(config.collection.find_one({"url": data_url}) is not None):
        return config.collection.find_one({"url": data_url})["jsonData"]
      # Fetch it from MongoDB otherwise
      else:
        response = urllib2.urlopen (data_url)
        jsonData = simplejson.load(response)
        config.collection.insert({'url': data_url, 'jsonData' : jsonData})
        return jsonData
  10. trends_app ディレクトリー内に、templates という名前のディレクトリーを作成します。続いて templates ディレクトリー内に index.html という名前のファイル (このプロジェクトの唯一のテンプレート) を追加して、そこに Highcharts JS ライブラリーをインポートします。Highcharts JS は、柔軟かつ単純な方法でデータを対話型グラフの形にレンダリングできることで評判の高い JavaScript グラフ生成エンジンです。

    以下のコード・リストには、Highcharts をインポートするコードが示されています。

     # Import highchart javascript
    <script src="//code.highcharts.com/highcharts.js"></script>
    <script src="//code.highcharts.com/modules/exporting.js"></script>
  11. index.html ファイルに JavaScript の fetch_and_draw() 関数を追加します。この関数は、バックエンドの fetch_and_draw_data ビュー関数に対して Ajax 呼び出しを行います (以下のコード・リストを参照)。
     $.ajax({
                    url : "/trends/fetch_and_draw_data",
                    type : "GET",
                    dataType: "json",
                    data : {
                        csrfmiddlewaretoken: '{{ csrf_token }}',
                        country : country,
                        metric : metric
                    },

    タブ・メニューからメトリックが選択された時点、またはドロップダウン・メニューから国が選択された時点で、tab_id が取得されて fetch_and_draw() 関数が呼び出されます。するとこの関数が fetch_and_draw_data URL に対して Ajax 呼び出しを行って、バックエンドからデータを取得します。そして最後に Highcharts を使用して棒グラフがレンダリングされるという仕組みです。以下のコード・スニペットに、JavaScript の fetch_and_draw() 関数の呼び出しが示されています。

    $('#tabs').tabs({
            activate: function(event ,ui){
              var tab_id = ($("#tabs").tabs('option', 'active'));
              tab_id += 1;
              fetch_and_draw(tab_id);
    
            }
        });
    
    
    $('#countries_id').change(function()
            {
              var tab_id = ($("#tabs").tabs('option', 'active'));
              tab_id += 1;
              fetch_and_draw(tab_id);
    
        });

    views.py ファイルおよび index.html ファイルの完全なコード・リストは、IBM DevOps Services で参照することができます。

ステップ 4. アプリケーションを Bluemix にデプロイする

アプリケーションのコーディングが完了したら、次は、アプリケーションを Bluemix にデプロイします。

  1. プロジェクトのルート・ディレクトリーに requirement.txt ファイルを追加します。requirement.txt ファイルには、グラフ生成アプリケーションを実行するために必要なすべての外部依存関係 (Django や PyMongo など) を含める必要があります。このアプリケーションが実行されたときに、requrement.txt ファイルが読み取られること、そしてこのファイルに記載されている依存関係がインストールされることが、Bluemix によって確実になります。

    このプロジェクトに必要な requirement.txt ファイルの中身は以下のとおりです。

    Django==1.6.5
    pymongo==2.7.1
  2. プロジェクトのルートに run.sh ファイルを作成します。run.sh ファイルは、Web アプリケーションが Bluemix にデプロイされた後にそのアプリケーションを起動するシェル・スクリプトです。Web サーバーの起動時に、ポートの値が VCAP_APP_PORT 環境変数から取得されるようにしてください。

    そのためには、以下の行を run.sh ファイルに追加します。

    #!/bin/bash
    if [ -z "$VCAP_APP_PORT" ];
    then SERVER_PORT=5000;
    else SERVER_PORT="$VCAP_APP_PORT";
    fi
    echo port is $SERVER_PORT
    python manage.py runserver --noreload 0.0.0.0:$SERVER_PORT
  3. アプリケーションをアップロードしたり管理したりする際に使用する Cloud Foundry (cf) コマンドライン・ツールをダウンロードしてインストールします。Cloud Foundry が正常にインストールされたことを検証するには、以下のコマンドを実行してバージョンを表示します。
    cf --version
  4. Bluemix にログインして、エンドポイントを設定します。Bluemix に CLI からログインするには、以下のコマンドを実行します。
    cf login -a https://api.ng.bluemix.net
  5. アプリケーションを Bluemix にプッシュします。それにはカレント・ディレクトリーをプロジェクトのルート (trends_app/) に変更し、グラフ生成アプリケーションを Bluemix にアップロードするために、以下のコマンドを実行します。
    cf push  trendsapp001 --no-manifest --no-start -b https://github.com/cloudfoundry/python-buildpack  -c "sh run.sh"

    --no-start オプションは、アプリケーションが必須サービスにバインドされていない場合には、アプリケーションは起動されないことを示しています。このオプションにより、アプリケーションが起動される前に MongoDB サービスがアプリケーションにバインドされることが確実になります。

    -c オプションは、アプリケーションの起動中に Bluemix が実行する開始コマンドを指定するために使用します。

    The -b フラグは、使用するビルドパックを指定します。このグラフ生成アプリケーションには Python ランタイムが必要なので、このランタイムを取得するために Python ビルドパックの Git リポジトリー URL (https://github.com/cloudfoundry/python-buildpack) を -b オプションで指定しています。

    以下のように、manifest.yml 構成ファイルの中でアプリケーション名、ビルドパック情報、sh run.sh コマンドを指定することもできます。

    ---
    applications:
    - name: trendsapp001
      memory: 256M
      command: sh run.sh
      buildpack: https://github.com/cloudfoundry/python-buildpack
  6. manifest.yml ファイルをプロジェクトのルートに含めます。manifest.yml ファイルを使用する場合、以下のコマンドを使用してアプリケーションを Bluemix にプッシュします。
    cf push  --no-start

    生成される URL ルートがデモ用 URL と競合しないように、必ず別のホスト名を選択してください。グラフ生成アプリケーションを Bluemix にプッシュすると、以下のような画面が表示されます。

    cf push コマンドの出力のスクリーン・キャプチャー
    cf push コマンドの出力のスクリーン・キャプチャー
  7. MongoDB サービスのインスタンスを作成します。ターミナル・ソフトで、カレント・ディレクトリーをプロジェクトのルートに変更し、以下のコマンドを入力することで、一意の名前を持つ MongoDB サービス・インスタンスが作成されます。
    cf create-service mongodb 100 mongodb001
  8. MongoDB サービス・インスタンスを新規アプリケーション (この例では trendsapp001) にバインドするために、以下のコマンドを入力します。
    cf bind-service trendsapp001 mongodb001

    あるいは MongDB サービス・インスタンスを作成する別の方法として、Bluemix 管理ダッシュボードにログインし、「APPS (アプリ)」メニューからグラフ生成アプリケーションを見つけます。

    Bluemix ダッシュボード ― アプリケーションのリスト
  9. 作成した新規アプリケーションを選択します。この操作によって表示されるページで、「Add Service (サービスの追加)」オプションを使用して MongoDB サービスをアプリケーションに追加します。Bluemix ダッシュボードで MongoDB をサービスとして追加する画面のスクリーン・キャプチャー
    Bluemix ダッシュボードで MongoDB をサービスとして追加する画面のスクリーン・キャプチャー

    Bluemix 管理ダッシュボードには、アプリケーションにバインドされた MongoDB サービス・インスタンスが表示されます。

    バインドされたサービスが表示された Bluemix ダッシュボードのスクリーン・キャプチャー
    バインドされたサービスが表示された Bluemix ダッシュボードのスクリーン・キャプチャー

    MongoDB サービス・インスタンスをアプリケーションにバインドした後は、以下の構成が VCAP_SERVICES 環境変数に追加されます。

    BBluemix ダッシュボード ― 環境変数
    BBluemix ダッシュボード ― 環境変数
  10. 以下のコマンドを実行してアプリケーションを起動します。
    cf start trendsapp001
  11. trendsapp001.mybluemix.net/trends にアクセスして (「trendsapp001」は、manifest.yml ファイルの中で指定した固有のホスト名に置き換えてください)、グラフ生成アプリケーションを表示します。また、この記事の最初のほうにある「アプリを実行する」ボタンをクリックして、ライブ・デモを試してください。

    以下のスクリーン・キャプチャーには、このアプリケーションに表示された、米国の太陽光エネルギー消費量のグラフが示されています。画面右側にあるメニューの項目をクリックすることで、このグラフを印刷することや、画像としてまたは PDF 形式でグラフをダウンロードすることができます。

    Sエネルギー消費量を示すダッシュボードのスクリーン・キャプチャー
    Sエネルギー消費量を示すダッシュボードのスクリーン・キャプチャー

まとめ

この記事では、Bluemix プラットフォーム上で Django アプリケーションを作成してデプロイする方法をデモンストレーションしました。また、Bluemix MongoDB サービスをデータ・キャッシュとして使用する方法、このサービスを Django フレームワークに統合する方法についても詳しく説明しました。この記事で紹介したグラフ生成アプリケーションのソース・コードは、IBM DevOps Services のリポジトリーからダウンロードすることができます。このリポジトリーには、アプリケーションを起動させて実行状態にするために必要なすべての構成ファルも格納されています。このグラフ生成アプリケーションを作成した今では、皆さんはそのプロセスを独自のプロジェクトに適用できるはずです。可能性は無限に広がります!


ダウンロード可能なリソース


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Cloud computing
ArticleID=996593
ArticleTitle=Python、Django、MongoDB を使用して Bluemix 上で世界銀行のデータをグラフ化するアプリを作成、デプロイする
publish-date=02052015