Exercise 3: WSGI's Callback vs. Rack's Return Triplet — Possible Solution ==================================================================== THE TWO REAL INTERFACES, RESTATED ------------------------------ WSGI (this chapter): def app(environ, start_response): start_response('200 OK', [('Content-type', 'text/plain')]) return [b'body'] Rack (Web Framework Internals 9, Rack's own real spec): def call(env) [status, headers, body] end WHICH CATCHES "FORGOT TO SEND STATUS/HEADERS" MORE EASILY, AND WHY ------------------------------ Rack's model catches it automatically, by construction: call(env) MUST return the [status, headers, body] triplet as its own return value, so there is no way to "forget" to produce a status and headers - if the method returns at all, it has returned something in that position, and a genuinely missing or malformed value fails immediately and obviously at the return-type level (e.g. the wrong number of elements, or a nil status), independent of any runtime bookkeeping. WSGI's model does NOT catch it automatically. start_response is a callback the application must remember to invoke as a side effect, separately from returning the body. Skipping that call is a real, silent-looking mistake from the application author's own point of view - nothing about Python's own syntax stops a function from simply never calling start_response and just returning a body anyway. It's only caught because Python's own wsgiref reference server chooses to track, at runtime, whether start_response was ever actually invoked before the body is written - raising a real AssertionError ("write() before start_response()") specifically because that bookkeeping was deliberately added to the reference implementation, not because the interface itself makes the mistake impossible. WHY THIS WORKS AS AN ANSWER ------------------------------ It correctly identifies the real, structural difference between the two designs: Rack's model makes "missing status/headers" a return-value shape problem, checkable the instant call() returns, while WSGI's model makes it a call-ordering problem, only catchable by a server willing to track callback invocation at runtime - and ties that difference directly back to this chapter's own verified AssertionError finding, rather than treating the two interfaces as interchangeable.