Flask app, global variable over multiple files [duplicate] - python

This question already has answers here:
Are global variables thread-safe in Flask? How do I share data between requests?
(4 answers)
What is the g object in this Flask code?
(1 answer)
Closed 1 year ago.
I'm trying to share a variable I defined in my main function with a flask app which is imported from another file. First I tried to solve it via a classic global variable which did not bring me any further, until I stumbled over the concept of flask.g and the app context.
So I tried the following: I have two files in the same directory, a main.py:
# main.py
import app
from flask import g
if __name__ == "__main__":
with app.app.app_context():
g.value = "Hello World"
app.app.run(debug=True, threaded=True, host='localhost', port=5000)
and a app.py:
# app.py
from flask import Flask, g
app = Flask(__name__)
#app.route('/helloworld')
def send_response():
return g.value
However, when I request at http://localhost:5000/helloworld I get
AttributeError: '_AppCtxGlobals' object has no attribute 'value'
So it seems that setting the value g.value in one file is not reflected in the app.
I'm a beginner in Flask and it is very likely I did not get the concept right.
Similar questions did not get me any answer I could use to fix the issue:
Flask passing global variable, python-How to set global variables in Flask?, Preserving global state in a flask application
Help would be much appreciated!

Just use a regular Python module-level variable.
# app.py
g = "Example"
#app.route("/example")
def example_endpoint():
return g
# main.py
import app
app.g = "Hello"
Quoting the same page you linked:
The application context is created and destroyed as necessary. When a Flask application begins handling a request, it pushes an application context and a request context. When the request ends it pops the request context then the application context. Typically, an application context will have the same lifetime as a request.
So your setting flask.g outside of a request context (in your main.py) doesn't carry your value to anywhere.

Related

Why am I getting this? "NameError: name 'Response' is not defined"

I'm trying to get data from another of my servers. The other server is just an html file with "Hello World" I can reach my homepage fine, but when I go to /farmdata, I get this error:
NameError: name 'Response' is not defined"
from flask import Flask, render_template
import requests
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/farmdata')
def farmdata():
r = requests.get('http://74.114.75.91:8080')
r.url
r.encoding
return Response(
r.text,
status=r.status_code,
content_type=r.headers['content-type'],
)
if __name__== '__main__':
app.run(debug=True, port=80, host='0.0.0.0')
Edit - to anyone else with the problem, this was the solution.
from flask import Flask, render_template, Response
You have never defined Response. If you want to use flask.Response, you either have to import flask and then access it via flask.Response, or from flask import Response and then simply use Response.
In your code, you import Flask from the flask module, and that's where you get Flask from. If you remove the from flask import Flask line, you'll get a NameError complaining about Flask not being defined as well.
In Python, a name is defined if:
you defined it via variable assignment [or with a def or a class statement, which is pretty much the same] (like app in your example)
you imported it from another module explicitly (like Flask)
it's defined on startup (like list)
Is there not a " ," too much before closing the brackets of the response?

Can Flask server cache request body? [duplicate]

This question already has answers here:
Are global variables thread-safe in Flask? How do I share data between requests?
(4 answers)
Closed 3 years ago.
I have a small flask API setup as following,
from flask import Flask, request, jsonify, Response
import json
import subprocess
import os
app = Flask(__name__)
shellScripts = {
'redeploy': ['/bin/bash', 'redeploy.sh'],
'script-exec': ['/bin/bash', 'script-exec.sh']
}
def prepareShellCommand(json_data, scriptKey):
script=shellScripts[scriptKey]
print('script is')
print(script)
for key in json_data:
if scriptKey == 'redeploy':
script.append("-{0}".format(key[0]))
script.append(json_data[key])
return script
#app.route('/redeploy', methods=['POST'])
def setup_redeploy():
branches_data_json = request.get_json()
if ('frontendBranch' not in branches_data_json and 'backendBranch' not in branches_data_json):
return jsonify({'error': 'Need to provide at least one branch'}), 400
command = prepareShellCommand(branches_data_json, 'redeploy')
sp = subprocess.Popen(command)
return jsonify({'message': 'Redeployment under process'}), 201
#app.route('/execute', methods=['POST'])
def execute_script():
script_data_json = request.get_json()
if ('scriptPath' not in script_data_json):
return jsonify({'error': 'Need to provide script path'}), 400
command = prepareShellCommand(script_data_json, 'script-exec')
sp = subprocess.Popen(command)
return jsonify({'message': 'Script execution under process'}), 201
What's happening is, say I initiate an API endpoint, /execute with some data as {scriptPath: 'some-file'}, and it runs successfully. However, sometimes, regardless of change in the request body data, the API seems to work with the old data, {scriptPath: 'some-file'}, even if I am initiating the API with something like {scriptPath: 'new-file'}. And it doesn't change until I kill the python process, and restart it.
What could be the reason for this? I am running this as a development server, on a google cloud instance.
It's happening with both the endpoints, and I have a gut feeling that it's got something to do with either the subprocess or the dictionary that contains the boilerplate.
Can anyone help me with this?
This is almost certainly because you have defined shellScripts at module level but modify it from your handlers. The changes to the values of that dictionary will persist for the lifetime of the server process.
You should copy the value and modify that instead:
def prepareShellCommand(json_data, scriptKey):
script = shellScripts[scriptKey].copy()

ModuleNotFoundError: No module named 'flask.ext' [duplicate]

This question already has answers here:
Importing flask.ext raises ModuleNotFoundError
(3 answers)
Python flask.ext.mysql is deprecated?
(2 answers)
Closed 4 years ago.
I've created an AngularJS app served by node.js and now I've been asked to move from that to python flask. I encountered some errors and after search I was informed I have to include flask.ext.triangle but when I try to access localhost:5000 I get this error:
flask.cli.NoAppException: While importing "server", an ImportError was
raised: ModuleNotFoundError: No module named 'flask.ext'
I have installed flask-triangle using pip. My server.py is this:
from flask import Flask, render_template
from flask.ext.triangle import Triangle
app = Flask(__name__)
Triangle(app)
#app.route('/')
def mainPage():
return render_template('main.html')
Before importing triangle I got errors regarding AngularJS filters. All the routing and utility is handled by AngularJS, I just want flask to serve my app.
Couldn't get triangle to work so I found another way to make things happen. Found out that if you change the AngularJS expression brackets to something else and you forget completely about triangle the page loads. Here is my configuration on AngularJS app.js:
.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('//').endSymbol('//');
});
Now all I had to do is go to my HTML files and change {{ }} to // //.
EDIT:
Found the most proper way to do it. Instead of using render_template and have to mess with Jinja I used current_app.send_static_file to serve my HTML and faced no problems at all. My updated server.py:
from flask import Flask, current_app
app = Flask(__name__)
#app.route('/')
def mainPage():
return current_app.send_static_file('main.html')
Everything else is handled by AngularJS, no need to configure expression delimiters, used the built-in {{ }}.

how to save output from the shell by using python flask [duplicate]

This question already has an answer here:
Testing code that requires a Flask app or request context
(1 answer)
Closed 5 years ago.
First of all, I am very new at programming.
I am trying to save a variable from bash shell
>curl http://169.254.169.254/latest/meta-data/
this line would return data such as local-ipv4. And I am trying to use phython and flask to save those variables. I wrote
from flask import Flask, request
app = Flask(__name__)
#app.route('/')
def testRequest():
url1 = "http://169.254.169.254/latest/meta-data/"
name1 = request.get(url1)
nameText = name1.text
return nameText
testOutput = testRequest()
print testOutput
But this gives me runtime error : working outside of the request context.
can someone guide me to where to look for possible solution?
To things to comment here:
First, it seems that you'll be just fine by using requests, a highly recommended library for HTTP requests. With it you could do:
import requests
url = "http://169.254.169.254/latest/meta-data/"
resp = requests.get(url)
print resp.text
Regards to the error you're getting runtime error : working outside of the request context, is because by testOutput = testRequest() you're calling a method that's part of the Flask app app. Another thing related to the error is that you never ran the Flask app. To do this, include this at the end of your code.
if __name__ == '__main__':
app.run()
But again, Flask is rather a web framework that it's useful to create web sites, APIs, web apps, etc. It's very useful, but I don't think you may need it for what you're trying to achieve.
Further info about requests and Flask:
http://docs.python-requests.org/
http://flask.pocoo.org/
Since you only need to make an HTTP GET request and print the response, you don't need Flask. You can use the urllib standard library to send the GET request (https://docs.python.org/3/library/urllib.request.html):
import urllib.request
def testRequest():
url1 = "http://169.254.169.254/latest/meta-data/"
response = urllib.request.urlopen(url1)
nameText = response.read().decode('utf-8')
return nameText
testOutput = testRequest()
print testOutput

How can I call a specific function based on url in python web frameworks? [duplicate]

This question already has an answer here:
EVE - define custom flask controllers [closed]
(1 answer)
Closed 8 years ago.
I have developed a python application which takes in post variables and inserts data into postgresql.
Now I want to call specific function when we call a url.
For example
if I do
curl -i http://127.0.0.1:5000/abc/cde
it should call
def aaa()
if curl -i http://127.0.0.1:5000/pqr/xyz
it should call
def bbb()
is there a way to achieve that in python flask web frameworks ?
This is the one of the main features of a web framework. The most minimal example in Flask would be:
# my_app.py
from flask import Flask
app = Flask(__name__)
#app.route('/abc/cde')
def aaa():
return 'Hello, this is aaa'
#app.route('/pqr/xyz')
def bbb():
return 'Hello, this is bbb'
if __name__ == '__main__':
app.run()
You can then run this:
$ python my_app.py
Like any Python script. I suggest you have a look at Flask's Quickstart page as a starting point.

Categories

Resources