How to get file path of a add_static_view() in Pyramid

橙三吉。 提交于 2020-01-04 05:29:41

问题


When I am adding a static view like this:

cfg = config.Configurator(...)
cfg.add_static_view(name='static', path='MyPgk:static')

# And I want to add a view for 'favicon.ico'.
cfg.add_route(name='favicon', pattern='/favicon.ico')
cfg.add_view(route_name='favicon', view='MyPgk.views.mymodule.favicon_view')

I am trying to add that favicon.ico annoying default path of /favicon.ico called by the browser if it's undefined in the webpage. I would like to use the example at http://docs.pylonsproject.org/projects/pyramid_cookbook/en/latest/files.html and modify it to have:

def favicon_view(request, cache=dict()):
    if (not cache):
        _path_to_MyPkg_static = __WHAT_GOES_HERE__
        _icon = open(os.path.join(_path_to_MyPkg_static, 'favicon.ico')).read()
        cache['response'] = Response(content_type='image/x-icon', body=_icon)
    return cache['response']

Since, I can't really define the _here proposed in the example, how can I make it dependent to request to get the actual full path at runtime? Or do I really have to deal with:

_here = os.path.dirname(__file__)
_path_to_MyPkg_static = os.path.join(os.path.dirname(_here), 'static')

and having to be careful when I decide to refactor and put the view in another pkg or subpackage, or where-ever?

Something equivalent to request.static_path() but instead of getting the url path, to actually get a directory path:

request.static_file_path('static') -> /path/to/site-packages/MyPkg/static

Thanks,


回答1:


You can use the pkg_resources module to make paths that are relative to Python modules (and thus, independent of the module that retrieves them). For example:

import pkg_resources
print pkg_resources.resource_filename('os.path', 'static/favicon.ico')
# 'C:\\Python27\\lib\\static\\favicon.ico'

Just substitute os.path with whatever module that is the parent of your static files.

EDIT: If you need to remember that 'static' route mapped to 'MyPkg:static', then the easiest way is to save it in some dictionary in the first place:

STATIC_ROUTES = {'static': 'MyPkg:static'}
for name, path in STATIC_ROUTES.iteritems():
    cfg.add_static_view(name=name, path=path)

and then simply retrieve the path:

static_path = STATIC_ROUTES['static']
package, relative_path = static_path.split(':')
icon_path = pkg_resources.resource_filename(
    package, os.path.join(relative_path, 'favicon.ico'))

If that's impossible, though (e.g. you don't have access to the cfg object), you can retrieve this path, it's just quite painful. Here's a sample function that uses undocumented calls (and so may change in future Pyramid versions) and ignores some additional settings (like route_prefix configuration variable):

def get_static_path(request, name):
    from pyramid.config.views import StaticURLInfo
    registrations = StaticURLInfo()._get_registrations(request.registry)
    if not name.endswith('/'):
        name = name + '/'
    route_name = '__%s' % name
    for _url, spec, reg_route_name in registrations:
        print ':', reg_route_name
        if reg_route_name == route_name:
            return spec

In your case, it should work like this:

>>> get_static_path(request, 'static')
MyPkg:static/


来源:https://stackoverflow.com/questions/9289675/how-to-get-file-path-of-a-add-static-view-in-pyramid

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!