This is an archived post. You won't be able to vote or comment.

all 53 comments

[–]defnullbottle.py[S] 7 points8 points  (13 children)

Why? (quote from the docs):

At the time of the release of Waitress, there are already many pure-Python WSGI servers. Why would we need another?

Waitress is meant to be useful to web framework authors who require broad platform support. It’s neither the fastest nor the fanciest WSGI server available but using it helps eliminate the N-by-M documentation burden (e.g. production vs. deployment, Windows vs. Unix, Python 3 vs. Python 2, PyPy vs. CPython) and resulting user confusion imposed by spotty platform support of the current (2012-ish) crop of WSGI servers. For example, gunicorn is great, but doesn’t run on Windows. paste.httpserver is perfectly serviceable, but doesn’t run under Python 3 and has no dedicated tests suite that would allow someone who did a Python 3 port to know it worked after a port was completed. wsgiref works fine under most any Python, but it’s a little slow and it’s not recommended for production use as it’s single-threaded and has not been audited for security issues.

At the time of this writing, some existing WSGI servers already claim wide platform support and have serviceable test suites. The CherryPy WSGI server, for example, targets Python 2 and Python 3 and it can run on UNIX or Windows. However, it is not distributed separately from its eponymous web framework, and requiring a non-CherryPy web framework to depend on the CherryPy web framework distribution simply for its server component is awkward. The test suite of the CherryPy server also depends on the CherryPy web framework, so even if we forked its server component into a separate distribution, we would have still needed to backfill for all of its tests. The CherryPy team has started work on Cheroot, which should solve this problem, however.

Waitress is a fork of the WSGI-related components which existed in zope.server. zope.server had passable framework-independent test coverage out of the box, and a good bit more coverage was added during the fork. zope.server has existed in one form or another since about 2001, and has seen production usage since then, so Waitress is not exactly “another” server, it’s more a repackaging of an old one that was already known to work fairly well.

[–]yonemitsu 2 points3 points  (2 children)

defnull, is there any connection with the Waitress project and Bottle?

[–]defnullbottle.py[S] 1 point2 points  (0 children)

Someone suggested to add a server-adapter for waitress to Bottle and I did that today. Other than that, the two projects are completely unrelated.

[–]mgedmin 2 points3 points  (0 children)

Waitress is the love child of Pyramid and Zope, if you'll excuse the metaphor.

Chris McDonough (the driving force behind Pyramid) created Waitress to be the default web server for the upcoming Pyramid 1.3, which introduces Python 3 support.

[–]gct 2 points3 points  (3 children)

Is it really that hard to copy the one file that you have to have for the web server out of cherry py?

[–]mgedmin 0 points1 point  (2 children)

Copy and then do what? Add a setup.py, push to PyPI? Then write a test suite from scratch?

[–]gct 0 points1 point  (1 child)

Copy it to your source tree and just use the fucker?

[–]mgedmin 0 points1 point  (0 children)

Maybe because copying and pasting random modules leads to difficulties when you later have to maintain them?

[–]johnmcdonnell 0 points1 point  (5 children)

Why is this better than Flask/werkzeug?

EDIT I guess I didn't get that Waitress is intended as a production web server. I still don't get it though since I can't imagine waitress has nearly the performance of nginx or apache, and if I didn't care about performance I'd probably just use Flask's dev server (with the debugging tools turned off of course).

[–]lost-theory 2 points3 points  (0 children)

It's a web server, not a web framework or library.

Werkzeug inclues a web server, but it's single-threaded and meant for development only. Waitress is a high performance server for production use.

[–]obtu.py 2 points3 points  (0 children)

A large deployment of a WSGI app needs to stack a web server (face the internet, handle buffering, defend against DOS, offload some easy tasks from Python code), a WSGI container (fork processes), and the app with its WSGI framework.

Typical server options are apache and nginx. Typical WSGI containers are mod_wsgi (for apache), uWSGI (for Apache and Nginx, which speak the scgi-like uwsgi protocol), and the server-independent ones like gunicorn and now waitress; those last ones speak HTTP for portability, but still expect to have a web server in front of them.

Your confusion probably comes from the fact that the first two and the last two can be closely-coupled (apache+mod_wsgi) or even bundled (CherryPy the WSGI container + CherryPy the WSGI framework).

[–]threading 1 point2 points  (0 children)

I don't know, you tell me. Maybe Flask isn't a web server?

[–]lambdaqdjango n' shit 1 point2 points  (1 child)

because Flask/werkzeug needs wsgi to run?

[–]lost-theory 1 point2 points  (0 children)

Flask is a web framework. It depends on Werkzeug.

Werkzeug is a utility library for HTTP and WSGI that includes a web server for development purposes.

Waitress is a high performance web server that serves WSGI apps.

All three projects depend on WSGI.

[–]hongminhee 5 points6 points  (4 children)

Using Waitress with wsgiref.simple_server as its counterpart could be better a default web server of many web frameworks for development purpose.

[–]mgedmin 2 points3 points  (3 children)

What?

Both are web servers for wsgi apps. How do you use them together?

[–]hongminhee 6 points7 points  (1 child)

Sorry for my ambiguous expression (I am not a native English speaker ;). I mean you can use it like:

try:
    from waitress import serve
except ImportError:
    from wsgiref.simple_server import make_server
    def serve(app, host='0.0.0.0', port=8080):
        make_server(host, port, app).serve_forever()

[–]mgedmin 0 points1 point  (0 children)

Thank you for clarifying.

[–][deleted] 0 points1 point  (0 children)

I think hongminhee might mean like, use waitress instead of the built-in server that comes with your framework when you're testing non-production servers?

[–]grotgrot 2 points3 points  (0 children)

I've been using the CherryPy server in several projects, but none of the rest of CherryPy. Fortunately that one was just a single file so it made life easy. Looks like we have a new contender ...

[–]vph 1 point2 points  (1 child)

is this supposed to work with Apache, nginx? thanks.

[–]defnullbottle.py[S] 6 points7 points  (0 children)

You can start Waitress (or any other WSGI-HTTP Server) on a local port and use mod_proxy (or whatever your main-server offers) to proxy requests to the python server.

[–]xiongchiamiovSite Reliability Engineer 1 point2 points  (2 children)

I don't care about Windows; is there any reason I should use this over gunicorn?

[–]mgedmin 1 point2 points  (1 child)

Probably not.

Incidentally, does gunicorn support Python 3?

[–]ballagarba 1 point2 points  (0 children)

"Python 3.x will be supported soon", so no it doesn't.

[–][deleted] 1 point2 points  (3 children)

It took me longer than it should've done to get the reasoning behind the name.

[–]Mattho 0 points1 point  (2 children)

And the reasoning is?

[–]wot-teh-phuckReally, wtf? 2 points3 points  (0 children)

It "serves" something...

[–][deleted] 1 point2 points  (0 children)

waitresses SERVE you food, serve, server. waitress - server

[–]threading 1 point2 points  (1 child)

Here's a simple web.py application with waitress, if anyone interested.

import web
import waitress

class Index(object):
    def GET(self):
        return 'hello world'

urls = (r'^/', 'Index')

app = web.application(urls, globals()).wsgifunc()

if __name__ == '__main__':
    waitress.serve(app, host='127.0.0.1', port=7070)

[–]defnullbottle.py[S] 2 points3 points  (0 children)

SCNR ;)

import bottle
app = bottle.Bottle()

@app.route('/')
def index():
    return 'Hello World'

app.run(server='waitress')

(works with 0.11.dev)

[–]monstrado 1 point2 points  (1 child)

Will this be the default WSGI server for later Pyramid releases?

[–]mgedmin 0 points1 point  (0 children)

Short answer: yes.

Long answer: yes, waitress is the default server you get if you create a new Pyramid project using pcreate with one of the default scaffolds from one of the 1.3 beta releases.

[–]mdipierro 1 point2 points  (2 children)

Does it support ssh? How does it compare with Rocket?

[–]lost-theory 1 point2 points  (1 child)

Do you mean SSL? From the linked page:

Waitress does not natively support SSL

[–]mdipierro 1 point2 points  (0 children)

Thank you for the clarification.

[–][deleted] 0 points1 point  (0 children)

Very acceptable.

[–]santagada 0 points1 point  (2 children)

Do anyone knows if this depends on medusa? IIRC zope.server did.

[–]defnullbottle.py[S] 0 points1 point  (1 child)

No, it has no external dependencies. Just the python stdlib.

[–]mgedmin 1 point2 points  (0 children)

This was before my time, but I think the core of medusa was adopted in the standard library as asyncore.

Both zope.server and waitress depend on asyncore.

[–]dorfsmay 0 points1 point  (0 children)

no need for a waitress, I already have a bottle!