In a Python authorization app, in my main py I have the following code:
# main.py
from flask import Blueprint, render_template
from flask_login import login_required, current_user
theapp = Blueprint('main', __name__)
#theapp.route('/')
def index():
return render_template('index.html')
When I try:
FLASK_APP=main.py
FLASK_DEBUG=1
flask run
I get the following error:
Error: Could not locate a Flask application. You did not provide the "FLASK_APP" environment variable, and a "wsgi.py" or "app.py" module was not found in the current directory.
Basically a Blueprint is a way for you to organize your flask application into smaller and reusable applications. I am not sure why you have used it here in the main.py.
You could do that some other file, for example, you have a set of endpoints to implement login functionality in a separate file then what you should be doing is:
Assume you have a login.py .Sample Code looks like follows:
from flask import Blueprint
bp = Blueprint('login_bp', __name__)
def login_bp():
return bp
And the following code goes into you main.py , you need to start the Flask Server using .run()
from flask import Flask
from flask import Blueprint, render_template
from login import login_bp #Assume you have a module login and I am importing login_bp from login.py
theapp = Flask(__name__) #Creating Flask instance
theapp.register_blueprint(login_bp()) # Registering Blueprint here
#theapp.route('/')
def index():
return render_template('index.html')
theapp.run(host="0.0.0.0", port=2019, debug=True) #Starting the Flask Server
Hope this works, please do look out for documents and code example to get deeper insights.
Related
I'm trying to build an API with flask_restful, but I don't know how to connect classes that inherit from Resource, with the actual app.
I have the following structure
page
├───api
│ └───__init__.py
│ └───resources.py
└───__init__.py
page/api/resources.py:
from flask_restful import Resource
from page import api
#api.resource("/hello-world")
class HelloWorld(Resource):
def get(self):
return {"hello": "World"}
page/init.py:
from flask import Flask
from flask_restful import Api
from page.config import Config1
api = Api()
def create_app(config_class=Config1):
app = Flask(__name__)
app.config.from_object(config_class)
api.init_app(app)
return app
run.py (outside of the page package):
from page import create_app
if __name__ == "__main__":
app = create_app()
app.run(debug=True)
test:
import requests
BASE = "http://127.0.0.1:5000/"
response = requests.get(BASE + "hello-world")
print(response.json())
Obviously, making a request to "/hello-world" doesn't work. How can I "make Flask aware" of the resources, so that I get a valid response.
Probably there is a much clever way of doing this but for me, the solution would be to remove the decorator #api.resource decorator at page/api/resources.py and make the following changes at page/init.py
from flask import Flask
from page.config import Config1
def create_app(config_class=Config1):
app = Flask(__name__)
app.config.from_object(config_class)
return app
I would also move the run.py inside the page folder and rename it to app.py according to Flask documentation. This app.py should have your routes so change it to something like this:
from page import create_app
from page.api.resources import HelloWorld
from flask_restfull import api
app = create_app()
api = Api(app)
api.add_resource(HelloWorld, '/hello-world')
And to run it just type flask run inside the page folder.
I've rummaged through maybe 50 different answers to this and still I haven't manage to fix it... I'm pretty new to flask and python.
I have an app which was running great locally but I've struggled with deploying on python anywhere. Initially I had a few import modules issues, now it runs but doesn't return any html template, despite not seeing any other issue. The main issue I had was that it couldn't find the "routes" app from wsgi, and I sort of fixed adding the app = Flask(name) line on routes.py (the short blueprint object is not callable).
routes.py:
from flask import Blueprint, render_template, request, redirect, send_file
import pyqrcode
from pyqrcode import QRCode
import subprocess
from extensions import db
from models import Link
app = Flask(__name__)
short = Blueprint('short', __name__, url_prefix='/')
#short.route('/index')
def index():
return render_template('index.html')
init.py
from flask import Flask
from extensions import db
from routes import short
def create_app(config_file='settings.py'):
app = Flask(__name__)
app.config.from_pyfile(config_file)
db.init_app(app)
app.register_blueprint(short)
return app
wsgi.py
import sys
# add your project directory to the sys.path
project_home = u'/home/b297py/mysite'
if project_home not in sys.path:
sys.path = [project_home] + sys.path
# import flask app but need to call it "application" for WSGI to work
from routes import app as application
For the purpose of testing, I've placed all the html templates both in the root directory and in the specific /template directory but it just didn't fix the issue.
In wsgi.py you are not calling create_app so you are never registering the blueprint. You should replace :
from routes import app as application
by something like :
from package_name import create_app
application = create_app()
(Example: https://www.pythonanywhere.com/forums/topic/12889/#id_post_50171)
Also as you mentioned, the fix adding app = Flask(__name__) to routes.pyallows you to bypass create_app (so you should remove it if you want to stick to the create_app approach).
I'm attempting to break a small app into units and use the Blueprint pattern in Flask. However I seem to have trouble in getting the app running.
Here is my structure:
\myapp
login.py
\upload
__init__.py
views.py
Here is login.py:
import sys, os
from flask import Flask, Blueprint, request
from flask import render_template, session
from .upload import views
app = Flask(__name__)
app.register_blueprint(views)
#app.route('/')
def index():
return render_template('index.html')
if __name__ == '__main__':
print app.url_map
print app.blueprints
app.run(debug = True)
for __init__.py
from flask import Flask
app.register_blueprint('upload', __name__)
and in views.py
from flask import Flask, Blueprint, request, redirect, url_for, render_template
import views
upload = Blueprint('upload', __name__)
#upload.route('/uploaded', methods=['GET', 'POST'])
def upload_file():
...
Looking at the logs on heroku, here is the error:
from .upload import views
2015-09-05T10:59:00.506513+00:00 app[web.1]: ValueError: Attempted relative import in non-package
Have a structured my package and blueprint correctly? I used the documentation, but I think I'm missing something here.
There are three problems with your code:
You are using a relative import in login.py to include views, but given the folder structure and the fact that you use login.py as starting point, it cannot work here. Simply use from upload import views instead.
The __init__.py references an unknown variable, app. You actually don't need anything in this file, remove everything.
You try to register a module as a blueprint via app.register_blueprint(views) in login.py. This cannot work, a module is not a blueprint. Instead, import the upload variable defined in the views module, that is a blueprint: app.register_blueprint(views.upload).
Changing that should get you started. Two side notes:
You have an import in views.py that should probably not be there: import views. This should be harmless however.
I answered a question about Flask blueprints some days ago, and gave an example about how to use them. Maybe would you find the answer useful in your case as well (in particular the part where the blueprint definition is moved to the __init__.py file defining the blueprint).
I am using Twilio's flask.ext.restful extension with the following setup:
Top level folder is app
Inside of which is: ___init___.py:
from flask import Flask
from flask.ext import restful
# Basic app configuration
app = Flask(__name__)
api = restful.Api(app)
and inside this app module a file called api.py
from flask.ext.restful import Resource
from app import api
class HelloWorld(restful.Resource):
def get(self):
return {'hello': 'world'}
api.add_resource(HelloWorld, '/hello')
This setup just gives me 404s when accessing /hello
However, if I move the api.py to the __init__.py model then everything works.
Why is this the case?
I think the app gets ran before api.py gets executed and it hangs on Flask. How are you executing this?
class HelloWorld(restful.Resource)
should be
class HelloWorld(Resource)
however
Try transferring from app import api to your __init__.py
from flask import Flask
from flask.ext import restful
# Basic app configuration
app = Flask(__name__)
api = restful.Api(app)
from app import api
Also, you should rename one of the app to avoid confusion.
I have the following structure in my project
\ myapp
\ app
__init__.py
views.py
run.py
And the following code:
run.py
from app import create_app
if __name__ == '__main__':
app = create_app()
app.run(debug=True, host='0.0.0.0', port=5001)
views.py
#app.route("/")
def index():
return "Hello World!"
_init_.py
from flask import Flask
def create_app():
app = Flask(__name__)
from app import views
return app
I'm trying to use the factory design pattern to create my app objects with different config files each time, and with a subdomain dispatcher be able to create and route different objects depending on the subdomain on the user request.
I'm following the Flask documentation where they talk about, all of this:
Application Context
Applitation Factories
Application with Blueprints
Application Dispatching
But I couldn't make it work, it seems that with my actual project structure there are no way to pass throw the app object to my views.py and it throw and NameError
NameError: name 'app' is not defined
After do what Miguel suggest (use the Blueprint) everything works, that's the final code, working:
_init.py_
...
def create_app(cfg=None):
app = Flask(__name__)
from api.views import api
app.register_blueprint(api)
return app
views.py
from flask import current_app, Blueprint, jsonify
api = Blueprint('api', __name__)
#api.route("/")
def index():
# We can use "current_app" to have access to our "app" object
return "Hello World!"