How to access class object inside the class in flask? - python

I've got flask running in a class
from flask import Flask
class Server:
app = Flask(__name__)
def __init__(self, object_with_data):
self.object = object_with_data
#app.route("/")
def hello(self):
return self.object.get_data()
def run():
self.app.run(host='0.0.0.0')
but I get an error saying
TypeError: hello() missing 1 required positional argument: 'self'.
How do I get access to an instance of the object when running flask within a class?
One dirty solution I thought of was using sockets to create a link between my server class and the object_with_data class, but I'm sure someone will know a better way to do this.
I read something about event handlers, but I don't fully understand that.

Related

Does this Python ABC interface, implementations, factory pattern make sense?

I've got a Django app and a message queue and I want to be able to switch between queue services easily (SQS or RabbitMQ for example).
So I set up a BaseQueue "interface":
class BaseQueue(ABC):
#abstractmethod
def send_message(self, queue_name, message, message_attributes=None):
pass
And two concrete classes that inherit from BaseQueue:
class SqsQueue(BaseQueue):
def send_message(self, queue_name, message, message_attributes=None):
# code to send message to SQS
class RabbitMqQueue(BaseQueue):
def send_message(self, queue_name, message, message_attributes=None):
# code to send message to RabbitMQ
Then in settings.py I've got a value pointing to the implementation the app should use:
QUEUE_SERVICE_CLS = "queues.sqs_queue.SqsQueue"
Because it's a Django app it's in settings.py, but this value could be coming from anywhere. It just says where the class is.
Then I've got a QueueFactory whose job is to return the queue service to use:
class QueueFactory:
#staticmethod
def default():
return import_string(settings.QUEUE_SERVICE_CLS)()
The factory imports the class and instantiates it.
I would then use it like so:
QueueFactory.default().send_message(queue_name, message)
It works, but I was wondering if there's a more Python way to do it? Like with some magic methods?

How to decorate class functions with flask-socketio if the socketIO instance is a class member variable?

I'm trying to create a hello world example for a flask application with socketio, that is wrapped into a class.
I want to wrap the whole application into a class, that can be embedded into other applications. For this purpose, I am creating the Flask application in the constructor of my class, and also create the SocketIO instance as a member too.
The problem is that I get a NameError exception tellimg me that 'socketio' is not defined.
I have tried to adapt the minimum working example from : the flask-socketio tutorial (https://flask-socketio.readthedocs.io/en/latest/)
Here is the example code I'm trying to get to work:
from flask import Flask
from flask_socketio import SocketIO, emit
class ApplicationExample:
def __init__(self):
self.app = Flask(__name__)
self.socketio = SocketIO(self.app)
#socketio.on('ping')
def pongResponse(self, message):
emit('pong')
def run(self):
self.socketio.run(service.app, host='0.0.0.0')
if __name__ == '__main__':
service = ApplicationExample()
service.run()
I would like to bind the pongResponse function to the socketio instance inside my class. How is it possible to decorate the function while having the SocketIO class as a member?
According to the documentation you can use the below instead of a decorator
def my_function_handler(data):
pass
socketio.on_event('my event', my_function_handler, namespace='/test')
Which would become something like
from flask import Flask
from flask_socketio import SocketIO, emit
class ApplicationExample:
def __init__(self):
self.app = Flask(__name__)
self.socketio = SocketIO(self.app)
self.socketio.on_event('ping', self.pongResponse, namespace='/test')
def pongResponse(self, message):
emit('pong')
def run(self):
self.socketio.run(service.app, host='0.0.0.0')
Since decorating a function simply calls the decorator and passes the decorated function as the first argument you can write:
def __init__(self):
...
self.pongResponse = self.socketio.on('ping')(self._pongResponse)
def _pongResponse(self, message):
...
A method beginning with a _ denotes that is not part of the public API of the class (thus this simply is a convention). Also note that in python you should use snake_caseinstead of camelCase to name your functions and variables, although this is also just a convention.

Adding a Flask class instance into a LoginManager Class instance

I cant find anywhere a good explanation for a beginner what exactly happens when I pass the Flask class instance into the LoginManager class instance from the flask_login module.
app = Flask(__name__)
login_manager = LoginManager(app)
Per my understanding the "app" is an instance of the class Flask. Also login_manager is an instance of the class LoginManager (from another module). How comes, that I can easily pass a whole class into a different (module) class? What exactly happens here?
I found the answer myself.
in the login_manager = LoginManager(app) we have created an instance of the class LoginManager and passed the app class, which is an instance of Flask. The reason behind this is, we can use the methods of the app instance from within the login_manger instance now. Hence we can extend functionalities of the app.
Best was to understand this was to reproduce this in small exercise files.
Here my example:
File 1 (This will serve as example for Flask Module):
class FirstClass:
def _init_(self):
pass
def say_1(self):
print("Hello First Class")
def _repr_(self):
print("hello from first class")
File 2 (This will serve for example of LoginManager Module):
class SecondClass:
def _init_(self, x):
self.x = x
pass
def say_2(self):
print("Hello Second Class")
File 3 (from which we run the app):
from first import FirstClass
from second import SecondClass
one = FirstClass()
two = SecondClass(one)

Flask initialisation for unit test and app

I've got a Flask application which I'd like to run some unit tests on. To do so, I create a new Flask object, initialise blueprints, SQLA and a few other packages and execute the test case.
However, I've noticed that some endpoints on the test flask object are missing, which made me wonder about the general way of how initialisation is handled in flask.
Taking a minimal example, an endpoint would be created like so:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()
If I was to create a new Flask object somewhere in my testcase's setUp method, it would most certainly not contain a route '/' as this route was created from another flask object (the one from the file above). So my question is: How should a test case be written and how is the initialisation meant to work in general? Somewhere I read that one should avoid initialisation at import (i.e. on a module level), but this seems to be impossible if annotations are used.
You don't create a new Flask object in your test cases. You import your existing app instead.
In many project setups you already added all your extensions to that app. In many of mine I have a factory method that'll take a configuration object and returns the fully initialized app object for me; I use this to create a base test case:
import unittest
import project
class Config(object):
DEBUG = False
TESTING = True
CACHE_NO_NULL_WARNING = True # silence Flask-Cache warning
SECRET_KEY = 'SECRET_KEY'
class ProjectCoreViewCase(unittest.TestCase):
"""Base test case for the Project core app"""
def setUp(self, **kwargs):
config = Config()
config.__dict__.update(kwargs)
app = project.create_app(config)
self.app = app.test_client()
and any tests can then use self.app as the test client in all tests.
This is a base test case, you'd inherit from it; the setUp() method allows for additional configuration to be set, by passing in keyword arguments to a super() call:
class ConcreteTestCase(ProjectCoreViewCase):
def setUp(self):
super(ConcreteTestCase, self).setUp(
SQLALCHEMY_DATABASE_URI='your_test_specific_connection_uri',
)

Any good working example for webapp2 using http put method?

I would like to use HTTP PUT method , to send data to my google app engine application, any good example? I can't find any from google.
And my following example also not working.
import webapp2
class MainHandler(webapp2.RequestHandler):
def put(self):
self.response.write('test put')
app = webapp2.WSGIApplication([
(r'/test/(.*)', MainHandler)
], debug=True)
And i got this error.
TypeError: put() takes exactly 1 argument (2 given)
you are passing the put an argument with mapping it like this:
(r'/test/(.*)', MainHandler)
the (.*) passes the put method whatever you use to access this urlpath after /test/.
update your handler like this:
class MainHandler(webapp2.RequestHandler):
def put(self, myarg):
self.response.write('test put, myarg is %s' %myarg)
TypeError: put() takes exactly 1 argument (2 given)
Means that the method 'put' was called with 2 arguments while you specified only 1 (self).
This should work:
class MainHandler(webapp2.RequestHandler):
def put(self, param):
self.response.write('test put')
You can using POST variable from request object
class MainHandler(webapp2.RequestHandler):
def put(self):
self.response.write(self.request.POST)
example usage using curl
curl -X PUT -d"x=1&y=2" http://localhost:8080/add

Categories

Resources