This question already has answers here:
Add a prefix to all Flask routes
(15 answers)
Closed 7 years ago.
I have a Flask App, which will run later as a "subpart" of a server and I am unsure how to configure that.
As an example:
localhost/OtherServer/rest/myFlask/
OtherServer is an IIS Website which normally handles all my requests, but for certain requsts control is handed to Flask - e.g. all routes which are found unter myFlask/*.
This already works thanks to WFASTCGI and some config magic, but in Flask I have to supply to the full URL for each route:
#app.route('/OtherServer/rest/myFlask/status')
I would like to only specify the part including or after myFlask, particularly because the firt part of the url is configurable in a C#-app and getting the name at runtime is a major headache.
So:
#app.route('/myFlask/status')
You can use blueprint, use the url_prefix parameter.
I'll show you a simple example:
view.py
from flask import Blueprint
my_blueprint = Blueprint('my_blueprint', __name__, template_folder='templates',
url_prefix='/OtherServer/rest')
#my_blueprint.route('/myFlask/status')
def index():
return 'Hello, world.'
...other routes...
in your app.py, you can
from flask import Flask
from my_app.view import my_blueprint
app = Flask(__name__)
app.register_blueprint(my_blueprint)
Related
I have been tasked with working on an existing Flask project (Flask with Templates/Jinja2 style monolith application). I have to add new features to this app and I'm also intending to re-design the app so it becomes a more micro-services based architecure (i.e. initially Flask-restful based backend with React based front-end). Can I just use Flask-restful by just wrapping the existing app and start creating the new endpoints using Resource?
from flask import Flask
from flask_restful import Resource, Api
app = Flask(__name__)
api = Api(app)
Are there any specific caveats/gotcha's I need to worry about?
Let's try it and see what happens. We start with a basic Flask app:
from flask import Flask
app = Flask(__name__)
#app.route("/")
def index():
return "This is index\n"
#app.route("/endpoint1")
def endpoint1():
return "This is endpoint1\n"
This works and we can request the / and /endpoint1 endpoints and get the expected response:
$ curl localhost:5000
This is index
$ curl localhost:5000/endpoint1
This is endpoint1
Let's see if we can mash a flask_restful managed endpoint in there without disrupting the existing functionality:
from flask import Flask, make_response
from flask_restful import Resource, Api
app = Flask(__name__)
api = Api(app)
class Widgets(Resource):
def get(self):
return make_response('Yes we have no widgets today\n')
api.add_resource(Widgets, '/widgets')
#app.route("/")
def index():
return "This is index\n"
#app.route("/endpoint1")
def endpoint1():
return "This is endpoint1\n"
Are our original routes still active?
$ curl localhost:5000
This is index
$ curl localhost:5000/endpoint1
This is endpoint1
How about the new one?
$ curl localhost:5000/widgets
Yes we have no widgets today
It looks like the answer is "yes"!
This question already has answers here:
Sending data from HTML form to a Python script in Flask
(2 answers)
Closed last year.
I encountered some problems when trying to open the link provided by the flask. I have updated my code and when I run and open the link only hello world is displayed and not the current code. Can someone explain why pls?
Also the review page asks for the user to input their name and I tried this as code in the python flask although I can't check if this will get the user input due to the problem mentioned above. Does this code make sense?
from flask import Flask,request,render_template
app = Flask(__name__)
#app.route("/")
def index():
return render_template("index.html")
#app.route("/")
def name():
name = request("name")
The problem is that you have the same route twice.
You have to use different routes for different endpoints.
Example:
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route("/")
def index():
return render_template("index.html")
#app.route("/name")
def name():
return "This is the name endpoint."
When you go to /name, you should see 'This is the name endpoint.'.
This question already has an answer here:
Global variables in Flask templates
(1 answer)
Closed 1 year ago.
So I have this Flask app that I need a pass a particular user to all routes as all pages in the app will be needing the particular user to render templates. I don't want to pass the user as it's normal done
return render_template('index.html',user=user)
Because I'd have to repeat the same thing for all routes in the render_templates.
Please how can I do this?
You can do so by creating a custom render template function using the following implementation
from flask import render_template as real_render_template
from yourapp import user # Import the user variable or set it
def render_template(*args, **kwargs):
return real_render_template(*args, **kwargs, user=user)
it can also be done via functools.partial:
from flask import render_template as real_render_template
from yourapp import user # Import the user variable or set it
from functools import partial
render_template = partial(real_render_template, user=user)
If you want to send a variable to all routes/pages/templates. You can use sessions in flask
from flask import Flask,session
[...]
session['x'] = user
Now you can use it anywhere in the code, templates using session['x']
In templates
{{session['x']}}
Is there a way to get the routes defined in a blueprint? I know this (http://flask.pocoo.org/snippets/117/) snippit exists, but requires to have the app initalized to use url_map. Is there a way to view the routes without an application? I'm developing an api with flask-restful and I would like to display the routes from within the blueprint without the app to keep it self contained.
Using the information provided by polyfunc, I was able to come up with this solution:
from flask import Blueprint, current_app, url_for
from flask_restful import Resource, Api
api_blueprint = Blueprint('api', __name__)
api = Api(api_blueprint)
#api.resource('/foo')
class Foo(Resource):
def get(self):
prefix = api_blueprint.name + '.' # registered classes will have this as their prefix
# Get current rules
rules = current_app.url_map.iter_rules()
# Get list from routes registered under the blueprint
routes = [url_for(rule.endpoint) for rule in rules if rule.endpoint.startswith(prefix)]
I want to use Flask blueprints to organize my Flask-Restful resources into separate url prefixes. Regardless of what url prefix I set (during either blueprint creation or registration), everything gets mapped to the raw route paths. How do I correctly use Restful with blueprints?
app = Flask(__name__)
api = Api(app)
api.add_resource(Building, '/<int:id>', endpoint='building')
api.add_resource(Jack, '/<int:id>', endpoint='jack')
building_api = Blueprint('building_api', __name__)
jack_api = Blueprint('jack_api', __name__)
app.register_blueprint(building_api, url_prefix='/buildings')
app.register_blueprint(jack_api, url_prefix='/jacks')
All documentation I can find says that these should now be available at /buildings/<int:id> and /jacks/<int:id>, but both of those urls 404 and instead I can access the building one at /<int:id>. Hard coding the path in add_resource fixes it, but defeats the point of url_prefix.
You need to pass the blueprint to the Api instance, not the app.
building_bp = Blueprint('buildings', __name__)
building_api = Api(building_bp)
building_api.add_resource(Building, '/<int:id>')
app.register_blueprint(building_bp, url_prefix='/buildings')
This is zhe best way to do with blueprint:
from flask import Flask, Blueprint
from flask_restful import Api, Resource, url_for
app = Flask(__name__)
api_bp = Blueprint('api', __name__)
api = Api(api_bp)
class TodoItem(Resource):
def get(self, id):
return {'task': 'Say "Hello, World!"'}
api.add_resource(TodoItem, '/todos/<int:id>')
app.register_blueprint(api_bp)
you should send Blueprint'instance to Api
I do not know why but I struggled using the Blueprint as mentioned in the answers.
But here's a quick solution I found while going through the doc link. Making use of the prefix parameter in Api() does the job.
app = Flask(__name__)
api = Api(app, prefix='/buildings')
Now, all your routes will be prefixed with /buildings. Just make sure you use url_for('link') in places where you might have simply used a /link.
One more strange thing I noticed is that atleast for me, it did not work until I renamed my routes to the same name as their class names. For example, Class Home(Resource) should have a route to /home. Using /homeepage or any other route for Home Class causes an error. Not sure if it is only me.