Well i've this in my flask app :
#app.route("/changeip/<ip>")
def change_ip(ip) :
return ip
Now if i invoke it like :
http://127.0.0.1:5000/changeip?ip=1.2.2.2
It spits out "URL not found"...what is that i'm doing wrong here?
The first route describes a url with a value as part of the url. The second url describes a route with no variables, but with a query parameter in the url.
If you are using the first route, the url should look like http://127.0.0.1/changeip/1.2.2.2.
If you are using the second url, the route should look like /changeip, the function should be def change_ip():, and the value should be read from request.args['ip'].
Usually the route should describe any arguments that should always be present, and form or query params should be used for user-submitted data.
You should use:
app.route('/something/<ip>')
def function(ip):
And when you are using url_for, you should pass value of ip aswell:
url_for('function', ip='your_ip_address')
The accepted answer is correct, but I wanted to add the method that it appears the OP was originally trying in his http request.
Another way to pass in variables is through the question mark that separates variables in the url, and using requests.
import requests
Then in the method,
#app.route("/changeip")
def change_ip():
return requests.args.get('ip', '')
For the url, you pass the variable in using the question mark delimiter, the way you were originally trying.
http://127.0.0.1:5000/changeip?ip=1.2.2.2
Related
beginner's question:
is it possible to pass GET request parameters to a route function in Flask using add_url_rule?
I am getting the error message that the verify_username_route function I declare later (that takes 1 parameter) is called without any parameters passed.
self.application_.add_url_rule(self.path_ + '/verify', 'verify', self.verify_username_route, methods=['GET'])
To fetch query string parameters, you use request.args.get('argname') in your function. Nothing is passed in -- it's all done through the globals.
To pass any parameters in your URLs, you can use Flask's built-in patterns. These work for both #app.route decorators and add_url_route methods. Here is your code, with a parameter:
self.application_.add_url_rule(self.path_ + '/verify/<int:val>', 'verify', self.verify_username_route, methods=['GET'])
The important part from this is the exact route: /verify/<int:parameter>. This tells Flask that you want the route to be in the format of /verify/something, where something is any integer. Whatever integer is entered here when the request is made gets passed to your self.verify_username_route as a parameter called val.
Read more about this here.
I have a flask route like this:
#app.route('/foo/<var1>/<var2>')
def foo(var1, var2):
And later on, I try to do this:
return redirect(url_for('foo/bar/baz'))
This gives me
werkzeug.routing.BuildError
BuildError: ('foo/bar/baz', {}, None)
I've looked around and found no solutions, I've also tried things like
return redirect(url_for('foo'), var1='bar', var2='baz')
But I get the same error. Can anyone help me figure out how to properly redirect to this route?
url_for takes the function name as well as keyword arguments.
In your case, redirect(url_for('foo', var1='bar', var2='baz')) should work.
Note that what I have provided is different than the last example you provided.
I'm writing a RESTful API in Flask. I can access URL parameters via the Request Object. What is the best way to validate the given URL parameters?
For example:
/places?zip=97239 # This is a valid filter
/places?foo=bar # This is not a valid filter, 404 response?
One solution is to search through request.args and compare each entry against a set of valid URL parameters. Is there a better way?
Thanks!
Put the GET parameters in a dictionary and validate it using voluptuous.
For example:
parameters = Schema({
Required('zip'): Coerce(int),
})
will accept any dictionary with a "zip" key that has a value that can be coerced to an integer (so either 1 or "1" depending on how you get the values). You can then validate it using:
parameters(my_get_params) # should not raise an exception
Instead of doing validation by hand, you can use WTForms, which, besides helping you create actual forms, validates URL / POST parameters automatically according to specified models.
Whether this is better will depend on your specific situation.
You can use the flask-parameter-validation library in order to validate within Flask. This is useful as it uses Flask features under-the-hood, handles files/forms, and implicitly converts Query parameters.
For your example, you would do the following:
from flask import Flask
from typing import Optional
from flask_parameter_validation import ValidateParameters, Query
app = Flask(__name__)
#app.route("/places", methods=["GET"])
#ValidateParameters()
def check_places(
zip: Optional[int] = Query()
):
return "Hello World!"
if __name__ == "__main__":
app.run()
I'm trying to implement a batch request method in pyramid. I see in the docs that it's done with
subrequest = Request.blank('/relative/url')
request.invoke_subrequest(subrequest)
I'm just wondering how do you pass along the headers and cookies? Is it already done for you or is it
request.invoke_subrequest(subrequest, cookies=request.cookies, headers=request.headers)
What about parameters for different methods? The docs only have a POST keyword arg.
I feel like the docs are a little vague, or I can't find the correct docs on how to do this. Thanks
I'm just wondering how do you pass along the headers and cookies?
From http://docs.pylonsproject.org/projects/pyramid/en/1.5-branch/narr/subrequest.html#subrequest-chapter :
The pyramid.request.Request.invoke_subrequest() API accepts two
arguments: a positional argument request that must be provided, and
use_tweens keyword argument that is optional; it defaults to False.
This tells us that the constructor only wants a Request object, and optionally a value for use_tweens, so no, this
request.invoke_subrequest(subrequest, cookies=request.cookies, headers=request.headers)
will not work.
Then, from http://docs.pylonsproject.org/projects/pyramid/en/1.5-branch/narr/subrequest.html
It's a poor idea to use the original request object as an argument to
invoke_subrequest(). You should construct a new request instead as
demonstrated in the above example, using
pyramid.request.Request.blank(). Once you've constructed a request
object, you'll need to massage it to match the view callable you'd
like to be executed during the subrequest. This can be done by
adjusting the subrequest's URL, its headers, its request method, and
other attributes. The documentation for pyramid.request.Request
exposes the methods you should call and attributes you should set on
the request you create to massage it into something that will actually
match the view you'd like to call via a subrequest.
So basically, you need to configure your request before you pass it to invoke_subrequest().
Luckily there is an entire page that documents the Request class. There we can find a whole lot options to configure it, etc.
What about parameters for different methods? The docs only have a POST keyword arg.
Also on the Request class documentation page, there is this
method
Gets and sets the REQUEST_METHOD key in the environment.
And on http://docs.pylonsproject.org/projects/pyramid/en/1.3-branch/narr/viewconfig.html I found
request_method This value can be a string (typically "GET", "POST",
"PUT", "DELETE", or "HEAD") representing an HTTP REQUEST_METHOD
I must agree with you that the documentation is a little vague here and there, but I assume you can use it like this
request.method = 'POST'
# Or
request.method = 'GET'
# Etc.
Summary
You'll want to do it like this
subrequest = Request.blank('/relative/url')
# Configure the subrequest object
# set headers and other options you need.
request.invoke_subrequest(subrequest)
Note
I am aware this is not a 100% complete answer with some code that you can copy paste and it'll just work (especially regarding configuring the request object), but I think this answer contains some information that, at the very least, will get you on the right track and I hope it will be of some help to you.
The following code worked for me. It copies all (headers, cookies, query string, post parameters, etc.):
def subrequest(request, path):
subreq = request.copy()
subreq.path_info = path
response = request.invoke_subrequest(subreq)
return response
Somewhat late, but based on the above two answers here is how I did this. I didn't quite like the above answer to just copy everything. Looking at the documentation of the blank() method there is a kw argument and it says
All necessary keys will be added to the environ, but the values you pass in will take precedence. If you pass in base_url then wsgi.url_scheme, HTTP_HOST, and SCRIPT_NAME will be filled in from that value.
Assuming that the view's request contains the right header information and cookies that you need for your subrequest, you can use the following code:
#view_config( ... )
def something(request):
...
kwargs = { "cookies": request.cookies,
"host" : request.host,
}
req = Request.blank("/relative/url", **kwargs)
resp = request.invoke_subrequest(req)
Other header information (e.g. accept, accept_encoding, etc.) are properties of pyramid.request objects, and can be added to the kwargs dictionary like shown in the code snippet above.
The object returned by invoke_subrequest() is a Response object documented here.
Sample Bottle.py code:
#route('/show_<name>')
def show(name):
return ''
My question is:
Given a URL, how do we get the view function? E.g. the URL is /show_magic, I need to know the show() function is responsible for this request URL
Given a route (not Router!!) and parameters, how to get the URL? e.g. I need a function called reverse which reverse(default_app().routes[0], name='me') == '/show_me'
you might want to consider named routes
#route('/show_<item_name>', name='item_show')
def show(item_name):
return ''
now given the route name and params how to get the URL? we use get_url
get_url('item_show', item_name='my_item')
http://nongraphical.com/2012/08/using-bottle-py-in-production/
For your first question, use Bottle.match. Given a path (i.e. '/show_magic') and the method (GET or POST or whatever), the following will return a tuple containing a Route object and its parameters:
default_app().match({'PATH_INFO': path, 'REQUEST_METHOD': method})
The function called is the Route object's callback or call attribute.
For your second question, use the router's build method with the route's rule and kwargs:
default_app().router.build(route.rule, name='me')
That doesn't seem to be documented, but it works.