33
19.2.2 Tornado
Tornadoisanopensourceversionofthescalable,non-blockingwebserverandtools
that powerFriendFeed. Because it is non-blocking and uses epoll, it can handle thou-
sandsof simultaneous standing connections,which meansit is idealfor real-timeweb
services. Integrating this servicewith Flask is straightforward:
from tornado.wsgi import WSGIContainer
from tornado.httpserver import t HTTPServer
from tornado.ioloop import IOLoop
from yourapplication import app
http_server = HTTPServer(WSGIContainer(app))
http_server.listen(5000)
IOLoop.instance().start()
19.2.3 Gevent
Geventisacoroutine-basedPythonnetworkinglibrarythatuses greenlettoprovidea
high-level synchronous API on top oflibevent event loop:
from gevent.wsgi import WSGIServer
from yourapplication import app
http_server = WSGIServer((, , 5000), app)
http_server.serve_forever()
19.2.4 Twisted Web
Twisted Webisthewebservershippedwith Twisted,amature,non-blockingevent-
driven networkinglibrary. TwistedWebcomes witha standard WSGI containerwhich
can be controlledfrom the commandline using the twistd utility:
twistd web --wsgi myproject.app
Thisexample will run a Flask application calledapp from amodule namedmyproject.
TwistedWeb supportsmany flagsand options, and the twistdutility doesas well; see
twistd -h and twistd web -h for more information. For example, to run a Twisted
Web server in the foreground, on port 8080, with an application from myproject:
twistd -n web --port 8080 --wsgi myproject.app
19.2.5 Proxy Setups
If you deploy your application using one of these servers behind an HTTP proxy
you will need to rewrite a few headers in order for the application to work. The
161
45
two problematic values in the WSGI environment usually are REMOTE_ADDR and
HTTP_HOST. Youcan configure your httpdtopass theseheaders, or youcan fix them
in middleware. Werkzeug ships a fixer that will solve some common setups, but you
might want to write your own WSGI middleware for specific setups.
Here’s a simple nginx configuration which proxies to an application served on local-
host at port 8000, setting appropriateheaders:
server {
listen 80;
server_name _;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
proxy_pass
http://127.0.0.1:8000/;
proxy_redirect
off;
proxy_set_header
Host
$host;
proxy_set_header
X-Real-IP
$remote_addr;
proxy_set_header
X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
If your httpd is not providing theseheaders,themost common setupinvokes the host
being set from X-Forwarded-Host and the remoteaddress from X-Forwarded-For:
from werkzeug.contrib.fixers import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app)
Trusting Headers
Pleasekeep in mind that it is a securityissue tousesuch a middlewarein a non-proxy
setup because it will blindly trust the incoming headers which might be forged by
malicious clients.
If you want torewrite theheadersfrom another header, youmight want to use a fixer
like this:
class CustomProxyFix(object):
def __init__(self, app):
self.app = app
def __call__(self, environ, , start_response):
host = environ.get(HTTP_X_FHOST, , )
if host:
environ[HTTP_HOST] = host
return self.app(environ, start_response)
162
31
app.wsgi_app = CustomProxyFix(app.wsgi_app)
19.3 uWSGI
uWSGI is a deployment option on servers like e nginx, lighttpd , and d cherokee; see
FastCGI and Standalone WSGI Containers for other options. To use your WSGI appli-
cation with uWSGI protocol you will need a uWSGI server first. uWSGI is both a
protocol and an application server; the application server can serve uWSGI, FastCGI,
and HTTPprotocols.
ThemostpopularuWSGI server isuwsgi,whichwewill usefor thisguide. Makesure
to have it installed to follow along.
Watch Out
Pleasemakesurein advancethat anyapp.run() calls you might havein your applica-
tion file are inside an if __name__ == ’__main__’: block or moved to a separate file.
Just make sure it’s not called becausethis willalways start a local WSGI server which
we donot want if we deploy that application to uWSGI.
19.3.1 Starting your app with uwsgi
uwsgiisdesigned tooperate on WSGI callablesfound in python modules.
Given a flask application in myapp.py, use the following command:
$ uwsgi -s /tmp/uwsgi.sock --module myapp --callable app
Or, if you prefer:
$ uwsgi -s /tmp/uwsgi.sock -w myapp:app
19.3.2 Configuring nginx
Abasic flask uWSGI configuration for nginx looks like this:
location = /yourapplication { rewrite ^ /yourapplication/; }
location /yourapplication { try_files $uri @yourapplication; }
location @yourapplication {
include uwsgi_params;
uwsgi_param SCRIPT_NAME /yourapplication;
uwsgi_modifier1 30;
uwsgi_pass unix:/tmp/uwsgi.sock;
}
163
34
Thisconfiguration bindstheapplication to/yourapplication. If youwanttohaveit in the
URL root it’s a bit simpler because you don’t have to tell it the WSGI SCRIPT_NAME
or set the uwsgi modifier tomake use of it:
location / { try_files $uri @yourapplication; }
location @yourapplication {
include uwsgi_params;
uwsgi_pass unix:/tmp/uwsgi.sock;
}
19.4 FastCGI
FastCGI is a deployment option on servers likenginx, , lighttpd , andcherokee; see
uWSGI and Standalone WSGI Containers for other options. To use your WSGI applica-
tion with any of them you will need a FastCGI server first. The most popular one is
flupwhichwewilluseforthisguide.Makesuretohaveitinstalledtofollowalong.
Watch Out
Pleasemakesurein advancethat anyapp.run() calls you might havein your applica-
tion file are inside an if __name__ == ’__main__’: block or moved to a separate file.
Just make sure it’s not called becausethis willalways start a local WSGI server which
we donot want if we deploy that application to FastCGI.
19.4.1 Creating a .fcgi file
First you need to create the FastCGI server file. Let’scall it yourapplication.fcgi:
#!/usr/bin/python
from flup.server.fcgi import WSGIServer
from yourapplication import app
if __name__ == __main__:
WSGIServer(app).run()
Thisisenoughfor Apachetowork, however nginx andolderversionsof lighttpdneed
asocket to be explicitly passed to communicate with the FastCGI server. For that to
work youneed topass the path to the socket to the WSGIServer:
WSGIServer(application, bindAddress=/path/to/fcgi.sock).run()
The path has to be the exact same path you define in the server config.
Save the yourapplication.fcgi file somewhere you will find it again. It makes sense to
have that in /var/www/yourapplication or something similar.
Make sure toset the executable bit on that file so that the servers can executeit:
164
40
# chmod +x /var/www/yourapplication/yourapplication.fcgi
19.4.2 Configuring Apache
The example above is good enough for a basic Apache deployment but your .fcgi file
will appear in your application URL e.g. example.com/yourapplication.fcgi/news/.
Therearefew waystoconfigure yourapplication sothatyourapplication.fcgidoes not
appear in the URL. A preferable way is to use theScriptAlias configuration directive:
<VirtualHost *>
ServerName example.com
ScriptAlias / /path/to/yourapplication.fcgi/
</VirtualHost>
If you cannot set ScriptAlias, for example on an shared web host, you can use WSGI
middlewaretoremoveyourapplication.fcgi from the URLs. Set .htaccess:
<IfModule mod_fcgid.c>
AddHandler fcgid-script .fcgi
<Files ~ (\.fcgi)>
SetHandler fcgid-script
Options +FollowSymLinks +ExecCGI
</Files>
</IfModule>
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ yourapplication.fcgi/$1 [QSA,L]
</IfModule>
Set yourapplication.fcgi:
#!/usr/bin/python
#: optional path to your local python site-packages folder
import sys
sys.path.insert(0, <your_local_path>/lib/python2.6/site-packages)
from flup.server.fcgi import WSGIServer
from yourapplication import app
class ScriptNameStripper(object):
def __init__(self, app):
self.app = app
def __call__(self, environ, , start_response):
environ[SCRIPT_NAME] =
return self.app(environ, start_response)
165
37
app = ScriptNameStripper(app)
if __name__ == __main__:
WSGIServer(app).run()
19.4.3 Configuring lighttpd
Abasic FastCGI configuration for lighttpd looks likethat:
fastcgi.server = ("/yourapplication.fcgi" =>
((
"socket" => "/tmp/yourapplication-fcgi.sock",
"bin-path" => "/var/www/yourapplication/yourapplication.fcgi",
"check-local" => "disable",
"max-procs" => 1
))
)
alias.url = (
"/static/" => "/path/to/your/static"
)
url.rewrite-once = (
"^(/static($|/.*))$" => "$1",
"^(/.*)$" => "/yourapplication.fcgi$1"
Remembertoenable theFastCGI, aliasandrewritemodules. This configurationbinds
the application to/yourapplication. If youwant the application toworkin the URLroot
youhave to work arounda lighttpdbug with theLighttpdCGIRootFix middleware.
Make sure to apply it only if you are mounting the application the URL root. Also,
see the Lighty docs for more information onFastCGIandPython (note that explicitly
passing a socket to run() is no longer necessary).
19.4.4 Configuring nginx
Installing FastCGI applications on nginx is a bit different because by default no
FastCGI parameters are forwarded.
Abasic flask FastCGI configuration for nginx looks like this:
location = /yourapplication { rewrite ^ /yourapplication/ last; }
location /yourapplication { try_files $uri @yourapplication; }
location @yourapplication {
include fastcgi_params;
fastcgi_split_path_info ^(/yourapplication)(.*)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
166
C# Image: Save or Print Document and Image in Web Viewer or image, you can easily save the changes to DLL Library, including documents TIFF, PDF, Excel, Word string fileName = Request.Form["saveFileName"]; string fid
extracting data from pdf into excel; exporting pdf data to excel
39
fastcgi_pass unix:/tmp/yourapplication-fcgi.sock;
}
This configuration binds the application to /yourapplication. If you want to have it in
the URL root it’s a bit simpler because you don’t have to figure out how to calculate
PATH_INFO andSCRIPT_NAME:
location / { try_files $uri @yourapplication; }
location @yourapplication {
include fastcgi_params;
fastcgi_param PATH_INFO $fastcgi_script_name;
fastcgi_param SCRIPT_NAME "";
fastcgi_pass unix:/tmp/yourapplication-fcgi.sock;
}
19.4.5 Running FastCGI Processes
SinceNginx andothersdonot loadFastCGI apps,youhavetodoitbyyourself.Super-
visor can manage FastCGI processes. . YoucanlookaroundforotherFastCGIprocess
managers or writea script to run your .fcgifileat boot,e.g. using aSysV init.d script.
For atemporary solution, youcan alwaysrun the.fcgi script insideGNU screen. See
man screen for details, and note that this is a manual solution which does not persist
acrosssystem restart:
$ screen
$ /var/www/yourapplication/yourapplication.fcgi
19.4.6 Debugging
FastCGI deployments tend to be hard to debug on most webservers. Very often the
only thing the server log tells you is something along the lines of “premature end of
headers”. In order to debug the application the only thing that can really give you
ideas why it breaks is switching to the correct user and executing the application by
hand.
This example assumes your application is called application.fcgi and that your web-
server user iswww-data:
$ su www-data
$ cd /var/www/yourapplication
$ python application.fcgi
Traceback (most recent call last):
File "yourapplication.fcgi", line 4, in <module>
ImportError: No module named yourapplication
In this case the error seems to be “yourapplication” not being on the python path.
Common problemsare:
• Relativepaths being used. Don’t rely on thecurrent working directory
167
31
• Thecodedepending onenvironment variablesthat arenot set bythewebserver.
• Different python interpreters being used.
19.5 CGI
If all other deployment methods do not work, CGI will work for sure. CGI is sup-
ported by all major servers but usually has a sub-optimal performance.
This is also the way you can use a Flask application on Google’sAppEngine, where
execution happens in a CGI-like environment.
Watch Out
Pleasemakesurein advancethat anyapp.run() calls you might havein your applica-
tion file are inside an if __name__ == ’__main__’: block or moved to a separate file.
Just make sure it’s not called becausethis willalways start a local WSGI server which
we donot want if we deploy that application to CGI /app engine.
With CGI, you will also have to make sure that your code does not contain any print
statements, or that sys.stdout is overridden by something that doesn’t write into the
HTTPresponse.
19.5.1 Creating a .cgi file
First you need to create the CGI application file. Let’scall it yourapplication.cgi:
#!/usr/bin/python
from wsgiref.handlers import CGIHandler
from yourapplication import app
CGIHandler().run(app)
19.5.2 Server Setup
Usually there are two ways to configure the server. Either just copy the .cgi into a
cgi-bin (anduse mod_rewrite or something similar to rewrite the URL) or let the server
point tothefiledirectly.
In Apache for example you can put something like thisintotheconfig:
ScriptAlias /app /path/to/the/application.cgi
On shared webhosting, though, you might not have access to your Apache config. In
this case, a file called .htaccess, sitting in the public directory you want your app to be
available, works too but theScriptAlias directive won’t work in that case:
168
5
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f # # Dont t interfere with h static c files
RewriteRule ^(.*)$ /path/to/the/application.cgi/$1 [L]
For moreinformation consult the documentation of your webserver.
169
Documents you may be interested
Documents you may be interested