How to run django + email handler in App Engine - python

I try to run django and email handler app together in Google App Engine. I use code as google's doc and it must be run with python27. When I converted to code for python37 got script must be set to "auto" error. Can anyone help me? My code as below. Thanks in advance
app.yaml:
runtime: python37
entrypoint: gunicorn -b :$PORT myproject.wsgi
env_variables:
...
inbound_services:
- mail
- mail_bounce
handlers:
- url: /static
static_dir: static
- url: /_ah/mail/.+
script: handle_incoming_email.app
login: admin
handle_incoming_email.py:
import logging
from google.appengine.ext.webapp.mail_handlers import InboundMailHandler
class IncomingMailHandler(View, InboundMailHandler):
def receive(self, mail_message):
logging.info("Received a message from: " + mail_message.sender)
when I run this error raises from 'script: handle_incoming_email.app' script must be set 'auto'. How can I get handle_incoming_email.py to app.yaml if I set script: auto.
change '.+' as '.*' have tried.

In App Engine Standard, when using the Python3.7 runtime, the script tag under the handlers must be set to auto. You can check the documentation on this here on how the app.yaml must be configured, note that it's different than in the Python2.7 runtime, where you had to specify the script to run.
You can solve this by modifying your app.yaml file, like so:
runtime: python37
entrypoint: gunicorn -b :$PORT handle_incoming_email.app
env_variables:
...
inbound_services:
- mail
- mail_bounce
handlers:
- url: /static
static_dir: static
- url: /_ah/mail/
script: auto
login: admin
Notice how the required change was to set the script under /_ah/mail/ to auto, instead of specifying the path to the script to run. The handler then should automatically find the script to execute, from the files you deployed in App Engine.
Next, in your handle_incoming_email.py file you are not defining any entrypoint to handle your url /_ah/mail, you can solve this by adding the following, for example:
import webapp2
app = webapp2.WSGIApplication([
('/_ah/mail/', IncomingMailHandler),
], debug=True)
Notice now, how I changed the entrypoint in your app.yaml file to match the newly created WSGI entrypoint in your handle_incoming_email.py file.
Also I'm not sure about the '/.+' regex for the handler, you should leave it at '/.*'.

The handler parameter is used to route requests to static files, then the remaining routes are all routed to your main app (the auto value is the only option for the script element, as mentioned in the doc) at your entrypoint. That app must handle requests routing. You can't define another app in the same service.
I'd suggest to deploy your email app as a separate service in your App Engine app. This will allow you to specify specific resources or scaling for each one. This will follow the micro-services architecture principles enforced in App Engine.

Related

Setting up a gcloud appspot domain for a flask api- Getting URL not found error

I am currently trying to setup a gcloud appspot domain. I am consistently getting this error when I attempt to open up my appspot project on the browser:
Error: Not Found
The requested URL / was not found on this server.
Here is my code. How can I fix this?
app.yaml -
runtime: python
env: flex
entrypoint: gunicorn -t 120 -b :$PORT main:app
runtime_config:
python_version: 3
manual_scaling:
instances: 1
resources:
cpu: 2
memory_gb: 8
disk_size_gb: 20
handlers:
- url: /.*
script: auto
main.py
app=Flask(__name__)
api=Api(app)
.
.
.
api.add_resource(Multi,'/sentiment/<num>')
api.add_resource(Analyze,'/analyze/<query>')
api.add_resource(AddLike,'/addLike/<likedMovie>')
api.add_resource(AddDislike,'/addDislike/<dislikedMovie>')
api.add_resource(GetRecommendation,'/getRecommendation/<userID>')
if __name__=='__main__':
app.run(port=os.getenv('PORT',5000))
app.logger.addHandler(logging.StreamHandler(sys.stdout))
app.logger.setLevel(logging.ERROR)
(In between, it contains the classes and methods to serve the api calls)
and my file structure looks like:(inside root folder)
app.yaml
main.py
(other files)
What you're trying to deploy on App Engine is a web app. You cannot deploy Android apps on App Engine. If you look at the picture in the Final System section, the system has two main parts and that is your Android app (client) and a request server. You are deploying the request server in App Engine Flex (which is a managed Compute Engine VM under the hood).
From what I can understand, your request server is designed to handle backend API calls. If you want to display some sort of UI interface when users access /, then register the URL to a function that renders your view page.
I suggest that you study how Flask app routing works. You get that error because the URL (/) is not associated to any of your functions on your app. You can get started at Flask docs. Here's a sample from GitHub

getting No 'Access-Control-Allow-Origin' header is present on the requested resource. GCP and Flask

Hello i've developed an API with Python Flask on the Google App Engine and added the following:
#!flask/bin/python
from flask import Flask, jsonify, request
from flask.ext.cors import CORS, cross_origin
from flask_cors import CORS, cross_origin
app = Flask(__name__)
CORS(app)
app.config['CORS_HEADERS'] = 'Content-Type'
#app.route('/companyInfoFull', methods=['GET'])
#cross_origin()
When trying to deploy a platform using my API I get the following:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Thus, i've added the following to the following app.yaml file and now looks like this:
runtime: python
env: flex
entrypoint: gunicorn -b :$PORT main:app --timeout 220
runtime_config:
python_version: 3.6
handlers:
- url: /.*
script: main.py
http_headers:
Access-Control-Allow-Origin: '*'
but i'm getting the following error when trying to compile from GCP:
An app.yaml (or appengine-web.xml) file is required to deploy this directory as an App Engine application. Create an app.yaml file using the directions at https://cloud.google
.com/appengine/docs/flexible/python/configuring-your-app-with-app-yaml (App Engine flexible environment) or https://cloud.google.com/appengine/docs/standard/python/config/appref (App
Engine standard environment) under the tab for your language.
Any ideas? Many thanks!
The app.yaml must contains CPU, memory, network and disk resources, scaling, and other settings including environment variables. From looking at this error message your app.yaml appears to be missing those parameters. For more information please follow the
Configuring your App with app.yaml.
runtime: python
env: flex
entrypoint: gunicorn -b :$PORT main:app
runtime_config:
python_version: 3
# This sample incurs costs to run on the App Engine flexible environment.
# The settings below are to reduce costs during testing and are not appropriate
# for production use. For more information, see:
# https://cloud.google.com/appengine/docs/flexible/python/configuring-your-app-with-app-yaml
manual_scaling:
instances: 1
resources:
cpu: 1
memory_gb: 0.5
disk_size_gb: 10

how to solve gcloud app deploy network connectivity error?

When I try to deploy my Django project on Google App Engine with command:
gcloud app deploy
then i got network connectivity error every time. Error massage is:
ERROR: (gcloud.app.deploy) EOF occurred in violation of protocol (_ssl.c:661)
This may be due to network connectivity issues. Please check your network settings, and the status of the service you are trying to reach.
I try google but not solve it. Please anyone help me.
My app.yaml file is:
runtime: python37
entrypoint: gunicorn -b :8080 scanner_api.wsgi
handlers:
# This configures Google App Engine to serve the files in the app's static
# directory.
- url: /static
static_dir: static
# This handler routes all requests not caught above to your main app. It is
# required when static routes are defined, but can be omitted (along with
# the entire handlers section) when there are no static files defined.
- url: /.*
script: auto
Try after lowering the number of parallel tasks by setting GAM_THREADS environment variable:
$env:GAM_THREADS=5
If you get the same error, keep it lowering by 4,3,2 ...
try gcloud app deploy --log-http you may get more information about the error
Try changing your network too if nothing help...like mobile hotspot!!
Your openssl is either missing or out of date. Run:
python -m pip install pyopenssl
and try again.

Google App Engine Python: Error in yaml config file when deploying

I'm using Google App Engine, Python37 environment.
I got an error message when trying to deploy a microservice today:
I run the command:
gcloud app deploy app.yaml
Got the error:
...
File upload done.
ERROR: (gcloud.app.deploy) INVALID_ARGUMENT: script field for handler '/.*'
must be set to 'auto' for runtime python37.
PS C:\path_to_app> gcloud app deploy app.yaml
...
My app.yaml is:
service: service_name
runtime: python37
handlers:
- url: /.*
script: main.py
It looks exactly the same from other microservices that I have deployed recently, just the service name is different.
I tried to re-deploy a services that is already running and got same error message.
So I double check app.yaml reference document: https://cloud.google.com/appengine/docs/standard/python3/config/appref
But I couldn't find out what is wrong neither why the same yaml file that had worked before doesn't work anymore.
Does anyone know what can be wrong or maybe what can be changed on Google App Engine in the last days?
Thanks in advance.
As per the AppEngine documentation for Python 3.7,
The only accepted value for the script element is auto
Below is a sample entry from the documentation:
handlers:
- url: /images
static_dir: static/images
- url: /.*
secure: always
redirect_http_response_code: 301
script: auto
The earlier answer from #Omair, while correct, is only part of the story. The OP's original question utilizes an App Engine first-generation ("Gen1") runtime app's app.yaml configuration file where the routing happens, requiring the script: directive in handlers:. While that's a perfectly valid app.yaml for a Gen1 (go111, python [2.5], python27, php55) app, it won't work for next generation ("Gen2") apps.
NOTE: Python 2 is only supported by App Engine Gen1 whereas Python 3 is only supported by App Engine Gen2 (Standard or Flex), so if you migrate from Python 2 to 3, you're also porting from Gen1 to Gen2 and need to keep in mind these differences as well. (Unfortunately, this means migrating from webapp2 to a web framework that handles routing, i.e., Django, Flask, etc.)
App Engine Gen2 requires routing to be done by your framework. As a result, all Gen1 app.yaml files need to be updated. Use of handlers: for your routes must be either removed or changed to auto (because it's done by your web framework now). If you have specific app startup instructions, you can provide an entrypoint: directive; check out these examples.
Both handlers: and entrypoint: are optional. If all script handlers are auto, you don't need handlers: unless your app is serving static files like client-side JS, CSS, HTML, images, etc., and entrypoint: is optional because if you don't specify a server, gunicorn is selected (and started) by default. Basically if you take all the defaults and don't serve static files, you can reduce app.yaml down to 1 line, like this one. That sample is from a repo I'm working on to help developers upgrade Python 2 App Engine apps to Python 3 who need more help than what's available in the official migration guide.
I got this error when deploying a flask app with a blueprint structure. The solution is to have main.py file in the same directory as app.yaml file. In the main.py file, import the app object e.g from app import app (here the first 'app' is the folder containing an init file where the flask app instance is created). After doing this, setting script to auto should work fine.

django non rel and google app engine: remote api issue

I am deploying a django-nonrel app on Google App Engine. The app deploys alright but I can't login to the remote shell.
This is my app.yaml file:
application: masnun
version: 1
runtime: python
api_version: 1
builtins:
- remote_api: on
inbound_services:
- warmup
handlers:
- url: /_ah/queue/deferred
script: djangoappengine/deferred/handler.py
login: admin
- url: /media/admin
static_dir: django/contrib/admin/media
expiration: '0'
- url: /.*
script: djangoappengine/main/main.py
But I am getting an error:
urllib2.URLError: <urlopen error HTTP Error 500: Internal Server Error
Couldn't reach remote_api handler at https://masnun.appspot.com/_ah/remote_api(/.*)?.
Make sure you've deployed your project and installed a remote_api handler in app.yaml.>
Please help me out!
Update: When using Python2.5, getting this error:
DEBUG:google.appengine.tools.appengine_rpc:Got http error, this is try #3
DEBUG:google.appengine.tools.appengine_rpc:Sending HTTPS request:
GET /_ah/remote_api(/.*)? HTTPS/1.1
Host: masnun.appspot.com
X-appcfg-api-version: 1
Content-type: application/octet-stream
User-agent: Google-remote_api/1.0 Linux/2.6.35-25-generic Python/2.5.5.final.0
Add this on app.yaml section handlers, first item:
handlers:
- url: /remote_api
script: $PYTHON_LIB/google/appengine/ext/remote_api/handler.py
login: admin
and deploy again.
The problem is with
GET /_ah/remote_api(/.*)? HTTPS/1.1
If you notice, the URL contains invalid characters "(/.*)?" towards the end.
Assuming you are using django-nonrel, it is an easy fix. Open the file
djangoappengine/db/base.py
and change the line
self.remote_api_path = handler.url
to
self.remote_api_path = handler.url.split('(')[0] # remove '(/.*)' introduced in newer GAE
and that should take care of ensuring the URL is correct.
You can connect to the remote shell using
python manage.py remote shell
and only if you created your App Engine app with Google Accounts Authentication. But remote_api requires a deployed app and since your
python manage.py deploy
fails, the above error is normal.
What error do you get when you try to deploy?

Categories

Resources