I am trying to setup simple flask application to perceive app_context() feature.
This is my code:
# config.py
UPDATE_PERIOD = 100.0
# init.py
from flask import Flask
import config
app = Flask(__name__)
app.config.from_object(config)
app.config['DEBUG'] = True
#app.route('/')
def hello_world():
return 'Hello, World!'
if __name__ == "__main__":
app.run()
# ex.py
from flask import current_app
from flask import Flask
app = Flask(__name__)
with app.app_context() as app:
print(current_app.config['DEBUG'])
print(current_app.config['UPDATE_PERIOD'])
Now, I am running my init.py:
python3 init.py
* Serving Flask app "init" (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://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 666-659-182
which is okay, how it should be.
Here I expect that app.config['DEBUG'] = True and app.config['UPDATE_PERIOD'] = 100.0
And I am trying to extract this vars in ex.py.
The problem is: when I execute: python3 ex.py I expect this:
True
100.0
but eventually I am getting this:
False
Traceback (most recent call last):
File "ex.py", line 10, in <module>
print(current_app.config['UPDATE_PERIOD'])
KeyError: 'UPDATE_PERIOD'
so I cannot get how app_context() feature is working whereas I think I am doing the same things as written in docs.
There is an option to import in ex.py:
from init import app
but I want to get working instance without complex import since my application is quite big.
Can anyone please help me with this..?
Thank you in advance!
Related
I am developing an app and the development setup was really easy.
I run it locally with:
$ . .venv/bin/activate
(.venv) $
(.venv) $ python -m flask run
* Serving Flask app 'app'
* Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:8080
Press CTRL+C to quit
* Restarting with stat
* Debugger is active!
* Debugger PIN: -###-###
and I have configured apache2 on my (ubuntu) laptop with:
ProxyPass / http://127.0.0.1:8080
My code is structured like:
app.py
pages/scc_main/scc.html
...
The code has this:
import re
import jinja2
from flask import Flask
from flask import request
import data
app = Flask(__name__)
env = jinja2.Environment(loader=jinja2.FileSystemLoader("pages"))
#app.route('/')
def hello_world():
return '<h2>Hello, World!</h2>'
#app.route('/contracts/scc')
#app.route('/contracts/scc/')
def contracts_main():
main = env.get_template('scc_main/scc.html')
context = data.build('scc_main')
return main.render(**context)
And everything works great. As in:
$ curl 'http://localhost/'
<h2>Hello, World!</h2>$
But when I deploy. Wow. I set my site's root to point to the app. That is actually working. I can hit https://opencalaccess.org/ and it gets my static content.
I have:
import sys
import logging
logging.basicConfig(
level=logging.DEBUG,
filename='/var/www/<full-path>/logs/contracts_scc.log',
format='^(asctime)s %(message)s')
sys.path.insert(0, '/var/www/<full-path>')
sys.path.insert(0, '/var/www/<full-path>/.venv/lib/python3.8/site-packages')
And https://opencalaccess.org/contracts/scc works. But only after I change the Environment call above to:
env = jinja2.Environment(loader=jinja2.FileSystemLoader("/var/www/full-path>/pages"))
Now, any link which is just a link is fine. But anything that looks at the flask.request.path gives me:
The browser (or proxy) sent a request that this server could not understand.
What the heck? Setting up the dev environment was so easy. What do you have to do to get this working in deployment? Any suggestions?
ADDED:
Well, it seems clear that it is the WSGI part that is having the problem. My script is not receiving the request structure and so it cannot read any parameters. I have all my parameters on the URL, so my data building method reads the request.path to see what to do.
So, where to go from here. We will see.
I am no longer able to reproduce this.
I am trying to deploy my flask app on heroku but it shows a runtime error on the heroku server, but when i test it on my end, AKA localhost, it seems to work fine
My Code:
import flask
from flask import request
from flask import jsonify
from GoogleNews import GoogleNews
from apscheduler.schedulers.background import BackgroundScheduler
import multiprocessing
googlenews = GoogleNews()
news_latest = []
googlenews.set_lang('en')
googlenews.set_period('1d')
googlenews.set_encode('utf-8')
def get_latest_news():
global news_latest
googlenews.get_news('TECHNOLOGY')
news_latest = googlenews.result()
my_scheduler = BackgroundScheduler()
my_scheduler.add_job(func=get_latest_news, trigger="interval", seconds=5)
my_scheduler.start()
app=flask.Flask(__name__)
#app.route('/', methods=["GET"])
def home():
return jsonify(news_latest[0: 3])
app.run()
requirements.txt:
gunicorn
GoogleNews
APScheduler
PROCFILE:
web: gunicorn app:appweb: gunicorn app:app
runtime.txt:
python-3.9.4
But the server seems to crash when you open it,
And what is remarkable is in the logs, Flask says it is running on a DEVELOPMENT server. It prints the location where it has started the app as 127.0.0.0.5000
I was able to overcome this problem, The right way of doing this is:
import flask
from flask import request
from flask import jsonify
from GoogleNews import GoogleNews
from apscheduler.schedulers.background import BackgroundScheduler
import multiprocessing
googlenews = GoogleNews()
news_latest = []
googlenews.set_lang('en')
googlenews.set_period('1d')
googlenews.set_encode('utf-8')
def get_latest_news():
global news_latest
googlenews.get_news('TECHNOLOGY')
news_latest = googlenews.result()
my_scheduler = BackgroundScheduler()
my_scheduler.add_job(func=get_latest_news, trigger="interval", seconds=5)
my_scheduler.start()
app=flask.Flask(__name__)
#app.route('/', methods=["GET"])
def home():
return jsonify(news_latest[0: 3])
The change was to remove app.run() since heroku servers will already be running your code, if you put the app.run() heroku will consider this as default code and will run that too, hence the interpretation process will stop at app.run() and will never complete the interpretation. Hence the app will crash with no return response.
On localhost is fine to use the default 5000 port but on Heroku you need to use the one provided by the platform in the $PORT env variable
server_port = int(os.environ.get("PORT", 5000))
app.run(debug=False, port=server_port, host='0.0.0.0')
So I am just starting a project in flask and I am using the proper folder structure for the first time and I keep getting this error. I am confused as to why and haven't faced this problem before.
I have tried renaming files and using from . import views but to no avail.
app.py
from flask import Flask
from app import views
app = Flask(__name__)
views.py
from app import app
#app.route('/')
def index():
return "Hello World!"
run.py
from app import app
app.run(debug=True)
Folder structure:
app
static
templates
app.py
run.py
views.py
tmp
Traceback (most recent call last):
File "app.py", line 2, in
from app import views
File "/Users/Josh/PycharmProjects/web1/app/app.py", line 2, in
from app import views
ImportError: cannot import name 'views'
app.py
from flask import Flask
app = Flask(__name__)
import views
views.py
from app import app
#app.route('/')
def hello():
return "Hello World!"
run.py
from app import app
app.run(debug=True)
I used this tutorial to get Flask running on an IIS server, and the test app works great.
Now, I have developed a web app in Visual Studios 2013 and it works great on the localhost dev server.
When I transfer the files to the server I get the following errors for every package but Flask even though, I pip installed all the required packages on the server.. Note, I did change init.py to app.py to coincide with the tutorial.
Error occurred while reading WSGI handler:
Traceback (most recent call last):
File "D:\...\wfastcgi.py", line 779, in main
env, handler = read_wsgi_handler(response.physical_path)
File "D:\...\wfastcgi.py", line 621, in read_wsgi_handler
handler = get_wsgi_handler(os.getenv('WSGI_HANDLER'))
File "D:\...\wfastcgi.py", line 605, in get_wsgi_handler
raise ValueError('"%s" could not be imported%s' % (handler_name, last_tb))
ValueError: "app.app" could not be imported: Traceback (most recent call last):
File "D:\...\wfastcgi.py", line 589, in get_wsgi_handler
handler = __import__(module_name, fromlist=[name_list[0][0]])
File ".\app.py", line 6, in <module>
from flask_bootstrap import Bootstrap
ImportError: No module named 'flask_bootstrap'
StdOut:
StdErr:
This error occurs with all the imports (except Flask), including flask_sqlalchemy, etc...
app.py (Using Python 3.5)
from flask import Flask
from flask_bootstrap import Bootstrap
from flask_scss import Scss
from config import DevConfig, BaseConfig
from flask_admin import Admin
from flask_admin.contrib.sqla import ModelView
from flask_sqlalchemy import SQLAlchemy
from flask_mail import Mail
app = Flask(__name__)
app.config.from_object(BaseConfig)
db = SQLAlchemy(app)
mail = Mail(app)
Bootstrap(app)
admin = Admin(app, name='Admin', template_mode='bootstrap3')
import AppName.views
My server folders are as such:
/roothostingfolder
app.py
config.py
models.py
views.py
wfastcgi.py
web.config
/static
style.css
/templates
layout.html
index.html
login.html
...
Do you know how to fix the error?
I have a basic flask-restful application with a structure that looks like this as recommended on the flask website.
/application
/application
/config.py
/__init__.py
/wsgi.ini
Slightly irrelevant, but config.py is generated by our CD server.
wsgi.ini looks likes this
[uwsgi]
module = application:app
master = true
processes =5
socket = /tmp/application.sock
chmod-socket = 660
vacuum = true
die-on-term = true
and __init__.py looks something like this
import config
from flask import Flask, request, g
from flask_restful import Resource, Api, abort
app = Flask(__name__)
api = Api(app)
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
Now when I try to startup the application using uwsgi --ini wsgi.ini I get this error:
File "./application/__init__.py", line 2, in <module>
import config
Originally __init__.py was called main.py and I executed that to debug, which is why the import is now wrong. I'm guess I will need to change the import to be from .config import *
My question is two fold:
Could I have avoided the import problem completely. ie is there a way in python3 to import sibling modules that will work for both approaches
is my wsgi.ini in the correct place, or should it be in the inner application directory?
Python 3.x dropped support for infra-package relative imports. You need to use an absolute import:
from application import config
or the new spelling of relative imports:
from . import config
If you need to also support legacy versions of Python you can enable this behavior with:
from __future__ import absolute_import