0
votes

After a few days of searching and looking around for this, and I haven't been able to find the right answer.

I'm trying to run a cron job on Google App Engine (with Python). The cron job itself isn't that important, I'm just looking to run a python script every minute. For now I'm just trying to add a line with the current time in a separate text file (test.txt).

I'm pretty sure that I don't quite understand the concept of handlers, and that's what causing me problems. But I've spent hours in the documentation, and I still can't figure it out.

I sense that I should not be using main.py as my script for the cron job, but I have a hard time understanding what the url needs to be in cron.yaml, and what the handler/script should be.

Please help!

Here's a list of my files.

app.yaml

runtime: python
env: flex
entrypoint: gunicorn -b :$PORT main:app

runtime_config:
  python_version: 3

handlers:
- url: /main
  script: main.py

cron.yaml

cron:
- description : most recent test
  url : /main
  schedule: every 1 minutes

main.py

# Copyright 2015 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 datetime import datetime

current_time = str(datetime.now())

from flask import Flask


app = Flask(__name__)


@app.route('/')
def hello():
    """Return a friendly HTTP greeting."""
    return 'Hello World! The time is ' + current_time

    message = "this worked, as of " + current_time + "\n"

    with open("test.txt", "a") as myfile:
        myfile.write(message)


@app.errorhandler(500)
def server_error(e):
    logging.exception('An error occurred during a request.')
    return """
    An internal error occurred: <pre>{}</pre>
    See logs for full stacktrace.
    """.format(e), 500


if __name__ == '__main__':
    # This is used when running locally. Gunicorn is used to run the
    # application on Google App Engine. See entrypoint in app.yaml.
    app.run(host='127.0.0.1', port=8080, debug=True)
# [END app]
2

2 Answers

2
votes

You don't have a url handler for /main. Try this:

in app.yaml:

handlers:
- url: /.*      # wildcard.  every url goes there
  script: main.py

in main.py:

from flask import Response

@app.route('/main')
def main():
    """Return a friendly HTTP greeting."""
    Response("Hello main viewer", mimetype='text/plain')

Note: Another bug in your code is that you return the html view BEFORE the script gets a chance to write the .txt file. It will never get that far.

1
votes

Your app.yaml file is mixing up the standard environment Handlers element into a flexible environment configuration, so it is probably ignored.

Your cron.yaml configuration shows a /main URL for your cron job, but your app doesn't seem to have a route for such URL path, it only seems to handle the / path. I'd expect you'd see some 404 errors in the logs for the /main cron requests.

You should add a route for the /main path in your main.py. Or replace /main with / in your cron.yaml.

Side note: you have some non-executable code (it follows the return statement) inside hello() - just in case you're looking for that test.txt file...