Metadata-Version: 1.1
Name: klein
Version: 0.2.2
Summary: werkzeug + twisted.web
Home-page: https://github.com/twisted/klein
Author: David Reid
Author-email: dreid@dreid.org
License: MIT
Description: Klein
        =====
        
        .. image:: https://travis-ci.org/twisted/klein.png?branch=master
            :target: http://travis-ci.org/twisted/klein
            :alt: Build Status
        
        Klein is a micro-framework for developing production ready web services with
        python.  It is 'micro' in that it has an incredibly small API similar to bottle
        and flask.  It is not 'micro' in that it depends on things outside the standard
        library.  This is primarily because it is built on widely used and well tested
        components like werkzeug and Twisted.
        
        A Klein bottle is an example of a non-orientable surface, and a glass Klein
        bottle looks like a twisted bottle or twisted flask. This, of course, made it
        too good of a pun to pass up.
        
        Examples
        --------
        
        Here are some basic klein handler functions that return some strings.
        
        .. code-block:: python
        
            from klein import run, route
        
            @route('/')
            def home(request):
                return 'Hello, world!'
        
            run("localhost", 8080)
        
        
        Static files
        ~~~~~~~~~~~~
        
        Helpfully you can also return a ``twisted.web.resource.IResource`` such as
        ``static.File``.  If the ``branch=True`` is passed to ``route`` the
        returned ``IResource`` will also be allowed to handle all children path
        segments.  So ``http://localhost:8080/static/img.gif`` should return an
        image and ``http://localhost:8080/static/`` should return a directory
        listing.
        
        .. code-block:: python
        
            from twisted.web.static import File
            from klein import run, route
        
            @route('/static/', branch=True)
            def static(request):
                return File("./static")
        
            @route('/')
            def home(request):
                return '<img src="/static/img.gif">'
        
            run("localhost", 8080)
        
        
        Templates
        ~~~~~~~~~
        
        You can also make easy use of ``twisted.web.templates`` by returning anything
        that implements ``twisted.web.template.IRenderable`` such as
        ``twisted.web.template.Element`` in which case the template will be rendered
        and the result will be sent as the response body.
        
        .. code-block:: python
        
            from twisted.web.template import Element, XMLString, renderer
            from klein import run, route
        
            class HelloElement(Element):
                loader = XMLString((
                    '<h1 '
                    'xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1"'
                    '>Hello, <span t:render="name"></span>!</h1>'))
        
                def __init__(self, name):
                    self._name = name
        
                @renderer
                def name(self, request, tag):
                    return self._name
        
        
            @route('/hello/<string:name>')
            def home(request, name='world'):
                return HelloElement(name)
        
            run("localhost", 8080)
        
        
        Deferreds
        ~~~~~~~~~
        
        And of course, this is twisted.  So there is a wealth of APIs that return a
        ``twisted.internet.defer.Deferred``.  A ``Deferred`` may also be returned from
        handler functions and their result will be used as the response body.
        
        Here is a simple Google proxy.
        
        .. code-block:: python
        
            from twisted.web.client import getPage
            from klein import run, route
        
            @route('/')
            def google(request):
                return getPage('https://www.google.com' + request.uri)
        
        
            run("localhost", 8080)
        
        
        twistd
        ~~~~~~
        
        Another very important integration point with Twisted is the ``twistd``
        application runner.  It provides rich logging support, daemonization, reactor
        selection, profiler integration, and many more incredibly useful features.
        
        To provide access to these features (and others like HTTPS) klein provides the
        ``resource`` function which returns a valid ``twisted.web.resource.IResource``
        for your application.
        
        Here is our "Hello, World!" application again in a form that can be launched
        by ``twistd``.
        
        .. code-block:: python
        
            from klein import resource, route
        
            @route('/')
            def hello(request):
                return "Hello, world!"
        
        
        To run the above application we can save it as ``helloworld.py`` and use the
        ``twistd web`` plugin.
        
        ::
        
            twistd -n web --class=helloworld.resource
        
        
        Handling POST
        ~~~~~~~~~~~~~
        
        The ``route`` decorator supports a ``methods`` keyword which is the list of
        HTTP methods as strings.  For example ``methods=['POST']`` will cause the
        handler to be invoked when an ``POST`` request is received.  If a handler
        can support multiple methods the current method can be distinguished with
        ``request.method``.
        
        Here is our ``"Hello, world!"`` example extended to support setting the
        name we are saying Hello to via a ``POST`` request with a ``name``
        argument.
        
        This also demonstrates the use of the redirect method of the request to
        redirect back to ``'/'`` after handling the ``POST``.
        
        The most specific handler should be defined first.  So the ``POST`` handler
        must be defined before the handler with no ``methods``.
        
        .. code-block:: python
        
            from twisted.internet.defer import succeed
            from klein import run, route
        
            name='world'
        
            @route('/', methods=['POST'])
            def setname(request):
                global name
                name = request.args.get('name', ['world'])[0]
                request.redirect('/')
                return succeed(None)
        
            @route('/')
            def hello(request):
                return "Hello, {0}!".format(name)
        
            run("localhost", 8080)
        
        
        The following curl command can be used to test this behaviour::
        
            curl -v -L -d name='bob' http://localhost:8080/
        
        
        Non-global state
        ~~~~~~~~~~~~~~~~
        
        For obvious reasons it may be desirable for your application to have some
        non-global state that is used by the your route handlers.
        
        Below we have created a simple ``ItemStore`` class that has an instance of
        ``Klein`` as a class variable ``app``.  We can now use ``@app.route`` to
        decorate the methods of the class.
        
        
        .. code-block:: python
        
            import json
        
            from klein import Klein
        
        
            class ItemStore(object):
                app = Klein()
        
                def __init__(self):
                    self._items = {}
        
                @app.route('/')
                def items(self, request):
                    request.setHeader('Content-Type', 'application/json')
                    return json.dumps(self._items)
        
                @app.route('/<string:name>', methods=['PUT'])
                def save_item(self, request, name):
                    request.setHeader('Content-Type', 'application/json')
                    body = json.loads(request.content.read())
                    self._items[name] = body
                    return json.dumps({'success': True})
        
                @app.route('/<string:name>', methods=['GET'])
                def get_item(self, request, name):
                    request.setHeader('Content-Type', 'application/json')
                    return json.dumps(self._items.get(name))
        
        
            if __name__ == '__main__':
                store = ItemStore()
                store.app.run('localhost', 8080)
        
Keywords: twisted flask werkzeug web
Platform: UNKNOWN
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Software Development :: Libraries :: Python Modules
