| 160 | |
| 161 | @self.server.after_request |
| 162 | async def _after_request(response): # pragma: no cover - timing infra |
| 163 | timing_information = ( |
| 164 | getattr(quart_g, "timing_information", None) |
| 165 | if quart_g is not None |
| 166 | else None |
| 167 | ) |
| 168 | if timing_information is None: |
| 169 | return response |
| 170 | dash_total = timing_information.get("__dash_server", None) |
| 171 | if dash_total is not None: |
| 172 | dash_total["dur"] = round((time.time() - dash_total["dur"]) * 1000) |
| 173 | for name, info in timing_information.items(): |
| 174 | value = name |
| 175 | if info.get("desc") is not None: |
| 176 | value += f';desc="{info["desc"]}"' |
| 177 | if info.get("dur") is not None: |
| 178 | value += f";dur={info['dur']}" |
| 179 | # Quart/Werkzeug headers expose 'add' (not 'append') |
| 180 | if hasattr(response.headers, "add"): |
| 181 | response.headers.add("Server-Timing", value) |
| 182 | else: # fallback just in case |
| 183 | response.headers["Server-Timing"] = value |
| 184 | return response |
| 185 | |
| 186 | def register_error_handlers(self): # type: ignore[name-defined] |
| 187 | @self.server.errorhandler(PreventUpdate) |