2012-07-23 2 views
2

내 RequestHandler 객체를 만들 때 목록을 제공하는 대신 응용 프로그램을 꾸며서 내 RequestHandler 객체에 경로를 정의하고 싶습니다.Google 애플리케이션 엔진을 사용하는 webapp2 데코레이터 경로

내 WSGIApplication는 다음과 같이 정의된다 :

class WSGIApplication(webapp2.WSGIApplication): 
    def __init__(self, *args, **kwargs): 
     super(WSGIApplication, self).__init__(*args, **kwargs) 
     self.router.set_dispatcher(self.__class__.custom_dispatcher) 

    @staticmethod 
    def custom_dispatcher(router, request, response): 
     rv = router.default_dispatcher(request, response) 
     if isinstance(rv, basestring): 
      rv = webapp2.Response(rv) 
     elif isinstance(rv, tuple): 
      rv = webapp2.Response(*rv) 

     return rv 

    def route(self, url, name): 
     def outer_wrapped(cls): 
      logging.info("Adding route %s to class %s with name %s" 
         % (url, cls, name)) 
      self.router.add(RedirectRoute(url, cls, 
              name=name, 
              strict_slash=True)) 
      return cls 
     return outer_wrapped 

package.utils에 내가 내 응용 프로그램 package.application

애플리케이션 제목에 정의는

application: theapplication 
version: 1 
runtime: python27 
api_version: 1 
threadsafe: yes 

handlers: 
- url: .* 
    script: package.main.application 
    secure: always 

package.main가 같습니다있다 follo WS :

from package.application import application 
from package.pages import pages 

package.application은 다음과 같습니다 (비밀 키 함께 해시) : 여기

from package import utils 

conf = {} 
conf['webapp2_extras.sessions'] = {'secret_key': 
    """##############################################"""} 

application = utils.WSGIApplication([], config=conf) 

을하고 package.pages에서 핸들러의 커플 :

from package.application import application as app 


@app.route('/conversations', 'view_messages') 
class Messages(BaseHandler): 
    @users.require_login 
    def get(self): 
     conversations = self.current_user.get_user_conversations() 
     return self.render('conversations.slim', conversations=conversations) 


@app.route('/', 'index') 
class Index(BaseHandler): 
    def get(self): 
     return self.render('index.slim') 

인덱스 페이지 작품 좋아, 다른 모든 404s, 로그 단순히 말합니다 :

INFO  2012-07-23 14:23:46,258 __init__.py:26] /notifications 
INFO  2012-07-23 14:23:46,272 dev_appserver.py:2952] "GET /notifications HTTP/1.1" 404 - 

이것은 appengine의 가져 오기 캐싱으로 인해 발생하는 것으로 가정하여 데코레이터가 실행되는 것을 방지하고 앱에 자신을 추가하는 것을 방지합니다.

당연히 나는 문제의 원인이 무엇인지에 대한 단서가 있다고 가정하고 함정에 빠져 들었습니다. 나는 각각의 파견을 시도하기 전에 출력 경로의 목록을 추가 로깅 문을 추가하고 나는 하나가 예상하는대로 경로의 모든 라우터에있는 것을 발견 : 다음 로그 출력으로

... 
    def custom_dispatcher(router, request, response): 
     logging.info(router.match_routes) 
     logging.info(router.build_routes) 
     rv = router.default_dispatcher(request, response) 
    ... 

을/내 브라우저를 가리키는 대화 :

INFO  2012-08-04 13:16:40,513 utils.py:13] [<Route('/friendship', <class 'package.pages.pages.Friendship'>, name='friendship', defaults={}, build_only=False)>, <Route('/friendship/', <class 'webapp2.RedirectHandler'>, name=None, defaults={'_uri': <bound method RedirectRoute._redirect of <Route('/friendship', <class 'package.pages.pages.Friendship'>, name='friendship', defaults={}, build_only=False)>>, '_name': 'friendship'}, build_only=False)>, <Route('/signup', <class 'package.pages.pages.Signup'>, name='signup', defaults={}, build_only=False)>, <Route('/signup/', <class 'webapp2.RedirectHandler'>, name=None, defaults={'_uri': <bound method RedirectRoute._redirect of <Route('/signup', <class 'package.pages.pages.Signup'>, name='signup', defaults={}, build_only=False)>>, '_name': 'signup'}, build_only=False)>, <Route('/preferences', <class 'package.pages.pages.UserPage'>, name='user_prefs', defaults={}, build_only=False)>, <Route('/preferences/', <class 'webapp2.RedirectHandler'>, name=None, defaults={'_uri': <bound method RedirectRoute._redirect of <Route('/preferences', <class 'package.pages.pages.UserPage'>, name='user_prefs', defaults={}, build_only=False)>>, '_name': 'user_prefs'}, build_only=False)>, <Route('/<username:[a-zA-Z]+>', <class 'package.pages.pages.UserPage'>, name='user_page', defaults={}, build_only=False)>, <Route('/<username:[a-zA-Z]+>/', <class 'webapp2.RedirectHandler'>, name=None, defaults={'_uri': <bound method RedirectRoute._redirect of <Route('/<username:[a-zA-Z]+>', <class 'package.pages.pages.UserPage'>, name='user_page', defaults={}, build_only=False)>>, '_name': 'user_page'}, build_only=False)>, <Route('/message', <class 'package.pages.pages.SendMessagePage'>, name='send_message', defaults={}, build_only=False)>, <Route('/message/', <class 'webapp2.RedirectHandler'>, name=None, defaults={'_uri': <bound method RedirectRoute._redirect of <Route('/message', <class 'package.pages.pages.SendMessagePage'>, name='send_message', defaults={}, build_only=False)>>, '_name': 'send_message'}, build_only=False)>, <Route('/conversations', <class 'package.pages.pages.Messages'>, name='view_messages', defaults={}, build_only=False)>, <Route('/conversations/', <class 'webapp2.RedirectHandler'>, name=None, defaults={'_uri': <bound method RedirectRoute._redirect of <Route('/conversations', <class 'package.pages.pages.Messages'>, name='view_messages', defaults={}, build_only=False)>>, '_name': 'view_messages'}, build_only=False)>, <Route('/conversation/<conversation_id>', <class 'package.pages.pages.ConversationPage'>, name='conversation', defaults={}, build_only=False)>, <Route('/conversation/<conversation_id>/', <class 'webapp2.RedirectHandler'>, name=None, defaults={'_uri': <bound method RedirectRoute._redirect of <Route('/conversation/<conversation_id>', <class 'package.pages.pages.ConversationPage'>, name='conversation', defaults={}, build_only=False)>>, '_name': 'conversation'}, build_only=False)>, <Route('/boards', <class 'package.pages.pages.Boards'>, name='view_boards', defaults={}, build_only=False)>, <Route('/boards/', <class 'webapp2.RedirectHandler'>, name=None, defaults={'_uri': <bound method RedirectRoute._redirect of <Route('/boards', <class 'package.pages.pages.Boards'>, name='view_boards', defaults={}, build_only=False)>>, '_name': 'view_boards'}, build_only=False)>, <Route('/boards/<board>', <class 'package.pages.pages.BoardPage'>, name='view_board', defaults={}, build_only=False)>, <Route('/boards/<board>/', <class 'webapp2.RedirectHandler'>, name=None, defaults={'_uri': <bound method RedirectRoute._redirect of <Route('/boards/<board>', <class 'package.pages.pages.BoardPage'>, name='view_board', defaults={}, build_only=False)>>, '_name': 'view_board'}, build_only=False)>, <Route('/boards/<board>/new_thread', <class 'package.pages.pages.NewThreadPage'>, name='new_thread', defaults={}, build_only=False)>, <Route('/boards/<board>/new_thread/', <class 'webapp2.RedirectHandler'>, name=None, defaults={'_uri': <bound method RedirectRoute._redirect of <Route('/boards/<board>/new_thread', <class 'package.pages.pages.NewThreadPage'>, name='new_thread', defaults={}, build_only=False)>>, '_name': 'new_thread'}, build_only=False)>, <Route('/notifications', <class 'package.pages.pages.Notifications'>, name='notifications', defaults={}, build_only=False)>, <Route('/notifications/', <class 'webapp2.RedirectHandler'>, name=None, defaults={'_uri': <bound method RedirectRoute._redirect of <Route('/notifications', <class 'package.pages.pages.Notifications'>, name='notifications', defaults={}, build_only=False)>>, '_name': 'notifications'}, build_only=False)>, <Route('/img/<blob_key>', <class 'package.pages.pages.DisplayImagePage'>, name='display_image', defaults={}, build_only=False)>, <Route('/img/<blob_key>/', <class 'webapp2.RedirectHandler'>, name=None, defaults={'_uri': <bound method RedirectRoute._redirect of <Route('/img/<blob_key>', <class 'package.pages.pages.DisplayImagePage'>, name='display_image', defaults={}, build_only=False)>>, '_name': 'display_image'}, build_only=False)>, <Route('/', <class 'package.pages.pages.Index'>, name='index', defaults={}, build_only=False)>, <Route('/', <class 'webapp2.RedirectHandler'>, name=None, defaults={'_uri': <bound method RedirectRoute._redirect of <Route('/', <class 'package.pages.pages.Index'>, name='index', defaults={}, build_only=False)>>, '_name': 'index'}, build_only=False)>] 
INFO  2012-08-04 13:16:40,513 utils.py:14] {'index': <Route('/', <class 'package.pages.pages.Index'>, name='index', defaults={}, build_only=False)>, 'view_boards': <Route('/boards', <class 'package.pages.pages.Boards'>, name='view_boards', defaults={}, build_only=False)>, 'notifications': <Route('/notifications', <class 'package.pages.pages.Notifications'>, name='notifications', defaults={}, build_only=False)>, 'friendship': <Route('/friendship', <class 'package.pages.pages.Friendship'>, name='friendship', defaults={}, build_only=False)>, 'signup': <Route('/signup', <class 'package.pages.pages.Signup'>, name='signup', defaults={}, build_only=False)>, 'view_messages': <Route('/conversations', <class 'package.pages.pages.Messages'>, name='view_messages', defaults={}, build_only=False)>, 'conversation': <Route('/conversation/<conversation_id>', <class 'package.pages.pages.ConversationPage'>, name='conversation', defaults={}, build_only=False)>, 'send_message': <Route('/message', <class 'package.pages.pages.SendMessagePage'>, name='send_message', defaults={}, build_only=False)>, 'new_thread': <Route('/boards/<board>/new_thread', <class 'package.pages.pages.NewThreadPage'>, name='new_thread', defaults={}, build_only=False)>, 'view_board': <Route('/boards/<board>', <class 'package.pages.pages.BoardPage'>, name='view_board', defaults={}, build_only=False)>, 'display_image': <Route('/img/<blob_key>', <class 'package.pages.pages.DisplayImagePage'>, name='display_image', defaults={}, build_only=False)>, 'user_prefs': <Route('/preferences', <class 'package.pages.pages.UserPage'>, name='user_prefs', defaults={}, build_only=False)>, 'user_page': <Route('/<username:[a-zA-Z]+>', <class 'package.pages.pages.UserPage'>, name='user_page', defaults={}, build_only=False)>} 
INFO  2012-08-04 13:16:40,515 __init__.py:26] /conversations 
INFO  2012-08-04 13:16:40,533 dev_appserver.py:2952] "GET /conversations HTTP/1.1" 404 - 
INFO  2012-08-04 13:16:40,626 dev_appserver.py:2952] "GET /favicon.ico HTTP/1.1" 200 - 

내가 눈치 채지 못한 것은 무엇입니까?

+0

요청에 따라 게시물을 업데이트했습니다. 나는 주 기능을 추가하는 것이 cgi를 사용하는 오래된 비 스레드 안전 런타임에만 해당된다는 인상을 받았다. – KitB

+0

당신이 옳았습니다. 나는 그것을 시도하고 그것은 두 가지 방법으로 작동합니다. 문제는 데코레이터가 app.route 대신 app.route를 읽어야한다는 것입니다 (앱은 어디에도 정의되어 있지 않거나 packages.pages에 있습니까?)하지만 오류가 발생해야합니다. –

+0

오 ~ 나는 ~ 패키지에서.응용 프로그램 가져 오기 응용 프로그램으로 응용 프로그램 ' – KitB

답변

0

다른 루트를 모두 무시하지만 404를 발생시키는 경로가 있습니다 (/ 사용자 이름은 사용자 페이지로 연결되며 '대화'라는 사용자는 없습니다). 데코레이터 라우팅 방법으로 전환 할 때이 라우트를 최우선 순위로 만드는 것을 잊었습니다.

우선 앱 라우팅 엔진을 사용하여 최소한의 애플리케이션을 구축하여 앱 엔진에서 정상적으로 작동하는지 확인했습니다. 그렇다면 내 처리기에서 HTTPNotFound 예외를 발견하고 스택 추적을 인쇄했습니다. 이렇게하면 의도적으로 404를 던지는 내 사용자 페이지 클래스의 get 메서드에서 줄이 있다는 것을 분명히 알 수 있습니다. 그런 다음 문제가 상당히 명백합니다.