diff --git a/appengine/modules/README.md b/appengine/modules/README.md new file mode 100644 index 000000000000..82bb51d55ff9 --- /dev/null +++ b/appengine/modules/README.md @@ -0,0 +1,5 @@ +## App Engine Modules Docs Snippets + +This sample application demonstrates how to use Google App Engine's modules API. + + diff --git a/appengine/modules/app.yaml b/appengine/modules/app.yaml new file mode 100644 index 000000000000..102ed60d1b57 --- /dev/null +++ b/appengine/modules/app.yaml @@ -0,0 +1,7 @@ +runtime: python27 +api_version: 1 +threadsafe: yes + +handlers: +- url: .* + script: main.app diff --git a/appengine/modules/backend.py b/appengine/modules/backend.py new file mode 100644 index 000000000000..efe8318deff2 --- /dev/null +++ b/appengine/modules/backend.py @@ -0,0 +1,29 @@ +# Copyright 2016 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Sample backend module deployed by backend.yaml and accessed in main.py +""" + +import webapp2 + + +class BackendHandler(webapp2.RequestHandler): + def get(self): + self.response.write("hello world") + + +app = webapp2.WSGIApplication([ + ('/', BackendHandler), +], debug=True) diff --git a/appengine/modules/backend.yaml b/appengine/modules/backend.yaml new file mode 100644 index 000000000000..3beb1ed881fa --- /dev/null +++ b/appengine/modules/backend.yaml @@ -0,0 +1,8 @@ +runtime: python27 +api_version: 1 +threadsafe: yes +module: my-backend + +handlers: +- url: .* + script: backend.app diff --git a/appengine/modules/backend_test.py b/appengine/modules/backend_test.py new file mode 100644 index 000000000000..5d82f5a8298b --- /dev/null +++ b/appengine/modules/backend_test.py @@ -0,0 +1,29 @@ +# Copyright 2016 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import backend + +import pytest +import webtest + + +@pytest.fixture +def app(): + return webtest.TestApp(backend.app) + + +def test_get_module_info(app): + result = app.get('/') + assert result.status_code == 200 + assert 'hello world' in result.body diff --git a/appengine/modules/main.py b/appengine/modules/main.py new file mode 100644 index 000000000000..36e95d042d8f --- /dev/null +++ b/appengine/modules/main.py @@ -0,0 +1,52 @@ +# Copyright 2016 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Sample application that demonstrates getting information about this +AppEngine modules and accessing other modules in the same project. +""" + +import urllib2 +# [START modules_import] +from google.appengine.api import modules +# [END modules_import] +import webapp2 + + +class GetModuleInfoHandler(webapp2.RequestHandler): + def get(self): + # [START module_info] + module = modules.get_current_module_name() + instance_id = modules.get_current_instance_id() + self.response.write( + 'module_id={}&instance_id={}'.format(module, instance_id)) + # [END module_info] + + +class GetBackendHandler(webapp2.RequestHandler): + def get(self): + # [START access_another_module] + backend_hostname = modules.get_hostname(module='my-backend') + url = "http://{}/".format(backend_hostname) + try: + result = urllib2.urlopen(url).read() + self.response.write('Got response {}'.format(result)) + except urllib2.URLError: + pass + # [END access_another_module] + +app = webapp2.WSGIApplication([ + ('/', GetModuleInfoHandler), + ('/access_backend', GetBackendHandler), +], debug=True) diff --git a/appengine/modules/main_test.py b/appengine/modules/main_test.py new file mode 100644 index 000000000000..97f0a6f029ed --- /dev/null +++ b/appengine/modules/main_test.py @@ -0,0 +1,46 @@ +# Copyright 2016 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import main + +import mock +import pytest +import webtest + + +@pytest.fixture +def app(): + return webtest.TestApp(main.app) + + +@mock.patch("main.modules") +def test_get_module_info(modules_mock, app): + modules_mock.get_current_module_name.return_value = "default" + modules_mock.get_current_instance_id.return_value = 1 + response = app.get('/') + assert response.status_int == 200 + results = response.body.split('&') + assert results[0].split('=')[1] == 'default' + assert results[1].split('=')[1] == '1' + + +@mock.patch("main.modules") +@mock.patch("urllib2.urlopen") +def test_get_backend(url_open_mock, modules_mock, app): + url_read_mock = mock.Mock(read=mock.Mock(return_value='hello world')) + url_open_mock.return_value = url_read_mock + response = app.get('/access_backend') + + assert response.status_int == 200 + assert response.body == 'Got response hello world'