Hello, after a whole week trying different approaches I finally went with using BeforeEvent subscriber + a view deriver to add specific option on `request.environ` about which ones should enhance the response:
def my_view_deriver(view, info): def wrapper(context, request): if 'enhance_response' in info.options: request.environ['enhance_response'] = True return view(context, request) return wrapper config.add_view_deriver(my_view_deriver) @subscriber(BeforeEvent) def enhance_response(event): request = event.get('request') if request.environ.get('enhance_response'): event.rendering_val = { 'extra_key': 'something', 'former_response': event.rendering_val, } # no need to return anything here @view_config(..., enhance_response=True) def my_view(context, request): return {'response': 'whatever'} And that's it! El jueves, 11 de abril de 2024 a la(s) 4:55:56 p.m. UTC-3, Jonathan Vanasco escribió: > I don't know what is recommended, but have done similar things before. > > One way I've done something similar is to use a custom renderer in the > `@view_config`. > > Another way I've accomplished this is to set a request attribute early on > - either in a tween or in the view class instantiation or even a request > attribute, and having my return value reflect this. > > To illustrate the second example, in this project each view is configured > to handle 2 different API endpoints - one that is human HTML, and another > that is programmatic API for JSON. If the route is accessed for JSON, the > view returns a slightly different payload. > > 1- This code adds a "Request.wants_json" attribute: > > > https://github.com/aptise/peter_sslers/blob/main/src/peter_sslers/web/__init__.py#L136-L140 > > 2- This view returns a different payload, depending upon the wants_json > attribute. > > > https://github.com/aptise/peter_sslers/blob/main/src/peter_sslers/web/views_admin/acme_challenge.py#L114-L126 > > This was a quick, lazy and functional way to proceed. If I had to do this > again, I would probably use a single payload with a custom JSON renderer, > and have a function in the custom JSON renderer to only render specific > values from the payload (which would either be attached to the request, or > listed in a namespace in the payload). > > For your description though, I would probably just write a custom JSON > renderer. > > For example, here is a custom jsonp and gif renderer: > > def jsonp_renderer_factory(info): > def _render(value, system): > value = py2json(value) > request = system.get("request") > if request is None: > return value > # JSONP is GET only, unless you do some weird shit that doesn't > work reliably > callback = request.GET.get("callback", None) > if callback is None: > ct_json = "application/json" > else: > ct_json = "application/javascript" > value = "%s(%s)" % (callback, value) > response = request.response > if response.content_type == response.default_content_type: > response.content_type = ct_json > return value > > return _render > > def gif_renderer_factory(info): > def _render(value, system): > request = system.get("request") > if request is not None: > response = request.response > ct = response.content_type > if ct == response.default_content_type: > response.content_type = "image/gif" > return value > > return _render > > config.add_renderer("jsonp", jsonp_renderer_factory) > config.add_renderer("gif", gif_renderer_factory) > > > > On Wednesday, April 10, 2024 at 4:44:27 PM UTC-4 Pablo Díaz Ogni wrote: > >> Hello guys! I'm building an API using pyramid + pyramid_openapi3 package >> to use openapi3 features such as request validation, the web interface, and >> have well documented the endpoints. I'm having trouble understanding the >> different ways I can use views, view_derivers, tweens, decorators, etc. >> >> Let's say I have multiple views that return its own data as a >> dictionary/list and I want to wrap the response with more info before >> rendering to JSON: >> {request: <request_metadata>, response: <the actual data returned by the >> view>} >> >> I first tried with tweens, but that's post renderization so I have to >> deserialize and serialize the json. I also tried view_derivers and I was >> facing the same issue. I also saw that you can match a view with a Context >> such as an exception, but not sure if there is a way to use that Context in >> other way such as "all the View objects that have this specific attribute" >> >> I also tried a decorator with wrapper(context, request), but i switched >> from functions with @view_config to use View classes with get() method >> instead, so I should change the approach of the decorator >> >> I'm new to pyramid and it has its own way of plugging views so I would >> like to know what is the recommended way of doing this? >> > -- You received this message because you are subscribed to the Google Groups "pylons-discuss" group. To unsubscribe from this group and stop receiving emails from it, send an email to pylons-discuss+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/pylons-discuss/d632b5a2-7323-4d73-8d1f-a1f58c13f897n%40googlegroups.com.