I'm using flask app factory pattern like and have this run.py file:
from app import create_app
app = create_app()
if __name__ == '__main__':
app.run(host='localhost', debug=True)
Then I run the app like this:
python run.py
But when I go to http://localhost:5000 it doesn't work.
It says:
Not Found
The requested URL was not found on the server. If you entered the URL
manually please check your spelling and try again.
What could be wrong? it works well when I have 127.0.0.1 address...
I need to run on "localhost" because I'm integrating square payments and their sandbox setup requires I make requests to their API from a 'localhost'.
Also, when I make the request in the browser, on the terminal when flask responds there is this:
127.0.0.1 - - [09/Sep/2017 00:30:45] "GET / HTTP/1.1" 404 -
127.0.0.1 - - [09/Sep/2017 00:30:45] "GET /favicon.ico HTTP/1.1" 404 -
127.0.0.1 - - [09/Sep/2017 00:30:45] "GET /favicon.ico HTTP/1.1" 404 -
So it looks like request reaches flask but flask returns 404.
Here is part of my init.py file:
# from __future__ import print_function
# import flask
from flask import Flask, render_template, url_for, redirect, flash, request, \
session, current_app, abort
import os
# flask sqlaclhemy
from sqlalchemy import func, desc, asc, or_, and_
from flask_admin import Admin, AdminIndexView
from flask_admin.contrib.sqla import ModelView
# Flask secrutiy
from flask_security import (Security, SQLAlchemyUserDatastore,
login_required, current_user)
from flask_login import LoginManager
from flask_mail import Mail
# square connect setup
import uuid
import squareconnect
from squareconnect.rest import ApiException
# from squareconnect.apis.locations_api import LocationsApi
from squareconnect.apis.transactions_api import TransactionsApi
mail = Mail()
class CustomAdminIndexView(AdminIndexView):
def is_accessible(self):
return current_user.is_authenticated and current_user.has_role('admin')
def create_app():
app = Flask(__name__)
app.config.from_object(os.environ['APP_SETTINGS'])
mail.init_app(app)
from models import db, User, Role
db.init_app(app)
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security = Security(app, user_datastore)
#app.route('/')
def home():
return render_template('home.html')
return app
the simple alternative solution is first to check if the port 5000 is avialable you can check that with this comand :
netstat -lat
find more about available port here :
if you are not obliged to use port 5000 you can try anything else you want ..
if every thing is ok that mean you have a problem with your home page , you don't have a route to '/' , that why you are getting the 404 error when you go to localhost:5000/ :
so to correct it you have 3 solution :
add the app.route('/') in your init.py file
add it directly in your run.py after creating the app (not a good way)
try to use blueprints
as you didn't provide your init.py code let add it to your run.py ,
from app import create_app
app = create_app()
#app.route('/')
def homepage():
return 'hello world'
if __name__ == '__main__':
app.run(host='localhost', port=9874)
another solution as suggest in comment is to check if 127.0.0.1 resolve to localhost find the host file by typing this command and check if you have the same line as mine :
nano /etc/hosts
and open the file :
##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting. Do not change this entry.
##
127.0.0.1 localhost
255.255.255.255 broadcasthost
::1 localhost
Just incase anyone on a mac runs into this issue and has trouble finding any answers (like me), I just discovered that it's because Apple Airplay Receiver runs on port 5000. Disable airplay receiver and try again.
there will be no entry as localhost in your hosts file
example host file
127.0.0.1 localhost
you can check your hosts file in following ways
for linux
sudo vi /etc/hosts
for windows
open this file C:\Windows\System32\Drivers\etc\hosts
if there is no localhost in your hosts file add and save it.
May be you need to install virtual enviroment
pip install virtualenv
does this. Hope this works
You should try switching out localhost for 0.0.0.0.
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
This has it serve on localhost for me.
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return "Hello"
if name == "main":
app.run(host='0.0.0.0', port=9874)
Related
[Flask SSE API doesn't work on production]
Hi, i'm facing an issue in my flask application where I have multiple regular APIs and 1 HTTP API that sends SSE to my React app. In my local development env, the app works just fine as expected. However, when I deployed it to CPanel shared hosting, I noticed that the the React app makes proper request of Content-Type text/event-stream, but received text/html response header from the API after 2 minute timeout. Is there anything wrong with how I implemented the server?
main.py
from myapplication import create_app
from flask import stream_with_context
from gevent import monkey; monkey.patch_all()
from gevent.pywsgi import WSGIServer
app = create_app()
if __name__ == '__main__':
http_server = WSGIServer(("localhost", 5000), app)
http_server.serve_forever()
myapplication/init.py
from flask import Flask
from flask_cors import CORS
from flask_sqlalchemy import SQLAlchemy
from os import path, environ
from dotenv import load_dotenv
db = SQLAlchemy()
DATABASE_NAME = 'database.db'
load_dotenv()
def get_database_uri():
host = environ['DB_HOST']
port = environ['DB_PORT']
name = environ['DB_NAME']
username = environ['DB_USER']
password = environ['DB_PASS']
return f'postgresql+psycopg2://{username}:{password}#{host}:{port}/{name}'
def create_database(app):
if not path.exists('myapplication/' + DATABASE_NAME):
db.create_all(app=app)
print('Database created.')
def create_app():
app = Flask(__name__)
CORS(app)
cors = CORS(app, resource = {
r"/*": {
"origins": "*"
}
})
app.config['SECRET_KEY'] = environ['SECRET_KEY']
app.config['SQLALCHEMY_DATABASE_URI'] = get_database_uri()
db.init_app(app)
from .gallery import gallery
from .document import document
from .timer import timer
from .member import member
app.register_blueprint(gallery, url_prefix='/gallery')
app.register_blueprint(document, url_prefix='/document')
app.register_blueprint(timer, url_prefix='/timer')
app.register_blueprint(member, url_prefix='/member')
from .models import Member, Gallery, Document, Timer
create_database(app)
return app
timer.py (SSE api)
global_count = '60'
global_refresh_count = '0'
#timer.route('/stream')
def get_current_stream():
def send_event():
while True:
event_payload = '{"count": "%s", "refreshCount": "%s"}'%(global_count, global_refresh_count)
data_message = f'data: {str(event_payload)}\n\n'
yield data_message
time.sleep(1)
return Response(send_event(), mimetype='text/event-stream')
Local development response:
dev response
Local development eventstream response:
dev event stream response
Production response:
prod response
CPanel python app setup:
Application startup file: passenger_wsgi.py
Application Entry point: application
passenger_wsgi.py
import imp
import os
import sys
sys.path.insert(0, os.path.dirname(__file__))
wsgi = imp.load_source('wsgi', 'main.py')
application = wsgi.app
Please kindly help guide me folks, much appreciated!
you have to set certain headers like below
resp = Response(
send_event(),
mimetype='text/event-stream'
)
resp.headers['X-Accel-Buffering'] = 'no'
resp.headers['Cache-Control'] = 'no-cache'
return resp
and configure setting throughout your service
for example in case of nginx:
location '/' {
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 12h;
...
proxy_pass {your_route};
}
in case of gunicorn:
set timeout param to 0 when you execute it.
/{path_to}/gunicorn --workers {num_workers} --timeout 0 --bind {path} -m 007 {module}:{app_name}
I am trying to create my first script with flask.
Here is my code:
from flask import Flask
from flask import Blueprint, request
prediction_app = Blueprint('prediction_app', __name__)
#prediction_app.route('/health', methods=['GET'])
def health():
if request.method == 'GET':
return 'ok'
def create_app() -> Flask:
"""Create a flask app instance."""
flask_app = Flask('ml_api')
# import blueprints
flask_app.register_blueprint(prediction_app)
return flask_app
application = create_app()
if __name__ == '__main__':
application.run()
I run this code as python run.py and I am getting "Running on http://127.0.0.1:5000/".
I go to this link and I am getting instead of "ok" a page with the next error:
Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
Command promt gives the following output:
127.0.0.1 - - [17/Jun/2020 16:59:25] "[33mGET / HTTP/1.1[0m" 404 -
Where is the problem?
I don't see a default route (/) defined; did you try pointing your browser at http://localhost:5000/health? That's the route you did define.
(localhost and 127.0.0.1 are typically equivalent, by the way...)
-->project
--->run.py
--->config.py
--->readme.md
--->app
--->__init__.py
--->controllers
--->__init__.py
--->test_controller.py
--->model
--->__init__.py
--->test_model1.py
--->test_model2.py
run.py
from app import app
app.run(host = '0.0.0.0', port = 8080, debug = True)
config.py - All configuration variable
app/__init__.py
from flask import Flask
app = Flask(__name__)
controllers/__init__.py - Empty
controllers/test_controller.py
#app.route('/test', methods=['POST'])
def test():
return "Hello world"
When I start my server form run.py the server gets started.
But when I try the URL http://locahost:8080/test, it returns 404.
But if the route is configured in app/___init__.py it is working.
Can anyone please guide me what is incorrect here in configuration.
I want to keep the above structure, please let me know of any issues.
Unless you import the file containing the #app.route decorator, it won't be registered. Flask won't import and register all .py files automagically for you.
At the end of your __init__.py file in app/, import projectname.controllers, and import test_controller in the __init__.py file in the controllers module.
I want to give flask a try. Using flask 0.12, python 3.4
I've created the project tree similar like in:
https://damyanon.net/post/flask-series-structure/
controllers.py code:
from flask import Blueprint
import functools, operator
main = Blueprint('main', __name__)
#main.route('/')
def index():
return "Main world"
#main.route('/foo')
def foo():
return "this is foo"
when I run the app,
I got 404 for /foo route but '/' is OK
* Serving Flask app "run"
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [27/Dec/2017 15:19:21] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [27/Dec/2017 15:19:25] "GET /foo HTTP/1.1" 404 -
Any clue?
Thanks.
edit:
As requested, here how I register blueprint in
flask_app/localservice/init.py. Not sure about application factory. I'm still new with this. I substitute bookshelf with localservice and not use admin
from flask import Flask
from localservice.main.controllers import main
app = Flask(__name__)
app.register_blueprint(main, url_prefix='/')
I was following the same tutorial and the same error occurred for me as well. After being stuck on this for quite a while I finally figured it out.
So looks like there's an error in the tutorial. You can't register using '/'.
app.register_blueprint(main, url_prefix='/')
This is the actual github codebase where the tutorial guy wrote the code.
If you look at the code and commit history, he changed url_prefix from '/' to 'main'. Change your url_prefix and the code should work.
If you don't insist on following that tutorial, the code in the Flask Quickstart docs works perfectly fine
from flask import Flask
app = Flask(__name__)
#app.route('/')
def index():
return "Main world"
#app.route('/foo')
def foo():
return "this is foo"
if __name__ == '__main__':
app.run()
Following some advice that I found here I am trying to use Flask as a web interface for an application that runs with twisted.
As suggested in Flask documentation I created a "templates" directory which is at the same level as my script but when I launch the server I get the following error:
Internal Server Error
The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.
When I do not try to load a template and just write a string in the request it works fine. This is what makes me think it is related to the load of the template.
from twisted.internet import reactor
from twisted.web.resource import Resource
from twisted.web.wsgi import WSGIResource
from twisted.internet.threads import deferToThread
from twisted.web.server import Site, NOT_DONE_YET
from flask import Flask, request, session, redirect, url_for, abort, \
render_template, flash
app= Flask(__name__)
app.config.from_object(__name__)
#app.route('/login', methods= ['GET', 'POST'])
def login():
return render_template('login.html', error= error)
if __name__ == '__main__':
root = WSGIResource(reactor, reactor.getThreadPool(), app)
factory = Site(root)
reactor.listenTCP(8880, factory)
reactor.run()
Some frameworks will change directory from your current working directory when they are run in daemon mode, and this might very well be the case here.
Flask, since 0.7, has supported passing a template_folder keyword argument when calling Flask, so you could try:
import os
tmpl_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'templates')
The following is a shorter version that will work just fine:
tmpl_dir = os.path.join(os.path.dirname(__file__), 'templates)
# ...
app = Flask('myapp', template_folder=tmpl_dir)
You can feed Jinja2 with a default templates directory (as written here) like this :
import jinja2
app = Flask(__name__)
app.jinja_loader = jinja2.FileSystemLoader('path/to/templates/directory')