Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
DEVELOPING FLASK EXTENSIONS
Rachel Sanders @ PyTennessee 2014
Rachel Sanders




Engineer at LinkedIn & PyLadiesSF organizer
Our internal stack: Python + Flask
Team lead for a 30K L...
What we talkin’ about







The really really really quick intro to Flask
The really really quick intro to extending...
The really really quick intro to Flask
Like 3 min tops, promise
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello San Dimas High!"
if __name__ == "...
whaaaaaaa?




No database??
No forms?
No admin interface?
“The idea of Flask is to build a
good foundation for all applications.
Everything else is up to you or extensions.”
-- Arm...
All these are extensions




database  SQLAlchemy + Flask-SQLAlchemy
forms  WTForms + FlaskWTF
admin  Flask-Admin
The really quick intro to extending Flask
Like 5 min, promise
from flask import Flask

app = Flask(__name__)
@app.route("/")
def hello():
return "Hello San Dimas High!"
if __name__ == ...
from flask import Flask

app = Flask(__name__)
@app.route("/")
def hello():
return "Hello San Dimas High!"
if __name__ == ...
extending Flask = changing app
You can change the app object by



Hooking into request lifecycle
Adding more resources
 Jinja

filters, tests, global...
Flask-FeatureFlags
with the power to turn code on or off
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello San Dimas High!”
from flask import Flask
import flask_featureflags as feature
app = Flask(__name__)
feature_flag = feature.FeatureFlag(app)...
from flask import Flask
import flask_featureflags as feature
app = Flask(__name__)
feature_flag = feature.FeatureFlag(app)...
from flask import Flask
import flask_featureflags as feature
app = Flask(__name__)
feature_flag = feature.FeatureFlag(app)...
{% if 'pytennesse' is active_feature %}
“Hi PyTennessee!”
{% else %}
“Hello San Dimas High!”
{% endif %}
FEATURE FLAG SPEC


feature flags stored in config



Jinja template test called “active_feature”



Module function ca...
bit.ly/giantwallofcode
class FeatureFlags(object):
class FeatureFlags(object):
def __init__(self, app=None):
class FeatureFlags(object):
def __init__(self, app=None):
if app is not None:
self.init_app(app)
def init_app(self, app):
class FeatureFlags(object):
def __init__(self, app=None):
if app is not None:
self.init_app(app)
def init_app(self, app):
...
from flask import current_app
class FeatureFlags(object):
def __init__(self, app=None):
if app is not None:
self.init_app(...
FEATURE FLAGS SPEC


feature flags stored in config



Jinja template test



is_active function
{% if 'pytennesse' is active_feature %}
“Hi PyTennessee!”
{% else %}
“Hello San Dimas High!”
{% endif %}
from flask import current_app
class FeatureFlags(object):

def __init__(self, app=None):
if app is not None:
self.init_app...
class FeatureFlags(object):
def __init__(self, app=None):
if app is not None:
self.init_app(app)
def init_app(self, app):
...
FEATURE FLAGS SPEC


feature flags stored in config



Jinja template test



is_active function
from flask import Flask
import flask_featureflags as feature
app = Flask(__name__)
feature_flag = feature.FeatureFlag(app)...
class FeatureFlags(object):
def __init__(self, app=None):
if app is not None:
self.init_app(app)
def init_app(self, app):
...
from flask import current_app
def is_active(feature):
feature_flagger = current_app.extensions['FeatureFlags']
return feat...
FEATURE FLAGS SPEC


feature flags stored in config



Jinja template test



is_active function
ok so what’d we learn?







use init_app because app factories
be sure to set config defaults
calling Flask hooks
0...
Beyond the basics
ok what now lady
Flask-DebugToolbar
http://flask-debugtoolbar.readthedocs.org/
other great extensions




Flask-SeaSurf – request processing, cookies
Flask-Admin – SQLAlchemy, blueprints, static fil...
thanks everybody!




@trustrachel
github.com/trustrachel
trustrachel.com
Developing Flask Extensions
Developing Flask Extensions
Developing Flask Extensions
Developing Flask Extensions
Developing Flask Extensions
Developing Flask Extensions
Developing Flask Extensions
Developing Flask Extensions
Upcoming SlideShare
Loading in …5
×

Developing Flask Extensions

1,436 views

Published on

Talk given at PyTennessee on 2014. Download the original for all the speaker notes.

Published in: Technology
  • Be the first to comment

Developing Flask Extensions

  1. 1. DEVELOPING FLASK EXTENSIONS Rachel Sanders @ PyTennessee 2014
  2. 2. Rachel Sanders    Engineer at LinkedIn & PyLadiesSF organizer Our internal stack: Python + Flask Team lead for a 30K LOC Flask app
  3. 3. What we talkin’ about      The really really really quick intro to Flask The really really quick intro to extending Flask Flask-FeatureFlags: a case study Beyond the Basics Questions
  4. 4. The really really quick intro to Flask Like 3 min tops, promise
  5. 5. from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "Hello San Dimas High!" if __name__ == "__main__": app.run()
  6. 6. whaaaaaaa?    No database?? No forms? No admin interface?
  7. 7. “The idea of Flask is to build a good foundation for all applications. Everything else is up to you or extensions.” -- Armin Ronacher, creator of Flask
  8. 8. All these are extensions    database  SQLAlchemy + Flask-SQLAlchemy forms  WTForms + FlaskWTF admin  Flask-Admin
  9. 9. The really quick intro to extending Flask Like 5 min, promise
  10. 10. from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "Hello San Dimas High!" if __name__ == "__main__": app.run()
  11. 11. from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "Hello San Dimas High!" if __name__ == "__main__": app.run()
  12. 12. extending Flask = changing app
  13. 13. You can change the app object by   Hooking into request lifecycle Adding more resources  Jinja filters, tests, global variables  Routes, blueprints, static files   Middleware Monkeypatching
  14. 14. Flask-FeatureFlags with the power to turn code on or off
  15. 15. from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "Hello San Dimas High!”
  16. 16. from flask import Flask import flask_featureflags as feature app = Flask(__name__) feature_flag = feature.FeatureFlag(app) @app.route("/") def hello(): return "Hello San Dimas High!"
  17. 17. from flask import Flask import flask_featureflags as feature app = Flask(__name__) feature_flag = feature.FeatureFlag(app) @app.route("/") def hello(): if feature.is_active('pytennessee'): return "Hello PyTennessee!" else: return "Hello San Dimas High!"
  18. 18. from flask import Flask import flask_featureflags as feature app = Flask(__name__) feature_flag = feature.FeatureFlag(app) app.config['FEATURE_FLAGS']['pytennessee'] = True @app.route("/") def hello(): if feature.is_active('pytennessee'): return "Hello PyTennessee!" else: return "Hello San Dimas High!"
  19. 19. {% if 'pytennesse' is active_feature %} “Hi PyTennessee!” {% else %} “Hello San Dimas High!” {% endif %}
  20. 20. FEATURE FLAG SPEC  feature flags stored in config  Jinja template test called “active_feature”  Module function called “is_active”
  21. 21. bit.ly/giantwallofcode
  22. 22. class FeatureFlags(object):
  23. 23. class FeatureFlags(object): def __init__(self, app=None):
  24. 24. class FeatureFlags(object): def __init__(self, app=None): if app is not None: self.init_app(app) def init_app(self, app):
  25. 25. class FeatureFlags(object): def __init__(self, app=None): if app is not None: self.init_app(app) def init_app(self, app): app.config.setdefault('FEATURE_FLAGS’, {})
  26. 26. from flask import current_app class FeatureFlags(object): def __init__(self, app=None): if app is not None: self.init_app(app) def init_app(self, app): app.config.setdefault('FEATURE_FLAGS’, {}) def in_config(self, feature): try: return current_app.config['FEATURE_FLAGS'][feature] except (AttributeError, KeyError): return False
  27. 27. FEATURE FLAGS SPEC  feature flags stored in config  Jinja template test  is_active function
  28. 28. {% if 'pytennesse' is active_feature %} “Hi PyTennessee!” {% else %} “Hello San Dimas High!” {% endif %}
  29. 29. from flask import current_app class FeatureFlags(object): def __init__(self, app=None): if app is not None: self.init_app(app) def init_app(self, app): app.config.setdefault('FEATURE_FLAGS’, {}) app.add_template_test(self.in_config, name=’active_feature’) def in_config(self, feature): try: return current_app.config['FEATURE_FLAGS'][feature] except (AttributeError, KeyError): return False
  30. 30. class FeatureFlags(object): def __init__(self, app=None): if app is not None: self.init_app(app) def init_app(self, app): app.config.setdefault('FEATURE_FLAGS’, {}) if hasattr(app, "add_template_test"): app.add_template_test(self.in_config, name='active_feature') else: app.jinja_env.tests[’active_feature’] = self.in_config
  31. 31. FEATURE FLAGS SPEC  feature flags stored in config  Jinja template test  is_active function
  32. 32. from flask import Flask import flask_featureflags as feature app = Flask(__name__) feature_flag = feature.FeatureFlag(app) app.config['FEATURE_FLAGS']['pytennessee'] = True @app.route("/") def hello(): if feature.is_active('pytennessee'): return "Hello PyTennessee!" else: return "Hello San Dimas High!"
  33. 33. class FeatureFlags(object): def __init__(self, app=None): if app is not None: self.init_app(app) def init_app(self, app): app.config.setdefault('FEATURE_FLAGS’, {}) if hasattr(app, "add_template_test"): app.add_template_test(self.in_config, name='active_feature') else: app.jinja_env.tests[’active_feature’] = self.in_config app.extensions['FeatureFlags'] = self
  34. 34. from flask import current_app def is_active(feature): feature_flagger = current_app.extensions['FeatureFlags'] return feature_flagger.in_config(feature)
  35. 35. FEATURE FLAGS SPEC  feature flags stored in config  Jinja template test  is_active function
  36. 36. ok so what’d we learn?      use init_app because app factories be sure to set config defaults calling Flask hooks 0.10+ is a trap how to get to our extension later
  37. 37. Beyond the basics ok what now lady
  38. 38. Flask-DebugToolbar http://flask-debugtoolbar.readthedocs.org/
  39. 39. other great extensions    Flask-SeaSurf – request processing, cookies Flask-Admin – SQLAlchemy, blueprints, static files Flask-Classy – adds class-based views
  40. 40. thanks everybody!    @trustrachel github.com/trustrachel trustrachel.com

×