I'm using GAE 1.9.2 -- I have a cron.yaml file with a specific request I want routed to a module called updater.yaml. In my cron.yaml file I have:
cron:
- description: Daily updater
url: /update
schedule: every day 02:00
timezone: America/New_York
target: updater
I loaded my two modules to my dev server with:
$ dev_appserver.py app.yaml updater.yaml
Any ideas? Thanks.
Edit:
Relevant part of updater.yaml:
application: [my app name]
module: updater
version: one
runtime: python27
api_version: 1
threadsafe: true
instance_class: B4_1G
basic_scaling:
max_instances: 1
handlers:
- url: /update
script: downloader.application
login: admin
Edit 2:
I get this error on my app when hosted on google (i.e. not running on my dev_server) so it seems a handler isn't getting setup correctly...?:
W 2014-04-08 02:00:02.687 No handlers matched this URL.
From your error message, it looks like the updater module doesn't have the handler mapped correctly. Make sure you can call the /update url manually in the browser and that you get the correct log output.
I use cron.yaml with a target module in production right now. There is no dispatch.yaml entry for that module.
Related
I am new to GAE and API development. I have been getting this error message from GAE when I try to deploy my code.
10:01 AM Checking if Endpoints configuration has been updated.
10:01 AM Will check again in 60 seconds.
10:02 AM Checking if Endpoints configuration has been updated.
10:02 AM Failed to update Endpoints configuration. There is a /_ah/spi handler configured, but no Google Cloud Endpoints service was found in the app.
10:02 AM See the deployment troubleshooting documentation for more information: https://developers.google.com/appengine/docs/python/endpoints/test_deploy#troubleshooting_a_deployment_failure
10:02 AM Ignoring Endpoints failure and proceeding with update.
Based on the error message, the problem seems to be the application is not calling endpoints.api_server(), which is not exactly the case as you can see in the code below; endpoints.api_server() was called in the last line.
import endpoints
from protorpc import remote, messages
from google.appengine.api import memcache, mail
from google.appengine.ext import ndb
from google.appengine.api import taskqueue
from models import Player, Game, Score, NewGameForm, StringMessage, GameForm, PlayerForm, PlayerForms
from utils import get_by_urlsafe, check_winner
from settings import WEB_CLIENT_ID
EMAIL_SCOPE = endpoints.EMAIL_SCOPE
API_EXPLORER_CLIENT_ID = endpoints.API_EXPLORER_CLIENT_ID
#endpoints.api(name='tic_tac_toe',
version='v1',
allowed_client_ids=[WEB_CLIENT_ID, API_EXPLORER_CLIENT_ID],
scopes=[EMAIL_SCOPE])
class TicTacToeApi(remote.Service):
"""Game API"""
#endpoints.method(request_message=PLAYER_REQUEST,
response_message=StringMessage,
path='player',
name='create_player',
http_method='POST')
def create_player(self, request):
"""Check if user name is unique"""
if Player.get_player_by_name(request.name):
raise endpoints.ConflictException('The name has been taken!')
if not mail.is_email_valid(request.email):
raise endpoints.BadRequestException('Please input a valid email address')
player = Player(name=request.name, email=request.email)
player.put()
return StringMessage(message='Player {} created!'.format(request.name))
#endpoints.method(response_message=PlayerForms,
path='player/ranking',
name='get_player_rankings',
http_method='GET')
def get_player_rankings(self, request):
"""Return rankings for all Players"""
players = Player.query(Player.gamesCompleted > 0).fetch()
players = sorted(players, key=lambda x :x._points, reverse=True)
return PlayerForms(items=[player._copyPlayerToForm for player in players])
api = endpoints.api_server([TicTacToeApi])
Is there something wrong with the app.yaml file?
application: tic-tac-toe-api
version: 1
runtime: python27
api_version: 1
threadsafe: yes
handlers:
- url: /favicon\.ico
static_files: favicon.ico
upload: favicon\.ico
- url: .*
script: main.app
- url: /_ah/spi/.*
script: api.api
libraries:
- name: webapp2
version: "2.5.2"
- name: endpoints
version: 1.0
- name: pycrypto
version: 2.6
Please feel free to let me know what you think! Thanks a lot
I have the following config file for my google appengine app in python:
application: testapp-94974206
version: 1
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /helloworld
script: helloworld.application
- url: /
script: helloworld.application
when calling the url with no prefix (/) I get my "helloworld" app called, while when calling with /helloworld I get a 404 not found error page. What is wrong with the declaration of "/helloworld" above?
My question is actually close to another one that has been already answered here.
It turns out that the /helloworld url is actually well routed by the appengine, but then the culprit is the WSGI router that parses the whole absolute URL and not just the one relative to /helloworld, as I thought it would.
I am setting up a new GAE project, and I can't get my scripts in sub-directories to work.
EDIT: If I go to localhost:8080/testing_desc.html I don't any errors, just a blank page (view-source is blank, too). Scripts in my root dir work normally. There is a __init__.py in both the root and sub-dir.
Python script example ("/testing/testing_desc.py"):
import webapp2 as webapp
class DescTstPage(webapp.RequestHandler):
def get(self):
html = 'This should work.'
self.response.out.write(html)
app = webapp.WSGIApplication([('/.*', DescTstPage)], debug=True)
app.yaml:
application: blah
version: blah
runtime: python27
api_version: 1
default_expiration: "5d 12h"
threadsafe: false
libraries:
- name: webapp2
version: latest
handlers:
- url: / <-- This one works
script: main.app
- url: /index.html <-- This does NOT work (??)
script: main.app
- url: /(.*?)_desc.html <-- Also does NOT work
script: \1/\1_desc.app
#file not found
- url: /.*
script: file_not_found.app
I have also tried a simpler version of the yaml:
-url: /testing_desc.html
script: /testing/testing_desc.app
When you use WSGI Pyhon27 this will work. Use a dot for the seperator :
-url: /testing_desc.html
script: /testing.testing_desc.app
You are passing a list of routes to your WSGIApplicaiton call. Those routes must match whatever URL is being handled.
('/', DescTstPage) just matches the '/' URL to your handler. /.* matches all routes.
What routes are you setting in testing/testing_desc.app? They must match /testing_desc.html.
To get my scripts working in sub-dir, I changed the app.yaml and /testing/testing_desc.py to this:
app.yaml:
- url: /testing.html
script: testing/testing_desc.py
/testing/testing_desc.py:
app = webapp.WSGIApplication([('/.*', DescTstPage),], debug=True)
def main():
run_wsgi_app(app)
if __name__ == '__main__':
main()
ATM I do not understand how to make the routing work with sub-dir, so I will use this.
The answer is here:
How can i use script in sub folders on gae?
Its not explicitly stated, but in the answer you must change /foo/ to /foo in the WSGIApplication call, which maps to www.bar.com/foo. If you want to map to www.bar.com/foo.html you need to change /foo to /foo.* in the WSGIApplication call AND the url handler in app.yaml to - url: /foo\.html
As the title indicates my API isn't visible in the explorer and all my logs show is the following:
INFO 2013-03-08 13:39:08,182 dev_appserver.py:723] Internal redirection to http://127.0.0.1:8080/_ah/spi/BackendService.getApiConfigs
INFO 2013-03-08 13:39:08,198 dev_appserver.py:3104] "GET /_ah/api/discovery/v1/apis HTTP/1.1" 500 -
The relevant handler from my app.yaml file looks as follows:
13 # Endpoint handlers
14 - url: /_ah/spi/.*
15 script: main.app
And my code from main.py is as follows:
from google.appengine.ext import endpoints
from protorpc import messages
class Location(messages.Message):
reg_id = messages.StringField(1)
phone_number = messages.StringField(2)
latitude = messages.StringField(3)
longitude = messages.StringField(4)
#endpoints.api(name='locations', version='v1', description='Location API for where are you app')
class LocationApi(remote.Service):
#endpoints.method(Location, Location, name='location.insert', path='location', http_method='POST')
def insert(self, request):
return request
app = endpoints.api_server([LocationApi])
Anyone got a clue about what I'm doing wrong?
Please check the following:
As you should be able to see from the logs, you're getting an import error. In main.py add this
from protorpc import remote
From the documentation:
Note: If you want to test authenticated calls to your API using the Google API Explorer, you must also supply its client ID, which is available through the Endpoints library as endpoints.API_EXPLORER_CLIENT_ID.
Check your logs again to make sure the code actually runs. You're getting a 500 because of a Python exception being raise and there may be other issues with your code, though it doesn't seem like from what you've posted.
It works now that I list the endpoint handler before the other handlers.
This works:
handlers:
# Endpoint handler
- url: /_ah/spi/.*
script: endpoints.app
# Page handlers
- url: /.*
script: home.app
This doesn't work:
handlers:
# Page handlers
- url: /.*
script: home.app
# Endpoint handler
- url: /_ah/spi/.*
script: endpoints.app
The problem is that your python file can't find the import for:
from protorpc import remote
Therefore use the terminal, skip the GUI, navigate to the appengine sdk directory and put your project in there. For mac it is:
/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/
I wanted to download the data on my online app's datastore, I followed the guide on code.google, I added this to my app.yaml file
builtins:
- remote_api: on
But when I updated using appcfg.py update src and called this:
appcfg.py download_data --application=myapp --url=http://myapp.appspot.com/remote_api_path --filename=first-test-backup`
I got an Authentication error, pretty much the same case mentioned here, so I tried putting this:
- url: /remote_api
script: $PYTHON_LIB/google/appengine/ext/remote_api/handler.py
login: admin
before any catch-all handlers, but then got this error: threadsafe cannot be enabled with CGI handler when I tried to update, so according to this discussion, I replaced it by:
- url: /remote_api
script: google.appengine.ext.remote_api.handler.application
login: admin
Which gave me again the authentication error, I also tried adding ('/remote_api', google.appengine.ext.remote_api.handler) to app = webapp2.WSGIApplication, however still the authentication error persists.
I use a High Replication datastore, but according to code.google the only drawback is that I might not get the latest data.
How can I download my data?
Try this:
builtins:
- remote_api: on
And for url
appcfg.py download_data --application=~myapp --url=http://myapp.appspot.com/_ah/remote_api --filename=first-test-backup
Atttention _ah in url: http://myapp.appspot.com/_ah/remote_api