I'm new to python and wondering if it is possible using BaseHTTPServer to store a global var that is accessible to all requests? Basically I have an async process that requires a POST back into the server as a separate request from the original request, that I would like to write back through to the original request, via a token I'd generate.
No.
To maintain state, you'll need a web framework that supports global variables across requests, or some kind of session management.
Flask is super easy to get up and running and has sessions available.
import flask
app = flask.Flask(__name__)
#app.route('/')
def index():
flask.session['post_token'] = MakeToken()
return '...Content...'
#app.route('/poster', methods=['POST'])
def poster():
if flask.session['post_token']:
DO STUFF HERE
# set the secret key. keep this really secret:
app.secret_key = 'A0Zr98j/3yX R~XHH!jxxxRT'
Related
hi i have made a really basic example here to attempt to make this easy to understand, i have a simple flask api that returns a single string, it is fully accessible using localhost, but i want to be able to access it from outside of the local network. i have created a firewall rule that allows TCP traffic in and out on port 5000, but despite this, it does not work. this is currently running in a pycharm community edition IDE, but i have ran it from command line aswell with the same results.
Why can i not access it using http://[IP]:5000/test
my end goal is to be able to access it from any identity given using Tor service using Torrequests module, but to get that far i need to be able to access it externally in the first place
from flask import Flask, request
from flask_restful import Resource, Api
import logging
app = Flask(__name__)
api = Api(app)
class Test(Resource):
def post(self):
return "worked"
def get(self):
return "worked"
api.add_resource(Test, '/test', methods=['GET', 'POST'])
if __name__ == "__main__":
app.run(debug=False ,host='0.0.0.0', port=5000)
I need to have 'variables and activity associated with each client' without using cookies. How and where can i store this variables? I am pretty new to flask and servers.
For now, I thought of using a python dictionary and storing sessionID-variable pairs like shown below.
I have a feeling that this is a stupid idea, but I can not think of an alternative :/.
Hope, you can help me.
import flask
app = Flask(__name__)
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'
enter code heresocketio = SocketIO(app)
cache = {}
#app.route('/')
def index():
return send_from_directory('static', "index.html")
#socketio.on('savePseudonym')
def sendKeepAlive():
cache[(request.sid,'pseudonym')]= pseudonym
cache[(request.sid,'time')]= time
if __name__ == "__main__":
socketio.run(app, debug=True)
You can use session, in more or less the same way you use it with Flask routes.
from flask import session
#socketio.on('savePseudonym')
def sendKeepAlive():
session['pseudonym'] = pseudonym
session['time'] = time
The only thing to keep in mind is that because Socket.IO sessions are not based on cookies, any changes you make to the session in a Socket.IO handler will not appear on the Flask session cookie. If you need to share the session between Flask routes and Socket.IO event handlers, then you can use a server-side session with the Flask-Session extension.
I'm trying to write an HTTP server in python 2.7. I'm trying to use ready-made classes to simplify the job (such as SimpleHTTPServer, BaseHTTPRequestHandler, etc.).
The server should listen for GET requests, and once it gets one - parse the request (the path and the arguments), and interact with an already initialized object (which accesses a DB, counts number of requests, etc.) - let's call it the 'handler', and return a response.
I understand that the RequestHandler class (e.g. BaseHTTPRequestHandler) will be constructed for each request. How can I pass the 'handler' to the handling routines, so that they could call its methods?
Thanks!
Use a framework to further simplify your job. Here is an example in flask:
from flask import Flask
from flask import request
app = Flask(__name__)
your_handler = SomeHandlerClass()
#app.route("/")
def index():
return your_handler.do_something_with(request)
if __name__ == "__main__":
app.run()
request is a proxy object that holds all the incoming request data.
What is the easiest way to have a server-side session variable in Flask?
Variable value:
A simple string
Not visible to the client (browser)
Not persisted to a DB -- simply vanishes when the session is gone
There is a built-in Flask session, but it sends the session data to the client:
session["secret"] = "I can see you"
The data is Base64 encoded and sent in a cryptographically signed cookie, but it is still trivial to read on the client.
In many frameworks, creating a server-side session variable is a one-liner, such as:
session.secret = "You can't see this"
The Flask solutions I have found so far are pretty cumbersome and geared towards handling large chunks of data. Is there a simple lightweight solution?
I think the Flask-Session extension is what you are looking for.
Flask-Session is an extension for Flask that adds support for Server-side Session to your application.
From the linked website:
from flask import Flask, session
from flask_session import Session # new style
# from flask.ext.session import Session # old style
app = Flask(__name__)
# Check Configuration section for more details
SESSION_TYPE = 'redis'
app.config.from_object(__name__)
Session(app)
#app.route('/set/')
def set():
session['key'] = 'value'
return 'ok'
#app.route('/get/')
def get():
return session.get('key', 'not set')
This answer is from June 2020 for flask-session 0.3.2.
The documentation is here.
There are several available SESSION_TYPESs. filesystem is the most straightforward while you're testing. The expectation is you already have a Redis, database, etc. setup if you are going to use the other SESSION_TYPEs. Section on SESSION_TYPE and requirements
null: NullSessionInterface (default)
Redis: RedisSessionInterface
Memcached: MemcachedSessionInterface
filesystem: FileSystemSessionInterface
MongoDB: MongoDBSessionInterface
SQLAlchemy: SqlAlchemySessionInterface
Code example from the documentation. If you go to /set/ then the session['key'] is populated with the word 'value'. But if you go to /get/ first, then `session['key'] will not exist and it will return 'not set'.
from flask import Flask, session
from flask_session import Session
app = Flask(__name__)
app.config['SESSION_TYPE'] = 'filesystem'
#personal style preference compared to the first answer
Session(app)
#app.route('/set/')
def set():
session['key'] = 'value'
return 'ok'
#app.route('/get/')
def get():
return session.get('key', 'not set')
For a while now I am trying to learn how to use Ajax with Flask. On the official website of flask there is an example:
from flask import Flask, jsonify, render_template, request
app = Flask(__name__)
#app.route('/_add_numbers')
def add_numbers():
a = request.args.get('a', 0, type=int)
b = request.args.get('b', 0, type=int)
return jsonify(result=a + b)
#app.route('/')
def index():
return render_template('index.html')
It works for me well. But I am looking for the following program:
a jQuery code sends an initial number to the python app
the python app stores the number and responds 'received: [the number]'
while true: the python app waits for requests 'increase' for which it adds 1 to the number and returns it
The jQuery part doesn't matter, I can do that but I am not sure how to implement the python part:
#app.route('/_inc_number')
def inc_number():
n = request.args.get('n', 0, type=int)
while true:
req = request.args.get('req', 0, type=string)
if req == 'increase':
n = n + 1
return n #It exits the function. how respond without quit?
Please explain me how I can data back? I am new to both Ajax and Flask too, and I suspect that it is not "real" ajax...Is that right? How would you implement a simple function with the same functionality in flask?
I think what you are missing is that each time the client requests a number increase there is an independent request. Your inc_number handler would be coded as follows:
#app.route('/_inc_number')
def inc_number():
n = request.args.get('n', 0, type=int)
n = n + 1
return n
Then from the jQuery side you have to invoke an independent Ajax request each time you want to increase the number.
Note that with this type of solution the jQuery app is the one that keeps track of the current value of the counter, and it has to send it to Flask with each request. Another possibility would be to have the Flask side remember the number in a user session. For that type of solution your Flask app would have two view functions:
from flask import session
# you need to set a SECRET_KEY in configuration, used to sign the user session
#app.route('/set_number')
def set_number():
# store n in the user session
session['n'] = request.args.get('n', 0, type=int)
#app.route('/inc_number')
def inc_number():
session['n'] = session['n'] + 1
return session['n']
With this solution now jQuery can set the number and not have to send it every time when it invokes inc_number.
I hope this helps.
HTTP requests don't have a memory, they are independent of each other. It means when your Python app gets a request, it does something, sends a response immediately and quits. That's the nature of HTTP.
If you want something persistent (like your number) that lives through more requests, you need:
Persistent storage on the server. It can be a file, a database, or in case of Flask simply an object (variable) in memory.
Identify the user between separate requests. That's what session handling and cookies are for.
A very primitive method (shouldn't be used on production system):
persistent storage: create a global dict (called num) in main()
in index():
create a random session identifier (si)
set num[si] = 0
send si as a cookie
in inc_number() use si from cookie (sent back by the browser) to increase the appropriate num[si]