Issue running Python37 on Google App Engine - python

I know this question has been asked in some facet or another, but I have gone through readings as shown here and I am still not seeing where my issue is as I am still unable to publish my Django 2.1.1 app in the Python37 environment in Google App Engine:
Python 3 Django on App Engine Standard: App Fails to Start
Overall what I am attempting to do is publish a simple app engine app using:
gcloud app deploy
My application works locally but when I publish, it goes through without issue, but I get the annoying:
500 Server Error message
When I look at the logs in Google I get the same error as many others have gotten:
ModuleNotFoundError: No module named 'main'
here is my relevant directory structure
project_portal
project_portal
init.py
settings.py
urls.py
wsgi.py
main.py
app.yaml
requirements.txt
my app.yaml file
runtime: python37
entrypoint: gunicorn -b :$PORT project_portal.wsgi
env: standard
handlers:
- url: .*
secure: always
redirect_http_response_code: 301
script: project_portal.wsgi.application
my project_portal/wsgi.py file
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project_portal.settings')
application = get_wsgi_application()
from main.py in project root
from project_portal.wsgi import application
from requirements.txt
django == 2.1.1

Without an entrypoint defined, it will try to start from a file called main.py. Create one, at the same level as app.yamlwith some simple logic in it:
from project_portal.wsgi import application
Edit:
Since you have an entrypoint defined, it seems that is the issue. So, make sure you have gunicorn in your 'requirements.txt':
gunicorn==19.9.0
This did not help:
Try changing
entrypoint: gunicorn -b :$PORT project_portal.wsgi
to
entrypoint: gunicorn -b :$PORT project_portal.wsgi:application

Related

Failed to find Flask application or factory in module 'app'. Use 'FLASK_APP=app:name' to specify one

>>> flask run
* Serving Flask app 'app' (lazy loading)
* Environment: development
* Debug mode: on
Usage: flask run [OPTIONS]
Try 'flask run --help' for help.
Error: Failed to find Flask application or factory in module 'app'. Use 'FLASK_APP=app:name' to specify one.
Getting this error when trying to make a package from my simple flask app
Also it can be another error:
Error: While importing 'app', an ImportError was raised.
And maybe it is
>>> flask run
* Serving Flask app 'app' (lazy loading)
* Environment: development
* Debug mode: on
Usage: flask run [OPTIONS]
Try 'flask run --help' for help.
Error: Could not import 'app.app'.
But I'm doing everything by the docs "Large Applications as Packages":
https://flask.palletsprojects.com/en/2.0.x/patterns/packages/
In my case renaming app name from app to another one helped.
Maybe it was some kind of namespace error, because my package was ./app and Flask app object variable in __init__.py was named app (Despite Miguel in his tutorial did it the same way)
In general, while developing web applications you have to be careful with names like wsgi - they can be reserved.
I am executing set FLASK_APP=module, set FLASK_ENV=development, pip install -e . and flask run commands in the first (upper) module directory.
And maybe you only need to revert changes from flask doc tutorial returning to the file structure without __init__.py and with normal app.py. After that delete all __pycache__ folders and repeat this tutorial again

Django application structure,

I'm trying to deploy my Django project to Google AppEngine, however I can't figure out how to properly set up application entrypoint.
This is my whole project structure:
app.yaml
main.py
service:
manage.py
service-project:
wsgi.py
settings.py
...
service-app-1:
...
service-app-2:
...
How can I make it work? I tried to move main.py to service directory and use entrypoint: gunicorn --chdir /service main:application in app.yaml but it results in Error: can't chdir to '/service', I guess AppEngine doesn't allow to change directory.
You need to change entrypoint: gunicorn --chdir /service main:application to entrypoint: gunicorn --chdir ./service main:application in your app.yaml.
The reason you are seeing Error: can't chdir to '/service' is because gunicorn is trying to change directory to the service folder in your root directory.
Adding dot in front of the slash will make it change directory to the service folder in your project, this is because the dot refers to the current directory where your app.yaml is.

How to deploy Flask app as package to App Engine?

I'm following various tutorials from Google Cloud to try and deploy my first Python Flask application to App Engine. I organized my app as a package instead of a module, after watching the tutorial from Corey Schafer on YouTube titled: "Python Flask Tutorial: Full-Featured Web App Part 5 - Package Structure"
So now, in my working directory, I have a structure like this:
1. Project folder
1.1 myapp folder
1.1.1 __pycache__
1.1.2 static folder
1.1.3 __init__.py
1.1.4 app.yaml
1.1.5 requirements.txt
1.1.6 something_else.py
1.2 run.py
My run.py file has the following code:
from myapp import app
if __name__ == '__main__':
app.run(debug=True)
My app.yaml file looks like this:
runtime: python37
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
Now I am not sure how to set up my app.yaml file to specify the entry point, and also make my app run when I deploy it to App Engine. I am currently running the gcloud app deploy command via the Google Cloud SDK after I cd into myapp folder first?
The deployment phase in the console goes well, but when I check the app's browsing link, I am faced with a 502 Bad Gateway error (as I'm also expecting).
Everything works fine locally, but the deployment isn't too straightforward for me now that my app is structured like a package. Any help is greatly appreciated.
In your app.yaml, you can specify a custom entrypoint like so:
runtime: python37
entrypoint: gunicorn -b :$PORT myapp:app
Where myapp:app corresponds to the module to import the WSGI app from (from myapp import app)
You should also move your app.yaml file to be in the project folder instead, and run gcloud app deploy from there instead.
More details here: https://cloud.google.com/appengine/docs/standard/python3/runtime

Deploying a python flask web application on Heroku with Windows

I am trying to deploy a flask app I made to Heroku with success.
The app is generated but I get errors when I push the code to the Heroku repository.
My flask app is inside a module called server.py and the variable is named app.
At first I tried using gunicorn and writing
web: gunicorn server:app
and deplying but no web dynos were up and I get an error stating it is the Procfile file.
Red about it about and saw that Gunicorn is not really working on windows so I tried installing Waitress and deploying without success. this time my profcile was written as all of these (tried several times):
web: waitress-serve --listen=*:8000 server.wsgi:application
web: waitress-serve --listen=*:8000 app.wsgi:application
And so on.
to add a web dyno I should scale it because heroku ps: showes that there is no dynos.
When I try to run heroku ps:scale web=1 I get:
Scaling dynos... !
▸ Couldn't find that process type.
What am i doing wrong?
I was having the same problem. Particularly, waitress works locally in Windows (inside a Procfile.windows file web: waitress-serve index:server, then with heroku CLI heroku local -f Procfile.windows), but failed after Heroku deployment. Workaround for me was to locally test with waitress (like explained), but deploy with gunicorn (web: gunicorn index:server inside Procfile). Let me know if this works for you.

Auto reloading Flask app when source code changes

I know for a fact that Flask, in debug mode, will detect changes to .py source code files and will reload them when new requests come in.
I used to see this in my app all the time. Change a little text in an #app.route decoration section in my views.py file, and I could see the changes in the browser upon refresh.
But all of a sudden (can't remember what changed), this doesn't seem to work anymore.
Q: Where am I going wrong?
I am running on a OSX 10.9 system with a VENV setup using Python 2.7. I use foreman start in my project root to start it up.
App structure is like this:
[Project Root]
+-[app]
| +-__init__.py
| +- views.py
| +- ...some other files...
+-[venv]
+- config.py
+- Procfile
+- run.py
The files look like this:
# Procfile
web: gunicorn --log-level=DEBUG run:app
# config.py
contains some app specific configuration information.
# run.py
from app import app
if __name__ == "__main__":
app.run(debug = True, port = 5000)
# __init__.py
from flask import Flask
from flask.ext.login import LoginManager
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.mail import Mail
import os
app = Flask(__name__)
app.config.from_object('config')
db = SQLAlchemy(app)
#mail sending
mail = Mail(app)
lm = LoginManager()
lm.init_app(app)
lm.session_protection = "strong"
from app import views, models
# app/views.py
#app.route('/start-scep')
def start_scep():
startMessage = '''\
<html>
<header>
<style>
body { margin:40px 40px;font-family:Helvetica;}
h1 { font-size:40px; }
p { font-size:30px; }
a { text-decoration:none; }
</style>
</header>
<p>Some text</p>
</body>
</html>\
'''
response = make_response(startMessage)
response.headers['Content-Type'] = "text/html"
print response.headers
return response
The issue here, as stated in other answers, is that it looks like you moved from python run.py to foreman start, or you changed your Procfile from
# Procfile
web: python run.py
to
# Procfile
web: gunicorn --log-level=DEBUG run:app
When you run foreman start, it simply runs the commands that you've specified in the Procfile. (I'm going to guess you're working with Heroku, but even if not, this is nice because it will mimic what's going to run on your server/Heroku dyno/whatever.)
So now, when you run gunicorn --log-level=DEBUG run:app (via foreman start) you are now running your application with gunicorn rather than the built in webserver that comes with Flask. The run:app argument tells gunicorn to look in run.py for a Flask instance named app, import it, and run it. This is where it get's fun: since the run.py is being imported, __name__ == '__main__' is False (see more on that here), and so app.run(debug = True, port = 5000) is never called.
This is what you want (at least in a setting that's available publicly) because the webserver that's built into Flask that's used when app.run() is called has some pretty serious security vulnerabilities. The --log-level=DEBUG may also be a bit deceiving since it uses the word "DEBUG" but it's only telling gunicorn which logging statements to print and which to ignore (check out the Python docs on logging.)
The solution is to run python run.py when running the app locally and working/debugging on it, and only run foreman start when you want to mimic a production environment. Also, since gunicorn only needs to import the app object, you could remove some ambiguity and change your Procfile to
# Procfile
web: gunicorn --log-level=DEBUG app:app
You could also look into Flask Script which has a built in command python manage.py runserver that runs the built in Flask webserver in debug mode.
The solution was to stop using foreman start as stated in the comments and directly execute python run.py.
This way, the app.run method with the debug=True and use_reloader=True configuration parameters take effect.
Sample Application where app is our application and this application had been saved in the file start.py:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hallo():
return 'Hello World, this is really cool... that rocks... LOL'
now we start the application from the shell with the flag --reload
gunicorn -w 1 -b 127.0.0.1:3032 start:app --reload
and gunicorn reloads the application at the moment the file has changed automaticly. No need to change anything at all.
if you'd love to run this application in the background add the flag -D
gunicorn -D -w 1 -b 127.0.0.1:3032 start:app --reload
-D Demon mode
-w number of workers
-b address and port
start (start.py) :app - application
--reload gunicorns file monitoring
Look at the settings file:
http://docs.gunicorn.org/en/latest/settings.html
all options and flags are mentioned there. Have fun!

Categories