tldr: in 1.1 Response.environ had stuff in it, in 1.2b3 it no longer does.
Now the why....
For a while appengine's sdk has been heavily dependent on webob <= 1.1.1 for some of it's "magic" one being the webapp framework which you dont *have* to use, but I believe the blobstore handlers also used it.
A couple of months ago I managed to mock what I needed of blobstore's handlers in order to test everything in the application at our day job. One of the sticky points is that blobstores api gives you a magic url that has a url to redirect to (internally) after the file has been uploaded. I was able to accomplish this by stuffing a new Request in the responses environ, and a little piece of middleware would look out for that and forward it along.
Here's the middleware
def next_request_middleware(global_conf, environ_key="next_request", max_requests=10):
"""
this piece is for making internal requests.
it looks for"next_request" in the environ which should hold a webob request to pass to the internal application.
the app that gets wrapped better have specific urls, otherwise
this stuff could blow the stack
"""
def _filter(app):
def _app(environ, start_response):
res = Request(environ).get_response(app)
request_count = 0
while request_count < max_requests \
and environ_key in res.environ \
and isinstance(res.environ[environ_key], Request):
res = res.environ[environ_key].get_response(app)
request_count += 1
return res(environ, start_response)
return _app
return _filter
And the relevant code in the mock upload handler....
environ[next_request_key] = Request.blank(success_path,
headers=mimetools.Message(cStringIO.StringIO(complete_headers)),
body_file=cStringIO.StringIO(content_text), method="POST")
response = Response(status=200, body="forwarding to %s" % environ[next_request_key].path)
return response(environ, start_response)
So again under 1.1.1 this worked, and the request would make it to the handler etc.... but under 1.2b3 environ is None. I see from the release notes that the environ attribute was undeprecated. I also see that __call__ returns _app_iter instead of self. I also realize that use of middleware to do something like this is probably frowned upon by some, however keep in mind I am mocking an API that I have to live with that some would frown upon anyway. :)
Any suggestions on how I could accomplish this without relying on the environ? stuffing it in a header seems hackish but maybe no worse than what I'm already doing.