Encapsulate flask api in class for testing purposes - python

I have built flask apis in the past, but I've never had the luxury of being on a project where I was allowed to do test driven development while working on one. Now I am.
Every how-to I've ever read shows flask-apis being defined in a decidedly non-object-oriented style. This makes writing unit tests very difficult because one cannot pass optional or test-specific parameters into the instantiated api.
For example, this blog explains one method for creating unit tests for a flask-api:
http://mkelsey.com/2013/05/15/test-driven-development-of-a-flask-api/
The blog sets an environment variable when in test mode and the script watches for that variable, altering its behavior when it is found. This seems very inadvisable to me. There are a long list of reasons why letting your source code bleed into your OS environment is a Bad Idea. I'm a big believer in encapsulating functionality in order to maximize portability and to draw clear distinctions between where modules begin and end.
In order to satisfy my coding philosophy someone might suggest I just wrap the flask API up in a class. However, it isn't clear to me how one would do such a thing. For example, Flask uses decorators in order to define a route:
#app.route()
How could this be fit into a class?
I would greatly appreciate the guidance of anyone who has developed a flask api in an object oriented manner.

You can replace the use of #app.route with add_url_rule.
To put it in an example:
from flask import Flask
class MyFlaskApp:
def __init__(self):
self.app = Flask(__name__)
self.app.add_url_rule('/', 'index', self.index)
def index(self):
pass
Which is similar to:
from flask import Flask
app = Flask(__name__)
#app.route('/index')
def index():
pass

Related

Accessing Pyramid Settings throughout the program

I have a pyramid API which has basically three layers.
View -> validates the request and response
Controller -> Does business logic and retrieves things from the DB.
Services -> Makes calls to external third party services.
The services are a class for each external API which will have things like authentication data. This should be a class attribute as it does not change per instance. However, I cannot work out how to make it a class attribute.
Instead I extract the settings in the view request.registry.settings pass it to the controller which then passes it down in the init() for the service. This seems unnecessary.
Obviously I could hard code them in code but that's an awful idea.
Is there a better way?
Pyramid itself does not use global variables, which is what you are asking for when you ask for settings to be available in class-level or module-level attributes. For instance-level stuff, you can just pass the settings from Pyramid into the instance either from the view or from the config.
To get around this, you can always pass data into your models at config-time for your Pyramid app. For example, in your main just pull settings = config.get_settings() and pass some of them to where they need to be. As a general rule, you want to try to pass things around at config-time once, instead of from the view layer all the time.
Finally, a good way to do that without using class-level or module-level attributes is to register instances of your services with your app. pyramid_services library provides one approach to this, but the idea is basically to instantiate an instance of a service for your app, add it to your pyramid registry config.registry.foo = ... and when you do that you can pass in the settings. Later in your view code you can grab the service from there using request.registry.foo and it's already setup for you!

How to call a app function from a Flask blueprint

I want to move some commonly used parts of my webapps to Flask blueprints for better reuse. But some of the routes will need functionality which is specific to a webapp. An example would be a simple form submission where everything is handled by the blueprint, only the form validation would have to be defined by the implementing app.
How can I tell a blueprint view to call a function of the app. With inheritance I would create a abstract function which would be filled out by them implementing webapp. But I am lost how to do something similar with a blueprint.
Edit:
I am using Class based views, but the following snippet trys to explain what I am looking for:
#my_blueprint.route('/submit')
def submit():
errors = current_app.check_for_errors(request.form) # <--- How to?
return render_template('result.html', errors=error)
The errors = current_app.check_for_errors(request.form) is the one I don't know ho to implement. Sub-classing flask.Flask is the only way I can come up with, but this doesn't feel right.

Is it safe to execute another script from a protected route in Flask?

I've read about blueprints in Flask but I think my app is too small to use it yet. However I would like to keep my code clear. Since my app has a user login I would like to keep several functions protected. Now I'm wondering if the following code is as safe as putting all the code into a route or is that not proper coding?
import scriptwithseveralfunctions.py
#app.route('/functionone')
#login_required
def do_something():
scriptwithseveralfunctions.myfunction()
Yes, it's definitely safe. Only functions with #app.route wrapper will be exposed to the user.

What are Flask Blueprints, exactly?

I have read the official Flask documentation on Blueprints and even one or two blog posts on using them.
I've even used them in my web app, but I don't completely understand what they are or how they fit into my app as a whole. How is it similar to an instance of my app but not quite? The documentation is comprehensive but I seek a layman explanation or an enlightening analogy to spark it for me. I was sufficiently perplexed when a colleague asked me to explain a Flask blueprint to them that I elected to ask here.
A blueprint is a template for generating a "section" of a web application. You can think of it as a mold:
You can take the blueprint and apply it to your application in several places. Each time you apply it the blueprint will create a new version of its structure in the plaster of your application.
# An example
from flask import Blueprint
tree_mold = Blueprint("mold", __name__)
#tree_mold.route("/leaves")
def leaves():
return "This tree has leaves"
#tree_mold.route("/roots")
def roots():
return "And roots as well"
#tree_mold.route("/rings")
#tree_mold.route("/rings/<int:year>")
def rings(year=None):
return "Looking at the rings for {year}".format(year=year)
This is a simple mold for working with trees - it says that any application that deals with trees should provide access to its leaves, its roots, and its rings (by year). By itself, it is a hollow shell - it cannot route, it cannot respond, until it is impressed upon an application:
from tree_workshop import tree_mold
app.register_blueprint(tree_mold, url_prefix="/oak")
app.register_blueprint(tree_mold, url_prefix="/fir")
app.register_blueprint(tree_mold, url_prefix="/ash")
Once it is created it may be "impressed" on the application by using the register_blueprint function - this "impresses" the mold of the blueprint on the application at the locations specified by url_prefix.
As pointed out in a comment by #Devasish, this article provides a good answer:
http://exploreflask.com/en/latest/blueprints.html
Quoting from the article:
An example of this would be Facebook. If Facebook used Flask, it might
have blueprints for the static pages (i.e. signed-out home, register,
about, etc.), the dashboard (i.e. the news feed), profiles
(/robert/about and /robert/photos), settings (/settings/security and
/settings/privacy) and many more. These components all share a general
layout and styles, but each has its own layout as well
This is a very good interpretation, especially the part "if Facebook used Flask". It gives us a concrete situation to visualize how Blueprint actually works.
For bigger projects, all your code shouldn't be in the same file.
Instead you can segment or split bigger codes into separate files, mostly based on functionality. Like bricks forming a wall.
A simple Flask app
app = Flask(__name__)
A blueprinted Flask app
import from_any_module.part_1
import from_other_module.part_2
app = Flask(__name__)
app.register_blueprint(part_1)
app.register_blueprint(part_2)
A blueprint in the above app
from flask import Blueprint
part_1 = Blueprint(part_1)
#part_1.route('/url')
def function()
return view
I too just stumbled up this myself and was confused after reading a few of the documentation sources. At first I thought it was like C#/Java OOP Interface Implementation style where you define some stuff but dont have to worry about it implementation details til later. However, I stumbled up this page which puts it in very very laymens (and quite hilarious present-day events) terms. https://hackersandslackers.com/flask-blueprints/
Essentially one benefit that is mentioned in the link and provides me a clear idea of it's real world usage is that I can effectively logically organize/divide the app into several parts that only need to be concerned with it's own affairs. So it provides some designed encapsulation.
Edit: I'm currently using it to segment out my webapps code. It was good decision too because I found the lead designer wants to make the frontend in Vue.js. Which I havent used yet but looking at it's project files would look far more messy and probably provide many naming collision prone instances due to files with similar names
A Flask blueprint helps you to create reusable instances of your application. It does so by organizing your project in modules. Those modules are then registered the main application. They help in creating an application factory.

Sharing objects between applications

I am trying to share an object between two GAE apps. The first will have the class's file, and will offer up an instance of that object. The second, using a given url, will access the first app, get the object and then use is. Is this actually possible? If so what am I not doing right in the code below?
As a small side note I tried a solution with pickle, but both apps are required to have the class in its name space, but I will be working with a number of these. I thought about trying to imitate something like Java's abstract class by using inheritance, but that didn't work out. I can provide that code too if you want to see it.
I understand the possible Terms of Service, that is not a issue.
I know cloud computing is out there, I don't know how to work with it, and I would
prefer to avoid the costs because I am developing this as a class project.
I have seen some suggestions to use remote_api, but I have seen no good example
of how it can be used, let alone used to allow two applications to interact.
I have seen the solution to use multiple versions, but each student will have
an app, it would be incredibly messy, but possibly doable.
First.Py:
class SampleCritter():
def move():
...
class Access(webapp2.RequestHandler):
def post(self):
CritStore(stats=self.request.body).put()
def get(self):
creature = CritStore.all().order('-date').get()
if creature:
stats = loads(creature.stats)
return SampleCritter(stats)
else:
return SampleCritter()
Second.py:
class Out(webapp2.RequestHandler):
def post(self):
url = self.request.POST['url']
critter = urllib2.urlopen(url)
critter.move()
The short answer is, you can't share objects between apps.
The longer answer is, your first app can expose objects using an HTTP based API. Any client can access the HTTP API, including app 2.
App 2 will have to manipulate objects via the HTTP API. You won't be able to call critter.move() from app 2, though if you create a handler say, critter\move, you can have the handler pull up the appropriate Critter instance and call move() on it. You'll have to pass all the appropriate params via HTTP POST as well.

Categories