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
Related
I'm trying to deploy a gae project with endpoints but it's giving me errors that's should be happening.
I Don't Think there is anything wrong with my code but i keep getting this error when trying to deploy:
There is a /_ah/spi handler configured, but no Google Cloud Endpoints service was found in the app
my app.yaml :
application: app-id
version: 1
runtime: python27
api_version: 1
threadsafe: true
# --- Handlers
handlers:
- url: /favicon\.ico
static_files: favicon.ico
upload: favicon\.ico
- url: .*
script: main.app
secure: always
- url: /js
static_dir: static/js
- url: /img
static_dir: static/img
- url: /css
static_dir: static/bootstrap/css
- url: /fonts
static_dir: static/fonts
- url: /partials
static_dir: static/partials
- url: /_ah/spi/.*
script: game.api
secure: always
# --- Libraries
libraries:
- name: webapp2
version: "2.5.2"
- name: pycrypto
version: latest
- name: endpoints
version: latest
- name: jinja2
version: latest
and my game.py :
from datetime import datetime
import endpoints
from protorpc import messages
from protorpc import message_types
from protorpc import remote
from google.appengine.api import memcache
from google.appengine.api import taskqueue
from google.appengine.ext import ndb
# --- Setup Code
WEB_CLIENT_ID = 'app-id'
# --- Classes
class Hello(messages.Message):
"""String that stores a message."""
greeting = messages.StringField(1)
class TestOne(messages.Message):
''' TestOne message '''
msg = messages.StringField(1)
# --- API & Endpoints
#endpoints.api(name='whoamigame', version='v1')
class WhoAmIGameApi(remote.Service):
#endpoints.method(message_types.VoidMessage, TestOne, path='testone', http_method='GET', name='testonemethod')
def testOneM(self, req):
testOneMsgReturn = TestOne(msg='Test One...')
return testOneMsgReturn
# --- API
api = endpoints.api_server([WhoAmIGameApi])
Every time i try to deploy it, the endpoints fail. i'm not sure how to fix this issue. the code and syntax is perfect to me. everything is defined. the sdk fails every time.
I'm developing a matchmaking system with gae and python. I was finding a consistent system for automatic matchmaking, and I found the task queue. I implemented a cron job to run every 10 minutes to add a queue. However I'm getting the following error:
When running /queue_generator:
Traceback (most recent call last):
File"/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 267, in Handle
result = handler(dict(self._environ), self._StartResponse)
TypeError: 'module' object is not callable
The code that I have is:
(SessionID is just a db model)
queue_generator.py
import webapp2, time
from main import SessionID
from google.appengine.api import taskqueue
from google.appengine.ext import db
class Game(db.Model):
Users = db.ListProperty(str)
Score = db.IntegerProperty()
Turn = db.StringProperty()
class MainHandler(webapp2.RequestHandler):
def get(self):
taskqueue.add(url='/matchcreator',params={"id":str(time.time())})
class Gamegenerator(webapp2.RequestHandler):
def get(self):
while True:
q = Queue.get()
if len(q.queue) >= 4:
sids = []
for i in range(0,3):
sids.append(q.queue[i])
q.queue.remove(i)
q.put()
return self.response.set_status(204)
def post(self):
while True:
q = Queue.get()
if len(q.queue) >= 4:
sids = []
for i in range(0,3):
sids.append(q.queue[i])
q.queue.remove(i)
q.put()
return self.response.set_status(204)
app = webapp2.WSGIApplication([
('/queue_generator', MainHandler),
("/matchcreator",Gamegenerator)
], debug=True)
Why is this error occuring?
Edit
app.yaml
application: brobbinsgame
version: 1
runtime: python27
api_version: 1
threadsafe: yes
handlers:
- url: /favicon\.ico
static_files: favicon.ico
upload: favicon\.ico
- url: /css
static_dir: css
- url: /home.css
static_files: style.css
upload: style.css
application_readable: true
- url: /register
script: register.app
- url: /logout
script: logout.app
- url: /line
script: line.app
- url: /queue_generator
script: queue_generator
login: admin
- url: /home
script: home.app
- url: /resetsid
script: resetsid.app
login: admin
- url: .*
script: main.app
libraries:
- name: webapp2
version: "2.5.2"
- name: pycrypto
version: "latest"
For every path except "/queue_generator, you have correctly referenced the app object. But for that one path, you reference the module directly. You need to define it in exactly the same way:
- url: /queue_generator
script: queue_generator.app
login: admin
Also notice that there is no way to get to "/matchcreator": "/queue_generator" is the only URL that will be routed to that file. You need to either expose "/matchcreator" in app.yaml as well, or do the more usual thing which is to route all the paths to a main app which imports all the handlers and defines the specific routing there.
This error is occurring because you are calling a Module instead of a Class.. the call should be : Module.Class.Method()
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.
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'm following this tutorial
https://developers.google.com/bigquery/docs/authorization#service-accounts-appengine
Here is my main.py code
import httplib2
from apiclient.discovery import build
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from oauth2client.appengine import AppAssertionCredentials
# BigQuery API Settings
SCOPE = 'https://www.googleapis.com/auth/bigquery'
PROJECT_NUMBER = 'XXXXXXXXXX' # REPLACE WITH YOUR Project ID
# Create a new API service for interacting with BigQuery
credentials = AppAssertionCredentials(scope=SCOPE)
http = credentials.authorize(httplib2.Http())
bigquery_service = build('bigquery', 'v2', http=http)
class ListDatasets(webapp.RequestHandler):
def get(self):
datasets = bigquery_service.datasets()
listReply = datasets.list(projectId=PROJECT_NUMBER).execute()
self.response.out.write('Dataset list:')
self.response.out.write(listReply)
application = webapp.WSGIApplication(
[('/listdatasets(.*)', ListDatasets)],
debug=True)
def main():
run_wsgi_app(application)
if __name__ == "__main__":
main()
Here is my app.yaml file code
application: bigquerymashup
version: 1
runtime: python
api_version: 1
handlers:
- url: /favicon\.ico
static_files: favicon.ico
upload: favicon\.ico
- url: .*
script: main.py
And yes i have added app engine service account name in google api console Team tab with can edit permissions.
When upload the app and try to access the link it says
Oops! This link appears to be broken.
Ealier i ran this locally and tried to access it using link localhost:8080.Then i thought may be running locally might be giving the error so i uploaded my code to
http://bigquerymashup.appspot.com/
but still its giving error.
EDIT:
Updated App.yaml
application: bigquerymashup
version: 1
runtime: python
api_version: 1
handlers:
- url: /favicon\.ico
static_files: favicon.ico
upload: favicon\.ico
- url: .*
script: main.py
- url: /listdatasets
script: main.py
But getting another error
Traceback (most recent call last): File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/webapp/_webapp25.py", line 710, in call handler.get(*groups) TypeError: get() takes exactly 1 argument (2 given)
You need to define a Script Handlers that matches the URL you are trying to locate.
Try: http://[your_app_id_here].appspot.com/listdatasets
Read more about handlers here.