I have a flask app and I need to pass variables from one function to another. The requirement here is I need to pass the value of 'skill' from index() to get_image(), any idea on how this can be achieved?
#app.route('/', methods=['POST'])
def index():
data = json.loads(request.get_data())
skill = data['conversation']['skill']
#app.route("/get-image/<image_name>")
def get_image(image_name):
if skill == 'getpositions':
# some code
You can try use flask sessions for example:
from flask import Flask, session
...
#app.route('/', methods=['POST'])
def index():
data = json.loads(request.get_data())
skill = data['conversation']['skill']
session['skill'] = skill
#app.route("/get-image/<image_name>")
def get_image(image_name):
if session['skill'] == 'getpositions':
#some code
Check the documentation.
Related
How can I decouple this class? I would like to put the paths in another file, is it possible to move the routes in another file?
#api.route('/home', '/api/email')
class Server(Resource):
def create_server(app, oauth=None):
if not oauth:
oauth = default_provider(app)
app = prepare_app(app)
#app.before_request
def load_current_user():
user = User.query.get(1)
g.user = user
#app.route('/home')
def home():
return 'home'
#app.route('/oauth/authorize', methods=['GET', 'POST'])
#oauth.authorize_handler
def authorize(*args, **kwargs):
return True
Those
#app.route('/home') # and
#app.route('/oauth/authorize', methods=['GET', 'POST'])
have to be in another file.
My attempt was this, I tried to create a file for routers:
class Router():
def __init__(self, app, oauth):
self.app = app
self.oauth = oauth
#app.route('/home')
def home():
return 'home'
I'm getting this error:
NameError: name 'app' is not defined
Well, I see a package you can use for flask projects called Flask-Via [pypi], inspired by the Django URL configuration system and designed to add similar functionality to Flask applications that have grown beyond a simple single file application. The following example is given from the docs of this project:
from flask import Flask
from flask.ext.via import Via
from flask.ext.via.routers.default import Functional
app = Flask(__name__)
def foo(bar=None):
return 'Foo View!'
routes = [
Functional('/foo', foo),
Functional('/foo/<bar>', foo, endpoint='foo2'),
]
via = Via()
via.init_app(app, route_module='flask_via.examples.basic')
if __name__ == "__main__":
app.run(debug=True)
I think this is exactly what you want :) and you can move it to another python module for example called routers.py.
I am building a small app using a forex converter api, it's function is to take one currency, and convert a value into the new currency. I seem to be getting caught when accessing my class "Survey" everything I try to get data from my html form. My program is getting caught on self.convertFrom=request.form['convertFrom'] and the python debugger is giving me "RuntimeError: Working outside of request context." I would greatly appreciate if someone can show/explain to me what it is im doing wrong here.
app.py
from flask_debugtoolbar import DebugToolbar
from forex_python.converter import CurrencyRates
from handleForm import Survey
app = Flask(__name__)
survey = Survey()
result=["Give me something to convert!"]
#app.route("/")
def home_page():
"""Loads home page where user can enter their first conversion"""
return render_template('index.html')
#app.route("/conversion")
def show_conversion():
"""shows the users conversion"""
return render_template('convSubmit.html', result=result)
#app.route("/conversion/new", methods=["POST"])
def add_conversion():
"""clear old conversion from list and add new"""
result=[]
result.append(survey.convertCurrency())
return redirect("/conversion")
handleForm.py
from flask import Flask, render_template, request
from forex_python.converter import CurrencyRates
c = CurrencyRates()
class Survey():
def __init__(self):
self.convertFrom=request.form['convertFrom'] <---gets caught here
self.convertTo=request.form['convertTo']
self.value=request.form['value']
def convertCurrency(self):
currencyFrom = self.convertFrom
currencyTo = self.convertTo
getValue = int(self.value)
result = c.convert(currencyFrom, currencyTo, getValue)
return result
The request variable will be available only when a request is active. In simple terms it will be available only when it is invoked by a view function handling a route.
In your case, you are trying to initialise the survey object outside any root function. That line will be invoked when the app server is started, before any request has been reserved, and hence flask is throwing an error saying that you are invoking it outside of request context.
To fix it, you should move the survey = Survey() inside a view function
#app.route("/conversion/new", methods=["POST"])
def add_conversion():
"""clear old conversion from list and add new"""
result=[]
survey = Survey()
result.append(survey.convertCurrency())
return redirect("/conversion")
While this would fix the problem, it is still not a good pattern to make that class constructor to directly access the request global.
If you need the constructor itself to initialize these params, you can pass these as arguments to the constructor and then pass them when initializing
from flask import Flask, render_template, request
from forex_python.converter import CurrencyRates
c = CurrencyRates()
class Survey():
def __init__(self, convertFrom, convertTo, value):
self.convertFrom=convertFrom <---gets caught here
self.convertTo=convertTo
self.value=value
def convertCurrency(self):
currencyFrom = self.convertFrom
currencyTo = self.convertTo
getValue = int(self.value)
result = c.convert(currencyFrom, currencyTo, getValue)
return result
And then change the view function to pass the values to the constructor
#app.route("/conversion/new", methods=["POST"])
def add_conversion():
"""clear old conversion from list and add new"""
result=[]
survey = Survey(request.form["convertFrom"], request.form["convertTo"], request.form["value"])
result.append(survey.convertCurrency())
return redirect("/conversion")
I have just started with Flask I know django. We take a request parameter in a simple django view
from django.http import HttpResponse
def view(request):
#request is the local paramter for view
return HttpResponse('Welcome to Django')
Now this view is request aware because of parameter passed.
But now in Flask
from flask import Flask, request
app = Flask(__name__)
#app.route('/', methods=['GET','POST'])
def view():
if request.method == 'GET':
return "Hello from Flask"
request is not local to function view how it is aware of the request it should be like request is not defined.
Where it is coming from?
How it works here?
EDIT
I thought decorator is doing that
Decorator works this way
def deco(f):
def declare_x():
global x
x=9
f()
return declare_x
#deco
def do_it():
print(x)
do_it()
But I did not see any global reference at flask repo
and I dont think it is implemented like this here.
Please help me understand how it is working.Thanks in advance.
I am trying to do a GET request which should print a specific row from my database depending on what arguments are set. The argument should be a name of a course and I want it to get all data from the selected course. It might be a bit easier to explain this as a SQL query. The query could look like this "SELECT * FROM courselist WHERE course='D0024E';"
where "course".
I have managed to do a fetchall() and receive all rows from a specific table, but I have not managed to get the parameters working correctly so I can get information from a specific course.
from flask import Flask
from flask import render_template
import requests
from flask import request
from flask import jsonify
import mysql.connector
app = Flask(__name__)
mydb = mysql.connector.connect(user='Mille',
auth_plugin='mysql_native_password',
password='jagheter12',
host='localhost',
database='paraplyet')
#app.route('/')
def index():
return render_template("index2.html")
#app.route('/courses', methods= ["GET"])
def getStudentInCourse():
myCursor2 = mydb.cursor()
query2 = ("SELECT * FROM paraplyet.kursinfo")
myCursor2.execute(query2)
myresult2 = myCursor2.fetchall()
return jsonify(myresult2)
if __name__ == '__main__':
app.run()
You need to update your route url to receive parameters
#app.route('/courses/<course_code>', methods= ["GET"])
def getStudentInCourse(course_code):
Then you can use this course_code to filter result.
Actually there are several points where your code(s) can fail, because establishing a correct front-end back-end chain in Flask is a little tricky (but worth it at the end).
You have a counter part front-end HTML code where you start your request with the proper variable, like "course" in your example, which may looks like this:
<form action="/courses" method="post">
<input>
<button type="submit"></button>
</form>
Then Flask as back-end will get this variable(parameter) as part of your query string as part of the URL string. You can retrieve this parameter in the form:
course = request.form.get('course')
To achieve it you have to add "POST" the view's methods, as it handles only "GET"-s as default.
#app.route('/courses', methods=["GET", "POST"])
Then you can use this variable as you want to complete your back-end operations:
query2 = ("SELECT * FROM courseInfo where courseCode = '" + course + "';")
those results then you can pass it back to the front-end via:
return jsonify(myresult2)
Your python/flask code should be some like as follows:
from flask import Flask
from flask import render_template
import requests
from flask import request
from flask import jsonify
import mysql.connector
app = Flask(__name__)
mydb = mysql.connector.connect(user='Mille',
auth_plugin='mysql_native_password',
password='jagheter12',
host='localhost',
database='paraplyet')
#app.route('/')
def index():
return render_template("index2.html")
#app.route('/courses', methods= ["GET", "POST"])
def getStudentInCourse():
if request.method == "POST" and request.form.get('course') != '':
myCursor2 = mydb.cursor()
course = request.form.get('course')
query2 = ("SELECT * FROM courseInfo where courseCode = '" + course + "';")
myresult2 = myCursor2.execute(query2)
return jsonify(myresult2)
if __name__ == '__main__':
app.run()
I have a website that needs to be rebranded depending on the URL that a visitor comes in on. For the most part, the content is the same but the CSS is different. I'm brand new to flask and relatively new to session cookies, but I think the best way to do this is to create a session cookie containing a "client" session variable. Then, depending on the client (brand), I can append a specific css wrapper to a template.
How can I access URL params and set one of the param values to a session variable? For example, if a visitor comes in on www.example.com/index?client=brand1, then I'd like to set session['client'] = brand1.
My app.py file:
import os
import json
from flask import Flask, session, request, render_template
app = Flask(__name__)
# Generate a secret random key for the session
app.secret_key = os.urandom(24)
#app.route('/')
def index():
session['client'] =
return render_template('index.html')
#app.route('/edc')
def edc():
return render_template('pages/edc.html')
#app.route('/success')
def success():
return render_template('success.html')
#app.route('/contact')
def contact():
return render_template('pages/contact.html')
#app.route('/privacy')
def privacy():
return render_template('pages/privacy.html')
#app.route('/license')
def license():
return render_template('pages/license.html')
#app.route('/install')
def install():
return render_template('pages/install.html')
#app.route('/uninstall')
def uninstall():
return render_template('pages/uninstall.html')
if __name__ == '__main__':
app.run(debug=True)
You could do so in a #flask.before_request decorated function:
#app.before_request
def set_client_session():
if 'client' in request.args:
session['client'] = request.args['client']
set_client_session will be called on each incoming request.