-
Notifications
You must be signed in to change notification settings - Fork 889
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Preserve order of views using "accept" #1259
Conversation
Our code assumes that the first configured `accept` predicate will be picked if the client sends `Accept: */*` or no `Accept` header at all. However, when multiple views are added with different `accept` values, they may be shuffled around by the current call to `set()` and the one selected by `Accept: */*` is not the first one configured. This patch ensures the media types are offered in the same order they were configured in.
Due to the usage of the |
If the client sends We are using imperative configuration so we do know the order in which views are added. Basically I'm looking for some way to control the order in which views are selected based on the Accept header, if the client has no preference. In WebOb.their Accept class lets you use a tuple (mime_type, server_priority) which allows the options to be explicitly ordered. However, it doesn't look like pyramid supports this and I'm not using WebOb's Accept class anyway; I had to replace it because it doesn't take the media type parameters into account when ranking matches. If this patch seems undesirable (although it's a nice simple one and probably can run faster than the old code) then I'll have to devise another workaround. I may need to do that anyway. For example, I could put quality markers into the accept predicate itself and then fork the paste.util.mimeparse library I'm using to apply that in addition to the client's quality preferences. |
I believe I have figured out a workaround for my case - if the Accept header is I still think this patch is a minor improvement over what was there before but I have an acceptable alternative solution without waiting for this to be merged in. |
Well I'm -1 on this patch for the reason that it instills an ordering on the view definitions at import time. However, I fully agree that the current accept-header support is totally whack and we should do something about it. In my example below I would've expected some of those default views to be called a little more often than they are, or even conflict with each other.
from pyramid.config import Configurator
from pyramid.events import subscriber
from pyramid.view import view_config
@subscriber('pyramid.interfaces.INewRequest')
def new_request(event):
request = event.request
print('request: {}'.format(request.url))
print('headers:\n\t', end='')
print('\n\t'.join(
'{}: {}'.format(k, v) for k, v in request.headers.items()))
@view_config(renderer='string')
def default_view(request):
return 'default view'
@view_config(accept='*', renderer='string')
def default2_view(request):
return 'string view'
@view_config(accept='*/*', renderer='string')
def default3_view(request):
return 'another string view'
@view_config(accept='text/html')
def html_view(request):
response = request.response
response.text = 'html view'
response.content_type = 'text/html'
return response
@view_config(accept='application/json', renderer='json')
def json_view(request):
return 'json view'
def main(global_config, **app_settings):
settings = global_config
settings.update(app_settings)
config = Configurator(settings=settings)
config.scan(__name__)
return config.make_wsgi_app()
if __name__ == '__main__':
from waitress import serve
app = main({})
serve(app, host='0.0.0.0', port=8080) Note that the final request for
|
Yes, I agree. I created my own Accept class that uses the paste.util.mimeparse code to I think probably the optimal solution might be to copy and adapt the code It seemed a bit tricky to do this, though - in my case I didn't even On Thu, Mar 6, 2014 at 12:42 PM, Michael Merickel
|
Well if a client says they accept |
Treating I'm not suggesting that as a patch to pyramid itself, that would be more These empty Accept headers are coming in from a bunch of legacy mobile On Thu, Mar 6, 2014 at 2:47 PM, Michael Merickel
|
Perhaps this isn't the time to solve this at the pyramid level, unless you get more complaints or questions about it. |
Our code assumes that the first configured
accept
predicate will be picked if the client sendsAccept: */*
or noAccept
header at all. However, when multiple views are added with differentaccept
values, they may be shuffled around by the current call toset()
and the one selected byAccept: */*
is not the first one configured. This patch ensures the media types are offered in the same order they were configured in.