Reputation: 4564
This is very weird. The title says most of it, my code should say the rest. Here's my main.py
file:
from google.appengine.api import urlfetch
import webapp2
import jinja2
import json
import os
jinja_environment = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))
class MainPage(webapp2.RequestHandler):
def get(self):
response = urlfetch.fetch("http://localhost:8080/api/helloworld?name=totty", method=urlfetch.GET)
if response.status_code == 200:
result = json.loads(response.content)
template_values = {'response': result['msg']}
template = jinja_environment.get_template('index.html')
self.response.out.write(template.render(template_values))
app = webapp2.WSGIApplication(
[('/', MainPage)],
debug=True)
Here's my api.py
file:
import webapp2
import json
class HelloWorld(webapp2.RequestHandler):
def get(self):
name = self.request.get('name') or 'world'
msg = "Hello {}!".format(name)
payload = json.dumps({'msg': msg})
# payload = json.dumps({'dir': str(dir(self.request)), 'body': str(self.request.body), 'name': str(self.request.arguments())})
self.response.headers['Content-Type'] = 'application/json'
self.response.write(payload)
app = webapp2.WSGIApplication(
[('/api/helloworld', HelloWorld)],
debug=True)
And in case my app.yaml
file would help:
application: stacksort
version: 1
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /api/.*
script: api.app
- url: /.*
script: main.app
libraries:
- name: webapp2
version: latest
- name: jinja2
version: latest
Nothing changes even if I add deadline=30
to my urlfetch
call. I tested the API using httpie
and JQuery and it works perfectly fine and returns in under 5 seconds.
I looked at the other questions, but I'm still stumbling into the dark. Help, tips or refactoring would be appreciated.
I plan to add calls to the StackEchange Search API, so I suspect the problem might come in that time also. If there's a better way to do this, please tell. Thanks.
Upvotes: 0
Views: 240
Reputation: 617
You are trying to fetch a URL to and from your application which is strongly discouraged on Google App Engine.
Locally you won't be able to call the development server because it serves only one request at a time. Multi-threading is not observed.
Note: the new experimental development server is now able to handle multiple requests at a time.
Multithreaded serving for better performance for complex applications and more correct semantics e.g. accessing your own application through urlfetch no longer deadlocks.
On production environment, GAE prevents the fetch service to call the same application.
To prevent an app from causing an endless recursion of requests, a request handler is not allowed to fetch its own URL. It is still possible to cause an endless recursion with other means, so exercise caution if your app can be made to fetch requests for URLs supplied by the user.
Upvotes: 1
Reputation: 4564
While upgrading the SDK, I noticed this addition to the DevServer page:
Note:
dev_appserver.py
can only serve one request at a time. If your application makes URL fetch requests to itself while processing a request, these requests will fail when using the development web server. (They will not fail when running on App Engine.) To test such requests, you can run a second instance ofdev_appserver.py
on a different port, then code your application to use the other server when making requests to itself.
So I guess that solves my problem (or at least gives a satisfactory explanation for it).
Upvotes: 0