2

好的,所以我有我的应用程序,它接受来自 root 的请求/几乎所有东西都在使用遍历。

但我想在该站点之上制作一个休息 api。

所以我有两个选择。我要么将它分开在两个不同的应用程序中,然后将其余应用程序放到 : rest.site.com,或者我可以将它移动到 site.com/rest/*traversal

如果我正在执行“/rest/*traversal”,我想我必须添加一个名为rest_traversalwhere the traversal path will be *traversalwith the route 的路由/rest/*traversal。我为管理页面做过一次。

我想知道是否有最干净的方法可以做到这一点。我尝试使用 virtual_root,但据我了解,virtual_root 实际上已添加到遍历路径中。

喜欢拥有virtual_root = /cms和请求/fun将创建以下路径/cms/fun

另一方面,我希望/cms/fun变成/fun

4

2 回答 2

3

我知道这已经被回答了,但是如果有人来到这里寻找另一种可能的方式来制作“子应用程序”并在金字塔中使用它们,我想指出一些有趣的事情可以用pyramid.wsgi

"""
example of wsgiapp decorator usage
http://docs.pylonsproject.org/projects/pyramid/en/1.3-branch/api/wsgi.html
"""

from pyramid.wsgi import wsgiapp2, wsgiapp
from pyramid.config import Configurator
from webob import Request, Response
import pprint

# define some apps


def wsgi_echo(environ, start_response):
    """pretty print out the environ"""
    response = Response(body=pprint.pformat({k: v for k, v in environ.items()
                                             if k not in ["wsgi.errors",
                                                          "wsgi.input",
                                                          "SCRIPT_NAME"]}))
    return response(environ, start_response)


print Request.blank("/someurl").send(wsgi_echo).body


# convert wsgi app to a pyramid view callable
pyramid_echo = wsgiapp(wsgi_echo)
pyramid_echo_2 = wsgiapp2(wsgi_echo)

# wire up a pyramid application

config = Configurator()
config.add_view(pyramid_echo, name="foo")  # /foo
config.add_view(pyramid_echo, name="bar")  # /bar
config.add_view(pyramid_echo_2, name="foo_2")  # /foo
config.add_view(pyramid_echo_2, name="bar_2")  # /bar
pyramid_app = config.make_wsgi_app()

#call some urls
foo_body = Request.blank("/foo").send(pyramid_app).body
bar_body = Request.blank("/bar").send(pyramid_app).body
foo_body_2 = Request.blank("/foo_2").send(pyramid_app).body
bar_body_2 = Request.blank("/bar_2").send(pyramid_app).body

# both should be different because we arrived at 2 different urls
assert foo_body != bar_body, "bodies should not be equal"

# should be equal because wsgiapp2 fixes stuff before calling
# application in fact there's an additional SCRIPT_NAME in the
# environment that we are filtering out
assert foo_body_2 == bar_body_2, "bodies should be equal"

# so how to pass the path along? like /foo/fuuuu should come back
# /fuuuu does it
foo_body = Request.blank("/foo_2/fuuuu").send(pyramid_app).body
assert "'/fuuuu'," in foo_body, "path didn't get passed along"


# tldr: a wsgi app that is decorated with wsgiapp2 will recieve data
# as if it was mounted at "/", any url generation it has to do should
# take into account the SCRIPT_NAME variable that may arrive in the
# environ when it is called
于 2012-08-03T18:43:15.153 回答
1

如果您已经在使用遍历,为什么不在 Pyramid 遍历到时使用它来返回您的“rest API root”对象/rest/?从那里开始,一切都会自然而然地进行。

class ApplicationRoot(object):

    def __getitem__(self, name):
        if name == "rest":
            return RestAPIRoot(parent=self, name=name)
        ...

如果您的“应用程序树”和“API 树”具有相同的子项,并且您希望根据子项所在树的哪个分支为它们注册不同的视图,则可以使用containment视图谓词来注册您的 API 视图,所以只有当孩子在“API 分支”内时,它们才会匹配:

遏制

此值应该是对上下文资源沿袭中的父对象必须提供的 Python 类或接口的引用,以便找到和调用此视图。资源树中的资源必须是“位置感知的”才能使用此功能。

如果未提供包含,则在决定是否调用可调用视图时不考虑沿袭中的接口和类。

另一种方法不是构建单独的“API 树”,而是使用“主”应用程序的“URI 空间”作为 RESTful API。唯一的问题是 GET 和可能的 POST 请求方法已经在您的资源上“采用”并映射到返回 HTML 或使用 HTTP 表单 POST 的“正常”视图。有很多方法可以解决这个问题:

  • 使用单独的名称注册 API 视图,因此 sayGET /users/123将返回 HTML 并GET /users/123/json返回 JSON 对象。同样,POST /users/123期望发布 HTTP 表单并POST /users/123/json期望 JSON。这种方法的一个好处是您可以轻松地在GET /users/123/xml.

  • 使用自定义视图谓词 soGET /users/123并被GET /users/123?format=json路由到不同的视图。request_param实际上,自 Pyramid 1.2 以来就有一个内置谓词

  • 使用xhr谓词根据HTTP_X_REQUESTED_WITH标头区分请求或使用accept谓词区分HTTP_ACCEPT标头

于 2012-07-22T23:30:24.140 回答