Variable rules isn't working as I'd expect when static_url_path is used.
Simply, why does this work:
import flask
app = flask.Flask(__name__)
#app.route("/", defaults={"p": "")
#app.route("/<path:p>")
def main(p):
return "<h1>Hello %s</h1>" % p
if __name__ == '__main__':
app.run(debug=True)
But not this?
import flask
app = flask.Flask(__name__, static_url_path="")
#app.route("/", defaults={"p": "")
#app.route("/<path:p>")
def main(p):
return "<h1>Hello %s</h1>" % p
if __name__ == '__main__':
app.run(debug=True)
Note the added static_url_path
Some background details; I'm new to both Flask and AngularJS, but are using them here in conjunction with each other and for those not familiar with AngularJS; I'm using AngularJS to produce a single-page application in which paths are used for dynamically replacing content within a document, as opposed to reloading the whole page. Thus, I need all paths routed to the same html document (not included in the above example), ideally coming form the same function, so as to let AngularJS handle rendering as opposed to Flask.
The below answer solved that issue, but it isn't working when status_url_path is used, and I can't figure out why.
Flask route for AngularJS with HTML5 URL mode
Adding this for reference, as he is doing this exact thing.
http://www.youtube.com/watch?v=2geC50roans
You are effectively telling Flask to map /<path:static_path> to static files. That means that everything is now considered static. Don't do this!
Angular pages don't need to call into Flask static routes; keep your static routes under /static, have / produce your Angular application, then use other routes to handle Angular AJAX calls. These can have proper paths; Angular doesn't dictate what routes your Flask server will respond to.
Then keep your static route to serve the JavaScript and CSS and images, e.g. the actual static content referenced from your HTML page.
Related
I am working on a website where we have different levels and sublevels. Is it possible to generate the sublevels on the fly based on level clicked.
I am working with it in a flask application.
Note : Website is connected to google analytics and has multiple levels and is impossible to do it manually.
str.split('/') should do the trick, when used with Flask's request. Request's path holds the part after www.example.com/
Simple example. Note the empty first result in the returned list
from flask import Flask, request
app = Flask(__name__)
#app.route('/')
def main():
return 'Hello'
#app.route('/path/to/wherever')
def example():
for p in request.path.split('/'):
print(p)
return str(request.path.split('/'))
if __name__ == "__main__":
app.run()
I'm following a mooc for building quickly a website in flask.
I'm using Cloud9 but i'm unable to watch my preview on it, i get an :
"Unable to load http preview" :
the code is really simple, here the views.py code
from flask import Flask, render_template
app = Flask(__name__)
# Config options - Make sure you created a 'config.py' file.
app.config.from_object('config')
# To get one variable, tape app.config['MY_VARIABLE']
#app.route('/')
def index():
return "Hello world !"
if __name__ == "__main__":
app.run()
And the preview screen, is what I get when I execute
python views.py
Thank you in advance
you need to make FLASK_APP environment variable, and flask application is not running like python views.py but flask run. Quick start
# give an environment variable, give the absolute path or relative
# path to you flask app, in your case it is `views.py`
export FLASK_APP=views.py
#after this run flask application
flask run
I faced the same problem. There is no way we can preview http endpoints directly. Although in AWS documentation they have asked to follow certain steps, but those too wont work. Only way is to access it using instance public address and exposing required ports. Read here for this.
So, following the examples for swagger ui usage with flask blueprints (https://github.com/rantav/flask-restful-swagger/blob/master/examples/blueprints.py), I have the following code:
app = Flask(__name__)
test_blueprint = Blueprint('tests', __name__)
test_api = swagger.docs(restful.Api(test_blueprint), apiVersion='0.1',
basePath='http://localhost:5000',
produces=["application/json", "text/html"],
api_spec_url='/api/spec')
# Operation TestOp defined here
test_api.add_resource(TestOp, '/')
if __name__ == "__main__":
app.register_blueprint(test_blueprint, url_prefix='/test')
app.run(debug=True)
However, when I try to access the api spec docs, the URL cannot be located.
I've tried...
localhost:5000/api/spec
localhost:5000/test_api/api/spec
localhost:5000/test_api
...all of which return a 404. I've also tried creating the app without blueprints, creating the docs with
swagger.docs(restful.Api(app)...)
instead. When there this is done and no blueprints are involved, I can reach the docs at
localhost:5000/api/spec
So, am I creating my application incorrectly with blueprints, or am I just not hitting the right URL to get access to the docs?
I know this thread is old, but I ran into this exact problem today, trying to use flask-restful-swagger with my (somewhat) modern flask + python3 app that uses blueprints. Same problem, no errors, just no spec available no matter what i tried.
I finally abandoned this package (as it seems like it hasn't been very active anyway), even though I like the markup better with this package.
I chose Flasgger, which seemed to be updated more recently. In 10 minutes I had it up and running. Code and short tutorial are here: https://github.com/rochacbruno/flasgger
It looks like you're just not hitting the right URL. Because your blueprint url_prefix is "/test", the Swagger spec url should be at:
localhost:5000/test/api/spec
something wrong in swagger.docs()
from flask_restful import Api
test_blueprint = Blueprint('tests', __name__)
test_api = swagger.docs(Api(test_blueprint)...)
app.register_blueprint(test_blueprint)
what'more
main_blueprint = Blueprint('api', __name__, url_prefix='/demo')
I am currently working on an application that requires math expressions to be rendered (from latex) and needs to have some sort of native gui (even if it just uses gtk, then renders html in webkit).
I did some research and decided an easy way to do this would be to use webkit to load a web page and use a JavaScript library like MathJax to render the math.
Some other reasons why I chosen to do it this way over other solutions are I have had a fair amount of experience developing web apps in python (although a while ago), lack of experience with native guis and the portability it would provide.
For a web app framework I have chosen to use flask as it is one I am most familiar with.
The problem is this application needs to have it's own native GUI through preferably gtk (even if just renders html with webkit) and also preferably shouldn't have a http server that is attached to some socket.
So my question is, instead of running flask's server is there any way to do something like this:
import gtk
import webkit
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
return "<h1>Hello World!</h1>"
if __name__ == '__main__':
window = gtk.Window()
webview = webkit.WebView()
webview.load_string(
app.load_from_uri('/'),
"text/html",
"utf-8",
'/'
)
window.add(webview)
window.show_all()
Where app.load_from_uri('/') is just used as an example of a way to load the webpage for a given uri of a Flask app. But as this is just an example, how could app.load_from_uri('/') be done in real code?
Also is there anyway to override when the user clicks a link so it does something like this:
def link_clicked(uri):
webview.load_string(
app.load_from_uri(uri),
"text/html",
"utf-8",
uri
)
Thanks any help is greatly appreciated!
I've ended up finding a solution to this myself (but open to better ones).
The first thing, loading a page, was pretty easy. Flask provides a way to test apps which mainly just sets up all the things for WSGI to be able to process a request. This is just what I needed so I used this like so:
from flask import Flask
class WebViewFlask(Flask):
"""
Adds the ability to load a uri without the
need of a HTTP server.
"""
def load_from_uri(self, uri):
"""
Loads a uri without a running HTTP server.
"""
with self.test_client() as c:
response = c.get(uri)
return response.data, response.mimetype
The second part, overriding "when the user clicks a link", is a bit more trickier.
import os
import webkit
class FlaskAppView(webkit.WebView):
"""
Loads pages for flask apps into a WebView.
"""
def __init__(self, flask_app, *args, **kwargs):
# Protocol for flask app, by default file:// is used
# so a protocol is defined here to prevent that.
self.PROTOCOL = 'flask://'
super(webkit.WebView, self).__init__(*args, **kwargs)
self._flask_app = flask_app
# Register new navigation handler.
self.connect(
"navigation-policy-decision-requested",
self._nav_request
)
# For navigation handler.
self.prev_uri = None
# Redefine open like this as when using super
# an error like this occurs:
# AttributeError: 'super' object has no attribute 'open'
self._open = self.open
self.open = self.open_
def _nav_request(self, view, frame, net_req, nav_act, pol_dec):
"""
WebView navigation handler for Flask apps.
"""
# Get the uri
uri = net_req.get_uri()
# In order for flask apps to use relative links
# the protocol is removed and it is made into an absolute
# path.
if uri.startswith(self.PROTOCOL):
# In this case it is not relative but
# it needs to have it's protocol removed
uri = uri[len(self.PROTOCOL):]
elif not self.prev_uri.endswith(uri):
# It is relative and self.prev_uri needs to
# be appended.
uri = os.path.normpath(os.path.join(self.prev_uri, uri))
# This is used to prevent an infinite recursive loop due
# to view.load_string running this function with the same
# input.
if uri == self.prev_uri:
return False
self.prev_uri = uri
# Create response from Flask app.
response = app.load_from_uri(uri) + ('utf-8', uri)
# Load response.
view.load_string(*response)
# Return False to prevent additional
# handlers from running.
return False
def open_(self, uri):
"""
Prepends protocol to uri for webkit.WebView.open.
"""
self._open(self.PROTOCOL + uri)
Basically a new navigation event handler is registered with some code to allow for successful recursion and support for relative paths.
Anyway, with that code above by just replacing Flask with WebViewFlask and WebView with FlaskAppView everything pretty much just works.
And the result:
Which is a flask app being loaded in a webkit.WebView without any sort of server. The best thing about it is by just switching app back to an instance of Flask instead of WebViewFlask It's a plain webapp again.
I'm developing an web app using Flask in Heroku. My web will have k news pages. Information for each page is stored in database. When user make a request in web browser, the returned page can be generated using render_templates() in Flask.
The problem is when all users request same page, render_templates() will be called multiple times for the same page => kind of wasting resources to do the same thing
I curious whether I should use render_templates() or I should generate k static pages and use there static file instead?
You can use Flask-Cache package.
Support built-in cache backends like dictionary, file system, memcached, redis, and also custom cache backends.
Example:
#cache.cached(timeout=50)
def index():
return render_template('index.html')
.
#cache.memoize(timeout=50)
def big_foo(a, b):
return a + b + random.randrange(0, 1000)
.
#cache.cached(timeout=50)
def big_foo():
return big_bar_calc()
Also another option [beside that] is using front page caching, like varnish.