wsgi werkzeug and the challenges of building a python web framework
Post on 21-Feb-2015
235 Views
Preview:
TRANSCRIPT
WSGI WerkzeugAnd the challenges of
building a web frameworkigorgue
The Problems
bull A paradigm shift in web applications
bull More JavaScript (about 40 of our code base)
bull Applications are getting small
bull Backend is no longer so tied to the front end (no more crazy render of templates in the backend)
I want to write a Framework
bull Make it just talk REST
bull No ORM
bull No templates
bull Just a routing mechanism
bull httppappoprojectorg (started as a Haskell project)
My Goal
httpwebmachinebashocomimageshttp-headers-status-v3png
Hello World Time
WSGI
def13 hello_world(environ13 start_response)13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Hello13 World]
Run it but donrsquot
if13 __name__13 ==13 __main__13 13 13 13 from13 wsgirefsimple_server13 import13 make_server
13 13 13 13 host13 =13 localhost13 13 13 13 port13 =13 800013 13 13 13 server13 =13 make_server(host13 port13 hello_world)
13 13 13 13 print13 Server13 running13 on13 httphostportformat(host=host13 port=port)13 13 13 13 serverserve_forever()
Use a Webserver
mod_wsgi
Gunicorn
uWSGI
Gunicorn
$13 gunicorn13 modulemain_function_or_class
Or in our example
$13 gunicorn13 hello_worldhello_world13 if13 we13 have13 a13 hello_worldpy13 module
my personal favorite
Parsing Query String
def13 hello_world(environ13 start_response)13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 else13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]
Dealing with the Pathdef13 hello_world(environ13 start_response)13 13 13 13 requested_path13 =13 environ[PATH_INFO]13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 requested_path13 ==13 13 13 13 13 13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 13 13 13 13 else13 13 13 13 13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]13 13 13 13 elif13 requested_path13 ==13 lol13 or13 requested_path13 ==13 lol13 13 13 13 13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 13 13 13 13 return13 [LOL]13 13 13 13 else13 13 13 13 13 13 13 13 start_response(40413 NOT13 FOUND13 [(Content-shy‐Type13 textplain)])
13 13 13 13 13 13 13 13 return13 [Upps13 your13 requested13 path13 path13 was13 not13 foundformat(path=requested_path)]
Better Url Handlingdef13 hello(environ13 start_response)13 13 13 13 Says13 hello13 to13 the13 user13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 else13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]
def13 lol(environ13 start_response)13 13 13 13 Just13 prints13 LOL13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [LOL]
def13 not_found(environ13 start_response)13 13 13 13 Shows13 a13 40413 13 13 13 requested_path13 =13 environ[PATH_INFO]13 13 13 13 start_response(40413 NOT13 FOUND13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Resource13 path13 couldnt13 be13 foundformat(path=requested_path)]
Better Url Handling Matchingurls13 =13 [13 13 13 13 (r^$13 hello)13 13 13 13 (r^lol$13 lol)]
def13 application(environ13 start_response)13 13 13 13 13 13 13 13 WSGI13 application13 that13 will13 get13 served13 13 13 13 13 13 13 13 requested_path13 =13 environ[PATH_INFO]lstrip()
13 13 13 13 for13 regex13 callback13 in13 urls13 13 13 13 13 13 13 13 match13 =13 research(regex13 requested_path)
13 13 13 13 13 13 13 13 if13 match13 13 13 13 13 13 13 13 13 13 13 13 return13 callback(environ13 start_response)
13 13 13 13 return13 not_found(environ13 start_response)
Werkzeug
from13 werkzeugwrappers13 import13 Request13 Response
def13 hello_world(environ13 start_response)13 13 13 13 request13 =13 Request(environ)13 13 13 13 response13 =13 Response(Hello13 0format(requestargsget(name13 World)))
13 13 13 13 return13 response(environ13 start_response)
Routes
selfurl_map13 =13 Map([13 13 13 13 Rule(13 endpoint=index)13 13 13 13 Rule(ltnamegt13 endpoint=dashboard)13 13 13 13 Rule(ltnamegtinfo13 endpoint=contact_information)])
User Agent Queries
from13 werkzeugwrappers13 import13 Responsefrom13 werkzeuguseragents13 import13 UserAgent
def13 application(environ13 start_response)13 13 13 13 browser13 =13 UserAgent(environ)browser13 13 chrome13 13 13 13 response13 =13 Response(Hello13 browserformat(browser=browser))
13 13 13 13 return13 response(environ13 start_response)
Debugger Support
Debugger Shell
DeploymentltVirtualHost13 gt13 13 13 13 ServerName13 browserstuffdev
13 13 13 13 WSGIDaemonProcess13 browserstuff13 user=user113 group=group113 processes=213 threads=513 13 13 13 WSGIScriptAlias13 13 Usersigorcodewsgi_werkzeugwerkzeugappwsgi
13 13 13 13 ltDirectory13 Usersigorcodewsgi_werkzeugwerkzeuggt13 13 13 13 13 13 13 13 WSGIProcessGroup13 browserstuff13 13 13 13 13 13 13 13 WSGIApplicationGroup13 GLOBAL13 13 13 13 13 13 13 13 Order13 denyallow13 13 13 13 13 13 13 13 Allow13 from13 all13 13 13 13 ltDirectorygtltVirtualHostgt
Deploy Gunicorn with Supervisord
[programgunicorn]command=pathtogunicorn13 mainapplication13 -shy‐c13 pathtogunicornconfpydirectory=pathtoprojectuser=nobodyautostart=trueautorestart=trueredirect_stderr=True
httpsgithubcombenoitcgunicornblobmasterexamplessupervisorconf
Recap
bull WSGI isnrsquot hard
bull Werkzeug gives you a lot of the base
bull Stuff that Django doesnrsquot even have
bull Make your dreams come true and you might be the next DHH
Thanks
httphackdayfoundationorg 2K prize
httpsenzaricom wersquore hiring
Steal thishttpigorguecompresentationswsgi-werkzeugpdf
The Problems
bull A paradigm shift in web applications
bull More JavaScript (about 40 of our code base)
bull Applications are getting small
bull Backend is no longer so tied to the front end (no more crazy render of templates in the backend)
I want to write a Framework
bull Make it just talk REST
bull No ORM
bull No templates
bull Just a routing mechanism
bull httppappoprojectorg (started as a Haskell project)
My Goal
httpwebmachinebashocomimageshttp-headers-status-v3png
Hello World Time
WSGI
def13 hello_world(environ13 start_response)13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Hello13 World]
Run it but donrsquot
if13 __name__13 ==13 __main__13 13 13 13 from13 wsgirefsimple_server13 import13 make_server
13 13 13 13 host13 =13 localhost13 13 13 13 port13 =13 800013 13 13 13 server13 =13 make_server(host13 port13 hello_world)
13 13 13 13 print13 Server13 running13 on13 httphostportformat(host=host13 port=port)13 13 13 13 serverserve_forever()
Use a Webserver
mod_wsgi
Gunicorn
uWSGI
Gunicorn
$13 gunicorn13 modulemain_function_or_class
Or in our example
$13 gunicorn13 hello_worldhello_world13 if13 we13 have13 a13 hello_worldpy13 module
my personal favorite
Parsing Query String
def13 hello_world(environ13 start_response)13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 else13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]
Dealing with the Pathdef13 hello_world(environ13 start_response)13 13 13 13 requested_path13 =13 environ[PATH_INFO]13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 requested_path13 ==13 13 13 13 13 13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 13 13 13 13 else13 13 13 13 13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]13 13 13 13 elif13 requested_path13 ==13 lol13 or13 requested_path13 ==13 lol13 13 13 13 13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 13 13 13 13 return13 [LOL]13 13 13 13 else13 13 13 13 13 13 13 13 start_response(40413 NOT13 FOUND13 [(Content-shy‐Type13 textplain)])
13 13 13 13 13 13 13 13 return13 [Upps13 your13 requested13 path13 path13 was13 not13 foundformat(path=requested_path)]
Better Url Handlingdef13 hello(environ13 start_response)13 13 13 13 Says13 hello13 to13 the13 user13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 else13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]
def13 lol(environ13 start_response)13 13 13 13 Just13 prints13 LOL13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [LOL]
def13 not_found(environ13 start_response)13 13 13 13 Shows13 a13 40413 13 13 13 requested_path13 =13 environ[PATH_INFO]13 13 13 13 start_response(40413 NOT13 FOUND13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Resource13 path13 couldnt13 be13 foundformat(path=requested_path)]
Better Url Handling Matchingurls13 =13 [13 13 13 13 (r^$13 hello)13 13 13 13 (r^lol$13 lol)]
def13 application(environ13 start_response)13 13 13 13 13 13 13 13 WSGI13 application13 that13 will13 get13 served13 13 13 13 13 13 13 13 requested_path13 =13 environ[PATH_INFO]lstrip()
13 13 13 13 for13 regex13 callback13 in13 urls13 13 13 13 13 13 13 13 match13 =13 research(regex13 requested_path)
13 13 13 13 13 13 13 13 if13 match13 13 13 13 13 13 13 13 13 13 13 13 return13 callback(environ13 start_response)
13 13 13 13 return13 not_found(environ13 start_response)
Werkzeug
from13 werkzeugwrappers13 import13 Request13 Response
def13 hello_world(environ13 start_response)13 13 13 13 request13 =13 Request(environ)13 13 13 13 response13 =13 Response(Hello13 0format(requestargsget(name13 World)))
13 13 13 13 return13 response(environ13 start_response)
Routes
selfurl_map13 =13 Map([13 13 13 13 Rule(13 endpoint=index)13 13 13 13 Rule(ltnamegt13 endpoint=dashboard)13 13 13 13 Rule(ltnamegtinfo13 endpoint=contact_information)])
User Agent Queries
from13 werkzeugwrappers13 import13 Responsefrom13 werkzeuguseragents13 import13 UserAgent
def13 application(environ13 start_response)13 13 13 13 browser13 =13 UserAgent(environ)browser13 13 chrome13 13 13 13 response13 =13 Response(Hello13 browserformat(browser=browser))
13 13 13 13 return13 response(environ13 start_response)
Debugger Support
Debugger Shell
DeploymentltVirtualHost13 gt13 13 13 13 ServerName13 browserstuffdev
13 13 13 13 WSGIDaemonProcess13 browserstuff13 user=user113 group=group113 processes=213 threads=513 13 13 13 WSGIScriptAlias13 13 Usersigorcodewsgi_werkzeugwerkzeugappwsgi
13 13 13 13 ltDirectory13 Usersigorcodewsgi_werkzeugwerkzeuggt13 13 13 13 13 13 13 13 WSGIProcessGroup13 browserstuff13 13 13 13 13 13 13 13 WSGIApplicationGroup13 GLOBAL13 13 13 13 13 13 13 13 Order13 denyallow13 13 13 13 13 13 13 13 Allow13 from13 all13 13 13 13 ltDirectorygtltVirtualHostgt
Deploy Gunicorn with Supervisord
[programgunicorn]command=pathtogunicorn13 mainapplication13 -shy‐c13 pathtogunicornconfpydirectory=pathtoprojectuser=nobodyautostart=trueautorestart=trueredirect_stderr=True
httpsgithubcombenoitcgunicornblobmasterexamplessupervisorconf
Recap
bull WSGI isnrsquot hard
bull Werkzeug gives you a lot of the base
bull Stuff that Django doesnrsquot even have
bull Make your dreams come true and you might be the next DHH
Thanks
httphackdayfoundationorg 2K prize
httpsenzaricom wersquore hiring
Steal thishttpigorguecompresentationswsgi-werkzeugpdf
I want to write a Framework
bull Make it just talk REST
bull No ORM
bull No templates
bull Just a routing mechanism
bull httppappoprojectorg (started as a Haskell project)
My Goal
httpwebmachinebashocomimageshttp-headers-status-v3png
Hello World Time
WSGI
def13 hello_world(environ13 start_response)13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Hello13 World]
Run it but donrsquot
if13 __name__13 ==13 __main__13 13 13 13 from13 wsgirefsimple_server13 import13 make_server
13 13 13 13 host13 =13 localhost13 13 13 13 port13 =13 800013 13 13 13 server13 =13 make_server(host13 port13 hello_world)
13 13 13 13 print13 Server13 running13 on13 httphostportformat(host=host13 port=port)13 13 13 13 serverserve_forever()
Use a Webserver
mod_wsgi
Gunicorn
uWSGI
Gunicorn
$13 gunicorn13 modulemain_function_or_class
Or in our example
$13 gunicorn13 hello_worldhello_world13 if13 we13 have13 a13 hello_worldpy13 module
my personal favorite
Parsing Query String
def13 hello_world(environ13 start_response)13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 else13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]
Dealing with the Pathdef13 hello_world(environ13 start_response)13 13 13 13 requested_path13 =13 environ[PATH_INFO]13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 requested_path13 ==13 13 13 13 13 13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 13 13 13 13 else13 13 13 13 13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]13 13 13 13 elif13 requested_path13 ==13 lol13 or13 requested_path13 ==13 lol13 13 13 13 13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 13 13 13 13 return13 [LOL]13 13 13 13 else13 13 13 13 13 13 13 13 start_response(40413 NOT13 FOUND13 [(Content-shy‐Type13 textplain)])
13 13 13 13 13 13 13 13 return13 [Upps13 your13 requested13 path13 path13 was13 not13 foundformat(path=requested_path)]
Better Url Handlingdef13 hello(environ13 start_response)13 13 13 13 Says13 hello13 to13 the13 user13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 else13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]
def13 lol(environ13 start_response)13 13 13 13 Just13 prints13 LOL13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [LOL]
def13 not_found(environ13 start_response)13 13 13 13 Shows13 a13 40413 13 13 13 requested_path13 =13 environ[PATH_INFO]13 13 13 13 start_response(40413 NOT13 FOUND13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Resource13 path13 couldnt13 be13 foundformat(path=requested_path)]
Better Url Handling Matchingurls13 =13 [13 13 13 13 (r^$13 hello)13 13 13 13 (r^lol$13 lol)]
def13 application(environ13 start_response)13 13 13 13 13 13 13 13 WSGI13 application13 that13 will13 get13 served13 13 13 13 13 13 13 13 requested_path13 =13 environ[PATH_INFO]lstrip()
13 13 13 13 for13 regex13 callback13 in13 urls13 13 13 13 13 13 13 13 match13 =13 research(regex13 requested_path)
13 13 13 13 13 13 13 13 if13 match13 13 13 13 13 13 13 13 13 13 13 13 return13 callback(environ13 start_response)
13 13 13 13 return13 not_found(environ13 start_response)
Werkzeug
from13 werkzeugwrappers13 import13 Request13 Response
def13 hello_world(environ13 start_response)13 13 13 13 request13 =13 Request(environ)13 13 13 13 response13 =13 Response(Hello13 0format(requestargsget(name13 World)))
13 13 13 13 return13 response(environ13 start_response)
Routes
selfurl_map13 =13 Map([13 13 13 13 Rule(13 endpoint=index)13 13 13 13 Rule(ltnamegt13 endpoint=dashboard)13 13 13 13 Rule(ltnamegtinfo13 endpoint=contact_information)])
User Agent Queries
from13 werkzeugwrappers13 import13 Responsefrom13 werkzeuguseragents13 import13 UserAgent
def13 application(environ13 start_response)13 13 13 13 browser13 =13 UserAgent(environ)browser13 13 chrome13 13 13 13 response13 =13 Response(Hello13 browserformat(browser=browser))
13 13 13 13 return13 response(environ13 start_response)
Debugger Support
Debugger Shell
DeploymentltVirtualHost13 gt13 13 13 13 ServerName13 browserstuffdev
13 13 13 13 WSGIDaemonProcess13 browserstuff13 user=user113 group=group113 processes=213 threads=513 13 13 13 WSGIScriptAlias13 13 Usersigorcodewsgi_werkzeugwerkzeugappwsgi
13 13 13 13 ltDirectory13 Usersigorcodewsgi_werkzeugwerkzeuggt13 13 13 13 13 13 13 13 WSGIProcessGroup13 browserstuff13 13 13 13 13 13 13 13 WSGIApplicationGroup13 GLOBAL13 13 13 13 13 13 13 13 Order13 denyallow13 13 13 13 13 13 13 13 Allow13 from13 all13 13 13 13 ltDirectorygtltVirtualHostgt
Deploy Gunicorn with Supervisord
[programgunicorn]command=pathtogunicorn13 mainapplication13 -shy‐c13 pathtogunicornconfpydirectory=pathtoprojectuser=nobodyautostart=trueautorestart=trueredirect_stderr=True
httpsgithubcombenoitcgunicornblobmasterexamplessupervisorconf
Recap
bull WSGI isnrsquot hard
bull Werkzeug gives you a lot of the base
bull Stuff that Django doesnrsquot even have
bull Make your dreams come true and you might be the next DHH
Thanks
httphackdayfoundationorg 2K prize
httpsenzaricom wersquore hiring
Steal thishttpigorguecompresentationswsgi-werkzeugpdf
My Goal
httpwebmachinebashocomimageshttp-headers-status-v3png
Hello World Time
WSGI
def13 hello_world(environ13 start_response)13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Hello13 World]
Run it but donrsquot
if13 __name__13 ==13 __main__13 13 13 13 from13 wsgirefsimple_server13 import13 make_server
13 13 13 13 host13 =13 localhost13 13 13 13 port13 =13 800013 13 13 13 server13 =13 make_server(host13 port13 hello_world)
13 13 13 13 print13 Server13 running13 on13 httphostportformat(host=host13 port=port)13 13 13 13 serverserve_forever()
Use a Webserver
mod_wsgi
Gunicorn
uWSGI
Gunicorn
$13 gunicorn13 modulemain_function_or_class
Or in our example
$13 gunicorn13 hello_worldhello_world13 if13 we13 have13 a13 hello_worldpy13 module
my personal favorite
Parsing Query String
def13 hello_world(environ13 start_response)13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 else13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]
Dealing with the Pathdef13 hello_world(environ13 start_response)13 13 13 13 requested_path13 =13 environ[PATH_INFO]13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 requested_path13 ==13 13 13 13 13 13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 13 13 13 13 else13 13 13 13 13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]13 13 13 13 elif13 requested_path13 ==13 lol13 or13 requested_path13 ==13 lol13 13 13 13 13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 13 13 13 13 return13 [LOL]13 13 13 13 else13 13 13 13 13 13 13 13 start_response(40413 NOT13 FOUND13 [(Content-shy‐Type13 textplain)])
13 13 13 13 13 13 13 13 return13 [Upps13 your13 requested13 path13 path13 was13 not13 foundformat(path=requested_path)]
Better Url Handlingdef13 hello(environ13 start_response)13 13 13 13 Says13 hello13 to13 the13 user13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 else13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]
def13 lol(environ13 start_response)13 13 13 13 Just13 prints13 LOL13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [LOL]
def13 not_found(environ13 start_response)13 13 13 13 Shows13 a13 40413 13 13 13 requested_path13 =13 environ[PATH_INFO]13 13 13 13 start_response(40413 NOT13 FOUND13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Resource13 path13 couldnt13 be13 foundformat(path=requested_path)]
Better Url Handling Matchingurls13 =13 [13 13 13 13 (r^$13 hello)13 13 13 13 (r^lol$13 lol)]
def13 application(environ13 start_response)13 13 13 13 13 13 13 13 WSGI13 application13 that13 will13 get13 served13 13 13 13 13 13 13 13 requested_path13 =13 environ[PATH_INFO]lstrip()
13 13 13 13 for13 regex13 callback13 in13 urls13 13 13 13 13 13 13 13 match13 =13 research(regex13 requested_path)
13 13 13 13 13 13 13 13 if13 match13 13 13 13 13 13 13 13 13 13 13 13 return13 callback(environ13 start_response)
13 13 13 13 return13 not_found(environ13 start_response)
Werkzeug
from13 werkzeugwrappers13 import13 Request13 Response
def13 hello_world(environ13 start_response)13 13 13 13 request13 =13 Request(environ)13 13 13 13 response13 =13 Response(Hello13 0format(requestargsget(name13 World)))
13 13 13 13 return13 response(environ13 start_response)
Routes
selfurl_map13 =13 Map([13 13 13 13 Rule(13 endpoint=index)13 13 13 13 Rule(ltnamegt13 endpoint=dashboard)13 13 13 13 Rule(ltnamegtinfo13 endpoint=contact_information)])
User Agent Queries
from13 werkzeugwrappers13 import13 Responsefrom13 werkzeuguseragents13 import13 UserAgent
def13 application(environ13 start_response)13 13 13 13 browser13 =13 UserAgent(environ)browser13 13 chrome13 13 13 13 response13 =13 Response(Hello13 browserformat(browser=browser))
13 13 13 13 return13 response(environ13 start_response)
Debugger Support
Debugger Shell
DeploymentltVirtualHost13 gt13 13 13 13 ServerName13 browserstuffdev
13 13 13 13 WSGIDaemonProcess13 browserstuff13 user=user113 group=group113 processes=213 threads=513 13 13 13 WSGIScriptAlias13 13 Usersigorcodewsgi_werkzeugwerkzeugappwsgi
13 13 13 13 ltDirectory13 Usersigorcodewsgi_werkzeugwerkzeuggt13 13 13 13 13 13 13 13 WSGIProcessGroup13 browserstuff13 13 13 13 13 13 13 13 WSGIApplicationGroup13 GLOBAL13 13 13 13 13 13 13 13 Order13 denyallow13 13 13 13 13 13 13 13 Allow13 from13 all13 13 13 13 ltDirectorygtltVirtualHostgt
Deploy Gunicorn with Supervisord
[programgunicorn]command=pathtogunicorn13 mainapplication13 -shy‐c13 pathtogunicornconfpydirectory=pathtoprojectuser=nobodyautostart=trueautorestart=trueredirect_stderr=True
httpsgithubcombenoitcgunicornblobmasterexamplessupervisorconf
Recap
bull WSGI isnrsquot hard
bull Werkzeug gives you a lot of the base
bull Stuff that Django doesnrsquot even have
bull Make your dreams come true and you might be the next DHH
Thanks
httphackdayfoundationorg 2K prize
httpsenzaricom wersquore hiring
Steal thishttpigorguecompresentationswsgi-werkzeugpdf
Hello World Time
WSGI
def13 hello_world(environ13 start_response)13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Hello13 World]
Run it but donrsquot
if13 __name__13 ==13 __main__13 13 13 13 from13 wsgirefsimple_server13 import13 make_server
13 13 13 13 host13 =13 localhost13 13 13 13 port13 =13 800013 13 13 13 server13 =13 make_server(host13 port13 hello_world)
13 13 13 13 print13 Server13 running13 on13 httphostportformat(host=host13 port=port)13 13 13 13 serverserve_forever()
Use a Webserver
mod_wsgi
Gunicorn
uWSGI
Gunicorn
$13 gunicorn13 modulemain_function_or_class
Or in our example
$13 gunicorn13 hello_worldhello_world13 if13 we13 have13 a13 hello_worldpy13 module
my personal favorite
Parsing Query String
def13 hello_world(environ13 start_response)13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 else13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]
Dealing with the Pathdef13 hello_world(environ13 start_response)13 13 13 13 requested_path13 =13 environ[PATH_INFO]13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 requested_path13 ==13 13 13 13 13 13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 13 13 13 13 else13 13 13 13 13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]13 13 13 13 elif13 requested_path13 ==13 lol13 or13 requested_path13 ==13 lol13 13 13 13 13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 13 13 13 13 return13 [LOL]13 13 13 13 else13 13 13 13 13 13 13 13 start_response(40413 NOT13 FOUND13 [(Content-shy‐Type13 textplain)])
13 13 13 13 13 13 13 13 return13 [Upps13 your13 requested13 path13 path13 was13 not13 foundformat(path=requested_path)]
Better Url Handlingdef13 hello(environ13 start_response)13 13 13 13 Says13 hello13 to13 the13 user13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 else13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]
def13 lol(environ13 start_response)13 13 13 13 Just13 prints13 LOL13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [LOL]
def13 not_found(environ13 start_response)13 13 13 13 Shows13 a13 40413 13 13 13 requested_path13 =13 environ[PATH_INFO]13 13 13 13 start_response(40413 NOT13 FOUND13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Resource13 path13 couldnt13 be13 foundformat(path=requested_path)]
Better Url Handling Matchingurls13 =13 [13 13 13 13 (r^$13 hello)13 13 13 13 (r^lol$13 lol)]
def13 application(environ13 start_response)13 13 13 13 13 13 13 13 WSGI13 application13 that13 will13 get13 served13 13 13 13 13 13 13 13 requested_path13 =13 environ[PATH_INFO]lstrip()
13 13 13 13 for13 regex13 callback13 in13 urls13 13 13 13 13 13 13 13 match13 =13 research(regex13 requested_path)
13 13 13 13 13 13 13 13 if13 match13 13 13 13 13 13 13 13 13 13 13 13 return13 callback(environ13 start_response)
13 13 13 13 return13 not_found(environ13 start_response)
Werkzeug
from13 werkzeugwrappers13 import13 Request13 Response
def13 hello_world(environ13 start_response)13 13 13 13 request13 =13 Request(environ)13 13 13 13 response13 =13 Response(Hello13 0format(requestargsget(name13 World)))
13 13 13 13 return13 response(environ13 start_response)
Routes
selfurl_map13 =13 Map([13 13 13 13 Rule(13 endpoint=index)13 13 13 13 Rule(ltnamegt13 endpoint=dashboard)13 13 13 13 Rule(ltnamegtinfo13 endpoint=contact_information)])
User Agent Queries
from13 werkzeugwrappers13 import13 Responsefrom13 werkzeuguseragents13 import13 UserAgent
def13 application(environ13 start_response)13 13 13 13 browser13 =13 UserAgent(environ)browser13 13 chrome13 13 13 13 response13 =13 Response(Hello13 browserformat(browser=browser))
13 13 13 13 return13 response(environ13 start_response)
Debugger Support
Debugger Shell
DeploymentltVirtualHost13 gt13 13 13 13 ServerName13 browserstuffdev
13 13 13 13 WSGIDaemonProcess13 browserstuff13 user=user113 group=group113 processes=213 threads=513 13 13 13 WSGIScriptAlias13 13 Usersigorcodewsgi_werkzeugwerkzeugappwsgi
13 13 13 13 ltDirectory13 Usersigorcodewsgi_werkzeugwerkzeuggt13 13 13 13 13 13 13 13 WSGIProcessGroup13 browserstuff13 13 13 13 13 13 13 13 WSGIApplicationGroup13 GLOBAL13 13 13 13 13 13 13 13 Order13 denyallow13 13 13 13 13 13 13 13 Allow13 from13 all13 13 13 13 ltDirectorygtltVirtualHostgt
Deploy Gunicorn with Supervisord
[programgunicorn]command=pathtogunicorn13 mainapplication13 -shy‐c13 pathtogunicornconfpydirectory=pathtoprojectuser=nobodyautostart=trueautorestart=trueredirect_stderr=True
httpsgithubcombenoitcgunicornblobmasterexamplessupervisorconf
Recap
bull WSGI isnrsquot hard
bull Werkzeug gives you a lot of the base
bull Stuff that Django doesnrsquot even have
bull Make your dreams come true and you might be the next DHH
Thanks
httphackdayfoundationorg 2K prize
httpsenzaricom wersquore hiring
Steal thishttpigorguecompresentationswsgi-werkzeugpdf
WSGI
def13 hello_world(environ13 start_response)13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Hello13 World]
Run it but donrsquot
if13 __name__13 ==13 __main__13 13 13 13 from13 wsgirefsimple_server13 import13 make_server
13 13 13 13 host13 =13 localhost13 13 13 13 port13 =13 800013 13 13 13 server13 =13 make_server(host13 port13 hello_world)
13 13 13 13 print13 Server13 running13 on13 httphostportformat(host=host13 port=port)13 13 13 13 serverserve_forever()
Use a Webserver
mod_wsgi
Gunicorn
uWSGI
Gunicorn
$13 gunicorn13 modulemain_function_or_class
Or in our example
$13 gunicorn13 hello_worldhello_world13 if13 we13 have13 a13 hello_worldpy13 module
my personal favorite
Parsing Query String
def13 hello_world(environ13 start_response)13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 else13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]
Dealing with the Pathdef13 hello_world(environ13 start_response)13 13 13 13 requested_path13 =13 environ[PATH_INFO]13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 requested_path13 ==13 13 13 13 13 13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 13 13 13 13 else13 13 13 13 13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]13 13 13 13 elif13 requested_path13 ==13 lol13 or13 requested_path13 ==13 lol13 13 13 13 13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 13 13 13 13 return13 [LOL]13 13 13 13 else13 13 13 13 13 13 13 13 start_response(40413 NOT13 FOUND13 [(Content-shy‐Type13 textplain)])
13 13 13 13 13 13 13 13 return13 [Upps13 your13 requested13 path13 path13 was13 not13 foundformat(path=requested_path)]
Better Url Handlingdef13 hello(environ13 start_response)13 13 13 13 Says13 hello13 to13 the13 user13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 else13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]
def13 lol(environ13 start_response)13 13 13 13 Just13 prints13 LOL13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [LOL]
def13 not_found(environ13 start_response)13 13 13 13 Shows13 a13 40413 13 13 13 requested_path13 =13 environ[PATH_INFO]13 13 13 13 start_response(40413 NOT13 FOUND13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Resource13 path13 couldnt13 be13 foundformat(path=requested_path)]
Better Url Handling Matchingurls13 =13 [13 13 13 13 (r^$13 hello)13 13 13 13 (r^lol$13 lol)]
def13 application(environ13 start_response)13 13 13 13 13 13 13 13 WSGI13 application13 that13 will13 get13 served13 13 13 13 13 13 13 13 requested_path13 =13 environ[PATH_INFO]lstrip()
13 13 13 13 for13 regex13 callback13 in13 urls13 13 13 13 13 13 13 13 match13 =13 research(regex13 requested_path)
13 13 13 13 13 13 13 13 if13 match13 13 13 13 13 13 13 13 13 13 13 13 return13 callback(environ13 start_response)
13 13 13 13 return13 not_found(environ13 start_response)
Werkzeug
from13 werkzeugwrappers13 import13 Request13 Response
def13 hello_world(environ13 start_response)13 13 13 13 request13 =13 Request(environ)13 13 13 13 response13 =13 Response(Hello13 0format(requestargsget(name13 World)))
13 13 13 13 return13 response(environ13 start_response)
Routes
selfurl_map13 =13 Map([13 13 13 13 Rule(13 endpoint=index)13 13 13 13 Rule(ltnamegt13 endpoint=dashboard)13 13 13 13 Rule(ltnamegtinfo13 endpoint=contact_information)])
User Agent Queries
from13 werkzeugwrappers13 import13 Responsefrom13 werkzeuguseragents13 import13 UserAgent
def13 application(environ13 start_response)13 13 13 13 browser13 =13 UserAgent(environ)browser13 13 chrome13 13 13 13 response13 =13 Response(Hello13 browserformat(browser=browser))
13 13 13 13 return13 response(environ13 start_response)
Debugger Support
Debugger Shell
DeploymentltVirtualHost13 gt13 13 13 13 ServerName13 browserstuffdev
13 13 13 13 WSGIDaemonProcess13 browserstuff13 user=user113 group=group113 processes=213 threads=513 13 13 13 WSGIScriptAlias13 13 Usersigorcodewsgi_werkzeugwerkzeugappwsgi
13 13 13 13 ltDirectory13 Usersigorcodewsgi_werkzeugwerkzeuggt13 13 13 13 13 13 13 13 WSGIProcessGroup13 browserstuff13 13 13 13 13 13 13 13 WSGIApplicationGroup13 GLOBAL13 13 13 13 13 13 13 13 Order13 denyallow13 13 13 13 13 13 13 13 Allow13 from13 all13 13 13 13 ltDirectorygtltVirtualHostgt
Deploy Gunicorn with Supervisord
[programgunicorn]command=pathtogunicorn13 mainapplication13 -shy‐c13 pathtogunicornconfpydirectory=pathtoprojectuser=nobodyautostart=trueautorestart=trueredirect_stderr=True
httpsgithubcombenoitcgunicornblobmasterexamplessupervisorconf
Recap
bull WSGI isnrsquot hard
bull Werkzeug gives you a lot of the base
bull Stuff that Django doesnrsquot even have
bull Make your dreams come true and you might be the next DHH
Thanks
httphackdayfoundationorg 2K prize
httpsenzaricom wersquore hiring
Steal thishttpigorguecompresentationswsgi-werkzeugpdf
Run it but donrsquot
if13 __name__13 ==13 __main__13 13 13 13 from13 wsgirefsimple_server13 import13 make_server
13 13 13 13 host13 =13 localhost13 13 13 13 port13 =13 800013 13 13 13 server13 =13 make_server(host13 port13 hello_world)
13 13 13 13 print13 Server13 running13 on13 httphostportformat(host=host13 port=port)13 13 13 13 serverserve_forever()
Use a Webserver
mod_wsgi
Gunicorn
uWSGI
Gunicorn
$13 gunicorn13 modulemain_function_or_class
Or in our example
$13 gunicorn13 hello_worldhello_world13 if13 we13 have13 a13 hello_worldpy13 module
my personal favorite
Parsing Query String
def13 hello_world(environ13 start_response)13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 else13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]
Dealing with the Pathdef13 hello_world(environ13 start_response)13 13 13 13 requested_path13 =13 environ[PATH_INFO]13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 requested_path13 ==13 13 13 13 13 13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 13 13 13 13 else13 13 13 13 13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]13 13 13 13 elif13 requested_path13 ==13 lol13 or13 requested_path13 ==13 lol13 13 13 13 13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 13 13 13 13 return13 [LOL]13 13 13 13 else13 13 13 13 13 13 13 13 start_response(40413 NOT13 FOUND13 [(Content-shy‐Type13 textplain)])
13 13 13 13 13 13 13 13 return13 [Upps13 your13 requested13 path13 path13 was13 not13 foundformat(path=requested_path)]
Better Url Handlingdef13 hello(environ13 start_response)13 13 13 13 Says13 hello13 to13 the13 user13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 else13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]
def13 lol(environ13 start_response)13 13 13 13 Just13 prints13 LOL13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [LOL]
def13 not_found(environ13 start_response)13 13 13 13 Shows13 a13 40413 13 13 13 requested_path13 =13 environ[PATH_INFO]13 13 13 13 start_response(40413 NOT13 FOUND13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Resource13 path13 couldnt13 be13 foundformat(path=requested_path)]
Better Url Handling Matchingurls13 =13 [13 13 13 13 (r^$13 hello)13 13 13 13 (r^lol$13 lol)]
def13 application(environ13 start_response)13 13 13 13 13 13 13 13 WSGI13 application13 that13 will13 get13 served13 13 13 13 13 13 13 13 requested_path13 =13 environ[PATH_INFO]lstrip()
13 13 13 13 for13 regex13 callback13 in13 urls13 13 13 13 13 13 13 13 match13 =13 research(regex13 requested_path)
13 13 13 13 13 13 13 13 if13 match13 13 13 13 13 13 13 13 13 13 13 13 return13 callback(environ13 start_response)
13 13 13 13 return13 not_found(environ13 start_response)
Werkzeug
from13 werkzeugwrappers13 import13 Request13 Response
def13 hello_world(environ13 start_response)13 13 13 13 request13 =13 Request(environ)13 13 13 13 response13 =13 Response(Hello13 0format(requestargsget(name13 World)))
13 13 13 13 return13 response(environ13 start_response)
Routes
selfurl_map13 =13 Map([13 13 13 13 Rule(13 endpoint=index)13 13 13 13 Rule(ltnamegt13 endpoint=dashboard)13 13 13 13 Rule(ltnamegtinfo13 endpoint=contact_information)])
User Agent Queries
from13 werkzeugwrappers13 import13 Responsefrom13 werkzeuguseragents13 import13 UserAgent
def13 application(environ13 start_response)13 13 13 13 browser13 =13 UserAgent(environ)browser13 13 chrome13 13 13 13 response13 =13 Response(Hello13 browserformat(browser=browser))
13 13 13 13 return13 response(environ13 start_response)
Debugger Support
Debugger Shell
DeploymentltVirtualHost13 gt13 13 13 13 ServerName13 browserstuffdev
13 13 13 13 WSGIDaemonProcess13 browserstuff13 user=user113 group=group113 processes=213 threads=513 13 13 13 WSGIScriptAlias13 13 Usersigorcodewsgi_werkzeugwerkzeugappwsgi
13 13 13 13 ltDirectory13 Usersigorcodewsgi_werkzeugwerkzeuggt13 13 13 13 13 13 13 13 WSGIProcessGroup13 browserstuff13 13 13 13 13 13 13 13 WSGIApplicationGroup13 GLOBAL13 13 13 13 13 13 13 13 Order13 denyallow13 13 13 13 13 13 13 13 Allow13 from13 all13 13 13 13 ltDirectorygtltVirtualHostgt
Deploy Gunicorn with Supervisord
[programgunicorn]command=pathtogunicorn13 mainapplication13 -shy‐c13 pathtogunicornconfpydirectory=pathtoprojectuser=nobodyautostart=trueautorestart=trueredirect_stderr=True
httpsgithubcombenoitcgunicornblobmasterexamplessupervisorconf
Recap
bull WSGI isnrsquot hard
bull Werkzeug gives you a lot of the base
bull Stuff that Django doesnrsquot even have
bull Make your dreams come true and you might be the next DHH
Thanks
httphackdayfoundationorg 2K prize
httpsenzaricom wersquore hiring
Steal thishttpigorguecompresentationswsgi-werkzeugpdf
Use a Webserver
mod_wsgi
Gunicorn
uWSGI
Gunicorn
$13 gunicorn13 modulemain_function_or_class
Or in our example
$13 gunicorn13 hello_worldhello_world13 if13 we13 have13 a13 hello_worldpy13 module
my personal favorite
Parsing Query String
def13 hello_world(environ13 start_response)13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 else13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]
Dealing with the Pathdef13 hello_world(environ13 start_response)13 13 13 13 requested_path13 =13 environ[PATH_INFO]13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 requested_path13 ==13 13 13 13 13 13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 13 13 13 13 else13 13 13 13 13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]13 13 13 13 elif13 requested_path13 ==13 lol13 or13 requested_path13 ==13 lol13 13 13 13 13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 13 13 13 13 return13 [LOL]13 13 13 13 else13 13 13 13 13 13 13 13 start_response(40413 NOT13 FOUND13 [(Content-shy‐Type13 textplain)])
13 13 13 13 13 13 13 13 return13 [Upps13 your13 requested13 path13 path13 was13 not13 foundformat(path=requested_path)]
Better Url Handlingdef13 hello(environ13 start_response)13 13 13 13 Says13 hello13 to13 the13 user13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 else13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]
def13 lol(environ13 start_response)13 13 13 13 Just13 prints13 LOL13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [LOL]
def13 not_found(environ13 start_response)13 13 13 13 Shows13 a13 40413 13 13 13 requested_path13 =13 environ[PATH_INFO]13 13 13 13 start_response(40413 NOT13 FOUND13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Resource13 path13 couldnt13 be13 foundformat(path=requested_path)]
Better Url Handling Matchingurls13 =13 [13 13 13 13 (r^$13 hello)13 13 13 13 (r^lol$13 lol)]
def13 application(environ13 start_response)13 13 13 13 13 13 13 13 WSGI13 application13 that13 will13 get13 served13 13 13 13 13 13 13 13 requested_path13 =13 environ[PATH_INFO]lstrip()
13 13 13 13 for13 regex13 callback13 in13 urls13 13 13 13 13 13 13 13 match13 =13 research(regex13 requested_path)
13 13 13 13 13 13 13 13 if13 match13 13 13 13 13 13 13 13 13 13 13 13 return13 callback(environ13 start_response)
13 13 13 13 return13 not_found(environ13 start_response)
Werkzeug
from13 werkzeugwrappers13 import13 Request13 Response
def13 hello_world(environ13 start_response)13 13 13 13 request13 =13 Request(environ)13 13 13 13 response13 =13 Response(Hello13 0format(requestargsget(name13 World)))
13 13 13 13 return13 response(environ13 start_response)
Routes
selfurl_map13 =13 Map([13 13 13 13 Rule(13 endpoint=index)13 13 13 13 Rule(ltnamegt13 endpoint=dashboard)13 13 13 13 Rule(ltnamegtinfo13 endpoint=contact_information)])
User Agent Queries
from13 werkzeugwrappers13 import13 Responsefrom13 werkzeuguseragents13 import13 UserAgent
def13 application(environ13 start_response)13 13 13 13 browser13 =13 UserAgent(environ)browser13 13 chrome13 13 13 13 response13 =13 Response(Hello13 browserformat(browser=browser))
13 13 13 13 return13 response(environ13 start_response)
Debugger Support
Debugger Shell
DeploymentltVirtualHost13 gt13 13 13 13 ServerName13 browserstuffdev
13 13 13 13 WSGIDaemonProcess13 browserstuff13 user=user113 group=group113 processes=213 threads=513 13 13 13 WSGIScriptAlias13 13 Usersigorcodewsgi_werkzeugwerkzeugappwsgi
13 13 13 13 ltDirectory13 Usersigorcodewsgi_werkzeugwerkzeuggt13 13 13 13 13 13 13 13 WSGIProcessGroup13 browserstuff13 13 13 13 13 13 13 13 WSGIApplicationGroup13 GLOBAL13 13 13 13 13 13 13 13 Order13 denyallow13 13 13 13 13 13 13 13 Allow13 from13 all13 13 13 13 ltDirectorygtltVirtualHostgt
Deploy Gunicorn with Supervisord
[programgunicorn]command=pathtogunicorn13 mainapplication13 -shy‐c13 pathtogunicornconfpydirectory=pathtoprojectuser=nobodyautostart=trueautorestart=trueredirect_stderr=True
httpsgithubcombenoitcgunicornblobmasterexamplessupervisorconf
Recap
bull WSGI isnrsquot hard
bull Werkzeug gives you a lot of the base
bull Stuff that Django doesnrsquot even have
bull Make your dreams come true and you might be the next DHH
Thanks
httphackdayfoundationorg 2K prize
httpsenzaricom wersquore hiring
Steal thishttpigorguecompresentationswsgi-werkzeugpdf
Gunicorn
$13 gunicorn13 modulemain_function_or_class
Or in our example
$13 gunicorn13 hello_worldhello_world13 if13 we13 have13 a13 hello_worldpy13 module
my personal favorite
Parsing Query String
def13 hello_world(environ13 start_response)13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 else13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]
Dealing with the Pathdef13 hello_world(environ13 start_response)13 13 13 13 requested_path13 =13 environ[PATH_INFO]13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 requested_path13 ==13 13 13 13 13 13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 13 13 13 13 else13 13 13 13 13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]13 13 13 13 elif13 requested_path13 ==13 lol13 or13 requested_path13 ==13 lol13 13 13 13 13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 13 13 13 13 return13 [LOL]13 13 13 13 else13 13 13 13 13 13 13 13 start_response(40413 NOT13 FOUND13 [(Content-shy‐Type13 textplain)])
13 13 13 13 13 13 13 13 return13 [Upps13 your13 requested13 path13 path13 was13 not13 foundformat(path=requested_path)]
Better Url Handlingdef13 hello(environ13 start_response)13 13 13 13 Says13 hello13 to13 the13 user13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 else13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]
def13 lol(environ13 start_response)13 13 13 13 Just13 prints13 LOL13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [LOL]
def13 not_found(environ13 start_response)13 13 13 13 Shows13 a13 40413 13 13 13 requested_path13 =13 environ[PATH_INFO]13 13 13 13 start_response(40413 NOT13 FOUND13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Resource13 path13 couldnt13 be13 foundformat(path=requested_path)]
Better Url Handling Matchingurls13 =13 [13 13 13 13 (r^$13 hello)13 13 13 13 (r^lol$13 lol)]
def13 application(environ13 start_response)13 13 13 13 13 13 13 13 WSGI13 application13 that13 will13 get13 served13 13 13 13 13 13 13 13 requested_path13 =13 environ[PATH_INFO]lstrip()
13 13 13 13 for13 regex13 callback13 in13 urls13 13 13 13 13 13 13 13 match13 =13 research(regex13 requested_path)
13 13 13 13 13 13 13 13 if13 match13 13 13 13 13 13 13 13 13 13 13 13 return13 callback(environ13 start_response)
13 13 13 13 return13 not_found(environ13 start_response)
Werkzeug
from13 werkzeugwrappers13 import13 Request13 Response
def13 hello_world(environ13 start_response)13 13 13 13 request13 =13 Request(environ)13 13 13 13 response13 =13 Response(Hello13 0format(requestargsget(name13 World)))
13 13 13 13 return13 response(environ13 start_response)
Routes
selfurl_map13 =13 Map([13 13 13 13 Rule(13 endpoint=index)13 13 13 13 Rule(ltnamegt13 endpoint=dashboard)13 13 13 13 Rule(ltnamegtinfo13 endpoint=contact_information)])
User Agent Queries
from13 werkzeugwrappers13 import13 Responsefrom13 werkzeuguseragents13 import13 UserAgent
def13 application(environ13 start_response)13 13 13 13 browser13 =13 UserAgent(environ)browser13 13 chrome13 13 13 13 response13 =13 Response(Hello13 browserformat(browser=browser))
13 13 13 13 return13 response(environ13 start_response)
Debugger Support
Debugger Shell
DeploymentltVirtualHost13 gt13 13 13 13 ServerName13 browserstuffdev
13 13 13 13 WSGIDaemonProcess13 browserstuff13 user=user113 group=group113 processes=213 threads=513 13 13 13 WSGIScriptAlias13 13 Usersigorcodewsgi_werkzeugwerkzeugappwsgi
13 13 13 13 ltDirectory13 Usersigorcodewsgi_werkzeugwerkzeuggt13 13 13 13 13 13 13 13 WSGIProcessGroup13 browserstuff13 13 13 13 13 13 13 13 WSGIApplicationGroup13 GLOBAL13 13 13 13 13 13 13 13 Order13 denyallow13 13 13 13 13 13 13 13 Allow13 from13 all13 13 13 13 ltDirectorygtltVirtualHostgt
Deploy Gunicorn with Supervisord
[programgunicorn]command=pathtogunicorn13 mainapplication13 -shy‐c13 pathtogunicornconfpydirectory=pathtoprojectuser=nobodyautostart=trueautorestart=trueredirect_stderr=True
httpsgithubcombenoitcgunicornblobmasterexamplessupervisorconf
Recap
bull WSGI isnrsquot hard
bull Werkzeug gives you a lot of the base
bull Stuff that Django doesnrsquot even have
bull Make your dreams come true and you might be the next DHH
Thanks
httphackdayfoundationorg 2K prize
httpsenzaricom wersquore hiring
Steal thishttpigorguecompresentationswsgi-werkzeugpdf
Parsing Query String
def13 hello_world(environ13 start_response)13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 else13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]
Dealing with the Pathdef13 hello_world(environ13 start_response)13 13 13 13 requested_path13 =13 environ[PATH_INFO]13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 requested_path13 ==13 13 13 13 13 13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 13 13 13 13 else13 13 13 13 13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]13 13 13 13 elif13 requested_path13 ==13 lol13 or13 requested_path13 ==13 lol13 13 13 13 13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 13 13 13 13 return13 [LOL]13 13 13 13 else13 13 13 13 13 13 13 13 start_response(40413 NOT13 FOUND13 [(Content-shy‐Type13 textplain)])
13 13 13 13 13 13 13 13 return13 [Upps13 your13 requested13 path13 path13 was13 not13 foundformat(path=requested_path)]
Better Url Handlingdef13 hello(environ13 start_response)13 13 13 13 Says13 hello13 to13 the13 user13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 else13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]
def13 lol(environ13 start_response)13 13 13 13 Just13 prints13 LOL13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [LOL]
def13 not_found(environ13 start_response)13 13 13 13 Shows13 a13 40413 13 13 13 requested_path13 =13 environ[PATH_INFO]13 13 13 13 start_response(40413 NOT13 FOUND13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Resource13 path13 couldnt13 be13 foundformat(path=requested_path)]
Better Url Handling Matchingurls13 =13 [13 13 13 13 (r^$13 hello)13 13 13 13 (r^lol$13 lol)]
def13 application(environ13 start_response)13 13 13 13 13 13 13 13 WSGI13 application13 that13 will13 get13 served13 13 13 13 13 13 13 13 requested_path13 =13 environ[PATH_INFO]lstrip()
13 13 13 13 for13 regex13 callback13 in13 urls13 13 13 13 13 13 13 13 match13 =13 research(regex13 requested_path)
13 13 13 13 13 13 13 13 if13 match13 13 13 13 13 13 13 13 13 13 13 13 return13 callback(environ13 start_response)
13 13 13 13 return13 not_found(environ13 start_response)
Werkzeug
from13 werkzeugwrappers13 import13 Request13 Response
def13 hello_world(environ13 start_response)13 13 13 13 request13 =13 Request(environ)13 13 13 13 response13 =13 Response(Hello13 0format(requestargsget(name13 World)))
13 13 13 13 return13 response(environ13 start_response)
Routes
selfurl_map13 =13 Map([13 13 13 13 Rule(13 endpoint=index)13 13 13 13 Rule(ltnamegt13 endpoint=dashboard)13 13 13 13 Rule(ltnamegtinfo13 endpoint=contact_information)])
User Agent Queries
from13 werkzeugwrappers13 import13 Responsefrom13 werkzeuguseragents13 import13 UserAgent
def13 application(environ13 start_response)13 13 13 13 browser13 =13 UserAgent(environ)browser13 13 chrome13 13 13 13 response13 =13 Response(Hello13 browserformat(browser=browser))
13 13 13 13 return13 response(environ13 start_response)
Debugger Support
Debugger Shell
DeploymentltVirtualHost13 gt13 13 13 13 ServerName13 browserstuffdev
13 13 13 13 WSGIDaemonProcess13 browserstuff13 user=user113 group=group113 processes=213 threads=513 13 13 13 WSGIScriptAlias13 13 Usersigorcodewsgi_werkzeugwerkzeugappwsgi
13 13 13 13 ltDirectory13 Usersigorcodewsgi_werkzeugwerkzeuggt13 13 13 13 13 13 13 13 WSGIProcessGroup13 browserstuff13 13 13 13 13 13 13 13 WSGIApplicationGroup13 GLOBAL13 13 13 13 13 13 13 13 Order13 denyallow13 13 13 13 13 13 13 13 Allow13 from13 all13 13 13 13 ltDirectorygtltVirtualHostgt
Deploy Gunicorn with Supervisord
[programgunicorn]command=pathtogunicorn13 mainapplication13 -shy‐c13 pathtogunicornconfpydirectory=pathtoprojectuser=nobodyautostart=trueautorestart=trueredirect_stderr=True
httpsgithubcombenoitcgunicornblobmasterexamplessupervisorconf
Recap
bull WSGI isnrsquot hard
bull Werkzeug gives you a lot of the base
bull Stuff that Django doesnrsquot even have
bull Make your dreams come true and you might be the next DHH
Thanks
httphackdayfoundationorg 2K prize
httpsenzaricom wersquore hiring
Steal thishttpigorguecompresentationswsgi-werkzeugpdf
Dealing with the Pathdef13 hello_world(environ13 start_response)13 13 13 13 requested_path13 =13 environ[PATH_INFO]13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 requested_path13 ==13 13 13 13 13 13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 13 13 13 13 else13 13 13 13 13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]13 13 13 13 elif13 requested_path13 ==13 lol13 or13 requested_path13 ==13 lol13 13 13 13 13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 13 13 13 13 return13 [LOL]13 13 13 13 else13 13 13 13 13 13 13 13 start_response(40413 NOT13 FOUND13 [(Content-shy‐Type13 textplain)])
13 13 13 13 13 13 13 13 return13 [Upps13 your13 requested13 path13 path13 was13 not13 foundformat(path=requested_path)]
Better Url Handlingdef13 hello(environ13 start_response)13 13 13 13 Says13 hello13 to13 the13 user13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 else13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]
def13 lol(environ13 start_response)13 13 13 13 Just13 prints13 LOL13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [LOL]
def13 not_found(environ13 start_response)13 13 13 13 Shows13 a13 40413 13 13 13 requested_path13 =13 environ[PATH_INFO]13 13 13 13 start_response(40413 NOT13 FOUND13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Resource13 path13 couldnt13 be13 foundformat(path=requested_path)]
Better Url Handling Matchingurls13 =13 [13 13 13 13 (r^$13 hello)13 13 13 13 (r^lol$13 lol)]
def13 application(environ13 start_response)13 13 13 13 13 13 13 13 WSGI13 application13 that13 will13 get13 served13 13 13 13 13 13 13 13 requested_path13 =13 environ[PATH_INFO]lstrip()
13 13 13 13 for13 regex13 callback13 in13 urls13 13 13 13 13 13 13 13 match13 =13 research(regex13 requested_path)
13 13 13 13 13 13 13 13 if13 match13 13 13 13 13 13 13 13 13 13 13 13 return13 callback(environ13 start_response)
13 13 13 13 return13 not_found(environ13 start_response)
Werkzeug
from13 werkzeugwrappers13 import13 Request13 Response
def13 hello_world(environ13 start_response)13 13 13 13 request13 =13 Request(environ)13 13 13 13 response13 =13 Response(Hello13 0format(requestargsget(name13 World)))
13 13 13 13 return13 response(environ13 start_response)
Routes
selfurl_map13 =13 Map([13 13 13 13 Rule(13 endpoint=index)13 13 13 13 Rule(ltnamegt13 endpoint=dashboard)13 13 13 13 Rule(ltnamegtinfo13 endpoint=contact_information)])
User Agent Queries
from13 werkzeugwrappers13 import13 Responsefrom13 werkzeuguseragents13 import13 UserAgent
def13 application(environ13 start_response)13 13 13 13 browser13 =13 UserAgent(environ)browser13 13 chrome13 13 13 13 response13 =13 Response(Hello13 browserformat(browser=browser))
13 13 13 13 return13 response(environ13 start_response)
Debugger Support
Debugger Shell
DeploymentltVirtualHost13 gt13 13 13 13 ServerName13 browserstuffdev
13 13 13 13 WSGIDaemonProcess13 browserstuff13 user=user113 group=group113 processes=213 threads=513 13 13 13 WSGIScriptAlias13 13 Usersigorcodewsgi_werkzeugwerkzeugappwsgi
13 13 13 13 ltDirectory13 Usersigorcodewsgi_werkzeugwerkzeuggt13 13 13 13 13 13 13 13 WSGIProcessGroup13 browserstuff13 13 13 13 13 13 13 13 WSGIApplicationGroup13 GLOBAL13 13 13 13 13 13 13 13 Order13 denyallow13 13 13 13 13 13 13 13 Allow13 from13 all13 13 13 13 ltDirectorygtltVirtualHostgt
Deploy Gunicorn with Supervisord
[programgunicorn]command=pathtogunicorn13 mainapplication13 -shy‐c13 pathtogunicornconfpydirectory=pathtoprojectuser=nobodyautostart=trueautorestart=trueredirect_stderr=True
httpsgithubcombenoitcgunicornblobmasterexamplessupervisorconf
Recap
bull WSGI isnrsquot hard
bull Werkzeug gives you a lot of the base
bull Stuff that Django doesnrsquot even have
bull Make your dreams come true and you might be the next DHH
Thanks
httphackdayfoundationorg 2K prize
httpsenzaricom wersquore hiring
Steal thishttpigorguecompresentationswsgi-werkzeugpdf
Better Url Handlingdef13 hello(environ13 start_response)13 13 13 13 Says13 hello13 to13 the13 user13 13 13 13 parameters13 =13 parse_qs(environget(QUERY_STRING13 ))
13 13 13 13 if13 subject13 in13 parameters13 13 13 13 13 13 13 13 subject13 =13 escape(parameters[subject][0])13 13 13 13 else13 13 13 13 13 13 13 13 subject13 =13 World
13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Hello13 subjectformat(subject=subject)]
def13 lol(environ13 start_response)13 13 13 13 Just13 prints13 LOL13 13 13 13 start_response(20013 OK13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [LOL]
def13 not_found(environ13 start_response)13 13 13 13 Shows13 a13 40413 13 13 13 requested_path13 =13 environ[PATH_INFO]13 13 13 13 start_response(40413 NOT13 FOUND13 [(Content-shy‐Type13 textplain)])
13 13 13 13 return13 [Resource13 path13 couldnt13 be13 foundformat(path=requested_path)]
Better Url Handling Matchingurls13 =13 [13 13 13 13 (r^$13 hello)13 13 13 13 (r^lol$13 lol)]
def13 application(environ13 start_response)13 13 13 13 13 13 13 13 WSGI13 application13 that13 will13 get13 served13 13 13 13 13 13 13 13 requested_path13 =13 environ[PATH_INFO]lstrip()
13 13 13 13 for13 regex13 callback13 in13 urls13 13 13 13 13 13 13 13 match13 =13 research(regex13 requested_path)
13 13 13 13 13 13 13 13 if13 match13 13 13 13 13 13 13 13 13 13 13 13 return13 callback(environ13 start_response)
13 13 13 13 return13 not_found(environ13 start_response)
Werkzeug
from13 werkzeugwrappers13 import13 Request13 Response
def13 hello_world(environ13 start_response)13 13 13 13 request13 =13 Request(environ)13 13 13 13 response13 =13 Response(Hello13 0format(requestargsget(name13 World)))
13 13 13 13 return13 response(environ13 start_response)
Routes
selfurl_map13 =13 Map([13 13 13 13 Rule(13 endpoint=index)13 13 13 13 Rule(ltnamegt13 endpoint=dashboard)13 13 13 13 Rule(ltnamegtinfo13 endpoint=contact_information)])
User Agent Queries
from13 werkzeugwrappers13 import13 Responsefrom13 werkzeuguseragents13 import13 UserAgent
def13 application(environ13 start_response)13 13 13 13 browser13 =13 UserAgent(environ)browser13 13 chrome13 13 13 13 response13 =13 Response(Hello13 browserformat(browser=browser))
13 13 13 13 return13 response(environ13 start_response)
Debugger Support
Debugger Shell
DeploymentltVirtualHost13 gt13 13 13 13 ServerName13 browserstuffdev
13 13 13 13 WSGIDaemonProcess13 browserstuff13 user=user113 group=group113 processes=213 threads=513 13 13 13 WSGIScriptAlias13 13 Usersigorcodewsgi_werkzeugwerkzeugappwsgi
13 13 13 13 ltDirectory13 Usersigorcodewsgi_werkzeugwerkzeuggt13 13 13 13 13 13 13 13 WSGIProcessGroup13 browserstuff13 13 13 13 13 13 13 13 WSGIApplicationGroup13 GLOBAL13 13 13 13 13 13 13 13 Order13 denyallow13 13 13 13 13 13 13 13 Allow13 from13 all13 13 13 13 ltDirectorygtltVirtualHostgt
Deploy Gunicorn with Supervisord
[programgunicorn]command=pathtogunicorn13 mainapplication13 -shy‐c13 pathtogunicornconfpydirectory=pathtoprojectuser=nobodyautostart=trueautorestart=trueredirect_stderr=True
httpsgithubcombenoitcgunicornblobmasterexamplessupervisorconf
Recap
bull WSGI isnrsquot hard
bull Werkzeug gives you a lot of the base
bull Stuff that Django doesnrsquot even have
bull Make your dreams come true and you might be the next DHH
Thanks
httphackdayfoundationorg 2K prize
httpsenzaricom wersquore hiring
Steal thishttpigorguecompresentationswsgi-werkzeugpdf
Better Url Handling Matchingurls13 =13 [13 13 13 13 (r^$13 hello)13 13 13 13 (r^lol$13 lol)]
def13 application(environ13 start_response)13 13 13 13 13 13 13 13 WSGI13 application13 that13 will13 get13 served13 13 13 13 13 13 13 13 requested_path13 =13 environ[PATH_INFO]lstrip()
13 13 13 13 for13 regex13 callback13 in13 urls13 13 13 13 13 13 13 13 match13 =13 research(regex13 requested_path)
13 13 13 13 13 13 13 13 if13 match13 13 13 13 13 13 13 13 13 13 13 13 return13 callback(environ13 start_response)
13 13 13 13 return13 not_found(environ13 start_response)
Werkzeug
from13 werkzeugwrappers13 import13 Request13 Response
def13 hello_world(environ13 start_response)13 13 13 13 request13 =13 Request(environ)13 13 13 13 response13 =13 Response(Hello13 0format(requestargsget(name13 World)))
13 13 13 13 return13 response(environ13 start_response)
Routes
selfurl_map13 =13 Map([13 13 13 13 Rule(13 endpoint=index)13 13 13 13 Rule(ltnamegt13 endpoint=dashboard)13 13 13 13 Rule(ltnamegtinfo13 endpoint=contact_information)])
User Agent Queries
from13 werkzeugwrappers13 import13 Responsefrom13 werkzeuguseragents13 import13 UserAgent
def13 application(environ13 start_response)13 13 13 13 browser13 =13 UserAgent(environ)browser13 13 chrome13 13 13 13 response13 =13 Response(Hello13 browserformat(browser=browser))
13 13 13 13 return13 response(environ13 start_response)
Debugger Support
Debugger Shell
DeploymentltVirtualHost13 gt13 13 13 13 ServerName13 browserstuffdev
13 13 13 13 WSGIDaemonProcess13 browserstuff13 user=user113 group=group113 processes=213 threads=513 13 13 13 WSGIScriptAlias13 13 Usersigorcodewsgi_werkzeugwerkzeugappwsgi
13 13 13 13 ltDirectory13 Usersigorcodewsgi_werkzeugwerkzeuggt13 13 13 13 13 13 13 13 WSGIProcessGroup13 browserstuff13 13 13 13 13 13 13 13 WSGIApplicationGroup13 GLOBAL13 13 13 13 13 13 13 13 Order13 denyallow13 13 13 13 13 13 13 13 Allow13 from13 all13 13 13 13 ltDirectorygtltVirtualHostgt
Deploy Gunicorn with Supervisord
[programgunicorn]command=pathtogunicorn13 mainapplication13 -shy‐c13 pathtogunicornconfpydirectory=pathtoprojectuser=nobodyautostart=trueautorestart=trueredirect_stderr=True
httpsgithubcombenoitcgunicornblobmasterexamplessupervisorconf
Recap
bull WSGI isnrsquot hard
bull Werkzeug gives you a lot of the base
bull Stuff that Django doesnrsquot even have
bull Make your dreams come true and you might be the next DHH
Thanks
httphackdayfoundationorg 2K prize
httpsenzaricom wersquore hiring
Steal thishttpigorguecompresentationswsgi-werkzeugpdf
Werkzeug
from13 werkzeugwrappers13 import13 Request13 Response
def13 hello_world(environ13 start_response)13 13 13 13 request13 =13 Request(environ)13 13 13 13 response13 =13 Response(Hello13 0format(requestargsget(name13 World)))
13 13 13 13 return13 response(environ13 start_response)
Routes
selfurl_map13 =13 Map([13 13 13 13 Rule(13 endpoint=index)13 13 13 13 Rule(ltnamegt13 endpoint=dashboard)13 13 13 13 Rule(ltnamegtinfo13 endpoint=contact_information)])
User Agent Queries
from13 werkzeugwrappers13 import13 Responsefrom13 werkzeuguseragents13 import13 UserAgent
def13 application(environ13 start_response)13 13 13 13 browser13 =13 UserAgent(environ)browser13 13 chrome13 13 13 13 response13 =13 Response(Hello13 browserformat(browser=browser))
13 13 13 13 return13 response(environ13 start_response)
Debugger Support
Debugger Shell
DeploymentltVirtualHost13 gt13 13 13 13 ServerName13 browserstuffdev
13 13 13 13 WSGIDaemonProcess13 browserstuff13 user=user113 group=group113 processes=213 threads=513 13 13 13 WSGIScriptAlias13 13 Usersigorcodewsgi_werkzeugwerkzeugappwsgi
13 13 13 13 ltDirectory13 Usersigorcodewsgi_werkzeugwerkzeuggt13 13 13 13 13 13 13 13 WSGIProcessGroup13 browserstuff13 13 13 13 13 13 13 13 WSGIApplicationGroup13 GLOBAL13 13 13 13 13 13 13 13 Order13 denyallow13 13 13 13 13 13 13 13 Allow13 from13 all13 13 13 13 ltDirectorygtltVirtualHostgt
Deploy Gunicorn with Supervisord
[programgunicorn]command=pathtogunicorn13 mainapplication13 -shy‐c13 pathtogunicornconfpydirectory=pathtoprojectuser=nobodyautostart=trueautorestart=trueredirect_stderr=True
httpsgithubcombenoitcgunicornblobmasterexamplessupervisorconf
Recap
bull WSGI isnrsquot hard
bull Werkzeug gives you a lot of the base
bull Stuff that Django doesnrsquot even have
bull Make your dreams come true and you might be the next DHH
Thanks
httphackdayfoundationorg 2K prize
httpsenzaricom wersquore hiring
Steal thishttpigorguecompresentationswsgi-werkzeugpdf
Routes
selfurl_map13 =13 Map([13 13 13 13 Rule(13 endpoint=index)13 13 13 13 Rule(ltnamegt13 endpoint=dashboard)13 13 13 13 Rule(ltnamegtinfo13 endpoint=contact_information)])
User Agent Queries
from13 werkzeugwrappers13 import13 Responsefrom13 werkzeuguseragents13 import13 UserAgent
def13 application(environ13 start_response)13 13 13 13 browser13 =13 UserAgent(environ)browser13 13 chrome13 13 13 13 response13 =13 Response(Hello13 browserformat(browser=browser))
13 13 13 13 return13 response(environ13 start_response)
Debugger Support
Debugger Shell
DeploymentltVirtualHost13 gt13 13 13 13 ServerName13 browserstuffdev
13 13 13 13 WSGIDaemonProcess13 browserstuff13 user=user113 group=group113 processes=213 threads=513 13 13 13 WSGIScriptAlias13 13 Usersigorcodewsgi_werkzeugwerkzeugappwsgi
13 13 13 13 ltDirectory13 Usersigorcodewsgi_werkzeugwerkzeuggt13 13 13 13 13 13 13 13 WSGIProcessGroup13 browserstuff13 13 13 13 13 13 13 13 WSGIApplicationGroup13 GLOBAL13 13 13 13 13 13 13 13 Order13 denyallow13 13 13 13 13 13 13 13 Allow13 from13 all13 13 13 13 ltDirectorygtltVirtualHostgt
Deploy Gunicorn with Supervisord
[programgunicorn]command=pathtogunicorn13 mainapplication13 -shy‐c13 pathtogunicornconfpydirectory=pathtoprojectuser=nobodyautostart=trueautorestart=trueredirect_stderr=True
httpsgithubcombenoitcgunicornblobmasterexamplessupervisorconf
Recap
bull WSGI isnrsquot hard
bull Werkzeug gives you a lot of the base
bull Stuff that Django doesnrsquot even have
bull Make your dreams come true and you might be the next DHH
Thanks
httphackdayfoundationorg 2K prize
httpsenzaricom wersquore hiring
Steal thishttpigorguecompresentationswsgi-werkzeugpdf
User Agent Queries
from13 werkzeugwrappers13 import13 Responsefrom13 werkzeuguseragents13 import13 UserAgent
def13 application(environ13 start_response)13 13 13 13 browser13 =13 UserAgent(environ)browser13 13 chrome13 13 13 13 response13 =13 Response(Hello13 browserformat(browser=browser))
13 13 13 13 return13 response(environ13 start_response)
Debugger Support
Debugger Shell
DeploymentltVirtualHost13 gt13 13 13 13 ServerName13 browserstuffdev
13 13 13 13 WSGIDaemonProcess13 browserstuff13 user=user113 group=group113 processes=213 threads=513 13 13 13 WSGIScriptAlias13 13 Usersigorcodewsgi_werkzeugwerkzeugappwsgi
13 13 13 13 ltDirectory13 Usersigorcodewsgi_werkzeugwerkzeuggt13 13 13 13 13 13 13 13 WSGIProcessGroup13 browserstuff13 13 13 13 13 13 13 13 WSGIApplicationGroup13 GLOBAL13 13 13 13 13 13 13 13 Order13 denyallow13 13 13 13 13 13 13 13 Allow13 from13 all13 13 13 13 ltDirectorygtltVirtualHostgt
Deploy Gunicorn with Supervisord
[programgunicorn]command=pathtogunicorn13 mainapplication13 -shy‐c13 pathtogunicornconfpydirectory=pathtoprojectuser=nobodyautostart=trueautorestart=trueredirect_stderr=True
httpsgithubcombenoitcgunicornblobmasterexamplessupervisorconf
Recap
bull WSGI isnrsquot hard
bull Werkzeug gives you a lot of the base
bull Stuff that Django doesnrsquot even have
bull Make your dreams come true and you might be the next DHH
Thanks
httphackdayfoundationorg 2K prize
httpsenzaricom wersquore hiring
Steal thishttpigorguecompresentationswsgi-werkzeugpdf
Debugger Support
Debugger Shell
DeploymentltVirtualHost13 gt13 13 13 13 ServerName13 browserstuffdev
13 13 13 13 WSGIDaemonProcess13 browserstuff13 user=user113 group=group113 processes=213 threads=513 13 13 13 WSGIScriptAlias13 13 Usersigorcodewsgi_werkzeugwerkzeugappwsgi
13 13 13 13 ltDirectory13 Usersigorcodewsgi_werkzeugwerkzeuggt13 13 13 13 13 13 13 13 WSGIProcessGroup13 browserstuff13 13 13 13 13 13 13 13 WSGIApplicationGroup13 GLOBAL13 13 13 13 13 13 13 13 Order13 denyallow13 13 13 13 13 13 13 13 Allow13 from13 all13 13 13 13 ltDirectorygtltVirtualHostgt
Deploy Gunicorn with Supervisord
[programgunicorn]command=pathtogunicorn13 mainapplication13 -shy‐c13 pathtogunicornconfpydirectory=pathtoprojectuser=nobodyautostart=trueautorestart=trueredirect_stderr=True
httpsgithubcombenoitcgunicornblobmasterexamplessupervisorconf
Recap
bull WSGI isnrsquot hard
bull Werkzeug gives you a lot of the base
bull Stuff that Django doesnrsquot even have
bull Make your dreams come true and you might be the next DHH
Thanks
httphackdayfoundationorg 2K prize
httpsenzaricom wersquore hiring
Steal thishttpigorguecompresentationswsgi-werkzeugpdf
Debugger Shell
DeploymentltVirtualHost13 gt13 13 13 13 ServerName13 browserstuffdev
13 13 13 13 WSGIDaemonProcess13 browserstuff13 user=user113 group=group113 processes=213 threads=513 13 13 13 WSGIScriptAlias13 13 Usersigorcodewsgi_werkzeugwerkzeugappwsgi
13 13 13 13 ltDirectory13 Usersigorcodewsgi_werkzeugwerkzeuggt13 13 13 13 13 13 13 13 WSGIProcessGroup13 browserstuff13 13 13 13 13 13 13 13 WSGIApplicationGroup13 GLOBAL13 13 13 13 13 13 13 13 Order13 denyallow13 13 13 13 13 13 13 13 Allow13 from13 all13 13 13 13 ltDirectorygtltVirtualHostgt
Deploy Gunicorn with Supervisord
[programgunicorn]command=pathtogunicorn13 mainapplication13 -shy‐c13 pathtogunicornconfpydirectory=pathtoprojectuser=nobodyautostart=trueautorestart=trueredirect_stderr=True
httpsgithubcombenoitcgunicornblobmasterexamplessupervisorconf
Recap
bull WSGI isnrsquot hard
bull Werkzeug gives you a lot of the base
bull Stuff that Django doesnrsquot even have
bull Make your dreams come true and you might be the next DHH
Thanks
httphackdayfoundationorg 2K prize
httpsenzaricom wersquore hiring
Steal thishttpigorguecompresentationswsgi-werkzeugpdf
DeploymentltVirtualHost13 gt13 13 13 13 ServerName13 browserstuffdev
13 13 13 13 WSGIDaemonProcess13 browserstuff13 user=user113 group=group113 processes=213 threads=513 13 13 13 WSGIScriptAlias13 13 Usersigorcodewsgi_werkzeugwerkzeugappwsgi
13 13 13 13 ltDirectory13 Usersigorcodewsgi_werkzeugwerkzeuggt13 13 13 13 13 13 13 13 WSGIProcessGroup13 browserstuff13 13 13 13 13 13 13 13 WSGIApplicationGroup13 GLOBAL13 13 13 13 13 13 13 13 Order13 denyallow13 13 13 13 13 13 13 13 Allow13 from13 all13 13 13 13 ltDirectorygtltVirtualHostgt
Deploy Gunicorn with Supervisord
[programgunicorn]command=pathtogunicorn13 mainapplication13 -shy‐c13 pathtogunicornconfpydirectory=pathtoprojectuser=nobodyautostart=trueautorestart=trueredirect_stderr=True
httpsgithubcombenoitcgunicornblobmasterexamplessupervisorconf
Recap
bull WSGI isnrsquot hard
bull Werkzeug gives you a lot of the base
bull Stuff that Django doesnrsquot even have
bull Make your dreams come true and you might be the next DHH
Thanks
httphackdayfoundationorg 2K prize
httpsenzaricom wersquore hiring
Steal thishttpigorguecompresentationswsgi-werkzeugpdf
Deploy Gunicorn with Supervisord
[programgunicorn]command=pathtogunicorn13 mainapplication13 -shy‐c13 pathtogunicornconfpydirectory=pathtoprojectuser=nobodyautostart=trueautorestart=trueredirect_stderr=True
httpsgithubcombenoitcgunicornblobmasterexamplessupervisorconf
Recap
bull WSGI isnrsquot hard
bull Werkzeug gives you a lot of the base
bull Stuff that Django doesnrsquot even have
bull Make your dreams come true and you might be the next DHH
Thanks
httphackdayfoundationorg 2K prize
httpsenzaricom wersquore hiring
Steal thishttpigorguecompresentationswsgi-werkzeugpdf
Recap
bull WSGI isnrsquot hard
bull Werkzeug gives you a lot of the base
bull Stuff that Django doesnrsquot even have
bull Make your dreams come true and you might be the next DHH
Thanks
httphackdayfoundationorg 2K prize
httpsenzaricom wersquore hiring
Steal thishttpigorguecompresentationswsgi-werkzeugpdf
Thanks
httphackdayfoundationorg 2K prize
httpsenzaricom wersquore hiring
Steal thishttpigorguecompresentationswsgi-werkzeugpdf
top related