I have a simple flask app:
def create_app():
config_name = 'testing_local'
app = Flask(__name__)
app.config.from_object(CONFIG_BY_NAME[config_name])
app.url_map.converters['bool'] = BooleanConverter
#app.before_request
def incoming_request_logging():
print(request)
return app
I get the error:
Undefined variable 'request'
I thought the wrapper included the request object when called?
In this example, first approved answer seems like the request object is inherited?
Can anyone link me to a full example? How can I retrieve this variable?
I guess declaring this at top of your program might solve your issue, if I think what you said it is:
from flask import request
Related
I have a Flask app which has a Flask-RestPlus API as well as a "/" route. When I try to access "/" however, I get a 404. If I remove the Flask-RestPlus extension, the route works. How do I make both parts work together?
from flask import Flask
from flask_restplus import Api
app = Flask(__name__)
api = Api(app, doc="/doc/") # Removing this makes / work
#app.route("/")
def index():
return "foobar"
This is an open issue in Flask-RestPlus. As described in this comment on that issue, changing the order of the route and Api solves the issue.
from flask import Flask
from flask_restplus import Api
app = Flask(__name__)
#app.route("/")
def index():
return "foobar"
api = Api(app, doc="/doc/")
flask-restplus defines a different way of assigning routes according to their docs:
#api.route('/')
class Home(Resource):
def get(self):
return {'hello': 'world'}
Notice that the api variable is used instead of the app. Moreover, a class is used although I am not 100% sure it is required.
Is there a way to inject a Flask request object into a different Flask app. This is what I'm trying to do:
app = flask.Flask(__name__)
#app.route('/foo/<id>')
def do_something(id):
return _process_request(id)
def say_hello(request):
# request is an instance of flask.Request.
# I want to inject it into 'app'
I'm trying this with Google Cloud Functions, where say_hello() is a function that is invoked by the cloud runtime. It receives a flask.Request as the argument, which I want to then process through my own set of routes.
I tried the following, which doesn't work:
def say_hello(request):
with app.request_context(request.environ):
return app.full_dispatch_request()
This responds with 404 errors for all requests.
Edit:
The simple way to implement say_hello() is as follows:
def say_hello(request):
if request.method == 'GET' and request.path.startswith('/foo/'):
return do_something(_get_id(request.path))
flask.abort(404)
This essentially requires me to write the route matching logic myself. I'm wondering if there's a way to avoid doing that, and instead use Flask's built-in decorators and routing capabilities.
Edit 2:
Interestingly, dispatching across apps work locally:
app = flask.Flask(__name__)
# Add app.routes here
functions = flask.Flask('functions')
#functions.route('/', defaults={'path': ''})
#functions.route('/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE'])
def catch_all(path):
with app.request_context(flask.request.environ):
return app.full_dispatch_request()
if __name__ == '__main__':
functions.run()
But the same technique doesn't seem to work on GCF.
I wouldn't recommend this method, but this is technically possible by abusing the request stack and rewriting the current request and re-dispatching it.
However, you'll still need to do some type of custom "routing" to properly set the url_rule, as the incoming request from GCF won't have it (unless you explicitly provide it via the request):
from flask import Flask, _request_ctx_stack
from werkzeug.routing import Rule
app = Flask(__name__)
#app.route('/hi')
def hi(*args, **kwargs):
return 'Hi!'
def say_hello(request):
ctx = _request_ctx_stack.top
request = ctx.request
request.url_rule = Rule('/hi', endpoint='hi')
ctx.request = request
_request_ctx_stack.push(ctx)
return app.dispatch_request()
I have friend helping with English this time.
I have more problems with getting new route to loading.
I have this testing code:
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/')
def index():
return render_template('main.html')
#app.route('/order')
def index():
return render_template('order.html')
if __name__ == '__main__':
app.run()
And I get this error:
View function mapping is overwriting an existing endpoint function: index
Please help me. I hope English better.
You define index() two times. You have to change name one of the function.
You are defining a function index twice in the same scope. The flask decorator is making it sound more complicated than that, is all.
Can someone show me examples of making a RESTful API which uses database information in Flask? I have no idea how to implement POST, PUT and DELETE and I always get the 405 error where I can't use the method in url.
Have you add request method in your routing? you can following reference from: flask-restful
from flask import Flask, request
from flask_restful import Resource, Api
app = Flask(__name__)
api = Api(app)
class TodoSimple(Resource):
def get(self):
# do get something
def put(self):
# do put something
def delete(self):
# do delete something
def post(self):
# do post something
api.add_resource(TodoSimple, '/api/todo')
if __name__ == '__main__':
app.run(debug=True)
in flask-restful the HTTP actions (GET, PUT, POST, DELETE) have their corresponding method in the resource class, so is just a matter of defining those method in the resource (with the corresponding parameter defined in the routing)
I've also built a lightweight framework for building restful apis that makes it super easy to build apis. You can take a look at the code to have an idea of how an API can be built, configured and run, and of course, build on top of it
here's the code: https://github.com/sebastiandev/peach
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.