I have been following the methods provided in this post:
https://stackoverflow.com/questions/12167729/flask-subdomains-with-blueprint-getting-404
Here is my relevant code:
__init__.py
from flask import Flask, render_template
app = Flask(__name__, static_url_path="", static_folder="static"
import myApp.views
views.py
from flask import Flask, render_template, request, Blueprint
from myApp import app
app.config['SERVER_NAME'] = 'myapp.com'
app.url_map.default_subdomain = "www"
#app.route("/")
def index():
return "This is index page."
test = Blueprint('test', 'test', subdomain='test')
#test.route("/")
def testindex():
return "This is test index page."
app.register_blueprint(test)
if __name__ == "__main__":
app.run()
Using this method I am able to get subdomains 'test' and 'www' working, but now I am unable to access my website via IP address.
Any guidance into the right direction would be appreciated!
Related
I am using flask with blueprints each blueprint is single subdomain. What I am trying to do is to redirect from one blueprint route to another subdomain.
Simplified file structure:
|-about_domain
| |-__init__.py
|-store_domain
|-__init__.py
wsgi.py
wsgi.py:
from flask import Flask, redirect, url_for
from store_basicwear import store
from about_basicwear import about
app = Flask(__name__, subdomain_matching=True, static_folder='static')
app.register_blueprint(store)
app.register_blueprint(about)
#app.route("/")
def default():
return redirect(url_for('store.index'))
if __name__ == '__main__':
app.run()
/store_domain/__init__.py:
from flask import Blueprint, render_template
store = Blueprint('store', __name__, subdomain='store')
#store.route('/about')
def about():
return # redirect to about.index
/about_domain/__init__.py:
from flask import Blueprint, render_template
about = Blueprint('about', __name__, subdomain='about')
#about.route('/')
def index():
return render_template('main.html')
How I want it to work:
store.domain/about ---(redirect)---> about.domain/
I want to avoid circular import as well as hardcoded routes. Is it possible, maybe by current_app?
when I run the website on any browser, the typical 404 error "The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again." regardless of what I route it to or if I route it at all. I have checked, and everything seems to be in the right place, but I have no idea what is causing the error, especially as I have tried every fix I have found online.
My route.py file is as follows:
from flask import Flask, render_template, url_for
from blog import app, db
from blog.models import User, Post
app = Flask(__name__, template_folder='templates', static_folder='static')
app = Flask(__name__)
#app.route('/')
#app.route("/home")
def home():
posts = Post.query.all()
return render_template('home.html', posts=posts)
#app.route("/about")
def about():
return render_template('about.html', title='About')
The WSGI is:
from blog import app as application
if __name__ == '__main__':
app.run(debug=True)
and the __init__.py file is:
from flask import Flask
import os
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SECRET_KEY'] = 'be35984218226b31d6ca0bf1ccefdaf78e47c9181177a41a'
basedir = os.path.abspath(os.path.dirname(__file__))
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'blog.db')
db = SQLAlchemy(app)
from blog import routes
Thanks in advance for any advice given
There are 2 things that could be going wrong:
Your Firewall is blocking the flask app
You entered the wrong IP Address.
If you entered the wrong IP Address, use this IP instead: localhost:5000.
A better alternative would be to use this app.run function instead
app.run(host="0.0.0.0", port=ENTER YOUR DESIRED PORT HERE)
If the firewall is the issue, stackoverflow isn't the right place :/
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 am trying to use the wsgi DispatcherMiddleware in order to prefix a url on my application. I've written one module for the dispatcher and one for the app, which has just one view called home and this is where the homepage is served from.
here is my app1.py
import flask
from flask import request, jsonify
app = flask.Flask(__name__)
app.config["DEBUG"] = True
#app.route('/home', methods=['GET'])
def home():
return "<h1>Home</h1>"
and dispatcher.py
from flask import Flask
from werkzeug.wsgi import DispatcherMiddleware
from werkzeug.exceptions import NotFound
from app1 import app
app = Flask(__name__)
app.wsgi_app = DispatcherMiddleware(NotFound(), {
"/prefix": app
})
if __name__ == "__main__":
app.run()
what I wanna do is be able to navigate to http://127.0.0.1:5000/prefix/home
when I run on console py dispatcher.py, but however when I navigate on that url I get a 404 response. What works in only the navigation to the pagehttp://127.0.0.1:5000/home. Could someone help me understand why this happens? I appreciate any help you can provide
Adding prefix to all routes is really simple if you opt for using Blueprints
https://flask.palletsprojects.com/en/1.0.x/tutorial/views/#create-a-blueprint
from flask import Flask, Blueprint
app = Flask(__name__)
prefixed = Blueprint('prefixed', __name__, url_prefix='/prefixed')
#app.route('/nonprefixed')
def non_prefixed_route():
return 'this is the nonprefixed route'
#prefixed.route('/route')
def some_route():
return 'this is the prefixed route'
app.register_blueprint(prefixed)
if __name__ == "__main__":
app.run()
Testing the routes:
> curl localhost:5000/
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>404 Not Found</title>
<h1>Not Found</h1>
<p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>
> curl localhost:5000/nonprefixed
this is the nonprefixed route
> curl localhost:5000/prefixed/route
this is the prefixed route
SOLUTION:
I was using wrong tha same name for the dispacher and the app1.
dispacher.py should be edited as follows:
from flask import Flask
from werkzeug.wsgi import DispatcherMiddleware
from werkzeug.exceptions import NotFound
from app1 import app as app1
app = Flask(__name__)
app.wsgi_app = DispatcherMiddleware(NotFound(), {
"/prefix": app1
})
if __name__ == "__main__":
app.run()
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!"