SlideShare a Scribd company logo
1 of 45
Download to read offline
Secrets of

a WSGI master.
Graham Dumpleton

Graham.Dumpleton@gmail.com
@GrahamDumpleton
https://www.slideshare.net/GrahamDumpleton/secrets-of-a-wsgi-master
What is WSGI?
Web Browser
Web Browser
Web Browser
Web Server
HTTP
HTTP
HTTP
File System
(Static Files)
Python
Web Application
WSGI
WSGI == Web Server Gateway Interface (PEP 3333)
WSGI is a specification for an
Application Programming Interface
WSGI is NOT a wire protocol
WSGI is NOT an implementation
of any anything
def application(environ, start_response):
status = '200 OK'
output = b'Hello World!'
response_headers = [
('Content-Type', 'text/plain'),
('Content-Length', str(len(output)))]
start_response(status, response_headers)
return [output]
Friends don’t let friends
use raw WSGI
You still need a way to host a
WSGI application
The development servers builtin to
a framework are not good enough
Installing mod_wsgi the easy way
pip install mod_wsgi
https://pypi.python.org/pypi/mod_wsgi
Run mod_wsgi from the command line
mod_wsgi-express start-server wsgi.py
No Apache configuration required
$ mod_wsgi-express start-server wsgi.py
Server URL : http://localhost:8000/
Server Root : /tmp/mod_wsgi-localhost:8000:502
Server Conf : /tmp/mod_wsgi-localhost:8000:502/httpd.conf
Error Log File : /tmp/mod_wsgi-localhost:8000:502/error_log (warn)
Request Capacity : 5 (1 process * 5 threads)
Request Timeout : 60 (seconds)
Startup Timeout : 15 (seconds)
Queue Backlog : 100 (connections)
Queue Timeout : 45 (seconds)
Server Capacity : 20 (event/worker), 20 (prefork)
Server Backlog : 500 (connections)
Locale Setting : en_AU.UTF-8
Django framework integration
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'mod_wsgi.server',
] Add mod_wsgi.server
Run with Django management command
python manage.py runmodwsgi
Automatic code reloading
python manage.py runmodwsgi --reload-on-changes
Interactive debugger
python manage.py runmodwsgi --enable-debugger
Production configuration #1
python manage.py runmodwsgi 
--server-root /etc/wsgi-port-80 
--user www-data --group www-data 
--port 80 --setup-only
Production configuration #2
mod_wsgi-express start-server wsgi.py 
--server-root /etc/wsgi-port-80 
--user www-data --group www-data 
--port 80 --url-alias /static static 
--setup-only
Running in production
/etc/wsgi-port-80/apachectl start
/etc/wsgi-port-80/apachectl restart
/etc/wsgi-port-80/apachectl stop
Build a container image
FROM python:3
RUN apt-get update && 
apt-get install -y --no-install-recommends apache2 apache2-dev locales && 
apt-get clean && rm -r /var/lib/apt/lists/*
RUN echo 'en_US.UTF-8 UTF-8' >> /etc/locale.gen && locale-gen
ENV LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8
RUN pip install --no-cache-dir mod_wsgi
WORKDIR /opt/app-root
COPY . /opt/app-root
EXPOSE 80
CMD [ "mod_wsgi-express", "start-server", "--port", "80", "--user", 
"www-data", "--group", "www-data", "--log-to-terminal", "wsgi.py" ]
Install Apache
Fix Unicode Problems
Run mod_wsgi-express
Building the container
$ docker build -t mypyapp .
Sending build context to Docker daemon 3.584kB
Step 1/9 : FROM python:3
---> 968120d8cbe8
Step 2/9 : WORKDIR /opt/app-root
---> Using cache
---> 003096a40d39
Step 3/9 : .......
Starting the container
$ docker run --rm -p 80:80 mypyapp
Friends don’t let friends
run containers as root
Friends don’t let friends
use Python without a
Python virtual environment
A better container image #1
FROM python:3
RUN apt-get update && 
apt-get install -y --no-install-recommends apache2 apache2-dev locales && 
apt-get clean && 
rm -r /var/lib/apt/lists/*
RUN adduser --disabled-password --gecos "Warp Drive" --uid 1001 
--gid 0 --home /opt/app-root warpdrive && 
chmod g+w /etc/passwd
RUN echo 'en_US.UTF-8 UTF-8' >> /etc/locale.gen && locale-gen
ENV LANG=en_US.UTF-8 
LC_ALL=en_US.UTF-8 
PATH=/opt/app-root/bin:$PATH 
HOME=/opt/app-root
Create non root user
A better container image #2
RUN pip install --no-cache-dir virtualenv && 
virtualenv /opt/app-root && 
. /opt/app-root/bin/activate && 
pip install --no-cache-dir warpdrive && 
warpdrive fixup /opt/app-root
WORKDIR /opt/app-root
COPY . /opt/app-root/src
RUN warpdrive fixup /opt/app-root/src
USER 1001
RUN warpdrive build && 
warpdrive fixup /opt/app-root
EXPOSE 8080
CMD [ "warpdrive", "start" ]
Create a Python

virtual environment
Use warpdrive,
it's magicUse non
root user
Non
privileged
port
Running as non root
$ docker run mypyapp warpdrive exec id
uid=1001(warpdrive) gid=0(root) groups=0(root)
$ docker run -u 100001 mypyapp warpdrive exec id
uid=100001(warpdrive) gid=0(root) groups=0(root)
Default to assigned non root user
Can be run as arbitrary high user ID
Same tools for development
$ warpdrive project mypyapp
(warpdrive+mypyapp) $ warpdrive build
(warpdrive+mypyapp) $ warpdrive start
https://pypi.python.org/pypi/warpdrive
Generate image with no Dockerfile
$ warpdrive image mypyapp
$ docker run --rm -p 80:8080 mypyapp
Source-to-Image
$ s2i build https://github.com/GrahamDumpleton/warpdrive-django-modwsgi 
getwarped/warp0-debian8-python35 mypyapp
https://github.com/openshift/source-to-image
OpenShift
$ oc new-app --image-stream getwarped/warp0-debian8-python35 
--code https://github.com/GrahamDumpleton/warpdrive-django-modwsgi 
--name mypyapp
https://www.openshift.com
Manual Apache configuration
$ mod_wsgi-express module-config
LoadModule wsgi_module "/.../venv/.../mod_wsgi/server/mod_wsgi-py27.so"
WSGIPythonHome "/.../venv"
Friends don’t let friends
use embedded mode
of mod_wsgi
Embedded mode
Daemon mode
Manual daemon mode configuration
WSGIRestrictEmbedded On
WSGIDaemonProcess mypyapp python-home=/.../env
WSGIScriptAlias / /.../src/wsgi.py 
process-group=mypyapp application-group=%{GLOBAL}
<Directory /.../src>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
The missing options
• display-name='%{GROUP}'
• lang='en_US.UTF-8'
• locale='en_US.UTF-8'
• startup-timeout=15
• connect-timeout=15
• socket-timeout=60
• queue-timeout=45
• request-timeout=60
• inactivity-timeout=0
• restart-interval=0
• maximum-requests=0
• shutdown-timeout=5
• deadlock-timeout=60
• graceful-timeout=15
• eviction-timeout=0
http://modwsgi.readthedocs.io/en/develop/configuration-directives/WSGIDaemonProcess.html
Failed application loading
• startup-timeout=15



Defines the maximum number of seconds allowed to pass waiting to
see if a WSGI script file can be loaded successfully by a daemon
process. When the timeout is passed, the process will be restarted.
Connection timeouts
• connect-timeout=15



Defines the maximum amount of time for an Apache child process to wait trying to get a
successful connection to the mod_wsgi daemon processes. This defaults to 15 seconds.
• socket-timeout=60



Defines the timeout on individual reads/writes on the socket connection between the Apache
child processes and the mod_wsgi daemon processes. If not specified, the number of seconds
specified by the Apache Timeout directive will be used instead. See also response-socket-
timeout if need to control this only for writing back content of the response.
• queue-timeout=45



Defines the timeout on how long to wait for a mod_wsgi daemon process to accept a request for
processing. Not enabled by default.
Time triggered restart
• request-timeout=60



Defines the maximum number of seconds that a request is allowed
to run before the daemon process is restarted.
• inactivity-timeout=0



Defines the maximum number of seconds allowed to pass before
the daemon process is shutdown and restarted when the daemon
process has entered an idle state. To restart on stuck requests use
request-timeout instead.
Request Monitoring
import mod_wsgi
def event_handler(name, **kwargs):
if name == 'request_started':
...
elif name == 'request_finished':
environ = kwargs['request_environ']
response_time = kwargs.get('response_time')
cpu_user_time = kwargs.get('cpu_user_time')
cpu_system_time = kwargs.get('cpu_system_time')
...
elif name == 'request_exception':
...
mod_wsgi.subscribe_events(event_handler)
Resources
• mod_wsgi - http://modwsgi.readthedocs.io
• warpdrive - http://warpdrive.readthedocs.io
• Source-to-Image - https://github.com/openshift/source-to-image
• OpenShift - https://www.openshift.com
Friends don't let friends
use Windows for running
Python web applications
Friends don't let friends use the
mod_wsgi which comes packaged
with the operating system
Friends don't let friends use
those other WSGI servers
Friends don't let friends
make things too complicated,
simple is good
Graham.Dumpleton@gmail.com
@GrahamDumpleton
https://www.slideshare.net/GrahamDumpleton/secrets-of-a-wsgi-master

More Related Content

More from Graham Dumpleton

PyCon AU 2015 - Using benchmarks to understand how wsgi servers work
PyCon AU 2015  - Using benchmarks to understand how wsgi servers workPyCon AU 2015  - Using benchmarks to understand how wsgi servers work
PyCon AU 2015 - Using benchmarks to understand how wsgi servers workGraham Dumpleton
 
PyCon NZ 2013 - Advanced Methods For Creating Decorators
PyCon NZ 2013 - Advanced Methods For Creating DecoratorsPyCon NZ 2013 - Advanced Methods For Creating Decorators
PyCon NZ 2013 - Advanced Methods For Creating DecoratorsGraham Dumpleton
 
PyCon US 2013 Making Apache suck less for hosting Python web applications
PyCon US 2013 Making Apache suck less for hosting Python web applicationsPyCon US 2013 Making Apache suck less for hosting Python web applications
PyCon US 2013 Making Apache suck less for hosting Python web applicationsGraham Dumpleton
 
PyCon AU 2010 - Getting Started With Apache/mod_wsgi.
PyCon AU 2010 - Getting Started With Apache/mod_wsgi.PyCon AU 2010 - Getting Started With Apache/mod_wsgi.
PyCon AU 2010 - Getting Started With Apache/mod_wsgi.Graham Dumpleton
 
PyCon US 2012 - State of WSGI 2
PyCon US 2012 - State of WSGI 2PyCon US 2012 - State of WSGI 2
PyCon US 2012 - State of WSGI 2Graham Dumpleton
 
PyCon AU 2012 - Debugging Live Python Web Applications
PyCon AU 2012 - Debugging Live Python Web ApplicationsPyCon AU 2012 - Debugging Live Python Web Applications
PyCon AU 2012 - Debugging Live Python Web ApplicationsGraham Dumpleton
 
PyCon US 2012 - Web Server Bottlenecks and Performance Tuning
PyCon US 2012 - Web Server Bottlenecks and Performance TuningPyCon US 2012 - Web Server Bottlenecks and Performance Tuning
PyCon US 2012 - Web Server Bottlenecks and Performance TuningGraham Dumpleton
 
DjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New RelicDjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New RelicGraham Dumpleton
 

More from Graham Dumpleton (8)

PyCon AU 2015 - Using benchmarks to understand how wsgi servers work
PyCon AU 2015  - Using benchmarks to understand how wsgi servers workPyCon AU 2015  - Using benchmarks to understand how wsgi servers work
PyCon AU 2015 - Using benchmarks to understand how wsgi servers work
 
PyCon NZ 2013 - Advanced Methods For Creating Decorators
PyCon NZ 2013 - Advanced Methods For Creating DecoratorsPyCon NZ 2013 - Advanced Methods For Creating Decorators
PyCon NZ 2013 - Advanced Methods For Creating Decorators
 
PyCon US 2013 Making Apache suck less for hosting Python web applications
PyCon US 2013 Making Apache suck less for hosting Python web applicationsPyCon US 2013 Making Apache suck less for hosting Python web applications
PyCon US 2013 Making Apache suck less for hosting Python web applications
 
PyCon AU 2010 - Getting Started With Apache/mod_wsgi.
PyCon AU 2010 - Getting Started With Apache/mod_wsgi.PyCon AU 2010 - Getting Started With Apache/mod_wsgi.
PyCon AU 2010 - Getting Started With Apache/mod_wsgi.
 
PyCon US 2012 - State of WSGI 2
PyCon US 2012 - State of WSGI 2PyCon US 2012 - State of WSGI 2
PyCon US 2012 - State of WSGI 2
 
PyCon AU 2012 - Debugging Live Python Web Applications
PyCon AU 2012 - Debugging Live Python Web ApplicationsPyCon AU 2012 - Debugging Live Python Web Applications
PyCon AU 2012 - Debugging Live Python Web Applications
 
PyCon US 2012 - Web Server Bottlenecks and Performance Tuning
PyCon US 2012 - Web Server Bottlenecks and Performance TuningPyCon US 2012 - Web Server Bottlenecks and Performance Tuning
PyCon US 2012 - Web Server Bottlenecks and Performance Tuning
 
DjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New RelicDjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New Relic
 

Recently uploaded

Call Girls In Sukhdev Vihar Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Sukhdev Vihar Delhi 💯Call Us 🔝8264348440🔝Call Girls In Sukhdev Vihar Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Sukhdev Vihar Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
CALL ON ➥8923113531 🔝Call Girls Lucknow Lucknow best sexual service Online
CALL ON ➥8923113531 🔝Call Girls Lucknow Lucknow best sexual service OnlineCALL ON ➥8923113531 🔝Call Girls Lucknow Lucknow best sexual service Online
CALL ON ➥8923113531 🔝Call Girls Lucknow Lucknow best sexual service Onlineanilsa9823
 
Enjoy Night⚡Call Girls Dlf City Phase 3 Gurgaon >༒8448380779 Escort Service
Enjoy Night⚡Call Girls Dlf City Phase 3 Gurgaon >༒8448380779 Escort ServiceEnjoy Night⚡Call Girls Dlf City Phase 3 Gurgaon >༒8448380779 Escort Service
Enjoy Night⚡Call Girls Dlf City Phase 3 Gurgaon >༒8448380779 Escort ServiceDelhi Call girls
 
✂️ 👅 Independent Andheri Escorts With Room Vashi Call Girls 💃 9004004663
✂️ 👅 Independent Andheri Escorts With Room Vashi Call Girls 💃 9004004663✂️ 👅 Independent Andheri Escorts With Room Vashi Call Girls 💃 9004004663
✂️ 👅 Independent Andheri Escorts With Room Vashi Call Girls 💃 9004004663Call Girls Mumbai
 
Pune Airport ( Call Girls ) Pune 6297143586 Hot Model With Sexy Bhabi Ready...
Pune Airport ( Call Girls ) Pune  6297143586  Hot Model With Sexy Bhabi Ready...Pune Airport ( Call Girls ) Pune  6297143586  Hot Model With Sexy Bhabi Ready...
Pune Airport ( Call Girls ) Pune 6297143586 Hot Model With Sexy Bhabi Ready...tanu pandey
 
𓀤Call On 7877925207 𓀤 Ahmedguda Call Girls Hot Model With Sexy Bhabi Ready Fo...
𓀤Call On 7877925207 𓀤 Ahmedguda Call Girls Hot Model With Sexy Bhabi Ready Fo...𓀤Call On 7877925207 𓀤 Ahmedguda Call Girls Hot Model With Sexy Bhabi Ready Fo...
𓀤Call On 7877925207 𓀤 Ahmedguda Call Girls Hot Model With Sexy Bhabi Ready Fo...Neha Pandey
 
Call Girls Dubai Prolapsed O525547819 Call Girls In Dubai Princes$
Call Girls Dubai Prolapsed O525547819 Call Girls In Dubai Princes$Call Girls Dubai Prolapsed O525547819 Call Girls In Dubai Princes$
Call Girls Dubai Prolapsed O525547819 Call Girls In Dubai Princes$kojalkojal131
 
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
Hire↠Young Call Girls in Tilak nagar (Delhi) ☎️ 9205541914 ☎️ Independent Esc...
Hire↠Young Call Girls in Tilak nagar (Delhi) ☎️ 9205541914 ☎️ Independent Esc...Hire↠Young Call Girls in Tilak nagar (Delhi) ☎️ 9205541914 ☎️ Independent Esc...
Hire↠Young Call Girls in Tilak nagar (Delhi) ☎️ 9205541914 ☎️ Independent Esc...Delhi Call girls
 
VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting High Prof...
VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting  High Prof...VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting  High Prof...
VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting High Prof...singhpriety023
 
On Starlink, presented by Geoff Huston at NZNOG 2024
On Starlink, presented by Geoff Huston at NZNOG 2024On Starlink, presented by Geoff Huston at NZNOG 2024
On Starlink, presented by Geoff Huston at NZNOG 2024APNIC
 
Call Girls In Pratap Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Pratap Nagar Delhi 💯Call Us 🔝8264348440🔝Call Girls In Pratap Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Pratap Nagar Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
Call Girls Service Chandigarh Lucky ❤️ 7710465962 Independent Call Girls In C...
Call Girls Service Chandigarh Lucky ❤️ 7710465962 Independent Call Girls In C...Call Girls Service Chandigarh Lucky ❤️ 7710465962 Independent Call Girls In C...
Call Girls Service Chandigarh Lucky ❤️ 7710465962 Independent Call Girls In C...Sheetaleventcompany
 
AWS Community DAY Albertini-Ellan Cloud Security (1).pptx
AWS Community DAY Albertini-Ellan Cloud Security (1).pptxAWS Community DAY Albertini-Ellan Cloud Security (1).pptx
AWS Community DAY Albertini-Ellan Cloud Security (1).pptxellan12
 
(+971568250507 ))# Young Call Girls in Ajman By Pakistani Call Girls in ...
(+971568250507  ))#  Young Call Girls  in Ajman  By Pakistani Call Girls  in ...(+971568250507  ))#  Young Call Girls  in Ajman  By Pakistani Call Girls  in ...
(+971568250507 ))# Young Call Girls in Ajman By Pakistani Call Girls in ...Escorts Call Girls
 
Call Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service Available
Call Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service AvailableCall Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service Available
Call Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service AvailableSeo
 
Lucknow ❤CALL GIRL 88759*99948 ❤CALL GIRLS IN Lucknow ESCORT SERVICE❤CALL GIRL
Lucknow ❤CALL GIRL 88759*99948 ❤CALL GIRLS IN Lucknow ESCORT SERVICE❤CALL GIRLLucknow ❤CALL GIRL 88759*99948 ❤CALL GIRLS IN Lucknow ESCORT SERVICE❤CALL GIRL
Lucknow ❤CALL GIRL 88759*99948 ❤CALL GIRLS IN Lucknow ESCORT SERVICE❤CALL GIRLimonikaupta
 

Recently uploaded (20)

Call Girls In Sukhdev Vihar Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Sukhdev Vihar Delhi 💯Call Us 🔝8264348440🔝Call Girls In Sukhdev Vihar Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Sukhdev Vihar Delhi 💯Call Us 🔝8264348440🔝
 
CALL ON ➥8923113531 🔝Call Girls Lucknow Lucknow best sexual service Online
CALL ON ➥8923113531 🔝Call Girls Lucknow Lucknow best sexual service OnlineCALL ON ➥8923113531 🔝Call Girls Lucknow Lucknow best sexual service Online
CALL ON ➥8923113531 🔝Call Girls Lucknow Lucknow best sexual service Online
 
Enjoy Night⚡Call Girls Dlf City Phase 3 Gurgaon >༒8448380779 Escort Service
Enjoy Night⚡Call Girls Dlf City Phase 3 Gurgaon >༒8448380779 Escort ServiceEnjoy Night⚡Call Girls Dlf City Phase 3 Gurgaon >༒8448380779 Escort Service
Enjoy Night⚡Call Girls Dlf City Phase 3 Gurgaon >༒8448380779 Escort Service
 
✂️ 👅 Independent Andheri Escorts With Room Vashi Call Girls 💃 9004004663
✂️ 👅 Independent Andheri Escorts With Room Vashi Call Girls 💃 9004004663✂️ 👅 Independent Andheri Escorts With Room Vashi Call Girls 💃 9004004663
✂️ 👅 Independent Andheri Escorts With Room Vashi Call Girls 💃 9004004663
 
Pune Airport ( Call Girls ) Pune 6297143586 Hot Model With Sexy Bhabi Ready...
Pune Airport ( Call Girls ) Pune  6297143586  Hot Model With Sexy Bhabi Ready...Pune Airport ( Call Girls ) Pune  6297143586  Hot Model With Sexy Bhabi Ready...
Pune Airport ( Call Girls ) Pune 6297143586 Hot Model With Sexy Bhabi Ready...
 
𓀤Call On 7877925207 𓀤 Ahmedguda Call Girls Hot Model With Sexy Bhabi Ready Fo...
𓀤Call On 7877925207 𓀤 Ahmedguda Call Girls Hot Model With Sexy Bhabi Ready Fo...𓀤Call On 7877925207 𓀤 Ahmedguda Call Girls Hot Model With Sexy Bhabi Ready Fo...
𓀤Call On 7877925207 𓀤 Ahmedguda Call Girls Hot Model With Sexy Bhabi Ready Fo...
 
Call Girls Dubai Prolapsed O525547819 Call Girls In Dubai Princes$
Call Girls Dubai Prolapsed O525547819 Call Girls In Dubai Princes$Call Girls Dubai Prolapsed O525547819 Call Girls In Dubai Princes$
Call Girls Dubai Prolapsed O525547819 Call Girls In Dubai Princes$
 
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝
 
Hire↠Young Call Girls in Tilak nagar (Delhi) ☎️ 9205541914 ☎️ Independent Esc...
Hire↠Young Call Girls in Tilak nagar (Delhi) ☎️ 9205541914 ☎️ Independent Esc...Hire↠Young Call Girls in Tilak nagar (Delhi) ☎️ 9205541914 ☎️ Independent Esc...
Hire↠Young Call Girls in Tilak nagar (Delhi) ☎️ 9205541914 ☎️ Independent Esc...
 
@9999965857 🫦 Sexy Desi Call Girls Laxmi Nagar 💓 High Profile Escorts Delhi 🫶
@9999965857 🫦 Sexy Desi Call Girls Laxmi Nagar 💓 High Profile Escorts Delhi 🫶@9999965857 🫦 Sexy Desi Call Girls Laxmi Nagar 💓 High Profile Escorts Delhi 🫶
@9999965857 🫦 Sexy Desi Call Girls Laxmi Nagar 💓 High Profile Escorts Delhi 🫶
 
VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting High Prof...
VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting  High Prof...VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting  High Prof...
VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting High Prof...
 
Rohini Sector 26 Call Girls Delhi 9999965857 @Sabina Saikh No Advance
Rohini Sector 26 Call Girls Delhi 9999965857 @Sabina Saikh No AdvanceRohini Sector 26 Call Girls Delhi 9999965857 @Sabina Saikh No Advance
Rohini Sector 26 Call Girls Delhi 9999965857 @Sabina Saikh No Advance
 
On Starlink, presented by Geoff Huston at NZNOG 2024
On Starlink, presented by Geoff Huston at NZNOG 2024On Starlink, presented by Geoff Huston at NZNOG 2024
On Starlink, presented by Geoff Huston at NZNOG 2024
 
Call Girls In Pratap Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Pratap Nagar Delhi 💯Call Us 🔝8264348440🔝Call Girls In Pratap Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Pratap Nagar Delhi 💯Call Us 🔝8264348440🔝
 
Call Girls Service Chandigarh Lucky ❤️ 7710465962 Independent Call Girls In C...
Call Girls Service Chandigarh Lucky ❤️ 7710465962 Independent Call Girls In C...Call Girls Service Chandigarh Lucky ❤️ 7710465962 Independent Call Girls In C...
Call Girls Service Chandigarh Lucky ❤️ 7710465962 Independent Call Girls In C...
 
(INDIRA) Call Girl Pune Call Now 8250077686 Pune Escorts 24x7
(INDIRA) Call Girl Pune Call Now 8250077686 Pune Escorts 24x7(INDIRA) Call Girl Pune Call Now 8250077686 Pune Escorts 24x7
(INDIRA) Call Girl Pune Call Now 8250077686 Pune Escorts 24x7
 
AWS Community DAY Albertini-Ellan Cloud Security (1).pptx
AWS Community DAY Albertini-Ellan Cloud Security (1).pptxAWS Community DAY Albertini-Ellan Cloud Security (1).pptx
AWS Community DAY Albertini-Ellan Cloud Security (1).pptx
 
(+971568250507 ))# Young Call Girls in Ajman By Pakistani Call Girls in ...
(+971568250507  ))#  Young Call Girls  in Ajman  By Pakistani Call Girls  in ...(+971568250507  ))#  Young Call Girls  in Ajman  By Pakistani Call Girls  in ...
(+971568250507 ))# Young Call Girls in Ajman By Pakistani Call Girls in ...
 
Call Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service Available
Call Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service AvailableCall Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service Available
Call Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service Available
 
Lucknow ❤CALL GIRL 88759*99948 ❤CALL GIRLS IN Lucknow ESCORT SERVICE❤CALL GIRL
Lucknow ❤CALL GIRL 88759*99948 ❤CALL GIRLS IN Lucknow ESCORT SERVICE❤CALL GIRLLucknow ❤CALL GIRL 88759*99948 ❤CALL GIRLS IN Lucknow ESCORT SERVICE❤CALL GIRL
Lucknow ❤CALL GIRL 88759*99948 ❤CALL GIRLS IN Lucknow ESCORT SERVICE❤CALL GIRL
 

Secrets of a WSGI master

  • 1. Secrets of
 a WSGI master. Graham Dumpleton
 Graham.Dumpleton@gmail.com @GrahamDumpleton https://www.slideshare.net/GrahamDumpleton/secrets-of-a-wsgi-master
  • 2. What is WSGI? Web Browser Web Browser Web Browser Web Server HTTP HTTP HTTP File System (Static Files) Python Web Application WSGI WSGI == Web Server Gateway Interface (PEP 3333)
  • 3. WSGI is a specification for an Application Programming Interface WSGI is NOT a wire protocol WSGI is NOT an implementation of any anything
  • 4. def application(environ, start_response): status = '200 OK' output = b'Hello World!' response_headers = [ ('Content-Type', 'text/plain'), ('Content-Length', str(len(output)))] start_response(status, response_headers) return [output]
  • 5. Friends don’t let friends use raw WSGI
  • 6.
  • 7. You still need a way to host a WSGI application The development servers builtin to a framework are not good enough
  • 8. Installing mod_wsgi the easy way pip install mod_wsgi https://pypi.python.org/pypi/mod_wsgi
  • 9. Run mod_wsgi from the command line mod_wsgi-express start-server wsgi.py
  • 10. No Apache configuration required $ mod_wsgi-express start-server wsgi.py Server URL : http://localhost:8000/ Server Root : /tmp/mod_wsgi-localhost:8000:502 Server Conf : /tmp/mod_wsgi-localhost:8000:502/httpd.conf Error Log File : /tmp/mod_wsgi-localhost:8000:502/error_log (warn) Request Capacity : 5 (1 process * 5 threads) Request Timeout : 60 (seconds) Startup Timeout : 15 (seconds) Queue Backlog : 100 (connections) Queue Timeout : 45 (seconds) Server Capacity : 20 (event/worker), 20 (prefork) Server Backlog : 500 (connections) Locale Setting : en_AU.UTF-8
  • 11. Django framework integration INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'mod_wsgi.server', ] Add mod_wsgi.server
  • 12. Run with Django management command python manage.py runmodwsgi
  • 13. Automatic code reloading python manage.py runmodwsgi --reload-on-changes
  • 14. Interactive debugger python manage.py runmodwsgi --enable-debugger
  • 15. Production configuration #1 python manage.py runmodwsgi --server-root /etc/wsgi-port-80 --user www-data --group www-data --port 80 --setup-only
  • 16. Production configuration #2 mod_wsgi-express start-server wsgi.py --server-root /etc/wsgi-port-80 --user www-data --group www-data --port 80 --url-alias /static static --setup-only
  • 17. Running in production /etc/wsgi-port-80/apachectl start /etc/wsgi-port-80/apachectl restart /etc/wsgi-port-80/apachectl stop
  • 18. Build a container image FROM python:3 RUN apt-get update && apt-get install -y --no-install-recommends apache2 apache2-dev locales && apt-get clean && rm -r /var/lib/apt/lists/* RUN echo 'en_US.UTF-8 UTF-8' >> /etc/locale.gen && locale-gen ENV LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 RUN pip install --no-cache-dir mod_wsgi WORKDIR /opt/app-root COPY . /opt/app-root EXPOSE 80 CMD [ "mod_wsgi-express", "start-server", "--port", "80", "--user", "www-data", "--group", "www-data", "--log-to-terminal", "wsgi.py" ] Install Apache Fix Unicode Problems Run mod_wsgi-express
  • 19. Building the container $ docker build -t mypyapp . Sending build context to Docker daemon 3.584kB Step 1/9 : FROM python:3 ---> 968120d8cbe8 Step 2/9 : WORKDIR /opt/app-root ---> Using cache ---> 003096a40d39 Step 3/9 : .......
  • 20. Starting the container $ docker run --rm -p 80:80 mypyapp
  • 21. Friends don’t let friends run containers as root
  • 22. Friends don’t let friends use Python without a Python virtual environment
  • 23. A better container image #1 FROM python:3 RUN apt-get update && apt-get install -y --no-install-recommends apache2 apache2-dev locales && apt-get clean && rm -r /var/lib/apt/lists/* RUN adduser --disabled-password --gecos "Warp Drive" --uid 1001 --gid 0 --home /opt/app-root warpdrive && chmod g+w /etc/passwd RUN echo 'en_US.UTF-8 UTF-8' >> /etc/locale.gen && locale-gen ENV LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 PATH=/opt/app-root/bin:$PATH HOME=/opt/app-root Create non root user
  • 24. A better container image #2 RUN pip install --no-cache-dir virtualenv && virtualenv /opt/app-root && . /opt/app-root/bin/activate && pip install --no-cache-dir warpdrive && warpdrive fixup /opt/app-root WORKDIR /opt/app-root COPY . /opt/app-root/src RUN warpdrive fixup /opt/app-root/src USER 1001 RUN warpdrive build && warpdrive fixup /opt/app-root EXPOSE 8080 CMD [ "warpdrive", "start" ] Create a Python
 virtual environment Use warpdrive, it's magicUse non root user Non privileged port
  • 25. Running as non root $ docker run mypyapp warpdrive exec id uid=1001(warpdrive) gid=0(root) groups=0(root) $ docker run -u 100001 mypyapp warpdrive exec id uid=100001(warpdrive) gid=0(root) groups=0(root) Default to assigned non root user Can be run as arbitrary high user ID
  • 26. Same tools for development $ warpdrive project mypyapp (warpdrive+mypyapp) $ warpdrive build (warpdrive+mypyapp) $ warpdrive start https://pypi.python.org/pypi/warpdrive
  • 27. Generate image with no Dockerfile $ warpdrive image mypyapp $ docker run --rm -p 80:8080 mypyapp
  • 28. Source-to-Image $ s2i build https://github.com/GrahamDumpleton/warpdrive-django-modwsgi getwarped/warp0-debian8-python35 mypyapp https://github.com/openshift/source-to-image
  • 29. OpenShift $ oc new-app --image-stream getwarped/warp0-debian8-python35 --code https://github.com/GrahamDumpleton/warpdrive-django-modwsgi --name mypyapp https://www.openshift.com
  • 30. Manual Apache configuration $ mod_wsgi-express module-config LoadModule wsgi_module "/.../venv/.../mod_wsgi/server/mod_wsgi-py27.so" WSGIPythonHome "/.../venv"
  • 31. Friends don’t let friends use embedded mode of mod_wsgi
  • 34. Manual daemon mode configuration WSGIRestrictEmbedded On WSGIDaemonProcess mypyapp python-home=/.../env WSGIScriptAlias / /.../src/wsgi.py process-group=mypyapp application-group=%{GLOBAL} <Directory /.../src> <Files wsgi.py> Require all granted </Files> </Directory>
  • 35. The missing options • display-name='%{GROUP}' • lang='en_US.UTF-8' • locale='en_US.UTF-8' • startup-timeout=15 • connect-timeout=15 • socket-timeout=60 • queue-timeout=45 • request-timeout=60 • inactivity-timeout=0 • restart-interval=0 • maximum-requests=0 • shutdown-timeout=5 • deadlock-timeout=60 • graceful-timeout=15 • eviction-timeout=0 http://modwsgi.readthedocs.io/en/develop/configuration-directives/WSGIDaemonProcess.html
  • 36. Failed application loading • startup-timeout=15
 
 Defines the maximum number of seconds allowed to pass waiting to see if a WSGI script file can be loaded successfully by a daemon process. When the timeout is passed, the process will be restarted.
  • 37. Connection timeouts • connect-timeout=15
 
 Defines the maximum amount of time for an Apache child process to wait trying to get a successful connection to the mod_wsgi daemon processes. This defaults to 15 seconds. • socket-timeout=60
 
 Defines the timeout on individual reads/writes on the socket connection between the Apache child processes and the mod_wsgi daemon processes. If not specified, the number of seconds specified by the Apache Timeout directive will be used instead. See also response-socket- timeout if need to control this only for writing back content of the response. • queue-timeout=45
 
 Defines the timeout on how long to wait for a mod_wsgi daemon process to accept a request for processing. Not enabled by default.
  • 38. Time triggered restart • request-timeout=60
 
 Defines the maximum number of seconds that a request is allowed to run before the daemon process is restarted. • inactivity-timeout=0
 
 Defines the maximum number of seconds allowed to pass before the daemon process is shutdown and restarted when the daemon process has entered an idle state. To restart on stuck requests use request-timeout instead.
  • 39. Request Monitoring import mod_wsgi def event_handler(name, **kwargs): if name == 'request_started': ... elif name == 'request_finished': environ = kwargs['request_environ'] response_time = kwargs.get('response_time') cpu_user_time = kwargs.get('cpu_user_time') cpu_system_time = kwargs.get('cpu_system_time') ... elif name == 'request_exception': ... mod_wsgi.subscribe_events(event_handler)
  • 40. Resources • mod_wsgi - http://modwsgi.readthedocs.io • warpdrive - http://warpdrive.readthedocs.io • Source-to-Image - https://github.com/openshift/source-to-image • OpenShift - https://www.openshift.com
  • 41. Friends don't let friends use Windows for running Python web applications
  • 42. Friends don't let friends use the mod_wsgi which comes packaged with the operating system
  • 43. Friends don't let friends use those other WSGI servers
  • 44. Friends don't let friends make things too complicated, simple is good