2009-07-14 16 views
2

GoogleのAppEngineでPython関数デコレータを使用する際に問題があります。私はデコレータに精通しているわけではありませんが、特定の機能を実行する前にユーザーにログインさせたい場合には、ウェブプログラミングに役立つようです。Google App EngineのPython関数デコレータ

とにかく、私はflickrログインの例hereと一緒にdjangoを使い、flickrログインが必要な機能を装飾していました。このタイプのデコレータをAppEngineで動作させることはできません。

私はこれにそれを煮詰めてきました:

def require_auth(func): 
    def check_auth(*args, **kwargs): 
     print "Authenticated." 
     return func(*args, **kwargs) 
    return check_auth 

@require_auth 
def content(): 
    print "Release sensitive data!" 

content() 

このコードは、コマンドラインから動作しますが、私はGoogleAppEngineLauncher(OS用X)でそれを実行すると、私は次のエラーを取得する:

check_auth() takes at least 1 argument (0 given) 

そして私は、なぜ本当にわからないんだけど...

EDITは、実際のコードを含める:asperous.us @ 私は、可変引数を含むようにコンテンツ()の定義を変更し、ありますそれはあなたが意味することです @Alex Martelli、 'print'はAppEngine内で動作しますが、依然として完全に公正な批判です。 私が言ったように、私は上記のリンクからのflickrログインを使用しようとしています。私はそうのように私のアプリにそれを入れてみました:

def require_flickr_auth(view): 
    def protected_view(request,*args, **kwargs): 
     if 'token' in request.session: 
      token = request.session['token'] 
      log.info('Getting token from session: %s' % token) 
     else: 
      token = None 
      log.info('No token in session') 

     f = flickrapi.FlickrAPI(api_key, api_secret, 
           token=token, store_token=False) 

     if token: 
      # We have a token, but it might not be valid 
      log.info('Verifying token') 
      try: 
       f.auth_checkToken() 
      except flickrapi.FlickrError: 
       token = None 
       del request.session['token'] 

     if not token: 
      # No valid token, so redirect to Flickr 
      log.info('Redirecting user to Flickr to get frob') 
      url = f.web_login_url(perms='read') 
      print "Redirect to %s" % url 

     # If the token is valid, we can call the decorated view. 
     log.info('Token is valid') 
     return view(request,*args, **kwargs) 

    return protected_view 

@require_flickr_auth 
def content(*args, **kwargs): 
    print 'Welcome, oh authenticated user!' 

def main(): 
    print 'Content-Type: text/plain' 
    content() 

if __name__ == "__main__": 
    main() 

私は@require_flickr_auth装飾を削除すると、文字列が「ようこそ...」だけで罰金を出力します。そうでなければ私は底に

type 'exceptions.TypeError': protected_view() takes at least 1 argument (0 given) 

と大きな醜いAppEngineの例外ページを取得します。

答えて

3

あなたは引数なしでcontent()を呼び出していますが、装飾版​​にはrequest引数が必要です。引数をcontentに追加するか、​​から削除してください。

シンプルなバージョンでこのエラーが発生した場合は、contentがアレックスの提案するクラスメソッドであると思われます。そうでなければ、少なくとも1つの引数を期待して、それを供給しないようにしているように見えます。

+0

Doh - これだけです。ありがとう! – Owen

0

デコレータはPython 2.4で追加されました(おそらくgoogleappは古いバージョンを使用していますか?あなたも行うことができます :

def content(): 
    print "Release sensitive data!" 
    content = require_auth(content) 

それはデコレータと同じことをしますが、それはほんの少しより多くの仕事です。

+0

ええ、または少なくとも構文が変更されましたか?とにかく、AppEngineサイトでは、Pythonのバージョンが2.5.2であると主張しています。 – Owen

+0

いいえ、GAEはPython 2.5を使用しています。 –

+0

あなたはそうすることができると思いますよね?しかし、コンテンツ= require_auth(コンテンツ)は同じエラーを返します... – Owen

1

@Owenは、「少なくとも1つの引数をとります」というエラーは、クラス内で(つまりメソッドとして)コンテンツを定義していることを示しています。 GAEでそのコードを実行しますか?私。あなたのapp.yamlは何ですか& c?あなたはsilly.pyにそれを与えたとして、あなたは正確にあなたのコードを入れて、あなたのapp.yamlにあなたが持っている場合:

handlers: 
- url: /silly 
    script: silly.py 

をあなたはyourapp.appspot.com/sillyを訪問するとき、あなたは"GET /silly HTTP/1.1" 200 -内のほかのブラウザやログ(どちらかに絶対に何も表示されません後者はもちろん;-):エラーはありませんが、printは特に何もしません。だから私はあなたが私たちを示しているものとは別のコードを実行しようとした想像してい... - !)

0

なぜ

return func(*args, **kwargs)

はそれはFUNCを実行し、その結果を返さないでしょうか?

もしそうなら、引数を取らないので引数を与えてはいけません。 content()を編集して(*args, **kwargs)引数を追加した場合、それは機能しますか?

関連する問題