LoginSignup
1
1

More than 5 years have passed since last update.

Django で Google API を使った時の args エラーについて

Posted at

はじめに

DjangoでGoogle API(私の場合はYoutubeDataAPI)を使おうとしたとき、Google側からサンプルコードを流用することがある。その際、コード中にargparserが用いられていることがあり、それがDjangoの以下のコードと衝突する問題がある。

$ python manage.py runserver
Performing system checks...

usage: manage.py [--auth_host_name AUTH_HOST_NAME] [--noauth_local_webserver]
                 [--auth_host_port [AUTH_HOST_PORT [AUTH_HOST_PORT ...]]]
                 [--logging_level {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [--q Q]
                 [--max-results MAX_RESULTS]
manage.py: error: unrecognized arguments: runserver

解決法

  • []を渡す

サンプルコードは、それ単独で実行することが前提であるため、以下のようにargsを定義することが多い。

args = argparser.parse_args()

しかし、DjangoのようなWebフレームワークを用いて、ローカルサーバーを立ち上げた時にその挙動を見たい、という場合にはrunserverがargsに吸収されてしまい、argparserにrunserverを渡すことになる。それによってunrecognized arguments: runserverが吐かれている。そして、manage.pyはというとrunserverが抜かれて引数がないため、usage:~~を表示している。単純な解決法は、次のようにする。

args = argparser.parse_args([])

これにより空のリストを渡し、argparserに特に渡す引数はないことを明示してやる。

  • argparserを消去

上の解決策は応急処置みたいなものである。根本的に解決するためには、argparserを消去し、適切にclassを作成して元のサンプルコードが必要とするインスタンスを渡してやる必要がある。

例えば、Youtube Data API(https://developers.google.com/youtube/v3/code_samples/python?hl=ja#search_by_keyword)の「キーワードで検索」を例にとったとき、

#!/usr/bin/python

from apiclient.discovery import build
from apiclient.errors import HttpError
from oauth2client.tools import argparser


# Set DEVELOPER_KEY to the API key value from the APIs & auth > Registered apps
# tab of
#   https://cloud.google.com/console
# Please ensure that you have enabled the YouTube Data API for your project.
DEVELOPER_KEY = "REPLACE_ME"
YOUTUBE_API_SERVICE_NAME = "youtube"
YOUTUBE_API_VERSION = "v3"

def youtube_search(options):
  youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION,
    developerKey=DEVELOPER_KEY)

  # Call the search.list method to retrieve results matching the specified
  # query term.
  search_response = youtube.search().list(
    q=options.q,
    part="id,snippet",
    maxResults=options.max_results
  ).execute()

  videos = []
  channels = []
  playlists = []

  # Add each result to the appropriate list, and then display the lists of
  # matching videos, channels, and playlists.
  for search_result in search_response.get("items", []):
    if search_result["id"]["kind"] == "youtube#video":
      videos.append("%s (%s)" % (search_result["snippet"]["title"],
                                 search_result["id"]["videoId"]))
    elif search_result["id"]["kind"] == "youtube#channel":
      channels.append("%s (%s)" % (search_result["snippet"]["title"],
                                   search_result["id"]["channelId"]))
    elif search_result["id"]["kind"] == "youtube#playlist":
      playlists.append("%s (%s)" % (search_result["snippet"]["title"],
                                    search_result["id"]["playlistId"]))

  print "Videos:\n", "\n".join(videos), "\n"
  print "Channels:\n", "\n".join(channels), "\n"
  print "Playlists:\n", "\n".join(playlists), "\n"


if __name__ == "__main__":
  argparser.add_argument("--q", help="Search term", default="Google")
  argparser.add_argument("--max-results", help="Max results", default=25)
  args = argparser.parse_args()

  try:
    youtube_search(args)
  except HttpError, e:
    print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content)

ここで if name 以降で --q と --max-result のサブコマンドを追加しているが、これは、youtube_search()でoptions.qと options.max-resultで参照されているだけである。よって、これに適合するようにclassを作成し、渡してやればよい。

youtube_data_model.py
class YouTubeData():
    def __init__(self, q, max_results):
        self.q = q
        self.max_results = max_results

今回のケースでは、上記のようにモジュールを作成し、

from .youtube_data_model import YouTubeData
#...
    ytdata = YouTubeData(q="Google", max_results=25)
    try:
        youtube_search(ytdata)
    except HttpError as e:
        print("An HTTP error %d occurred:\n%s" % (e.resp.status, e.content))

とすれば解決argparserを消去できたことになる。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1