I'm getting this error from a request called from the task queue. It suggests I need to change the app.yaml handler but I think I have the correct handler
Here is the error log entry:
2011-11-17 13:30:35.849 /tasks/kacher 302 209ms 0kb
0.1.0.1 - - [17/Nov/2011:13:30:35 -0800] "GET /tasks/kacher HTTP/1.1" 302 0 - - "rawload.XXX.appspot.com" ms=209 cpu_ms=0 api_cpu_ms=0 cpm_usd=0.000032 queue_name=default task_name=cf2e2f1d39d108b3972a1da8c6532fea
W2011-11-17 13:30:35.842
Request failed because URL requires user login. For requests invoked within App Engine (offline requests like Task Queue, or webhooks like XMPP and Incoming Mail), the URL must require admin login (or no login).
This is the code to call the task:
taskqueue.add(url='/tasks/kacher',target='rawload',method='GET')
Here is my app.yaml, with the task urls as login:admin which seems correct (to me):
- url: /tasks.*
script: main.py
login: admin
- url: .*
script: main.py
login: required
secure: always
There's a known bug in the dev_appserver with tasks that require admin login sometimes failing like this. Try logging your browser session in as an admin before accessing the URL that enqueues the task, or try uploading your app to production to see if you experience the issue there.
Related
using push queues and flexible environment on Google AppEngine I get 403 (Forbidden) error when a task (to be executed on backend service), created with default service, is executed. The task is successfully pushed to queue, confirmed locally, but the execution of the task(s) fails with log:
INFO 2020-12-24 13:42:39,897 module.py:865] default: "POST /tasks/test-handler HTTP/1.1" 403 31
WARNING 2020-12-24 13:42:39,897 taskqueue_stub.py:2158] Task task2 failed to execute. The task has no remaining retries. Failing permanently after 1 retries and 0 seconds
The same happens both locally and on production. However, if a task is created with a cron job then the execution works just fine. I am using dev_appserver.py with Go 1.11 with the following .yaml definitions:
# backend service
service: backend
runtime: go111
instance_class: F2
inbound_services:
- warmup
- default
handlers:
- url: /tasks/.*
login: admin
redirect_http_response_code: 301
# default app service
service: default
runtime: go111
instance_class: F2
inbound_services:
- warmup
handlers:
- url: /api/.*
script: auto
secure: always
redirect_http_response_code: 301
Initial API request comes to an /api endpoint which then succesfully pushes a queue message using:
t := taskqueue.NewPOSTTask(taskURL, url.Values{
"testParam": {strconv.Itoa(testParam)},
})
if _, err := taskqueue.Add(ctx, t, "test-queue"); err != nil {
return ErrPublishingTaskToQueue
}
My queue.yaml definition (in reality I have many more):
total_storage_limit: 120M
queue:
- name: test-queue
rate: 1/s
bucket_size: 100
max_concurrent_requests: 10
retry_parameters:
task_retry_limit: 1
Any ideas why I'd be getting 403 (Forbidden) statuses on task execution if a task is not created via a cron job? The documentation and existing resources on this matter do not help much :/
Managed to make it work. If anyone struggles with getting 403 responses on task execution for push queues on Google AppEngine make sure that you set the right target service. In my example above I was missing target: backend in queue.yaml:
total_storage_limit: 120M
queue:
- name: test-queue
rate: 1/s
bucket_size: 100
max_concurrent_requests: 10
target: backend
retry_parameters:
task_retry_limit: 1
The problem was that the tasks were created with default service which by default means they hit the default service, but should hit backend service. Unfortunately default service had the required endpoint deployed as well, so I got 403 instead of 404.
More details on the target field:
https://cloud.google.com/appengine/docs/standard/python/config/queueref#target
I have a module that works fine when I push it to app engine. When it works it logs stuff nicely and the logs are accessible in the console logs viewer. But then after a while it just stops working and when I try to access any url give me 500 server errors with no info (it just says waiting 30 seconds might be a good idea). When this happens nothing gets logged for requests.
If I restart the module (by pushing my code to app engine) then it works for a little while again.
The module is running a Pyramid app and the configuration file looks a little something like:
application: my_app
module: my_module
version: dev
runtime: python27
api_version: 1
threadsafe: false
instance_class: B2
basic_scaling:
max_instances: 2
idle_timeout: 10m
handlers:
- url: /actions/.*
script: my_module.application
login: admin
- url: /.*
script: my_module.application
builtins:
- appstats: off
libraries:
- name: webob
version: latest
- name: setuptools
version: latest
includes:
- mapreduce/include.yaml
I think what is happening is that it's hitting the idle timeout and shutting down. I need requests to the module to turn it back on again. How do I do that?
Let me know if you need more info, I'm an app engine noob at this stage. Any help would be greatly appreciated.
When a module start, App Engine call the url /_ah/start. You mustn't handle this request.
In you my_module.application you need to add in the handler who match this request :
def get(self):
# Let module start
if "X-Appengine-Cron" in self.request.headers or "X-AppEngine-TaskName" in self.request.headers or "X-Appengine-Failfast" in self.request.headers:
return
Even if you hit the idle timeout, AppEngine will spin a new instance when new request is coming in.
Use Cloud Debugger to inspect the state of your application. The debugger makes it easier to view the application state and understand what happens after your app has been running for while.
Check the docs on startup state https://cloud.google.com/appengine/docs/python/modules/#Python_Instance_states
you current default handler /.* should be able deal with a /_ah/start if youe handler can gracefully deal with a 404.
Thats how I handle startups. Goes through the main handler which can deal with non existent url requests using the default pyramid not found.
I have a config.add_notfound_view(notfound) registered.
I've installed a CakePHP application onto App Engine, and I'm redirecting URLs into it using a wildcard URL in my app.yaml:
url: /.*
script: app/webroot/index.php
The documentation states that /_ah/* URLs will be ignored (I don't know what these are for yet), but they are being caught by my CakePHP app and throwing errors into the error log. I also suspect this is the cause of 500 errors with an appengine error of 204 that keep happening randomly.
Does anyone have a solution for this? How do I ensure that the /_ah/ urls pass through to the app engine and not my specific application code?
Example error:
E 08:51:48.957 2015-03-17 404 841 B 304ms /_ah/start
0.1.0.3 - - [17/Mar/2015:01:51:48 -0700] "GET /_ah/start HTTP/1.1" 404 841 - - "****.appspot.com" ms=304 cpu_ms=416 cpm_usd=0.000094 loading_request=1 instance=0 app_engine_release=1.9.18
E 08:51:48.854 error: [MissingControllerException] Controller class AhController could not be found.
MissingControllerException is thrown by my app.
Request to /_ah/start is an initial request from Appengine itself, to initialize your app. I think you can ignore it, if you don't need to do anything special. Or return empty response.
See docs: https://cloud.google.com/appengine/docs/php/modules/#PHP_Instance_states
I have an endpoint api named "gameApi"
I have an api called:
#ApiMethod(name = "startNewRound", path = "evaluateRound", httpMethod = HttpMethod.POST)
I'm trying to run the following task queue:
queue.add(
ofy().getTransaction(),
TaskOptions.Builder.withUrl("/_ah/api/gameApi/v1/evaluateRound")
.param("gameId", gameId.toString())
.method(TaskOptions.Method.POST)
.countdownMillis(5000));
I'm getting a 404 in the logs:
0.1.0.2 - - [14/Nov/2014:14:58:28 -0800] "POST /_ah/api/gameApi/v1/evaluateRound HTTP/1.1" 404 234 "https://some-appspot-123.appspot.com/_ah/spi/com.appspot.some_appspot_123.spi.GameAPI.playCard" "AppEngine-Google; (+http://code.google.com/appengine)" "some-appspot-123.appspot.com" ms=8 cpu_ms=21 cpm_usd=0.000026 queue_name=default task_name=62689306220576549071 instance=00c61b117c54ec2fb802c51c19fe26523ec51854 app_engine_release=1.9.16
It looks like it's hitting the HTTP and not the HTTPS page. Is there a way I can force it to use HTTPS?
In endpoints, HTTP 404 corresponds to com.google.api.server.spi.response.NotFoundException.
Is it possible that the method has not been defined in the API class, or that it doesn't have a correct annotation?
Also, it doesn't seem like it's hitting http, the trace clearly shows https as the protocol. I think it's only possible to use http on localhost.
I have a project on Google App Engine. It has 2 separate data-stores one which holds articles and the other holds any article which is classified as a crime. (True or False)
But when I try and run my cron to move the crime articles into the "crime" data-store I receive this error:
Has anyone experienced this and how did they over come it!?
0kb AppEngine-Google;
0.1.0.1 - - [22/Apr/2011:09:47:02 -0700] "GET /place HTTP/1.1" 500 138 - "AppEngine-Google;
(+http://code.google.com/appengine)"
"geo-event-maps.appspot.com" ms=1642
cpu_ms=801 api_cpu_ms=404
cpm_usd=0.022761 queue_name=__cron
task_name=740b13ec69de6ac36b81ff431d584a1a loading_request=1
As a result my cron fails.
I just had a similar problem where my cron was crashing due to the fact that it was finding an non-ascii character and not able to process it? Try encode('utf-8'). My cron's work ok without needing the login URL, but it's a good tip for future :-)
Just my 2 cents worth for your question ;-)
It's probably not related to cron. Trying to load your URL directly (http://geo-event-maps.appspot.com/place) returns an HTTP 500 error. As an admin of the app, you should be able to run any cron job without error just by pasting the URL into a browser, so start there.
By the way, make sure to require admin access to any cron URLs. As an unauthorized user I should have received a 401 error, not a 500. Even if you use just one handler, you can do something like this in your app.yaml:
- url: /cron/.*
script: main.py
login: admin
- url: /.*
script: main.py