Skip to content
This repository was archived by the owner on Jan 12, 2022. It is now read-only.

Commit 35722ab

Browse files
committed
Merge pull request #6 from andrewsg/user_middleware
Wrap user apps with user middleware at load time
2 parents e4f3805 + 68ad1ea commit 35722ab

2 files changed

Lines changed: 90 additions & 2 deletions

File tree

multicore_runtime/wsgi_config.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,43 @@ def app_for_script(script):
4545
logging.exception('Failed to import %s: %s', script, err)
4646
return None
4747
else:
48-
return app
48+
return app_wrapped_in_user_middleware(app)
49+
50+
51+
def app_wrapped_in_user_middleware(app):
52+
"""Returns the input WSGI app, wrapped in appengine_config middleware."""
53+
add_middleware = get_add_middleware_from_appengine_config()
54+
if add_middleware:
55+
return add_middleware(app)
56+
else:
57+
return app
58+
59+
60+
def get_add_middleware_from_appengine_config():
61+
"""Tries to import appengine_config and return middleware; fails silently.
62+
63+
`appengine_config` is optionally part of GAE-compatible user code.
64+
If the user chooses to define the `webapp_add_wsgi_middleware` function
65+
there, then we will use it to wrap app scripts. This is used for e.g.
66+
appstats. Many user apps do not have or need appengine_config, so failure
67+
to import it or failure to find `webapp_add_wsgi_middleware` is not an
68+
error.
69+
70+
Returns:
71+
The appengine_config.webapp_add_wsgi_middleware function or None.
72+
"""
73+
try:
74+
import appengine_config # pylint: disable=g-import-not-at-top
75+
try:
76+
return appengine_config.webapp_add_wsgi_middleware
77+
except AttributeError:
78+
return None
79+
except ImportError:
80+
return None
4981

5082

5183
def load_user_scripts_into_handlers(handlers):
52-
"""Preloads user scripts.
84+
"""Preloads user scripts, wrapped in appengine_config middleware if present.
5385
5486
Args:
5587
handlers: appinfo_external.handlers data as provided by get_module_config()
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Copyright 2015 Google Inc. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
import unittest
16+
17+
from mock import patch
18+
from werkzeug.test import Client
19+
from werkzeug.wrappers import Request
20+
from werkzeug.wrappers import Response
21+
22+
from wsgi_config import app_for_script
23+
24+
25+
@Request.application
26+
def salutation_world(request):
27+
salutation = request.args.get('salutation', 'Hello')
28+
return Response('%s World!' % salutation)
29+
30+
31+
def goodbye_world_middleware(app):
32+
def goodbye_wrapper(wsgi_env, start_response):
33+
wsgi_env['QUERY_STRING'] = 'salutation=Goodbye'
34+
return app(wsgi_env, start_response)
35+
return goodbye_wrapper
36+
37+
38+
class AppConfigTestCase(unittest.TestCase):
39+
40+
def test_app_for_script(self):
41+
with patch('wsgi_config.get_add_middleware_from_appengine_config',
42+
return_value=None):
43+
app = app_for_script('wsgi_config_test.salutation_world')
44+
client = Client(app, Response)
45+
response = client.get('/?salutation=Hello')
46+
self.assertEqual(response.status_code, 200)
47+
self.assertEqual(response.data, 'Hello World!')
48+
49+
def test_app_for_script_with_middleware(self):
50+
with patch('wsgi_config.get_add_middleware_from_appengine_config',
51+
return_value=goodbye_world_middleware):
52+
app = app_for_script('wsgi_config_test.salutation_world')
53+
client = Client(app, Response)
54+
response = client.get('/?salutation=Hello')
55+
self.assertEqual(response.status_code, 200)
56+
self.assertEqual(response.data, 'Goodbye World!')

0 commit comments

Comments
 (0)