This question already has answers here:
__del__ on exit behavior
(1 answer)
I don't understand this python __del__ behaviour
(8 answers)
Closed 2 years ago.
I have the following, seemingly easy, issue which I cannot figure out.
I made a short, self-containing example below:
from flask import Flask
class MyFlask(Flask):
def __init__(self, name):
super().__init__(name)
print(f'Initialising Flask app {id(self)}')
def __del__(self):
print(f'Deleting Flask app {id(self)}')
if __name__ == "__main__":
app = MyFlask(__name__)
app.run(host='0.0.0.0', port=5000, debug=True)
When one runs this, you will see two instances of MyFlask being initialized, but only one being destroyed. I know why there are two calls to the init method (the way Werkzeug works), but why is only one destroyed?
See the sample output below:
(venv) D:\Onedrive\Documents\Projects\FlaskReloader>python example.py
Initialising Flask app 1944027544880
* Serving Flask app "example" (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
Initialising Flask app 2213899877680
* Debugger is active!
* Debugger PIN: 247-475-647
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
Deleting Flask app 1944027544880
Any ideas? Thanks!
I think it cause by the override of Flask.__del__
Call super on that __del__ or don't override
print(f'Deleting Flask app {id(self)}')
super().__del__(self)
Related
I have been using the following python 3 script in a CDSW session which run just fine as long as the session is not killed.
I am able to click on the top-right grid and select my app
hello.py
from flask import Flask
import os
app = Flask(__name__)
#app.route('/')
def index():
return 'Web App with Python Flask!'
app.run(host=os.getenv("CDSW_IP_ADDRESS"), port=int(os.getenv('CDSW_PUBLIC_PORT')))
I would like this app to run 24/7, so instead of using a Session or scheduling a job that never ends, I would like to create a CDSW Application so that it doesn't stop.
This is the settings on my application:
Logs:
from flask import Flask
import os
app = Flask(__name__)
#app.route('/')
def index():
return 'Web App with Python Flask!'
app.run(host=os.getenv("CDSW_IP_ADDRESS"), port=int(os.getenv('CDSW_PUBLIC_PORT')))
* 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: off
OSError: [Errno 98] Address already in use
I tried to change the port from CDSW_PUBLIC_PORT to CDSW_APP_PORT but it ends up the same.
As it mentions here maybe you need to change this line of code
app.run(host=os.getenv("CDSW_IP_ADDRESS"), port=int(os.getenv('CDSW_PUBLIC_PORT')))
to this
app.run(host="127.0.0.1", port=int(os.environ['CDSW_APP_PORT']))
Hope it works!
This question already has answers here:
Why does running the Flask dev server run itself twice?
(7 answers)
Closed 2 years ago.
Here is my (simplified) flask code
from flask import Flask, request, redirect
from api_v1.api import api as api_blueprint
app = Flask(__name__)
app.register_blueprint(api_blueprint, url_prefix='/api/v1')
if __name__ == '__main__':
app.run(port=5001, debug=True, host="0.0.0.0")
here is api.py
from flask import Blueprint, request
from api_v1.db.connect_db import Dbs
db = Dbs() api = Blueprint('api/v1/', __name__)
here is connect_db.py
import mysql.connector
class Dbs:
def __init__(self):
print("connecting")
self.source_db = mysql.connector.connect(
# credentials goes here
)
self.main_db = mysql.connector.connect(
# credentials goes here
)
self.source_cursor = self.source_db.cursor()
self.main_cursor = self.main_db.cursor()
print("connected")
output:
connecting
connected
Serving Flask app "app" (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
connecting
connected
Debugger is active!
Debugger PIN: 000-00-000 *
Running on http://0.0.0.0:8080/ (Press CTRL+C to quit)
The problem is,
THIS CONNECTS TWICE TO THE DATABASES
And it's showing duplicate connections from the app in my mysql server
Why is this happening?
Anyone know a solution ?
You are clearly connecting twice as in:
self.source_db = mysql.connector.connect(
# credentials goes here
)
self.main_db = mysql.connector.connect(
# credentials goes here
)
Connect once and then run USE db_name to change database
MySQL Use statement
I'm building a Flask application that needs to access an initialized class across requests. The below POST request to the Flask server says that the global variable ex is of type None, despite it being initialized and reassigned to the Engine class in the main on startup. Why is this?
ex = None #Storing the executable so that it can be accessed
flask_app = Flask(__name__)
flask_app.debug = True
#flask_app.route('/reach_engine', methods = ['POST'])
def result():
global ex
print(ex.txt) #Prints type error, saying that ex is of type None (this is the problem)
class Engine:
def __init__(self):
super(Engine, self).__init__()
self.txt = 'The real Engine'
def startApp():
global ex
ex = Engine()
if __name__ == '__main__':
#Start a thread that will run the main app
t = threading.Thread(target=startApp)
t.daemon = True
t.start()
# Start the flask app
print(rd_info + "Intializing Flask application")
flask_app.run('0.0.0.0', '1000', debug=True,
threaded=True, use_reloader=False)
Try to use #flask_app.before_first_request and then create the thread. I leave you this link if you want more details: Global variable is None instead of instance - Python
I ran your code after adding the missing imports, setting rd_info, and changing the port to 5000 (because ports below 1024 are privileged ports on many systems)
$ python stackoverflow.py
random-Intializing Flask application
* Serving Flask app "stackoverflow" (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
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
then
$ curl --request POST --data '' http://0.0.0.0:5000/reach_engine
caused
The real Engine
10.0.2.2 - - [10/Jul/2020 17:31:18] "POST /reach_engine HTTP/1.1" 500 -
Traceback (most recent call last):
...
TypeError: The view function did not return a valid response. The function either returned None or ended without a return statement.
plus a spew of Flask/Werkzeug debug info on the curl side. I expected the TypeError, given the lack of return in the route. Still, this proves that the thread is running.
This was on Ubuntu 18.04 with Python 3.6.9.
This has now been resolved. In the original code, there was an intentional for loop in the initialization of the engine, causing the global variable ex never to be fully assigned. (Note for others finding this)
I'm trying to set-up an application which will receive HTTP GET's and POST's using python and flask-restful. The problem that I'm getting is that when I start the application I see that there are two instances of a queue being generated. I would like you to help me understand why?
Application output (terminal):
<queue.Queue object at 0x10876fdd8>
* 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:5000/ (Press CTRL+C to quit)
* Restarting with stat
<queue.Queue object at 0x10ce48be0>
* Debugger is active!
* Debugger PIN: 292-311-362
Python code (ran with the following command python -m main):
import json
from flask import Flask, request
from flask_restful import Resource, Api, reqparse
import requests
import os
import threading
import queue
import sys
app = Flask(__name__)
api = Api(app)
parser = reqparse.RequestParser()
parser.add_argument("endpoint")
queue = queue.Queue()
base_path = os.path.dirname(os.path.realpath(__file__))
config = Json_Parser().get_json_object(base_path + "path")
consumer = Consumer(config, queue)
t1 = threading.Thread(target=consumer.consume)
t1.start()
class Interaction(Resource):
def get(self):
self.create_interaction()
thread_queue = consumer.get_queue()
output = thread_queue.get()
return output
api.add_resource(Interaction, '/interaction')
if __name__ == '__main__':
print(queue)
app.run(debug=True)
With the help of #Richar de Wit I changed the following line:
app.run(debug=True)
to:
app.run(debug=True, use_reloader=False)
to prevent the debugger to instantiate two queues thus giving issues later on.
The problem is referenced in this question:
Why does running the Flask dev server run itself twice?
I have an app.py flask application, that I want to enable auto-reloading for. This is the entry point:
APP = Flask(__name__)
APP.config.from_object(os.environ['APP_SETTINGS'])
# a lot of configurations ommited
if __name__ == "__main__":
APP.run(debug=True, port=5005)
When I run the app, I get this in the terminal:
/Users/George/myproject/venv/bin/python /Users/George/myproject/app.py
* Running on http://127.0.0.1:5005/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger pin code: 338-825-330
and when I modify one of my controllers it picks up that a change has occurred:
* Detected change in '/Users/George/myproject/web_endpoints/user.py', reloading
but the change doesn't occur, and if I do another change, it never gets picked up (not reported in the terminal).
Flask is not recommended to use app.run() with automatic reloading as this is badly supported
Here's the comments in source code of Flask
def run(self, host=None, port=None, debug=None, load_dotenv=True, **options):
"""Runs the application on a local development server.
...
If you want to run the application in debug mode, but disable the
code execution on the interactive debugger, you can pass
``use_evalex=False`` as parameter. This will keep the debugger's
traceback screen active, but disable code execution.
It is not recommended to use this function for development with
automatic reloading as this is badly supported. Instead you should
be using the :command:`flask` command line script's ``run`` support.
...
"""
pass
But 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__'.