除了root之外,App Engine会为任何路径抛出404 Not Found

时间:2016-09-06 12:56:55

标签: python google-app-engine app.yaml

我想将App Engine实现拆分为多个文件。所以我在app.yaml文件中写道:

runtime: python27
api_version: 1
threadsafe: true

handlers:

- url: /imageuploader
  script: imageuploader.app

- url: /search
  script: main.app

- url: /
  static_files: index.html
  upload: index.html

libraries:
- name: MySQLdb
  version: "latest"

基本上我搜索和图像上传在不同的路径和根路径上以获得索引文件。

以下是我的处理程序:

main.py:

class MainPage(webapp2.RequestHandler):

    def get(self):
        #Implementation

app = webapp2.WSGIApplication([
    ('/', MainPage),
], debug=True)

imageuploader.py:

class UserPhoto(ndb.Model):
    blob_key = ndb.BlobKeyProperty()


class PhotoUploadFormHandler(webapp2.RequestHandler):
    def get(self):
        # [START upload_url]
        upload_url = blobstore.create_upload_url('/upload_photo')
        # [END upload_url]
        # [START upload_form]
        # To upload files to the blobstore, the request method must be "POST"
        # and enctype must be set to "multipart/form-data".
        self.response.out.write("""
<html><body>
<form action="{0}" method="POST" enctype="multipart/form-data">
  Upload File: <input type="file" name="file"><br>
  <input type="submit" name="submit" value="Submit">
</form>
</body></html>""".format(upload_url))
        # [END upload_form]


# [START upload_handler]
class PhotoUploadHandler(blobstore_handlers.BlobstoreUploadHandler):
    def post(self):
        try:
            upload = self.get_uploads()[0]
            user_photo = UserPhoto(
                user=users.get_current_user().user_id(),
                blob_key=upload.key())
            user_photo.put()

            self.redirect('/view_photo/%s' % upload.key())

        except:
            self.error(500)
# [END upload_handler]


# [START download_handler]
class ViewPhotoHandler(blobstore_handlers.BlobstoreDownloadHandler):
    def get(self, photo_key):
        if not blobstore.get(photo_key):
            self.error(404)
        else:
            self.send_blob(photo_key)
# [END download_handler]


app = webapp2.WSGIApplication([
    ('/', PhotoUploadFormHandler),
    ('/upload_photo', PhotoUploadHandler),
    ('/view_photo/([^/]+)?', ViewPhotoHandler),
], debug=True)
# [END all]

现在,奇怪的是,如果我设置

-url: /.*
    script: main.app

一切正常。我还尝试了/search/.+/imageuploader/.+。我一定忘记了一些完全明显的东西,但我无法弄清楚它是什么。

1 个答案:

答案 0 :(得分:2)

每个app.yaml路由脚本配置(如script: imageuploader.app)都需要一个名称匹配的python文件(在本例中为imageuploader.py),该文件定义了一个名为app的应用程序(就像main.py那样,app路由当然是app.yaml文件(在这种情况下为/imageuploader)的相应路径的子集(或等于)。

因此,您的实施存在问题:

  • main.py应用路径为/ - 与/search
  • 中相应的app.yaml路径不匹配
  • imageuploader.py中的3个应用路径模式均未与/imageuploader
  • 中的相应app.yaml路径匹配
  • /中的app.yaml路径实际上已映射到静态资源index.html,因此它将由GAE直接提供 - 没有必要为其添加处理程序永远不应该调用handler(你可能想重新访问静态资源映射)。

您使用映射到/.*的{​​{1}}的尝试只能在之前删除main.app中的处理程序代码,但不应该使用来自您问题的imageuploader.py内容。

假设main.py中的模式是您想要的模式,这些将是您需要的应​​用配置(继续您的方法):

main.py:

app.yaml

imageuploader.py:

app = webapp2.WSGIApplication([
    ('/search', MainPage),
], debug=True)

但我建议使用webapp2's lazy loading处理程序代码来管理更简单的方法。

您在app = webapp2.WSGIApplication([ ('/imageuploader', ...), # TODO: revisit mappings ], debug=True) 中保留了一个通用映射,该映射与app.yaml文件中的任何网址格式匹配:

main.py

您在- url: /.* script: main.app 中有一个应用程序路由映射定义,但它可以从main.py以及其他模块/文件延迟加载处理程序。例如:

main.py

也可以使用中间方法,允许您将app = webapp2.WSGIApplication([ ('/upload', 'imageuploader.PhotoUploadFormHandler'), ('/upload_photo', 'imageuploader.PhotoUploadHandler'), ('/view_photo/([^/]+)?', 'imageuploader.ViewPhotoHandler'), ('/main_page', MainPage), ], debug=True) imageuploader.py完全分离,但需要稍微仔细一点的网址格式选择。

你可以进入main.py

app.yaml

- url: /photo.* script: imageuploader.app 中,网址格式与imageuploader.py一个匹配:

/photo.*