Migrating GAE app from python 2.5 to 2.7 - google-app-engine

I am trying to migrate my app and everything worked fine until I changed in app.yaml
from threadsafe: false to threadsafe: true.
The error I was receiving was:
threadsafe cannot be enabled with CGI handler: a/b/xyz.app
After some googling I found:
Only scripts in the top-level directory work as handlers, so if you have any in subdirectories, they'll need to be moved, and the script reference changed accordingly:
- url: /whatever
# This doesn't work ...
# script: lib/some_library/handler.app
# ... this does work
script: handler.app
Is there any workaround for this(if above research is valid), as I don't want to change my project hirarchy?

You can have your handlers anywhere as long as it's a valid python import path.
My app.yaml is full of entries like
- url: /_ah/queue/deferred
script: google.appengine.ext.deferred.application
login: admin
The folders need __init__.py in them to make them work as modules, but you can usually replace any / with .
Alternatively do as Daniel suggest, and note that you'll probably have to mangle the sys.path first to include lib dir and then import handler.

Put a main file in the top-level directory and import all your handlers there, then reference them via that file

Related

How/where does Google App Engine cache YAML (changing `script`)?

Originally I had this in my app.yaml:
runtime: python39
- url: .*
script: main.app
I changed the script filename to gae.py and so updated app.yaml to thus:
runtime: python39
- url: .*
script: gae.app
The new version no longer starts up:
ModuleNotFoundError: No module named 'main'
I have tried changing the url but it's still trying to use a now-non-existent main.py to load the WSGI application. When I view the source of the version I see the correct app.yaml and file structure; I don't see main mentioned anywhere.
Any ideas?
The problem is not caching but rather that script is no longer used (and is ignored) in the Python 3 world of Google App Engine standard:
script: Optional. Specifies that requests to the specific handler should target your app. The only accepted value for the script element is auto because all traffic is served using the entrypoint command. In order to use static handlers, at least one of your handlers must contain the line script: auto or define an entrypoint element to deploy successfully.
(https://cloud.google.com/appengine/docs/standard/python3/config/appref#handlers_element)
The fix is to override entrypoint which defaults to:
/bin/sh -c exec gunicorn main:app --workers 2 -c /config/gunicorn.py
(https://cloud.google.com/appengine/docs/standard/python3/runtime#application_startup)

App Engine deploy with Go libraries

I'm new on Google App Engine. And, I'm getting an issue that I can't solve.
I've a very simple app (developped in Go) like this :
main/
| model/
| | user.go
| main.go
| app.yaml
These are the imports of main.go :
import (
"github.com/julienschmidt/httprouter"
"log"
"net/http"
)
My code works well when I run it locally.
But, when I try to publish it on my Google App Engine instance, I receive this error :
$ gcloud app deploy
You are about to deploy the following services:
- <MY_APP_ENGINE_URL> (from [<MY_LOCAL_YAML_PATH>])
Deploying to URL: [<MY_APP_ENGINE_URL>]
Do you want to continue (Y/n)? Y
Beginning deployment of service [default]...
Some files were skipped. Pass `--verbosity=info` to see which ones.
You may also view the gcloud log file, found at
[<LOCAL_APP_ENGINE_LOG>].
File upload done.
Updating service [default]...failed.
ERROR: (gcloud.app.deploy) Error Response: [9] Deployment contains files that cannot be compiled: Compile failed:
2017/05/27 14:48:24 go-app-builder: build timing: 5×compile (301ms total), 0×link (0s total)
2017/05/27 14:48:24 go-app-builder: failed running compile: exit status 2
main.go:4: can't find import: "github.com/julienschmidt/httprouter"
What did I do wrong ?
EDIT :
This is the content of my app.yaml file :
runtime: go
api_version: go1
handlers:
- url: /.*
script: _go_app
App Engine environment doesn't contain your dependencies, you can add an script to do a go get ... for each one but it's too hacky and Go has a solution for that, we can save our dependencies in a vendor folder on the root of our project.
Quick solution:
# Instal godep:
go get -v -u github.com/tools/godep
cd your/project/path
godep save
Now try to deploy again, you'll see a vendor folder in your project, don't remove it and add it to your git source, that folder contains all your third party dependencies like your httprouter (it's my favorite :) )
Note You can use other tools to save your dependencies
I haven't used the gcloud tool, but back in the day when goapp was the tool you had to create github.com/julienschmidt/httprouter (with the lib's source in it, of course) directly under you'r main and then deploy.
AFAIK the App Engine's go version is currently 1.6 which means that while the vendoring is on by default, it can be switched off - perhaps thats the case and thats why #Yandry Pozo's suggestion doesn't work.

bad import "syscall" for cloud storage APIs

I am following the instructions on https://cloud.google.com/appengine/docs/go/googlecloudstorageclient/download to begin migrating some code from the, now deprecated, Files API to the new Cloud Storage API without success.
The steps I'm following are ...
I'm running appengine v1.9.23 which is later than the required appengine v1.8.1.
My $GOPATH is set, so I skip step #1.
I proceed to step #2:
goapp get -u golang.org/x/oauth2
goapp get -u google.golang.org/cloud/storage
I am not developing on a managed VM, so I skip step #3.
Now when I run the application, I get:
go-app-builder: Failed parsing input: parser: bad import "syscall" in goapp/src/golang.org/x/net/internal/nettest/error_posix.go
What am I doing wrong?
Steps to reproduce
Download an install the Google Appengine runtime, version 1.9.23 from https://console.cloud.google.com/storage/browser/appengine-sdks/featured/ . Follow the installation instructions documented on https://cloud.google.com/appengine/downloads?hl=en
Create an appengine project directory:
% mkdir $HOME/myapp
Create a new app.yaml file as ~/myapp/app.yaml. Read the directions on the Google website for details: https://cloud.google.com/appengine/docs/go/config/appconfig
I use a version that does not have the static resources:
application: myapp
version: alpha-001
runtime: go
api_version: go1
handlers:
- url: /.*
script: _go_app
Create a location for the Go source files.
% mkdir $HOME/myapp/go
Set your GOPATH to the location of your sources
% export GOPATH=$HOME/myapp/go
Get the Go appengine example project: https://github.com/golang/example
% goapp get github.com/golang/example/appengine-hello
This command will download the example app to the first path entry in the GOPATH
Install the Google Cloud Storage client libraries as directed in https://cloud.google.com/appengine/docs/go/googlecloudstorageclient/download . Reference the steps at the top of this question for more details. Following the directions should result in you running 2 commands:
% go get -u golang.org/x/oauth2
% go get -u google.golang.org/cloud/storage
Attempt to run your go application
% goapp serve
You will see the following compilation error (no stack trace):
2015/12/23 10:37:07 go-app-builder: Failed parsing input: parser: bad import "syscall" in go/src/golang.org/x/net/ipv6/control_unix.go
This error is caused by either of two scenarios:
1) Implicitly importing syscall by importing another package that uses it, as referenced in this related question.
2) Having your package source files in your GOPATH located in a directory at or below the same level as your project's app.yaml (eg. app.yaml in ~/go, and packages sources in ~/go/gopath/src). If a package like x/net/internal/nettest exists in your GOPATH the syscall import will be parsed by goapp at compile time and throw the compilation error.
Avoiding these two scenarios should be sufficient to prevent any bad import "syscall" errors or related compilation errors.
Reproduced the initial steps above and got a similar error, even if not explicitly mentioning syscall. However, running “goapp serve” in the appengine-hello directory results in no error at all.
Adam’s explanation at point 2 applies here correctly: one needs to place the app.yaml file at the right level in the directory structure.
sirupsen/logrus references syscall.
They have an appengine tag specified, not to include syscall so it's usable in AppEngine, something like go build -tags appengine as per issue 310.
However I haven't yet succeeded including it in an AppEngine project so that this build param could be forwarded and specified somewhere so that it goes through. I'll come back to update if I manage.

Project Directory Does Not Contain app.yaml

I'm following the instructions here https://console.developers.google.com/start/appengine
I've downloaded and unzipped the project file from that page - it's the python and flask one. When I get to the instruction dev_appserver.py appending-try-python-flask it gives the error.
google.appengine.tools.devappserver2.errors.AppConfigNotFoundError: "." is a directory but does not contain app.yaml or app.yml
It most certainly does contain an app.yaml file. It looks like this.
application: hello-flask-app-engine
version: 1
runtime: python27
api_version: 1
threadsafe: yes
handlers:
- url: .*
script: main.app
libraries:
- name: jinja2
version: "2.6"
- name: markupsafe
version: "0.15"
Unlike this post Uploading a static project to google app engines mine doesn't have any skip files lines to delete.
There is a README.md that mostly follows the Google Dev web page, except that instead of downloading the project from that page it instructs to git clone https://github.com/GoogleCloudPlatform/appengine-python-flask-skeleton.git and that doesn't exactly match the zip file I downloaded.
The requirement.txt file says Run 'pip install -r requirements.txt -t lib/' but Windows 7 says pip is not a recognized command.
Is my app.yaml not correct? Why would it say it doesn't exist?
Simply closing the command prompt window and reopening it made it work. I don't know how or why.
You may be mis-typing appengine-try-python-flask (the real name) as appending-try-python-flask (which is what you show in your question).
If that's not the case, can you please show the effects of dir appengine-try-python-flask and dir appending-try-python-flask from the directory (AKA folder) you're now trying to run dev_appserver.py from?
probably you use py-charm, you need to add to configuration in line 'Working directory' the path of project like: C:\Users\user\Desktop\projects\water
It's repose to work

Google App Engine, can people download my source code?? (with PHP)

I'm new to GAE, and have big doutbts on how it works. Mainly the app.yaml configuration file. If i have this structure for example:
/
/index.php
/scripts/script.php
On app.yaml I should write something like this for example (the basic to work), right?
application: myapp
version: 1
runtime: php
api_version: 1
handlers:
- url: /
script: index.php
- url: /scripts/script.php
script: scripts/script.php
Is this correct? And if i have a lot of scripts on the scripts directory, should i put an entry for all of them?
I ask this (I think its a really stupid question but i want to be sure) because i have realised that if i put the scripts directory as a static_dir, like:
- url: /scripts
static_dir: scripts
... if i go to the URL of that file (http://mydomain.com/scripts.script.php) i can download the source code.
So I guess that static_dir is not for accessing a whole directory's content, and as it's name says... is just for static content like photos for example, right? so for each script i should write a line on the app.yaml to be accesible?
Sorry about my stupid question, my english is not so good and i'm new at this so i have this doutbt ;)
Thanks a lot in advance!
You can find some detailed examples here of PHP and app.yaml here:
https://developers.google.com/appengine/docs/php/config/appconfig
If you have a large number of *.php files that you want to make executable, you can use wildcards. For example:
- url: /(.+\.php)$
script: \1
Will map anything URL ending in .php to the equivalent filepath. So
http://myapp.appspot.com/some/directory/file.php
will map to
some/directory/file.php
in your app's directory.
Don't put anything in static directories that you don't want the world to see. static directories are intended as a fast shortcut for serving things like images, CSS, and JavaScript.
.php files (or .py files if you're using Python) need to be 'executed' (evaluated) on the server (App Engine) side. Putting them in a static_dir puts them out of reach of the execution environment, which isn't what you want.

Resources