python argparse - 传递值WITHOUT命令行

时间:2015-06-27 15:41:49

标签: python google-api youtube-api argparse

我想我不理解python的argparse的基本内容。

我正在尝试将Google YouTube API用于python脚本,但我不了解如何在不使用命令行的情况下将值传递给脚本。

例如,here是API的示例。 github和其他地方的示例将此示例显示为从命令行调用,在调用脚本时从该命令行传递argparse值。

我不想使用命令行。我正在构建一个使用装饰器获取用户登录凭据的应用程序,当该用户想要上传到他们的YouTube帐户时,他们会提交一个表单,然后调用此脚本并将argparse值传递给它。

如何从其他python脚本将值传递给argparser(请参阅下面的YouTube上传API脚本中的部分代码)?

if __name__ == '__main__':
    argparser.add_argument("--file", required=True, help="Video file to upload")
    argparser.add_argument("--title", help="Video title", default="Test Title")
    argparser.add_argument("--description", help="Video description",
        default="Test Description")
    argparser.add_argument("--category", default="22",
        help="Numeric video category. " +
            "See https://developers.google.com/youtube/v3/docs/videoCategories/list")
    argparser.add_argument("--keywords", help="Video keywords, comma separated",
        default="")
    argparser.add_argument("--privacyStatus", choices=VALID_PRIVACY_STATUSES,
        default=VALID_PRIVACY_STATUSES[0], help="Video privacy status.")
    args = argparser.parse_args()

    if not os.path.exists(args.file):
        exit("Please specify a valid file using the --file= parameter.")

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

编辑:每个请求,这里是我使用标准方法初始化字典或使用argparse创建字典的400错误的回溯。我以为我是因为参数设置错误而得到的,但可能不是:

Traceback (most recent call last):
  File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 1535, in __call__
    rv = self.handle_exception(request, response, e)
  File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 1529, in __call__
    rv = self.router.dispatch(request, response)
  File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 1278, in default_dispatcher
    return route.handler_adapter(request, response)
  File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 1102, in __call__
    return handler.dispatch()
  File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 572, in dispatch
    return self.handle_exception(e, self.app.debug)
  File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 570, in dispatch
    return method(*args, **kwargs)
  File "C:\Users\...\testapp\oauth2client\appengine.py", line 796, in setup_oauth
    resp = method(request_handler, *args, **kwargs)
  File "C:\Users\...\testapp\testapp.py", line 116, in get
    resumable_upload(insert_request)
  File "C:\Users\...\testapp\testapp.py", line 183, in resumable_upload
    status, response = insert_request.next_chunk()
  File "C:\Users\...\testapp\oauth2client\util.py", line 129, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "C:\Users\...\testapp\apiclient\http.py", line 874, in next_chunk
    return self._process_response(resp, content)
  File "C:\Users\...\testapp\apiclient\http.py", line 901, in _process_response
    raise HttpError(resp, content, uri=self.uri)
HttpError: <HttpError 400 when requesting https://www.googleapis.com/upload/youtube/v3/videos?alt=json&part=status%2Csnippet&uploadType=resumable returned "Bad Request">

3 个答案:

答案 0 :(得分:6)

这是否是最好的方法真的让你弄明白。但是使用没有命令行的argparse是容易。我一直这样做,因为我有可以从命令行运行的批处理。或者也可以通过其他代码调用 - 这对于单元测试非常有用,如上所述。例如,argparse特别擅长默认参数。

从您的样本开始。

import argparse

argparser = argparse.ArgumentParser()
argparser.add_argument("--file", required=True, help="Video file to upload")
argparser.add_argument("--title", help="Video title", default="Test Title")
argparser.add_argument("--description", help="Video description",
    default="Test Description")
argparser.add_argument("--category", default="22",
    help="Numeric video category. " +
        "See https://developers.google.com/youtube/v3/docs/videoCategories/list")
argparser.add_argument("--keywords", help="Video keywords, comma separated",
    default="")
VALID_PRIVACY_STATUSES = ("private","public")
argparser.add_argument("--privacyStatus", choices=VALID_PRIVACY_STATUSES,
    default=VALID_PRIVACY_STATUSES[0], help="Video privacy status.")

#pass in any positional or required variables.. as strings in a list
#which corresponds to sys.argv[1:].  Not a string => arcane errors.
args = argparser.parse_args(["--file", "myfile.avi"])

#you can populate other optional parameters, not just positionals/required
#args = argparser.parse_args(["--file", "myfile.avi", "--title", "my title"])


print vars(args)

#modify them as you see fit, but no more validation is taking place
#so best to use parse_args.
args.privacyStatus = "some status not in choices - already parsed"
args.category = 42

print vars(args)

#proceed as before, the system doesn't care if it came from the command line or not
# youtube = get_authenticated_service(args)    

输出:

{'category': '22', 'description': 'Test Description', 'title': 'Test Title', 'privacyStatus': 'private', 'file': 'myfile.avi', 'keywords': ''}
{'category': 42, 'description': 'Test Description', 'title': 'Test Title', 'privacyStatus': 'some status not in choices - already parsed', 'file': 'myfile.avi', 'keywords': ''}

答案 1 :(得分:5)

使用您自己的字符串列表调用parse_args是一种常见的argparse测试方法。如果您不提供parse_args此列表,则会使用sys.argv[1:] - 即shell提供的字符串。 sys.argv[0]是条名。

args = argparser.parse_args(['--foo','foovalue','barvalue'])

构造args对象也很容易。

args = argparse.Namespace(foo='foovalue', bar='barvalue')

事实上,如果您从args电话打印parse_args,它应该看起来像那样。如文档中所述,Namespace是一个简单的对象,值是artributes。因此,构建自己的namespace类很容易。所有args都需要在用作以下内容时返回适当的值:

x = args.foo
b = args.bar

同样如文档中所述,vars(args)将此命名空间转换为字典。有些代码喜欢使用字典,但显然这些youtub函数需要Namespace(或等效的)。

get_authenticated_service(args)
initialize_upload(youtube, args)

https://docs.python.org/3/library/argparse.html#beyond-sys-argv

https://docs.python.org/3/library/argparse.html#the-namespace-object

https://developers.google.com/youtube/v3/guides/uploading_a_video?hl=id-ID

get_authenticated_serviceinitialize_upload代码

def initialize_upload(youtube, options):
  tags = None
  if options.keywords:
    tags = options.keywords.split(",")

  body=dict(
    snippet=dict(
      title=options.title,
      description=options.description,
      tags=tags,
      categoryId=options.category
    ),
    status=dict(
      privacyStatus=options.privacyStatus
    )
  )
 ....

解析器中的argsoptions,用作options.categoryoptions.title等。您可以替换具有相同行为的任何其他对象必要的属性。

答案 2 :(得分:0)

如果您不想使用命令行,为什么使用argparse? Argparse是用于解析命令行参数的模块,没有其他用途。您无法以其他方式将值传递给argparse。

我认为你想要的是一个显示html表单的web应用程序,向一些服务器处理程序发出POST请求,该处理程序将值从表单传递给api调用connect to youtube并执行你的python代码。根本不需要Argparse。您可以从表单中获取价值并将其传递给您的api电话。