Metadata-Version: 1.1
Name: falcon
Version: 0.1.5
Summary: A supersonic micro-framework for building cloud APIs.
Home-page: http://falconframework.org
Author: Kurt Griffiths
Author-email: mail@kgriffs.com
License: Apache 2.0
Description: Falcon |Build Status| |Coverage Status|
        =======================================
        
        |Runner Emoji| Come hang out with us in **#falconframework** on freenode.
        
        Falcon is a `high-performance Python
        framework <http://falconframework.org/index.html>`__ for building cloud
        APIs. It tries to do as little as possible while remaining `highly
        effective <http://falconframework.org/index.html#Benefits>`__.
        
            Perfection is finally attained not when there is no longer anything
            to add, but when there is no longer anything to take away.
        
            *- Antoine de Saint-Exupéry*
        
        Design Goals
        ~~~~~~~~~~~~
        
        **Fast.** Cloud APIs need to turn around requests quickly, and make
        efficient use of hardware. This is particularly important when serving
        many concurrent requests. Falcon processes requests `several times
        faster <http://falconframework.org/#Metrics>`__ than other popular web
        frameworks.
        
        **Light.** Only the essentials are included, with *six* being the only
        dependency outside the standard library. We work to keep the code lean,
        making Falcon easier to test, optimize, and deploy.
        
        **Flexible.** Falcon can be deployed in a variety of ways, depending on
        your needs. The framework speaks WSGI, and works great with `Python 2.6
        and 2.7, PyPy, and Python 3.3 <hbttps://travis-ci.org/racker/falcon>`__.
        There's no tight coupling with any async framework, leaving you free to
        mix-and-match what you need.
        
        Features
        ~~~~~~~~
        
        -  Intuitive routing via URI templates and resource classes
        -  Easy access to headers and bodies through request and response
           classes
        -  Idiomatic HTTP error responses via a handy exception base class
        -  DRY request processing using global, resource, and method hooks
        -  Snappy unit testing through WSGI helpers and mocks
        -  20% speed boost when Cython is available
        -  Python 2.6, Python 2.7, PyPy and Python 3.3 support
        -  Speed, speed, and more speed!
        
        Install
        ~~~~~~~
        
        .. code:: bash
        
            $ pip install cython falcon
        
        Test
        ~~~~
        
        .. code:: bash
        
            $ pip install nose && nosetests
        
        To test across all supported Python versions:
        
        .. code:: bash
        
            $ pip install tox && tox
        
        Usage
        ~~~~~
        
        Read the source, Luke!
        
        Docstrings can be found throughout the Falcon code base for your
        learning pleasure. You can also ask questions in **#falconframework** on
        freenode. We are planning on having real docs eventually; if you need
        them right away, consider sending a pull request. ;)
        
        Here is a simple example showing how to create a Falcon-based API.
        
        .. code:: python
        
            class ThingsResource:
                def on_get(self, req, resp):
                    """Handles GET requests"""
                    resp.status = falcon.HTTP_200
                    resp.body = 'Hello world!'
        
            # falcon.API instances are callable WSGI apps
            wsgi_app = api = falcon.API()
        
            # Resources are represented by long-lived class instances
            things = ThingsResource()
        
            # things will handle all requests to the '/things' URL path
            api.add_route('/things', things)
        
        Here is a more involved example, demonstrating getting headers and query
        parameters, handling errors, and reading/writing message bodies.
        
        .. code:: python
        
        
            import json
            import logging
        
            import falcon
        
        
            class StorageEngine:
                pass
        
        
            class StorageError(Exception):
                pass
        
        
            def token_is_valid(token, user_id):
                return True  # Suuuuuure it's valid...
        
        
            def auth(req, resp, params):
                # Alternatively, do this in middleware
                token = req.get_header('X-Auth-Token')
        
                if token is None:
                    raise falcon.HTTPUnauthorized('Auth token required',
                                                  'Please provide an auth token '
                                                  'as part of the request',
                                                  'http://docs.example.com/auth')
        
                if not token_is_valid(token, params['user_id']):
                    raise falcon.HTTPUnauthorized('Authentication required',
                                                  'The provided auth token is '
                                                  'not valid. Please request a '
                                                  'new token and try again.',
                                                  'http://docs.example.com/auth')
        
        
            def check_media_type(req, resp, params):
                if not req.client_accepts_json():
                    raise falcon.HTTPUnsupportedMediaType(
                        'Media Type not Supported',
                        'This API only supports the JSON media type.',
                        'http://docs.examples.com/api/json')
        
        
            class ThingsResource:
        
                def __init__(self, db):
                    self.db = db
                    self.logger = logging.getLogger('thingsapi.' + __name__)
        
                def on_get(self, req, resp, user_id):
                    marker = req.get_param('marker') or ''
                    limit = req.get_param_as_int('limit') or 50
        
                    try:
                        result = self.db.get_things(marker, limit)
                    except Exception as ex:
                        self.logger.error(ex)
        
                        description = ('Aliens have attacked our base! We will '
                                       'be back as soon as we fight them off. '
                                       'We appreciate your patience.')
        
                        raise falcon.HTTPServiceUnavailable('Service Outage', description)
        
                    resp.set_header('X-Powered-By', 'Donuts')
                    resp.status = falcon.HTTP_200
                    resp.body = json.dumps(result)
        
                def on_post(self, req, resp, user_id):
                    try:
                        raw_json = req.stream.read()
                    except Exception:
                        raise falcon.HTTPError(falcon.HTTP_748,
                                               'Read Error',
                                               'Could not read the request body. Must be '
                                               'them ponies again.')
        
                    try:
                        thing = json.loads(raw_json, 'utf-8')
                    except ValueError:
                        raise falcon.HTTPError(falcon.HTTP_753,
                                               'Malformed JSON',
                                               'Could not decode the request body. The '
                                               'JSON was incorrect.')
        
                    try:
                        proper_thing = self.db.add_thing(thing)
        
                    except StorageError:
                        raise falcon.HTTPError(falcon.HTTP_725,
                                               'Database Error',
                                               "Sorry, couldn't write your thing to the "
                                               'database. It worked on my machine.')
        
                    resp.status = falcon.HTTP_201
                    resp.location = '/%s/things/%s' % (user_id, proper_thing.id)
        
            wsgi_app = api = falcon.API(before=[auth, check_media_type])
        
            db = StorageEngine()
            things = ThingsResource(db)
            api.add_route('/{user_id}/things', things)
        
        Contributing
        ~~~~~~~~~~~~
        
        Kurt Griffiths (kgriffs) is the creator and current maintainer of the
        Falcon framework. Pull requests are always welcome.
        
        Before submitting a pull request, please ensure you have added/updated
        the appropriate tests (and that all existing tests still pass with your
        changes), and that your coding style follows PEP 8 and doesn't cause
        pyflakes to complain.
        
        Commit messages should be formatted using `AngularJS
        conventions <http://goo.gl/QpbS7>`__ (one-liners are OK for now but body
        and footer may be required as the project matures).
        
        Comments follow `Google's style
        guide <http://google-styleguide.googlecode.com/svn/trunk/pyguide.html#Comments>`__.
        
        Legal
        ~~~~~
        
        Copyright 2013 by Rackspace Hosting, Inc.
        
        Falcon image courtesy of `John
        O'Neill <https://commons.wikimedia.org/wiki/File:Brown-Falcon,-Vic,-3.1.2008.jpg>`__.
        
        | Licensed under the Apache License, Version 2.0 (the "License");
        | you may not use this file except in compliance with the License.
        | You may obtain a copy of the License at
        
        ::
        
            http://www.apache.org/licenses/LICENSE-2.0
        
        | Unless required by applicable law or agreed to in writing, software
        | distributed under the License is distributed on an "AS IS" BASIS,
        | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
        implied.
        | See the License for the specific language governing permissions and
        | limitations under the License.
        
        .. |Build Status| image:: https://travis-ci.org/racker/falcon.png
           :target: https://travis-ci.org/racker/falcon
        .. |Coverage Status| image:: https://coveralls.io/repos/racker/falcon/badge.png?branch=master
           :target: https://coveralls.io/r/racker/falcon
        .. |Runner Emoji| image:: https://a248.e.akamai.net/assets.github.com/images/icons/emoji/runner.png
           :height: 20
           :width: 20
           :align: middle
        
Keywords: wsgi web api framework rest http cloud
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Web Environment
Classifier: Natural Language :: English
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: MacOS :: MacOS X
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX
Classifier: Topic :: Internet :: WWW/HTTP :: WSGI
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3.3
