SlideShare a Scribd company logo
Flask? No thanks!
by Alexey Popravka
About me
● 6+ years of Python
● Python developer / Tech Lead at Prom.ua
● Contributor of github.com/aio-libs
● github.com/popravich
What this talk is about?
● What is Flask
● What Flask is not (what is wrong)
● Alternatives
● Questions
What is Flask
“Flask is a microframework for Python based on
Werkzeug, Jinja 2 and good intentions.”
What is Flask
“Flask is a microframework for Python based on
Werkzeug, Jinja 2 and good intentions.”
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()
What is Flask
● Jinja2 templates out of the box
from flask import render_template
@app.route('/hello/')
@app.route('/hello/<name>')
def hello(name=None):
return render_template('hello.html', name=name)
<!doctype html>
<title>Hello from Flask</title>
{% if name %}
<h1>Hello {{ name }}!</h1>
{% else %}
<h1>Hello World!</h1>
{% endif %}
What is Flask
● Jinja2 templates
● Sessions
from flask import Flask, session, escape
app = Flask(__name__)
@app.route('/')
def index():
if 'username' in session:
return 'Logged in as %s' % escape(session['username'])
return 'You are not logged in'
What is Flask
● Jinja2 templates
● Sessions
● Static files serving
url_for('static', filename='style.css')
What is Flask
● Jinja2 templates
● Sessions
● Static files serving
● Debugger
app.run(debug=True)
What is Flask
● Jinja2 templates
● Sessions
● Static files serving
● Debugger
● Many extensions
$ pip search flask | wc -l
1020
What is wrong with: routes
● Preferred way – using decorator
# app/view.py
@app.route('/')
def index():
return “Hello world”
bp = Blueprint()
@bp.route('/')
def hello():
return “Hello world”
What is wrong with: routes
● Preferred way – using decorator
# proj/view.py
from proj import app
@app.route('/')
def index():
return “Hello world”
Must have application instance ->
# proj/__init__.py
from flask import Flask
app = Flask('proj')
We begin with already runnable app.
But, wait!
* Did we have time to configure it?
* Did we have time to configure something else (DB, etc)?
What is wrong with: routes
● Preferred way – using decorator?
# proj/view.py
from proj import app
if app.debug:
@app.route('/docs/')
def show_some_docs():
pass
How to control? ->
What is wrong with: composite apps
Say you need several apps not messing their
code:
# proj/app/__init__.py
from flask import Flask
app = Flask('proj.app')
@app.route('/')
def index():
return render_template(
'index.html')
# proj/admin/__init__.py
from flask import Flask
app = Flask('proj.admin')
@app.route('/')
def index():
return render_template(
'admin_index.html')
What is wrong with: composite apps
How to reuse apps' URLs?
# proj/admin/__init__.py
from flask import Flask
from flask import url_for
app = Flask('proj.admin')
@app.route('/')
def index():
url_for('app.index') #???
return render_template(
'admin_index.html')
??? ->
* Blueprints can help, but application must be only one
What is wrong with: jinja
Abused!
from celery import Celery
from flask import render_template
celery_app = Celery()
@celery_app.task
def send_periodic_email():
to = get_address()
html_body = render_template('mails/annoy.html')
send_mail(to, html_body)
Web Worker == Celery Worker
What is wrong with: global vars
● Magical request object
thread-local proxy object
from celery import Celery
from flask import render_template, session
celery_app = Celery()
@celery_app.task
def send_periodic_email():
to = get_address()
user_name = session['user_name']
html_body = render_template(
'mails/annoy.html',
{user_name: user_name})
send_mail(to, html_body)
Need request instance ->
What is wrong with: global vars
● Magical request object
from flask import Flask, request
from proj.db import session
from proj.redis import redis
# ... import other global instance
app = Flask()
@app.route('/')
def index():
uid = redis.get(request.cookies.get('cid'))
user_row = session.execute(“select * from ...”)
# ...
Alternatives
● Enough using WSGI, start using asyncio/aiohttp
Alternatives
● Can't cope asyncio? At least try using Flask
less self-destructive:
– Get rid of app.route decorator
def index():
return “Hello world”
# ... more views
def setup_routes(app):
app.add_url_rule('/', 'index', index)
app.add_url_rule(...)
from flask import Flask
from . import views
def main():
app = Flask()
views.setup_routes(app)
# more configuration
Alternatives
● Can't cope asyncio? At least try using Flask
less self-destructive:
– Use any kind of dependencies instead of global
(thread-local proxy) variables:
from flask import Flask, current_app
class MyApp:
def __init__(self, *args, redis, db_conn **kw):
super().__init__(*args, **kw)
self.redis = redis
self.db_conn = db_conn
def get_user_view():
redis = current_app.redis
....
Alternatives
● Still want to use Flask — use Werkzeug!
The End
Questions?
What Flask is not — it is not “micro framework” it is a “Werkzeug wrapper”

More Related Content

What's hot

Flask Introduction - Python Meetup
Flask Introduction - Python MeetupFlask Introduction - Python Meetup
Flask Introduction - Python Meetup
Areski Belaid
 
Flask RESTful Flask HTTPAuth
Flask RESTful Flask HTTPAuthFlask RESTful Flask HTTPAuth
Flask RESTful Flask HTTPAuth
Eueung Mulyana
 
Flask SQLAlchemy
Flask SQLAlchemy Flask SQLAlchemy
Flask SQLAlchemy
Eueung Mulyana
 
Laravel Design Patterns
Laravel Design PatternsLaravel Design Patterns
Laravel Design Patterns
Bobby Bouwmann
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
Elena Kolevska
 
Getting Started-with-Laravel
Getting Started-with-LaravelGetting Started-with-Laravel
Getting Started-with-Laravel
Mindfire Solutions
 
Php Unit With Zend Framework Zendcon09
Php Unit With Zend Framework   Zendcon09Php Unit With Zend Framework   Zendcon09
Php Unit With Zend Framework Zendcon09
Michelangelo van Dam
 
Learn flask in 90mins
Learn flask in 90minsLearn flask in 90mins
Learn flask in 90mins
Larry Cai
 
#30.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#30.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...#30.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#30.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
탑크리에듀(구로디지털단지역3번출구 2분거리)
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8
Michelangelo van Dam
 
Laravel 5 In Depth
Laravel 5 In DepthLaravel 5 In Depth
Laravel 5 In Depth
Kirk Bushell
 
Laravel 101
Laravel 101Laravel 101
Laravel 101
Commit University
 
Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friends
Michael Peacock
 
Flask restfulservices
Flask restfulservicesFlask restfulservices
Flask restfulservices
Marcos Lin
 
REST APIs in Laravel 101
REST APIs in Laravel 101REST APIs in Laravel 101
REST APIs in Laravel 101
Samantha Geitz
 
What happens in laravel 4 bootstraping
What happens in laravel 4 bootstrapingWhat happens in laravel 4 bootstraping
What happens in laravel 4 bootstraping
Jace Ju
 
Phinx talk
Phinx talkPhinx talk
Phinx talk
Michael Peacock
 
Laravel 5
Laravel 5Laravel 5
Laravel 5
Sudip Simkhada
 
#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
탑크리에듀(구로디지털단지역3번출구 2분거리)
 
Dance for the puppet master: G6 Tech Talk
Dance for the puppet master: G6 Tech TalkDance for the puppet master: G6 Tech Talk
Dance for the puppet master: G6 Tech Talk
Michael Peacock
 

What's hot (20)

Flask Introduction - Python Meetup
Flask Introduction - Python MeetupFlask Introduction - Python Meetup
Flask Introduction - Python Meetup
 
Flask RESTful Flask HTTPAuth
Flask RESTful Flask HTTPAuthFlask RESTful Flask HTTPAuth
Flask RESTful Flask HTTPAuth
 
Flask SQLAlchemy
Flask SQLAlchemy Flask SQLAlchemy
Flask SQLAlchemy
 
Laravel Design Patterns
Laravel Design PatternsLaravel Design Patterns
Laravel Design Patterns
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
 
Getting Started-with-Laravel
Getting Started-with-LaravelGetting Started-with-Laravel
Getting Started-with-Laravel
 
Php Unit With Zend Framework Zendcon09
Php Unit With Zend Framework   Zendcon09Php Unit With Zend Framework   Zendcon09
Php Unit With Zend Framework Zendcon09
 
Learn flask in 90mins
Learn flask in 90minsLearn flask in 90mins
Learn flask in 90mins
 
#30.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#30.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...#30.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#30.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8
 
Laravel 5 In Depth
Laravel 5 In DepthLaravel 5 In Depth
Laravel 5 In Depth
 
Laravel 101
Laravel 101Laravel 101
Laravel 101
 
Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friends
 
Flask restfulservices
Flask restfulservicesFlask restfulservices
Flask restfulservices
 
REST APIs in Laravel 101
REST APIs in Laravel 101REST APIs in Laravel 101
REST APIs in Laravel 101
 
What happens in laravel 4 bootstraping
What happens in laravel 4 bootstrapingWhat happens in laravel 4 bootstraping
What happens in laravel 4 bootstraping
 
Phinx talk
Phinx talkPhinx talk
Phinx talk
 
Laravel 5
Laravel 5Laravel 5
Laravel 5
 
#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
 
Dance for the puppet master: G6 Tech Talk
Dance for the puppet master: G6 Tech TalkDance for the puppet master: G6 Tech Talk
Dance for the puppet master: G6 Tech Talk
 

Similar to Kyiv.py #17 Flask talk

Developing Flask Extensions
Developing Flask ExtensionsDeveloping Flask Extensions
Developing Flask Extensions
Rachel Sanders
 
Plack - LPW 2009
Plack - LPW 2009Plack - LPW 2009
Plack - LPW 2009
Tatsuhiko Miyagawa
 
Psgi Plack Sfpm
Psgi Plack SfpmPsgi Plack Sfpm
Psgi Plack Sfpm
som_nangia
 
Psgi Plack Sfpm
Psgi Plack SfpmPsgi Plack Sfpm
Psgi Plack Sfpm
wilburlo
 
Flask-RESTPlusで便利なREST API開発 | Productive RESTful API development with Flask-...
Flask-RESTPlusで便利なREST API開発 | Productive RESTful API development with Flask-...Flask-RESTPlusで便利なREST API開発 | Productive RESTful API development with Flask-...
Flask-RESTPlusで便利なREST API開発 | Productive RESTful API development with Flask-...
Akira Tsuruda
 
React django
React djangoReact django
React django
Heber Silva
 
Python para web - Utilizando micro-framework Flask - PUG-MA
Python para web - Utilizando micro-framework Flask - PUG-MAPython para web - Utilizando micro-framework Flask - PUG-MA
Python para web - Utilizando micro-framework Flask - PUG-MA
Herson Leite
 
What The Flask? and how to use it with some Google APIs
What The Flask? and how to use it with some Google APIsWhat The Flask? and how to use it with some Google APIs
What The Flask? and how to use it with some Google APIs
Bruno Rocha
 
Lean Php Presentation
Lean Php PresentationLean Php Presentation
Lean Php Presentation
Alan Pinstein
 
Intro to PSGI and Plack
Intro to PSGI and PlackIntro to PSGI and Plack
Intro to PSGI and Plack
Tatsuhiko Miyagawa
 
Incredible Machine with Pipelines and Generators
Incredible Machine with Pipelines and GeneratorsIncredible Machine with Pipelines and Generators
Incredible Machine with Pipelines and Generators
dantleech
 
Don't worry be API with Slim framework and Joomla
Don't worry be API with Slim framework and JoomlaDon't worry be API with Slim framework and Joomla
Don't worry be API with Slim framework and Joomla
Pierre-André Vullioud
 
Collaboration hack with slackbot - PyCon HK 2018 - 2018.11.24
Collaboration hack with slackbot - PyCon HK 2018 - 2018.11.24Collaboration hack with slackbot - PyCon HK 2018 - 2018.11.24
Collaboration hack with slackbot - PyCon HK 2018 - 2018.11.24
Kei IWASAKI
 
Creating Sentiment Line Chart with Watson
Creating Sentiment Line Chart with Watson Creating Sentiment Line Chart with Watson
Creating Sentiment Line Chart with Watson
Dev_Events
 
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010
singingfish
 
MobileConf 2021 Slides: Let's build macOS CLI Utilities using Swift
MobileConf 2021 Slides:  Let's build macOS CLI Utilities using SwiftMobileConf 2021 Slides:  Let's build macOS CLI Utilities using Swift
MobileConf 2021 Slides: Let's build macOS CLI Utilities using Swift
Diego Freniche Brito
 
Plack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and serversPlack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and servers
Tatsuhiko Miyagawa
 
ParisJS #10 : RequireJS
ParisJS #10 : RequireJSParisJS #10 : RequireJS
ParisJS #10 : RequireJS
Julien Cabanès
 
You've done the Django Tutorial, what next?
You've done the Django Tutorial, what next?You've done the Django Tutorial, what next?
You've done the Django Tutorial, what next?
Andy McKay
 
Ecto and Phoenix: Doing web with Elixir - Yurii Bodarev
Ecto and Phoenix: Doing web with Elixir - Yurii BodarevEcto and Phoenix: Doing web with Elixir - Yurii Bodarev
Ecto and Phoenix: Doing web with Elixir - Yurii Bodarev
Elixir Club
 

Similar to Kyiv.py #17 Flask talk (20)

Developing Flask Extensions
Developing Flask ExtensionsDeveloping Flask Extensions
Developing Flask Extensions
 
Plack - LPW 2009
Plack - LPW 2009Plack - LPW 2009
Plack - LPW 2009
 
Psgi Plack Sfpm
Psgi Plack SfpmPsgi Plack Sfpm
Psgi Plack Sfpm
 
Psgi Plack Sfpm
Psgi Plack SfpmPsgi Plack Sfpm
Psgi Plack Sfpm
 
Flask-RESTPlusで便利なREST API開発 | Productive RESTful API development with Flask-...
Flask-RESTPlusで便利なREST API開発 | Productive RESTful API development with Flask-...Flask-RESTPlusで便利なREST API開発 | Productive RESTful API development with Flask-...
Flask-RESTPlusで便利なREST API開発 | Productive RESTful API development with Flask-...
 
React django
React djangoReact django
React django
 
Python para web - Utilizando micro-framework Flask - PUG-MA
Python para web - Utilizando micro-framework Flask - PUG-MAPython para web - Utilizando micro-framework Flask - PUG-MA
Python para web - Utilizando micro-framework Flask - PUG-MA
 
What The Flask? and how to use it with some Google APIs
What The Flask? and how to use it with some Google APIsWhat The Flask? and how to use it with some Google APIs
What The Flask? and how to use it with some Google APIs
 
Lean Php Presentation
Lean Php PresentationLean Php Presentation
Lean Php Presentation
 
Intro to PSGI and Plack
Intro to PSGI and PlackIntro to PSGI and Plack
Intro to PSGI and Plack
 
Incredible Machine with Pipelines and Generators
Incredible Machine with Pipelines and GeneratorsIncredible Machine with Pipelines and Generators
Incredible Machine with Pipelines and Generators
 
Don't worry be API with Slim framework and Joomla
Don't worry be API with Slim framework and JoomlaDon't worry be API with Slim framework and Joomla
Don't worry be API with Slim framework and Joomla
 
Collaboration hack with slackbot - PyCon HK 2018 - 2018.11.24
Collaboration hack with slackbot - PyCon HK 2018 - 2018.11.24Collaboration hack with slackbot - PyCon HK 2018 - 2018.11.24
Collaboration hack with slackbot - PyCon HK 2018 - 2018.11.24
 
Creating Sentiment Line Chart with Watson
Creating Sentiment Line Chart with Watson Creating Sentiment Line Chart with Watson
Creating Sentiment Line Chart with Watson
 
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010
 
MobileConf 2021 Slides: Let's build macOS CLI Utilities using Swift
MobileConf 2021 Slides:  Let's build macOS CLI Utilities using SwiftMobileConf 2021 Slides:  Let's build macOS CLI Utilities using Swift
MobileConf 2021 Slides: Let's build macOS CLI Utilities using Swift
 
Plack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and serversPlack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and servers
 
ParisJS #10 : RequireJS
ParisJS #10 : RequireJSParisJS #10 : RequireJS
ParisJS #10 : RequireJS
 
You've done the Django Tutorial, what next?
You've done the Django Tutorial, what next?You've done the Django Tutorial, what next?
You've done the Django Tutorial, what next?
 
Ecto and Phoenix: Doing web with Elixir - Yurii Bodarev
Ecto and Phoenix: Doing web with Elixir - Yurii BodarevEcto and Phoenix: Doing web with Elixir - Yurii Bodarev
Ecto and Phoenix: Doing web with Elixir - Yurii Bodarev
 

Recently uploaded

HijackLoader Evolution: Interactive Process Hollowing
HijackLoader Evolution: Interactive Process HollowingHijackLoader Evolution: Interactive Process Hollowing
HijackLoader Evolution: Interactive Process Hollowing
Donato Onofri
 
快速办理(Vic毕业证书)惠灵顿维多利亚大学毕业证完成信一模一样
快速办理(Vic毕业证书)惠灵顿维多利亚大学毕业证完成信一模一样快速办理(Vic毕业证书)惠灵顿维多利亚大学毕业证完成信一模一样
快速办理(Vic毕业证书)惠灵顿维多利亚大学毕业证完成信一模一样
3a0sd7z3
 
怎么办理(umiami毕业证书)美国迈阿密大学毕业证文凭证书实拍图原版一模一样
怎么办理(umiami毕业证书)美国迈阿密大学毕业证文凭证书实拍图原版一模一样怎么办理(umiami毕业证书)美国迈阿密大学毕业证文凭证书实拍图原版一模一样
怎么办理(umiami毕业证书)美国迈阿密大学毕业证文凭证书实拍图原版一模一样
rtunex8r
 
Discover the benefits of outsourcing SEO to India
Discover the benefits of outsourcing SEO to IndiaDiscover the benefits of outsourcing SEO to India
Discover the benefits of outsourcing SEO to India
davidjhones387
 
manuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal
manuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalmanuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal
manuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal
wolfsoftcompanyco
 
快速办理(新加坡SMU毕业证书)新加坡管理大学毕业证文凭证书一模一样
快速办理(新加坡SMU毕业证书)新加坡管理大学毕业证文凭证书一模一样快速办理(新加坡SMU毕业证书)新加坡管理大学毕业证文凭证书一模一样
快速办理(新加坡SMU毕业证书)新加坡管理大学毕业证文凭证书一模一样
3a0sd7z3
 
Ready to Unlock the Power of Blockchain!
Ready to Unlock the Power of Blockchain!Ready to Unlock the Power of Blockchain!
Ready to Unlock the Power of Blockchain!
Toptal Tech
 
Should Repositories Participate in the Fediverse?
Should Repositories Participate in the Fediverse?Should Repositories Participate in the Fediverse?
Should Repositories Participate in the Fediverse?
Paul Walk
 
Bengaluru Dreamin' 24 - Personal Branding
Bengaluru Dreamin' 24 - Personal BrandingBengaluru Dreamin' 24 - Personal Branding
Bengaluru Dreamin' 24 - Personal Branding
Tarandeep Singh
 
留学挂科(UofM毕业证)明尼苏达大学毕业证成绩单复刻办理
留学挂科(UofM毕业证)明尼苏达大学毕业证成绩单复刻办理留学挂科(UofM毕业证)明尼苏达大学毕业证成绩单复刻办理
留学挂科(UofM毕业证)明尼苏达大学毕业证成绩单复刻办理
uehowe
 
成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理
成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理
成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理
ysasp1
 
存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理
存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理
存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理
fovkoyb
 
一比一原版(USYD毕业证)悉尼大学毕业证如何办理
一比一原版(USYD毕业证)悉尼大学毕业证如何办理一比一原版(USYD毕业证)悉尼大学毕业证如何办理
一比一原版(USYD毕业证)悉尼大学毕业证如何办理
k4ncd0z
 
办理新西兰奥克兰大学毕业证学位证书范本原版一模一样
办理新西兰奥克兰大学毕业证学位证书范本原版一模一样办理新西兰奥克兰大学毕业证学位证书范本原版一模一样
办理新西兰奥克兰大学毕业证学位证书范本原版一模一样
xjq03c34
 
办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
uehowe
 
办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理
办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理
办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理
uehowe
 

Recently uploaded (16)

HijackLoader Evolution: Interactive Process Hollowing
HijackLoader Evolution: Interactive Process HollowingHijackLoader Evolution: Interactive Process Hollowing
HijackLoader Evolution: Interactive Process Hollowing
 
快速办理(Vic毕业证书)惠灵顿维多利亚大学毕业证完成信一模一样
快速办理(Vic毕业证书)惠灵顿维多利亚大学毕业证完成信一模一样快速办理(Vic毕业证书)惠灵顿维多利亚大学毕业证完成信一模一样
快速办理(Vic毕业证书)惠灵顿维多利亚大学毕业证完成信一模一样
 
怎么办理(umiami毕业证书)美国迈阿密大学毕业证文凭证书实拍图原版一模一样
怎么办理(umiami毕业证书)美国迈阿密大学毕业证文凭证书实拍图原版一模一样怎么办理(umiami毕业证书)美国迈阿密大学毕业证文凭证书实拍图原版一模一样
怎么办理(umiami毕业证书)美国迈阿密大学毕业证文凭证书实拍图原版一模一样
 
Discover the benefits of outsourcing SEO to India
Discover the benefits of outsourcing SEO to IndiaDiscover the benefits of outsourcing SEO to India
Discover the benefits of outsourcing SEO to India
 
manuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal
manuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalmanuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal
manuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal
 
快速办理(新加坡SMU毕业证书)新加坡管理大学毕业证文凭证书一模一样
快速办理(新加坡SMU毕业证书)新加坡管理大学毕业证文凭证书一模一样快速办理(新加坡SMU毕业证书)新加坡管理大学毕业证文凭证书一模一样
快速办理(新加坡SMU毕业证书)新加坡管理大学毕业证文凭证书一模一样
 
Ready to Unlock the Power of Blockchain!
Ready to Unlock the Power of Blockchain!Ready to Unlock the Power of Blockchain!
Ready to Unlock the Power of Blockchain!
 
Should Repositories Participate in the Fediverse?
Should Repositories Participate in the Fediverse?Should Repositories Participate in the Fediverse?
Should Repositories Participate in the Fediverse?
 
Bengaluru Dreamin' 24 - Personal Branding
Bengaluru Dreamin' 24 - Personal BrandingBengaluru Dreamin' 24 - Personal Branding
Bengaluru Dreamin' 24 - Personal Branding
 
留学挂科(UofM毕业证)明尼苏达大学毕业证成绩单复刻办理
留学挂科(UofM毕业证)明尼苏达大学毕业证成绩单复刻办理留学挂科(UofM毕业证)明尼苏达大学毕业证成绩单复刻办理
留学挂科(UofM毕业证)明尼苏达大学毕业证成绩单复刻办理
 
成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理
成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理
成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理
 
存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理
存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理
存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理
 
一比一原版(USYD毕业证)悉尼大学毕业证如何办理
一比一原版(USYD毕业证)悉尼大学毕业证如何办理一比一原版(USYD毕业证)悉尼大学毕业证如何办理
一比一原版(USYD毕业证)悉尼大学毕业证如何办理
 
办理新西兰奥克兰大学毕业证学位证书范本原版一模一样
办理新西兰奥克兰大学毕业证学位证书范本原版一模一样办理新西兰奥克兰大学毕业证学位证书范本原版一模一样
办理新西兰奥克兰大学毕业证学位证书范本原版一模一样
 
办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
 
办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理
办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理
办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理
 

Kyiv.py #17 Flask talk

  • 1. Flask? No thanks! by Alexey Popravka
  • 2. About me ● 6+ years of Python ● Python developer / Tech Lead at Prom.ua ● Contributor of github.com/aio-libs ● github.com/popravich
  • 3. What this talk is about? ● What is Flask ● What Flask is not (what is wrong) ● Alternatives ● Questions
  • 4. What is Flask “Flask is a microframework for Python based on Werkzeug, Jinja 2 and good intentions.”
  • 5. What is Flask “Flask is a microframework for Python based on Werkzeug, Jinja 2 and good intentions.” from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello World!' if __name__ == '__main__': app.run()
  • 6. What is Flask ● Jinja2 templates out of the box from flask import render_template @app.route('/hello/') @app.route('/hello/<name>') def hello(name=None): return render_template('hello.html', name=name) <!doctype html> <title>Hello from Flask</title> {% if name %} <h1>Hello {{ name }}!</h1> {% else %} <h1>Hello World!</h1> {% endif %}
  • 7. What is Flask ● Jinja2 templates ● Sessions from flask import Flask, session, escape app = Flask(__name__) @app.route('/') def index(): if 'username' in session: return 'Logged in as %s' % escape(session['username']) return 'You are not logged in'
  • 8. What is Flask ● Jinja2 templates ● Sessions ● Static files serving url_for('static', filename='style.css')
  • 9. What is Flask ● Jinja2 templates ● Sessions ● Static files serving ● Debugger app.run(debug=True)
  • 10. What is Flask ● Jinja2 templates ● Sessions ● Static files serving ● Debugger ● Many extensions $ pip search flask | wc -l 1020
  • 11. What is wrong with: routes ● Preferred way – using decorator # app/view.py @app.route('/') def index(): return “Hello world” bp = Blueprint() @bp.route('/') def hello(): return “Hello world”
  • 12. What is wrong with: routes ● Preferred way – using decorator # proj/view.py from proj import app @app.route('/') def index(): return “Hello world” Must have application instance -> # proj/__init__.py from flask import Flask app = Flask('proj') We begin with already runnable app. But, wait! * Did we have time to configure it? * Did we have time to configure something else (DB, etc)?
  • 13. What is wrong with: routes ● Preferred way – using decorator? # proj/view.py from proj import app if app.debug: @app.route('/docs/') def show_some_docs(): pass How to control? ->
  • 14. What is wrong with: composite apps Say you need several apps not messing their code: # proj/app/__init__.py from flask import Flask app = Flask('proj.app') @app.route('/') def index(): return render_template( 'index.html') # proj/admin/__init__.py from flask import Flask app = Flask('proj.admin') @app.route('/') def index(): return render_template( 'admin_index.html')
  • 15. What is wrong with: composite apps How to reuse apps' URLs? # proj/admin/__init__.py from flask import Flask from flask import url_for app = Flask('proj.admin') @app.route('/') def index(): url_for('app.index') #??? return render_template( 'admin_index.html') ??? -> * Blueprints can help, but application must be only one
  • 16. What is wrong with: jinja Abused! from celery import Celery from flask import render_template celery_app = Celery() @celery_app.task def send_periodic_email(): to = get_address() html_body = render_template('mails/annoy.html') send_mail(to, html_body) Web Worker == Celery Worker
  • 17. What is wrong with: global vars ● Magical request object thread-local proxy object from celery import Celery from flask import render_template, session celery_app = Celery() @celery_app.task def send_periodic_email(): to = get_address() user_name = session['user_name'] html_body = render_template( 'mails/annoy.html', {user_name: user_name}) send_mail(to, html_body) Need request instance ->
  • 18. What is wrong with: global vars ● Magical request object from flask import Flask, request from proj.db import session from proj.redis import redis # ... import other global instance app = Flask() @app.route('/') def index(): uid = redis.get(request.cookies.get('cid')) user_row = session.execute(“select * from ...”) # ...
  • 19. Alternatives ● Enough using WSGI, start using asyncio/aiohttp
  • 20. Alternatives ● Can't cope asyncio? At least try using Flask less self-destructive: – Get rid of app.route decorator def index(): return “Hello world” # ... more views def setup_routes(app): app.add_url_rule('/', 'index', index) app.add_url_rule(...) from flask import Flask from . import views def main(): app = Flask() views.setup_routes(app) # more configuration
  • 21. Alternatives ● Can't cope asyncio? At least try using Flask less self-destructive: – Use any kind of dependencies instead of global (thread-local proxy) variables: from flask import Flask, current_app class MyApp: def __init__(self, *args, redis, db_conn **kw): super().__init__(*args, **kw) self.redis = redis self.db_conn = db_conn def get_user_view(): redis = current_app.redis ....
  • 22. Alternatives ● Still want to use Flask — use Werkzeug!
  • 23. The End Questions? What Flask is not — it is not “micro framework” it is a “Werkzeug wrapper”