diff --git a/appengine/urlfetch/requests/.gitignore b/appengine/urlfetch/requests/.gitignore new file mode 100644 index 00000000000..a65b41774ad --- /dev/null +++ b/appengine/urlfetch/requests/.gitignore @@ -0,0 +1 @@ +lib diff --git a/appengine/urlfetch/app.yaml b/appengine/urlfetch/requests/app.yaml similarity index 100% rename from appengine/urlfetch/app.yaml rename to appengine/urlfetch/requests/app.yaml diff --git a/appengine/urlfetch/requests/appengine_config.py b/appengine/urlfetch/requests/appengine_config.py new file mode 100644 index 00000000000..c903d9a0ac5 --- /dev/null +++ b/appengine/urlfetch/requests/appengine_config.py @@ -0,0 +1,18 @@ +# Copyright 2016 Google Inc. +# +# 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. + +from google.appengine.ext import vendor + +# Add any libraries installed in the "lib" folder. +vendor.add('lib') diff --git a/appengine/urlfetch/requests/main.py b/appengine/urlfetch/requests/main.py new file mode 100644 index 00000000000..3d0ffb50f82 --- /dev/null +++ b/appengine/urlfetch/requests/main.py @@ -0,0 +1,49 @@ +# 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. + +# [START app] +import logging + +from flask import Flask + +# [start imports] +import requests +import requests_toolbelt.adapters.appengine + +# Use the App Engine Requests adapter. This makes sure that Requests uses +# URLFetch. +requests_toolbelt.adapters.appengine.monkeypatch() +# [END imports] + +app = Flask(__name__) + + +@app.route('/') +def index(): + # [START requests_get] + url = 'http://www.google.com/humans.txt' + response = requests.get(url) + response.raise_for_status() + return response.text + # [END requests_get] + + +@app.errorhandler(500) +def server_error(e): + logging.exception('An error ocurred during a request.') + return """ + An internal error occurred:
{}
+ See logs for full stacktrace.
+ """.format(e), 500
+# [END app]
diff --git a/appengine/urlfetch/requests/main_test.py b/appengine/urlfetch/requests/main_test.py
new file mode 100644
index 00000000000..23666009aa4
--- /dev/null
+++ b/appengine/urlfetch/requests/main_test.py
@@ -0,0 +1,24 @@
+# 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.
+
+
+def test_index(testbed):
+ # Import main here so that the testbed is active, otherwise none of the
+ # stubs will be available and it will error.
+ import main
+
+ app = main.app.test_client()
+ response = app.get('/')
+ assert response.status_code == 200
+ assert 'Google' in response.data.decode('utf-8')
diff --git a/appengine/urlfetch/requests/requirements.txt b/appengine/urlfetch/requests/requirements.txt
new file mode 100644
index 00000000000..a3a231c99db
--- /dev/null
+++ b/appengine/urlfetch/requests/requirements.txt
@@ -0,0 +1,3 @@
+Flask==0.10.1
+requests==2.10.0
+requests-toolbelt==0.6.0
diff --git a/appengine/urlfetch/snippets/app.yaml b/appengine/urlfetch/snippets/app.yaml
new file mode 100644
index 00000000000..102ed60d1b5
--- /dev/null
+++ b/appengine/urlfetch/snippets/app.yaml
@@ -0,0 +1,7 @@
+runtime: python27
+api_version: 1
+threadsafe: yes
+
+handlers:
+- url: .*
+ script: main.app
diff --git a/appengine/urlfetch/main.py b/appengine/urlfetch/snippets/main.py
similarity index 83%
rename from appengine/urlfetch/main.py
rename to appengine/urlfetch/snippets/main.py
index 552a40a1a2c..00950102429 100644
--- a/appengine/urlfetch/main.py
+++ b/appengine/urlfetch/snippets/main.py
@@ -35,12 +35,12 @@ class UrlLibFetchHandler(webapp2.RequestHandler):
def get(self):
# [START urllib-get]
- url = "http://www.google.com/"
+ url = 'http://www.google.com/humans.txt'
try:
result = urllib2.urlopen(url)
self.response.write(result.read())
- except urllib2.URLError, e:
- logging.error("Caught exception fetching url {}".format(e))
+ except urllib2.URLError:
+ logging.exception('Caught exception fetching url')
# [END urllib-get]
@@ -49,15 +49,15 @@ class UrlFetchHandler(webapp2.RequestHandler):
def get(self):
# [START urlfetch-get]
- url = "http://www.google.com/"
+ url = 'http://www.google.com/humans.txt'
try:
result = urlfetch.fetch(url)
if result.status_code == 200:
self.response.write(result.content)
else:
self.response.status_code = result.status_code
- except urlfetch.Error, e:
- logging.error("Caught exception fetching url {}".format(e))
+ except urlfetch.Error:
+ logging.exception('Caught exception fetching url')
# [END urlfetch-get]
@@ -65,8 +65,8 @@ class UrlPostHandler(webapp2.RequestHandler):
""" Demonstrates an HTTP POST form query using urlfetch"""
form_fields = {
- "first_name": "Albert",
- "last_name": "Johnson",
+ 'first_name': 'Albert',
+ 'last_name': 'Johnson',
}
def get(self):
@@ -75,13 +75,13 @@ def get(self):
form_data = urllib.urlencode(UrlPostHandler.form_fields)
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
result = urlfetch.fetch(
- url="http://localhost:8080/submit_form",
+ url='http://localhost:8080/submit_form',
payload=form_data,
method=urlfetch.POST,
headers=headers)
self.response.write(result.content)
- except urlfetch.Error, e:
- logging.error("Caught exception fetching url {}".format(e))
+ except urlfetch.Error:
+ logging.exception('Caught exception fetching url')
# [END urlfetch-post]
diff --git a/appengine/urlfetch/main_test.py b/appengine/urlfetch/snippets/main_test.py
similarity index 65%
rename from appengine/urlfetch/main_test.py
rename to appengine/urlfetch/snippets/main_test.py
index af33ed2ae12..aa84d48649d 100644
--- a/appengine/urlfetch/main_test.py
+++ b/appengine/urlfetch/snippets/main_test.py
@@ -20,31 +20,24 @@
@pytest.fixture
-def app():
+def app(testbed):
return webtest.TestApp(main.app)
def test_url_lib(app):
response = app.get('/')
- assert response.status_int == 200
- assert "I'm Feeling Lucky" in response.body
+ assert 'Google' in response.body
-@mock.patch("main.urlfetch")
-def test_url_fetch(urlfetch_mock, app):
- urlfetch_mock.fetch = mock.Mock(
- return_value=mock.Mock(content="I'm Feeling Lucky",
- status_code=200))
+def test_url_fetch(app):
response = app.get('/url_fetch')
- assert response.status_int == 200
- assert "I'm Feeling Lucky" in response.body
+ assert 'Google' in response.body
@mock.patch("main.urlfetch")
def test_url_post(urlfetch_mock, app):
urlfetch_mock.fetch = mock.Mock(
- return_value=mock.Mock(content="Albert",
+ return_value=mock.Mock(content='Albert',
status_code=200))
response = app.get('/url_post')
- assert response.status_int == 200
- assert "Albert" in response.body
+ assert 'Albert' in response.body