So I made a very simple flask-based app and hosted it in a kubernetes pod.
When I open the logs in Rancher, I can see this warning:
* Serving Flask app "app/preapproved_limits/api.py"
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
that I see as well when I start flask on my local machine.
But what I don't see on my local machine and do see in Rancher is this:
10.0.67.20 - - [02/Jul/2020 16:49:20] "GET /health HTTP/1.1" 200 -
INFO:werkzeug:10.0.67.20 - - [02/Jul/2020 16:49:20] "GET /health HTTP/1.1" 200 -
which gets logged every 5 seconds.
What the heck?
But the most important and annoying thing is I can't see my logs which I make with the Python's print() function.
Can someone explain:
Why do I see something both in Rancher and locally (the initial Flask warning), but
why do I see something only in Rancher (the /health or INFO:werkzeug logs)
and why do I see something only locally on my machine, but not in Rancher (print())
/health is a normal healthcheck endpoint that k8s needs.
Flask doesn't print to stdout by default because it buffers lines to make I/O more efficient. You can either call sys.stdout.flush(), print(flush=True), set env var PYTHONUNBUFFERED=1 in your Dockerfile (probably the easiest) or just use logging module as we all should.
You can read more about this env var here.
Related
I have a Flutter Web app with an iOS Safari-specific error. To debug it I create a build (flutter build web) and run Python's http.server (python3 -m http.server), then use ngrok to be able to open the app on my mobile device.
To be able to see logs I use OverlayEntry with Text, but it's not very convenient.
Python's http.server does some logging that looks like this:
Serving HTTP on :: port 8000 (http://[::]:8000/) ...
::1 - - [10/Sep/2022 20:05:06] "GET / HTTP/1.1" 200 -
::1 - - [10/Sep/2022 20:05:07] "GET /flutter.js HTTP/1.1" 304 -
Is it possible to log something from a Flutter app to see it inside Python's http.server logs?
Yes, it's possible. You can use print() to log something to the console. You can also use the dart:developer package to log to the browser's console. Example:
import 'dart:developer' as developer;
developer.log('Hello world!', name: 'my.app.category');
It's hard to remember when, but at one point the auto-reload function of Flask started to not work anymore in my project.
This is the output upon starting my app :
FLASK_APP = back/python/app/app.py:app
FLASK_ENV = development
FLASK_DEBUG = 1
In folder C:/path/to/project
ssh://[VirtualMachineIP]:22/root/env/bin/python3.7 -u -m flask run -h 0.0.0.0 -p 1234
* Serving Flask app 'back/python/app/app.py:app' (lazy loading)
* Environment: development
* Debug mode: on
* Running on all addresses.
WARNING: This is a development server. Do not use it in a production deployment.
* Running on http://[VirtualMachineIP]:1234/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 106-048-128
The development environment and Debug mode are both on. Thus, upon saving changes in a file (while the app is deployed) I get the usual message :
* Detected change in '/path/to/changed/file.py', reloading
Signaling that the app is reloading with the new code. Except it doesn't reload anything, and the message doesn't appear on any further changes until I'm forced to restart the app.
PyCharms runs on Windows and communicates via ssh to my Virtual Machine, where the code is executed. I have installed the following modules:
flask
flask-socketio
eventlet
flask-cors
Any help is welcomed. Thanks :)
The FLASK_DEBUG environment variable is badly supported, it may not behave as expected if set in code. (Quoted from the source of flask).
It suggest to use flask run in debug mode.
eg: $ flask --app hello --debug run
If it still not work, you can force to use reloader like this:
if __name__ == '__main__':
app.run(host=config.HOST, port=config.PORT, debug=True)
Take care, the app.run() must be wrapped with if __name__ == '__main__'.
doc: https://flask.palletsprojects.com/en/2.2.x/config/#DEBUG
I used Visual Studio 2017 as IDE for my small Flask project, but when I tried to upgrade to VS2019, it just won't start any more, the Python console stucked at
* Serving Flask app "flask_vs2019" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Restarting with stat
Then I created a new Flask project via VS2019 wizard, added debug=True and it stucked at restarting. The launch code are shown below:
import os
from flask_vs2019 import app
if __name__ == '__main__':
HOST = os.environ.get('SERVER_HOST', 'localhost')
try:
PORT = int(os.environ.get('SERVER_PORT', '5555'))
except ValueError:
PORT = 5555
app.run(HOST, PORT, debug=True)
I tried multiple workarounds and I'm pretty sure it is a VS 2019 issue.
Flask works when:
using VS 2017 with exact same code
using a cmd console and launch by flask run or python -m flask run
switch off reloader with use_reloader=False or DEBUG=False, which is unacceptable since you have to relaunch Flask whenever you change your code.
Flask won't work when:
using VS 2019 (16.7) for any version of Flask and werkzeug
set FLASK_ENV=development and/or DEBUG=True as environment variable
installing watchdog package in virtual environment
In fact I found that the exact same issue was reported on Visual Studio Developer Community back on March 2020, but "this issue didn't have much product team activity and a very small amount of new votes or comments. Based on this, its severity, and affected area, it’s my experience that this issue is very unlikely to be fixed". Well I guess I will have to stick with VS 2017 for now.
Even if I turned off debug mode, the Python console still didn't work properly as the color output was broken.
127.0.0.1 - - [08/Aug/2020 13:59:02] "[37mGET / HTTP/1.1[0m" 200 -
127.0.0.1 - - [08/Aug/2020 13:59:02] "[37mGET /static/content/bootstrap.min.css HTTP/1.1[0m" 200 -
127.0.0.1 - - [08/Aug/2020 13:59:02] "[37mGET /static/content/site.css HTTP/1.1[0m" 200 -
127.0.0.1 - - [08/Aug/2020 13:59:03] "[33mGET /favicon.ico HTTP/1.1[0m" 404 -
Work around with colorama setup colorama.init(autoreset=True) won't work. In VS2017 no workaround would be needed and color output just works as is.
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.
I am running a Flask app on Google Cloud App Engine (flex). Running it locally works just fine, but once it deploys I get a 502 Bad Gateway error (nginx). Now I would like to figure out what causes this, but I am not able to find any option to view the console logs that my app creates.
Since it works just fine on my local environment, my current workflow to solve this issue involves changing my code locally and deploying it to see if it works afterwards, but each deployment takes over 30min only to figure out it still does not work. There must be a way to do this more efficiently.
Following the docs https://cloud.google.com/appengine/docs/flexible/python/debugging-an-instance
I was able to SSH into my instance in debug-mode and launch the Flask app from the Cloud Shell, however it tells me to access it on http://127.0.0.1:8080/ which I can't access from the cloud server. Hence I can't navigate the webpage in order to reproduce the 502 error and then see the output in the console.
How can I figure out what causes the 502 error on the server?
Had the similar issue.
Found that app engine looks for app variable in main.py file.
My final app.yaml looks like below.
app.yaml
runtime: python
env: flex
entrypoint: gunicorn -b :$PORT main:app
runtime_config:
python_version: 3
and had requirements.txt, which looks like below.
requirements.txt
Flask==1.1.1
gunicorn==20.0.4
Here are my theories:
localhost (127.0.0.1) is being used; should use 0.0.0.0
Flask internal WSGI server is being used; should use e.g. Gunicorn
NB You may develop and test these solutions using Cloud Shell. Cloud Shell (now) includes a web preview feature that permits browsing endpoints (including :8080) for servers running on the Cloud Shell instance.
Flask
Flask includes a development (WSGI) server and tutorials generally include:
if __name__ == '__main__':
app.run(host='127.0.0.1', port=8080, debug=True)
Which, if run as python somefile.py will use Flask's inbuilt (dev) server and expose it on localhost (127.0.0.1).
This is inaccessible from other machines:
* Serving Flask app "main" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://127.0.0.1:8080/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 244-629-469
If instead, host='0.0.0.0' is used, then this will work:
* Serving Flask app "main" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://0.0.0.0:8080/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 244-629-469
192.168.9.1 - - [08/May/2019 23:59:59] "GET / HTTP/1.1" 200 -
192.168.9.1 - - [08/May/2019 23:59:59] "GET /favicon.ico HTTP/1.1" 404 -
E.g. Gunicorn
Flask's inbuilt server should not be used and Flex's documentation describes how to use gunicorn (one of various alternatives) should be configured:
https://cloud.google.com/appengine/docs/flexible/python/runtime#application_startup
Which, if run gunicorn --bind=0.0.0.0:8080 main:app gives:
[INFO] Starting gunicorn 19.9.0
[INFO] Listening at: http://0.0.0.0:8080 (1)
[INFO] Using worker: sync
[INFO] Booting worker with pid: 7
App Engine Flex
Using the recommended configuration, app.yaml would include:
runtime: python
env: flex
entrypoint: gunicorn --bind:$PORT main:app
Dockerfiles
You can test these locally with Dockerfiles and -- if you wish -- deploy these to Flex as custom runtimes (after revising app.yaml):
FROM python:3.7-alpine
WORKDIR /app
ADD . .
RUN pip install -r requirements.txt
For Flask add:
ENTRYPOINT ["python","main.py"]
NB In the above, the configuration results from the somefile.py app.run(...)
And for gunicorn:
ENTRYPOINT ["gunicorn","--bind=0.0.0.0:8080","main:app"]