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/e22a2d93-bf29-4393-bb71-b0499846ea30n%40googlegroups.com.