add real file path access to routes/views #440

Closed
danosaure opened this Issue Feb 16, 2012 · 7 comments

Projects

None yet

4 participants

@danosaure

Can we have an API to access the real file path of views through the "request" object?

If I have a

add_static_view(name='static', path='MyPKG:static')

I would like to be able to access that path at runtime with a call like:

static_path = request.file_path('static')

It would complement the already existing "request.route_path(routename)".

@mcdonc
Member
mcdonc commented Feb 16, 2012

It might not be a terrible idea to add a convenience API for this in the future, although likely not exactly the one you describe, because sometimes assets don't have paths (for example when they're in zipped eggs). In the meantime you can do this right now via:

from pyramid.path import AssetResolver
resolver = AssetResolver()
static_path = resolver.resolve('mypkg:static').abspath()
@danosaure

True, I was only thinking about my precise case. I'm using pyramid 1.2 (not me to decide to upgrade), so I don't have AssetResolver().

Is there a way for me to obtain "mypkg:static" from the static_view instead of being hard-coded? I would like it to be better encapsulated, perhaps something using the "request" object in a view. Ideally, I would like to be able to chain like this:

# I hate browser who requests /favicon.ico (in root of website).
add_route(name='favicon', patter='/favicon.ico')
add_view(route_name='favicon', view='mypkg.views.mymmodule.favicon')

# then in the module.
def favicon(request):
    # I know my real path is /static/meta/favicon.ico
    normal_path = request.get_asset_that_correspond_to('/static/meta/favicon.ico')
    # serve that file in a Reponse

so pyramid does the magic to find out how to locate the asset. I guess I could do a redirect here, but sometimes, I do want to get the file content that is not associated with another route.

@mikeorr
Member
mikeorr commented Feb 16, 2012

This might also be useful to check whether the asset exists, in cases where the assets correspond to something external (e.g., a record ID) but not all records have a corresponding asset. Then you could; e.g., link to an image asset if it exists, or link to a default image if it doesn't. I have done this, not with a static view per se, but with static files served through a view (because I had to check permissions). Still, the ability to do this on static_view assets may be useful.

Of course, it wouldn't work in the case of a remote media server, where the assets don't have local paths and you can't check whether they exist. So this feature may be incompatible with static_view?

@mmerickel
Member

Note that the name argument to add_static_view(name, path) is probably a bad name. You actually use the path argument in request.static_url(). This makes the path analagous to a route's name, if you follow. Specifically, the asset specification (mypkg:static) is actually the identifier here. You can either pass this asset spec to the AssetResolver or use the pkg_resources API directly if on Pyramid < 1.3. This can be done as follows:

import pkg_resources 

asset_path = 'mypackage:static/favicon.ico' 
package, file = asset_path.split(':', 1) 
abs_path = pkg_resources.resource_filename(package, file)
@danosaure

Is the "you" refers to me or to the API? I understand what you are saying, but those are the variables names in the methods' signatures, and I like to be explicit to be able to re-order parameters for harmonization of my code. Just like defining routes and associated view:

add_route(name='a_route_name', pattern='/a_pattern/{var1}')
add_view(route_name='a_route_name', view='mypkg.views.mymodule.mymethod', renderer='json')

I get both the same "value" at the beginning of the call so they are visually related.

And thanks for the code snippets, that is what I need right now for pyramid 1.2 to get the file from the asset_path, but if a future solution existed in regard of the route_name retrievable from the request, that would be even better encapsulation.

@mmerickel
Member

Is the "you" refers to me or to the API?

The API uses those argument names poorly. The static view's path is what is used by the API to find the static asset. The name is the actual base URL used. Between routes and static views they both support the same idea of modifying URLs without affecting your code. Static views again support modifying the URL (name) easily, but not the location of the resource in your project. That part (mypkg:static/favicon.ico) is referenced within your templates, etc and is not intended to be easy to change. It's more like a Python import, less like a URL, in that regard.

@mcdonc
Member
mcdonc commented Sep 17, 2012

Closing this issue. I'd suggest upgrading and using AssetResolver.

@mcdonc mcdonc closed this Sep 17, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment