Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
1
Help us understand the problem. What is going on with this article?
@moi1990sk

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

More than 1 year has passed since last update.

はじめに

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
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
moi1990sk
都内でML&Webやってます。Python, PHP, Swift, ...
gig-inc
クリエイティブとテクノロジーでセカイをより良くする スタートアップ企業

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
1
Help us understand the problem. What is going on with this article?