I initially gave URLs like #app.route('/volume/') and #app.route('/cvolume/') where c denoted another section. But now I think section/page would be better than c prefix to the page i.e. #app.route('/c/volume/'). Can I simply make the change or will this break my app?
P.S. - I am using <a href="{{url_for("volume")}}> in templates instead of the plain <a href="/volume">
No, because url_for takes the name of the function, not the url. So if your function is:
# ...Code, imports...
#app.route('/cvolume/')
def volume():
return 'Hello world!'
#app.route('/volume/')
def volume_2():
return 'Hello You!'
#app.route('/test/')
def test():
return redirect(url_for('volume'))
The redirection would be for /cvolume/ not /volume/.
Related
I have a function called getTableData() which runs another function get_table() and based on that get_table() output final function is called which renders a template and also routes to a different page.
So the problem is its not routing to a different url (/tabdata) from get_final() function
Flask code:
#app.route('/api/getTableData', methods=['POST'])
def getTableData():
value = request.json['value']
value=value[:8]
url="https://some.com"+value
df_time=get_table(url)
return get_final(df_time)
def get_table(url):
driver = webdriver.Chrome(options=options)
driver.get(url)
abv = pd.read_html(driver.find_element(By.ID,"frm_hist").get_attribute('outerHTML'))[0]
df_time = pd.DataFrame(abv)
return df_time
#app.route("/tabdata")
def get_final(df_time):
return render_template("new.html",df_time = df_time)
Code Explanation:
I am using the value from value variable then concat 2 strings to make the url and then passing the url to another function named get_table() which goes to that url and webscrapes the table and converts it into python dataframe.
So using the returned python dataframe get_final() is called to render the template in a html file and also route to the /tabdata url. Everything is working well except the page is not routing to that url
You have to return a redirect:
from flask import redirect
#app.route("/tabdata/<df_time>")
def get_final(df_time):
return redirect("http://www.example.com", code=200)
Use redirect and use it with url_for in case you decide to change your routes in the future. You also need to change your view function get_final
from flask import redirect, url_for
#app.route('/api/getTableData', methods=['POST'])
def getTableData():
value = request.json['value']
value = value[:8]
url = "https://some.com"+value
df_time = get_table(url)
return redirect(url_for('get_final', df_time=df_time))
def get_table(url):
driver = webdriver.Chrome(options=options)
driver.get(url)
abv = pd.read_html(driver.find_element(By.ID,"frm_hist").get_attribute('outerHTML'))[0]
df_time = pd.DataFrame(abv)
return df_time
#app.route("/tabdata/<df_time>") # notice change here!
def get_final(df_time):
return render_template("new.html", df_time=df_time)
In getTableData(), change
return get_final(df_time)
to
return redirect(url_for("get_final", df_time=df_time))
In get_final(), change
#app.route("/tabdata")
def get_final(df_time):
return render_template("new.html",df_time = df_time)
to
#app.route("/tabdata/<df_time>")
def get_final(df_time):
return render_template("new.html", df_time=df_time)
Although your redirected URL will look something like this; "http://localhost/tabdata/16606505". If this is not preferred, you can always redirect for GET request with query parameters (which will look like this; "http://localhost/tabdata&data=16606505") or redirect for POST request which will not show the df_time parameter in browser history.
I have a service that should return a string when a specific endpoint is called. But when it happens, the text is returned, but all the line jumpes '\n' are literally written instead of represent line jumps in my postman response.
Ex.:
"hello\nworld" is sent and I get "hello\nworld" instead of
"hello
world"
I've seen some solutions here on the stack overflow, but didn't understand how to implement it. Some use html scripts that seem not work on the python file. I really didn't understand.
As per this answer use <br> or <br/> instead of \n:
#app.route("/")
def test():
return "Hello<br>World!"
Hello
World!
Different from all the answers i've seen here, i found the answer to my question. Putting "" doesn't work. What solved my problem was to add a header in my file.
#code before
msg = (...) #what is to be returned
#create the variable where you will store the returned text
response = make_response(msg, 200)
#then you add the header to it
response.mimetype = "text/plain"
#then return
return response
For example:
I have a route: /foo
#app.route('/foo')
def foo():
#the logic
Is it possible to retrieve arguments from url /foo?arg1=abc&arg2=123
That's arg1=abc, arg2=123
Then redirect/keep the user within same URL but without arguments shown in the browser?
#app.route('/foo')
def foo():
arg1= request.args.get('arg1')
arg2= request.args.get('arg2')
if arg1 or arg2:
#some logic
#the logic
In other words, a user from URL (could be the link shared by someone else)
/foo?arg1=abc&arg2=123
will be redirected to URL
/foo
However, I need the arguments (arg1,arg2) to make some business logic and render it to the template. Is it possible to achieve?
Appreciate your help!
I found this question which seems to be what I'm looking for.
It says to use web.ctx['ip']
But I cant get it to work right, all I want is the IP of the visitor in a variable. So far I've been trying this:
import web
urls = (
'/', 'index'
)
class index:
def GET(self):
return "Hello, world!"
return web.ctx['ip'] #Trying to get it to just *show* so
#I can put it into a variable
print web.ctx['ip'] #Nothing happens here either
if __name__ == "__main__":
app = web.application(urls, globals())
app.run()
Thanks in advance, I think I'm close, I just need a little help. Maybe I need to import something else?
You are returning before even getting the IP address, Just re-order your code to the following way and remove return "Hello, world!" :
class index:
def GET(self):
print web.ctx['ip']
return web.ctx['ip']
Using a Bottle Sehttp://bottlepy.org/docs/dev/routing.html#wildcard-filters
I'd like to accept any url, and then do something with the url.
e.g.
#bottle.route("/<url:path>")
def index(url):
return "Your url is " + url
This is tricky because URLs have slashes in them, and Bottle splits by slashes.
Based on new Bottle (v0.10), use a re filter:
#bottle.route("/<url:re:.+>")
You can do that with old parameters too:
#bottle.route("/:url#.+#")
I think you (OP) were on the right track to begin with. <mypath:path> should do the trick.
I just tried it out with bottle 0.10 and it works:
~>python test.py >& /dev/null &
[1] 37316
~>wget -qO- 'http://127.0.0.1:8090/hello/cruel/world'
Your path is: /hello/cruel/world
Here's my code. What happens when you run this on your system?
from bottle import route, run
#route('<mypath:path>')
def test(mypath):
return 'Your path is: %s\n' % mypath
run(host='localhost', port=8090)
Cheers!
In Bottle 0.12.9 i did this to achieve optional dynamic routes:
#bottle.route("/<url:re:.*>")
def index(url):
return "Your url is " + url
#bottle.route("/hello/:myurl")
def something(myurl):
print myurl
return "Your url was %s" % myurl
Should work just fine
I would then write the regex into the function itself.
Or you could do it with a new filter, but to do that you have to write a filter function and add it to the app.